From 10441f7a03fa956b9e4772a073a05a96487983e2 Mon Sep 17 00:00:00 2001 From: MMS Date: Tue, 27 Feb 2024 17:45:11 -0500 Subject: [PATCH] 7.3.4 updated QV, QK for MSP430 Cmake support --- 3rd_party | 2 +- CMakeLists.txt | 207 ++++++++++++++++++++++++++++++ cmakeSupport.md | 171 ++++++++++++++++++++++++ examples | 2 +- ports/CMakeLists.txt | 16 +++ ports/arm-cm/CMakeLists.txt | 19 +++ ports/arm-cr/CMakeLists.txt | 14 ++ ports/embos/CMakeLists.txt | 3 + ports/freertos/CMakeLists.txt | 3 + ports/msp430/CMakeLists.txt | 10 ++ ports/pic32/CMakeLists.txt | 15 +++ ports/posix-qutest/CMakeLists.txt | 5 + ports/posix-qv/CMakeLists.txt | 6 + ports/posix/CMakeLists.txt | 6 + ports/qep-only/CMakeLists.txt | 2 + ports/threadx/CMakeLists.txt | 3 + ports/uc-os2/CMakeLists.txt | 3 + ports/win32-qutest/CMakeLists.txt | 5 + ports/win32-qv/CMakeLists.txt | 7 + ports/win32/CMakeLists.txt | 7 + qpcpp.md5 | 22 +++- qpcpp.qm | 70 +++++----- qpcpp_sdk_init.cmake | 49 +++++++ src/CMakeLists.txt | 7 + src/qf/CMakeLists.txt | 25 ++++ src/qk/CMakeLists.txt | 5 + src/qk/qk.cpp | 64 ++++----- src/qs/CMakeLists.txt | 9 ++ src/qv/CMakeLists.txt | 4 + src/qv/qv.cpp | 6 +- src/qxk/CMakeLists.txt | 7 + 31 files changed, 703 insertions(+), 71 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 cmakeSupport.md create mode 100644 ports/CMakeLists.txt create mode 100644 ports/arm-cm/CMakeLists.txt create mode 100644 ports/arm-cr/CMakeLists.txt create mode 100644 ports/embos/CMakeLists.txt create mode 100644 ports/freertos/CMakeLists.txt create mode 100644 ports/msp430/CMakeLists.txt create mode 100644 ports/pic32/CMakeLists.txt create mode 100644 ports/posix-qutest/CMakeLists.txt create mode 100644 ports/posix-qv/CMakeLists.txt create mode 100644 ports/posix/CMakeLists.txt create mode 100644 ports/qep-only/CMakeLists.txt create mode 100644 ports/threadx/CMakeLists.txt create mode 100644 ports/uc-os2/CMakeLists.txt create mode 100644 ports/win32-qutest/CMakeLists.txt create mode 100644 ports/win32-qv/CMakeLists.txt create mode 100644 ports/win32/CMakeLists.txt create mode 100644 qpcpp_sdk_init.cmake create mode 100644 src/CMakeLists.txt create mode 100644 src/qf/CMakeLists.txt create mode 100644 src/qk/CMakeLists.txt create mode 100644 src/qs/CMakeLists.txt create mode 100644 src/qv/CMakeLists.txt create mode 100644 src/qxk/CMakeLists.txt diff --git a/3rd_party b/3rd_party index ebe4896f..db8b6155 160000 --- a/3rd_party +++ b/3rd_party @@ -1 +1 @@ -Subproject commit ebe4896f82bdb7b883f42f930307d243a4cd43d6 +Subproject commit db8b6155e6931d2c55315dfd55b0e1fac0f96e33 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..c2469e2a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,207 @@ +# use a recent CMake version +cmake_minimum_required(VERSION 3.13 FATAL_ERROR) +cmake_policy(VERSION 3.13) +if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14") + cmake_policy(SET CMP0083 NEW) +endif() + +# QPC SDK project root CMakeLists.txt +set(QPCPP_HOST_PORTS posix win32) +set(QPCPP_RTOS_PORTS embos freertos threadx uc-os2) +set(QPCPP_BAREMETAL_PORTS arm-cm arm-cr msp430 pic32) +set(QPCPP_MISC_PORTS qep-only) +foreach(p in HOST RTOS BAREMETAL MISC) + list(APPEND QPCPP_ALL_PORTS ${QPCPP_${p}_PORTS}) +endforeach() + +# project configuration +if(DEFINED ENV{QPCPP_CFG_KERNEL} AND (NOT QPCPP_CFG_KERNEL)) + set(QPCPP_CFG_KERNEL $ENV{QPCPP_CFG_KERNEL}) + message("Using QPCPP_CFG_KERNEL from environment ('${QPCPP_CFG_KERNEL}')") +elseif(NOT QPCPP_CFG_KERNEL) + set(QPCPP_CFG_KERNEL qv) + message("Set QPCPP_CFG_KERNEL to ('${QPCPP_CFG_KERNEL}') since not specified") +endif() + +if(DEFINED ENV{QPCPP_CFG_PORT} AND (NOT QPCPP_CFG_PORT)) + set(QPCPP_CFG_PORT $ENV{QPCPP_CFG_PORT}) + message("Using QPCPP_CFG_PORT from environment ('${QPCPP_CFG_PORT}')") +endif() + +if(NOT QPCPP_CFG_GUI) + set(QPCPP_CFG_GUI OFF CACHE BOOL "enable GUI support for matching ports (e.g. win32 or posix & GTK)") + message("Set QPCPP_CFG_GUI to ('${QPCPP_CFG_GUI}') since not specified") +endif() + +if(NOT QPCPP_CFG_UNIT_TEST) + set(QPCPP_CFG_UNIT_TEST OFF CACHE BOOL "enable detailled unit testing support") + message("Set QPCPP_CFG_UNIT_TEST to ('${QPCPP_CFG_UNIT_TEST}') since not specified") +endif() + +if(NOT QPCPP_CFG_DEBUG) + set(QPCPP_CFG_DEBUG ON CACHE BOOL "enable debug sessions") + message("Set QPCPP_CFG_DEBUG to ('${QPCPP_CFG_DEBUG}') since not specified") +endif() + +if(NOT QPCPP_CFG_VERBOSE) + set(QPCPP_CFG_VERBOSE OFF CACHE BOOL "enable verbose build output") + message("Set QPCPP_CFG_VERBOSE to ('${QPCPP_CFG_VERBOSE}') since not specified") +endif() + +project( + qpcpp + VERSION "1.0.0" + DESCRIPTION "QPCPP library" + LANGUAGES C ASM +) + +# add support for SPY configuration if not set via CMAKE_TOOLCHAIN_FILE +if(NOT CMAKE_C_FLAGS_SPY) + foreach(LANG IN ITEMS C CXX ASM) + set(CMAKE_${LANG}_FLAGS_SPY "${CMAKE_${LANG}_FLAGS_DEBUG} -DQ_SPY") + endforeach() +endif() + +# check target port plausibility +if(NOT QPCPP_CFG_PORT) + message(WARNING "No PORT is configured! Falling back to target system '${CMAKE_SYSTEM_NAME}/${CMAKE_SYSTEM_PROCESSOR}'.") + if(CMAKE_SYSTEM_NAME) + string(TOLOWER ${CMAKE_SYSTEM_NAME} sysName) + else() + set(sysName generic) + endif() + if(CMAKE_SYSTEM_PROCESSOR) + string(TOLOWER ${CMAKE_SYSTEM_PROCESSOR} sysProc) + else() + set(sysproc none) + endif() + if((sysName STREQUAL generic) AND (sysProc STREQUAL arm)) + set(PORT arm-cm) + elseif(WIN32) + set(PORT win32) + elseif(UNIX) + set(PORT posix) + else() + message(FATAL_ERROR No valid target port could be found. Aborting!) + endif() +else() + string(TOLOWER ${QPCPP_CFG_PORT} PORT) +endif() + +if(NOT (${PORT} IN_LIST QPCPP_ALL_PORTS)) + if(DEFINED PORT) + message(FATAL_ERROR "Target port '${PORT}' not found!") + else() + message(FATAL_ERROR "Target port not defined!") + endif() +endif() + +set(QPCPP_CFG_PORT ${PORT} CACHE STRING "The QPC target port for the system platform") +message(STATUS "Set QPCPP_CFG_PORT to ('${QPCPP_CFG_PORT}')") + +# check/set Qx real time kernel +string(TOLOWER ${QPCPP_CFG_KERNEL} KERNEL) +list (APPEND kernList qv qk qxk) +if(NOT (${KERNEL} IN_LIST kernList)) + if(QPCPP_CFG_KERNEL) + message(WARNING "Unknown kernel '${QPCPP_CFG_KERNEL}' specified! + Falling back to QV kernel") + endif() + set(QPCPP_CFG_KERNEL QV CACHE STRING "set the desired micro kernel for your project. (default: QV)" FORCE) + set(KERNEL qv) +endif() +unset(kernList) + +add_library(qpcpp STATIC "") + +# set position independent code compile/link parameters +if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14") + include(CheckPIESupported) + check_pie_supported() +endif() +set_property(TARGET qpcpp PROPERTY POSITION_INDEPENDENT_CODE FALSE) + +# set up the include directory search path +target_include_directories(qpcpp PUBLIC + src + include +) + +# add subdirectories with source/header files +add_subdirectory(src) +add_subdirectory(ports) + +# set general defines +target_compile_definitions(qpcpp PRIVATE + $<$:${ADD_DEBUG_CODE}> + $<$:QWIN_GUI> + # $<$:Q_SPY> # set via toolchain file + $<$,$>:Q_UTEST> +) + +target_compile_options(qpcpp PRIVATE + $<$:-v> +) + +target_link_options(qpcpp PRIVATE + $<$:-v> +) + +target_link_libraries(qpcpp PUBLIC + $<$,$>:ws2_32> +) + +# print configuration +message(STATUS +"======================================================== + Configured project ${PROJECT_NAME} for ${PORT} + PROJECT_NAME = ${QPCPP_PROJECT} + TARGET = ${TARGET} + IMAGE = ${IMAGE} + SW_VERSION = ${SW_VERSION} + PORT = ${PORT} + + QPCPP_CFG_GUI = ${QPCPP_CFG_GUI} + QPCPP_CFG_UNIT_TEST = ${QPCPP_CFG_UNIT_TEST} + QPCPP_CFG_KERNEL = ${QPCPP_CFG_KERNEL} + QPCPP_CFG_DEBUG = ${QPCPP_CFG_DEBUG} + CMAKE_C_CPPCHECK = ${CMAKE_C_CPPCHECK} +-- ======================================================== +" +) + +if(QPCPP_CFG_VERBOSE) + message(STATUS +"======================================================== + System information: + CMAKE_VERSION = ${CMAKE_VERSION} + CMAKE_CROSSCOMPILING = ${CMAKE_CROSSCOMPILING} + CMAKE_HOST_SYSTEM = ${CMAKE_HOST_SYSTEM} + CMAKE_HOST_SYSTEM_NAME = ${CMAKE_HOST_SYSTEM_NAME} + CMAKE_HOST_LINUX = ${CMAKE_HOST_LINUX} + CMAKE_HOST_UNIX = ${CMAKE_HOST_UNIX} + CMAKE_HOST_WIN32 = ${CMAKE_HOST_WIN32} + CMAKE_SYSTEM = ${CMAKE_SYSTEM} + CMAKE_SYSTEM_NAME = ${CMAKE_SYSTEM_NAME} + CMAKE_SYSTEM_PROCESSOR = ${CMAKE_SYSTEM_PROCESSOR} + WIN32 = ${WIN32} + MSYS = ${MSYS} + MINGW = ${MINGW} + UNIX = ${UNIX} + LINUX = ${LINUX} + + CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE} + CMAKE_C_COMPILER = ${CMAKE_C_COMPILER} + CMAKE_C_COMPILER_ID = ${CMAKE_C_COMPILER_ID} + CMAKE_C_COMPILER_VERSION = ${CMAKE_C_COMPILER_VERSION} + CMAKE_C_FLAGS = ${CMAKE_C_FLAGS} + + CMAKE_CXX_COMPILER = ${CMAKE_CXX_COMPILER} + CMAKE_CXX_FLAGS = ${CMAKE_CXX_FLAGS} + + CMAKE_ASM_COMPILER = ${CMAKE_ASM_COMPILER} + CMAKE_ASM_FLAGS = ${CMAKE_ASM_FLAGS} +-- ======================================================== +" + ) +endif() diff --git a/cmakeSupport.md b/cmakeSupport.md new file mode 100644 index 00000000..2137b5de --- /dev/null +++ b/cmakeSupport.md @@ -0,0 +1,171 @@ +# cmake Support in QP/C++ + +This branch adds comprehensive cmake support to QP/C++ + +## Quick Start + +create your project with a root `CMakeLists.txt` file, following this blueprint. +1. copy [qpcpp_sdk_import.cmake](https://github.com/QuantumLeaps/3rd_party/cmake/qpcpp_sdk_import.cmake) into your project. Make sure, it can be found by `cmake` as an included script +2. Setup your 1st `CMakeLists.txt`: +``` +# use a recent CMake version +cmake_minimum_required(VERSION 3.23 FATAL_ERROR) +cmake_policy(VERSION 3.23...3.28) +cmake_policy(SET CMP0083 NEW) +cmake_policy(SET CMP0105 NEW) +cmake_policy(SET CMP0116 NEW) +cmake_policy(SET CMP0128 NEW) + +# include general project config & import qpcpp +set(QPCPP_SDK_PATH ${CMAKE_SOURCE_DIR}/Source/qpcpp-sdk) +# set(QPCPP_FETCH_FROM_GIT ON) +# set(QPCPP_FETCH_FROM_GIT_PATH ${CMAKE_SOURCE_DIR}/Source/qpcpp-sdk) +include(qpcpp_sdk_import) + +# default image/project name is trafficlight +# Give a special name via -DIMAGE= +# the main project +project(myProject + VERSION "1.0.0"" + DESCRIPTION "my 1st qpcpp project" + LANGUAGES C CXX) + +# the project target(s) +add_executable(qpcppApp main.cpp qpcppApp.cpp) + +include(${QPCPP_SDK_PATH}/qpcpp_sdk_init.cmake) +set(QPCPP_PROJECT qpcPrj) +set(QPCPP_CFG_KERNEL QV) +set(QPCPP_CFG_GUI TRUE) +set(QPCPP_CFG_PORT win32) +qpcpp_sdk_init() + +target_link_libraries(qpcppApp PRIVATE qpcpp) +``` +3. configure your project with + `cmake -B Build .` +4. build + `cmake --build Build` + +## Usage +### `qpcpp_sdk_import.cmake` +This file prepares your project for integrating qpcpp. +Before adding this file to your project with `include(qpcpp_sdk_import)` make sure to set `CMAKE_MODULE_PATH` accordingly. + +To configure the integration of qpcpp you can provide information either with cmake variables or via environment variables of the very same names. + +* Mandatory variables (only one of the two must be set) + - `QPCPP_SDK_PATH` - set this variable to point to the full path of an already installed qpcpp instance. + - `QPCPP_FETCH_FROM_GIT` - set this variable to ON or TRUE, if no pre-installed qpcpp directory exists. QPCPP + will then be downloaded from git automatically. The download URL is pre-defined in `qpcpp_sdk_import.cmake` +* Optional variables + - `QPCPP_FETCH_FROM_GIT_PATH` - set this variable to download qpcpp from git (`QPCPP_FETCH_FROM_GIT`) into the + specified directory + - `QPCPP_URL`- set this variable to the URL to download qpcpp from. This must point to a remote git + repository + +### `qpcpp_sdk_init.cmake` +This file is situated in the root directory of qpcpp. It performs a pre-initialization of the qpcpp package and provides the function `qpcpp_sdk_init`. Call this function from your project's `CMakeLists.txt` file to perform the final integration of qpcpp into your project. To configure qpcpp to your projects requirements set these variables before calling `qpcpp_sdk_init()` + +* `QPCPP_CFG_KERNEL` - STRING: set this variable to the QPCPP kernel for your project. Valid values are QV, QK or QXK. Default: QV +* `QPCPP_CFG_PORT` - STRING: set this variable to reflect the target platform of your project. Default: host system. Valid values are: + + `arm-cm`, `arm-cr` - Arm CortexM or CortexR micro controllers. Tested with GNU cross compiler environments. + + `freertos`, `esp-idf`, `emb-os`, `threadx`, `uc-os2` - real time OS + + `msp430`, `pic32` - TI MSP430 or PIC32 micro controllers + + `riscv`- Risc V µC + + `qep-only`, `qube` - test environments + + `win32`, `posix` - host environments MS Windows, Linux (Posix compatible systems) +* `QPCPP-CFG-GUI` - BOOL: set this Boolean variable to ON/TRUE, if GUI support (win32) shall be compiled in. Default: OFF +* `QPCPP_CFG_UNIT_TEST` - BOOL: set this to ON/TRUE to support qutest, if build configuration `Spy` is active. Default: OFF +* `QPCPP_CFG_VERBOSE` - BOOL: set this to enable more verbosity in message output. Default: OFF + +### General usage hints +1. Set `QPCPP_SDK_PATH` or `QPCPP_FETCH_FROM_GIT` either in your `CMakeLists.txt` file or as an environment variable. +2. Optionally set the configuration variable(s) +3. Include `qpcpp_sdk_import` __before__ defining the cmake `project()` +4. Define the project +5. Define the cmake target (executable or library) +6. Include `qpcpp_sdk_init.cmake` +7. configure the qpc SDK +8. call `qpcpp_sdk_init` +9. Add the qpcpp library to your cmake target: + `target_link_libraries(> PRIVATE qpcpp)` + +Generate and build your cmake project + +## Generation and building hints +* Generate with configuration support + The recommendation is to use a multi-configuration cmake generator like `"Ninja Multi-Config"` and set the cmake variable `CMAKE_CONFIGURATION_TYPES` to `"Debug;Release;Spy"`. + Then you can build with `cmake --build --config=. +* Use `CMakePresets.json` + Define the build configurations for your projects in a presets definitions file. + Refer to the [CMakePresets.json manual](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html) for further details. + Then you generate with `cmake --preset= .` from your project directory. The build then can be started with `cmake --build --preset=`. + +### QPC configurations support +Many `qpcpp` examples provide 3 build configurations: +* `Debug` - build with debug support and debug symbols. Most optimizations are turned off +* `Release` - build without debug support. Activate optimizations instead +* `Spy` - build like `Debug`. Additionally activate support for `QSpy`. + +These configurations are also supported by qpcpp with cmake. Different possibilities exist to activate those. + +### `qp_config.h` support +Some build configurations require the inclusion of `qp_config.h`. To achieve this, the QPC macro `QP_CONFIG` should be set, when compiling the +`qpcpp` source files. The include search paths also needs to be set accordingly in order for the preprocessor to be able to find the correct include +file. + +As `qp_config.hpp` is a project related file, which - in most cases - resides outside the `qpcpp` source code tree, the decision is to handle the +above mentioned topic within the root project's `CMakeLists.txt` file instead of integrating this topic into a rather complicated configuration +of `qpcpp` itself. + +An example can be found in the [cmake dpp example](https://github.com/QuantumLeaps/qpcpp-examples/tree/main/posix-win32-cmake/dpp). Have a look into +the example's [CMakeLists.txt](https://github.com/QuantumLeaps/qpcpp-examples/blob/main/posix-win32-cmake/dpp/CMakeLists.txt). + +You will find the reference to the `qpc` library, followed by the project's specific setup for `qp_config.h` like this: +``` +# set up qpcpp library +target_link_libraries(dpp + PRIVATE + qpcpp +) +# should a 'qp_config.h' configuration file be used and is it available +# edit the HINTS in the 'find_file()' call according to your project settings +if(USE_QP_CONFIG) + find_file(QP_CONFIG qp_config.h HINTS ${CMAKE_CURRENT_SOURCE_DIR}) # try to identify 'qp_config.h' + if(QP_CONFIG) # found 'qp_config.h' + cmake_path(GET QP_CONFIG PARENT_PATH QP_CONFIG_DIR) # extract the path from the FQFN + target_compile_definitions(qpcpp # add -DQP_CONFIG to the qpcpp build + PUBLIC + QP_CONFIG + ) + target_include_directories(qpcpp # add the path to 'qp_config.h' to the list of include paths for qpcpp + PUBLIC + ${QP_CONFIG_DIR} + ) + else() # 'qp_config.h' requested but not find - try to configure and build anyways + message(WARNING "File 'qp_config.h' not found!") + endif() +endif() +``` + +### Multi configuration generators +The most easy way to make use of the different configurations is to use a multi config generator like `Ninja Multi-Config` or `MS Visual Studio`. +Using one of such generators enables to generate the build system using `cmake` and afterwards simply selecting the desired build configuration like +`cmake --build --config=` + +To support this, the `cmake` variables +* `CMAKE_C_FLAGS_` +* `CMAKE_CXX_FLAGS_` +* `CMAKE_ASM_FLAGS_` +* `CMAKE_EXE_LINKER_FLAGS_` + +have to be set for all configurations. The desired place to hold these settings is the `toolchain` file of the compilation toolchain in use. +If no `toolchain` file is used, the `cmake` default configuration provides settings for the `Debug` and `Release` configuration fot the host +compiler setup. The `Spy` configuration will be added by the qpcpp `CMakeLists.txt` file. + +### Single configuration generators +For single configuration generators like `Makefile` or `Ninja`, specific build configurations need to configured. One for each configuration. +When generationg the build system, set the `cmake` variable `CMAKE_BUILD_TYPE` to the desired configuration (`Debug`, `Release` or `Spy`). + +Everything said above concerning the `CMAKE__FLAGS_` variables, also applies here. diff --git a/examples b/examples index c89346fe..a4becf08 160000 --- a/examples +++ b/examples @@ -1 +1 @@ -Subproject commit c89346fe6c765ac03d6d55d7ee0aa9c082bfa046 +Subproject commit a4becf08ed700750fce0bfea22a8968349330e55 diff --git a/ports/CMakeLists.txt b/ports/CMakeLists.txt new file mode 100644 index 00000000..66ff6be7 --- /dev/null +++ b/ports/CMakeLists.txt @@ -0,0 +1,16 @@ +# CMake the qpcpp libraries for different targets +set(PORT_DIR ${PORT}) +if((PORT STREQUAL win32) OR (PORT STREQUAL posix)) + if(QPCPP_CFG_UNIT_TEST) + set(PORT_DIR ${PORT_DIR}-qutest) + elseif(KERNEL STREQUAL qv) + set(PORT_DIR ${PORT_DIR}-qv) + endif() +endif() +if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${PORT_DIR}) + message(STATUS "Found port dir - './${PORT_DIR}' for port ${PORT}, KERNEL ${KERNEL}") +else() + message(FATAL_ERROR "Target port dir '${CMAKE_CURRENT_SOURCE_DIR}/${PORT_DIR}' not found!") +endif() + +add_subdirectory(${PORT_DIR}) diff --git a/ports/arm-cm/CMakeLists.txt b/ports/arm-cm/CMakeLists.txt new file mode 100644 index 00000000..eeaf33eb --- /dev/null +++ b/ports/arm-cm/CMakeLists.txt @@ -0,0 +1,19 @@ +# ports/arm-cm +string(TOLOWER ${CMAKE_C_COMPILER_ID} _compiler_) +list (APPEND compList gnu iar armclang) +if(NOT (${_compiler_} IN_LIST compList)) + message(WARNING "no support for compiler '${_compiler_}'. Falling back to GNU. Just give it a try :)") + set(_compiler_ gnu) +endif() +unset(compList) + +set(qx_port_cpp ${KERNEL}_port.cpp) + +if(QPCPP_CFG_UNIT_TEST) + target_include_directories(qpcpp PUBLIC qutest) +else() + target_include_directories(qpcpp PUBLIC ${KERNEL}/${_compiler_}) +endif() + +target_sources(qpcpp PRIVATE ${KERNEL}/${_compiler_}/${qx_port_cpp}) + diff --git a/ports/arm-cr/CMakeLists.txt b/ports/arm-cr/CMakeLists.txt new file mode 100644 index 00000000..26ad41ec --- /dev/null +++ b/ports/arm-cr/CMakeLists.txt @@ -0,0 +1,14 @@ +# ports/arm-cr +string(TOLOWER ${CMAKE_C_COMPILER_ID} _compiler_) +list (APPEND compList gnu iar ti) +if(NOT (${_compiler_} IN_LIST compList)) + message(WARNING "no support for compiler '${_compiler_}'. Falling back to GNU. Just give it a try :)") + set(_compiler_ gnu) +endif() +unset(compList) + +if(NOT KERNEL MATCHES "q[vk]") + message(WARNING "Kernel ${KERNEL} is not supported! Falling back to QV kernel") + set(KERNEL qv) +endif() +target_include_directories(qpcpp PUBLIC ${KERNEL}/${_compiler_}) diff --git a/ports/embos/CMakeLists.txt b/ports/embos/CMakeLists.txt new file mode 100644 index 00000000..325ff2fa --- /dev/null +++ b/ports/embos/CMakeLists.txt @@ -0,0 +1,3 @@ +# ports/embos +target_include_directories(qpcpp PUBLIC .) +target_sources(qpcpp PRIVATE qf_port.cpp) diff --git a/ports/freertos/CMakeLists.txt b/ports/freertos/CMakeLists.txt new file mode 100644 index 00000000..67eacd76 --- /dev/null +++ b/ports/freertos/CMakeLists.txt @@ -0,0 +1,3 @@ +# ports/freertos +target_include_directories(qpcpp PUBLIC .) +target_sources(qpcpp PRIVATE qf_port.cpp) diff --git a/ports/msp430/CMakeLists.txt b/ports/msp430/CMakeLists.txt new file mode 100644 index 00000000..bc2d3897 --- /dev/null +++ b/ports/msp430/CMakeLists.txt @@ -0,0 +1,10 @@ +# ports/msp430 +if(QPCPP_CFG_UNIT_TEST) + target_include_directories(qpcpp PUBLIC qutest) +else() + if(NOT KERNEL MATCHES "q[vk]") + message(WARNING "Kernel ${KERNEL} is not supported! Falling back to QV kernel") + set(KERNEL qv) + endif() + target_include_directories(qpcpp PUBLIC ${KERNEL}) +endif() diff --git a/ports/pic32/CMakeLists.txt b/ports/pic32/CMakeLists.txt new file mode 100644 index 00000000..22133c2d --- /dev/null +++ b/ports/pic32/CMakeLists.txt @@ -0,0 +1,15 @@ +# ports/pic32 +if(QPCPP_CFG_UNIT_TEST) + target_include_directories(qpcpp PUBLIC qutest/xc32) +else() + if(NOT KERNEL MATCHES "q[vk]") + message(WARNING "Kernel ${KERNEL} is not supported! Falling back to QV kernel") + set(KERNEL qv) + endif() + + set(KERNEL_PORT_CPP ${CMAKE_CURRENT_LIST_DIR}/${KERNEL}/xc32/${KERNEL}_port.cpp) + if(EXISTS ${KERNEL_PORT_CPP}) + target_sources(qpcpp PRIVATE ${KERNEL_PORT_CPP}) + endif() + target_include_directories(qpcpp PUBLIC ${KERNEL}/xc32) +endif() diff --git a/ports/posix-qutest/CMakeLists.txt b/ports/posix-qutest/CMakeLists.txt new file mode 100644 index 00000000..f526975f --- /dev/null +++ b/ports/posix-qutest/CMakeLists.txt @@ -0,0 +1,5 @@ +# ports/posix-qutest +target_include_directories(qpcpp PUBLIC .) +target_sources(qpcpp PRIVATE + qutest_port.cpp +) \ No newline at end of file diff --git a/ports/posix-qv/CMakeLists.txt b/ports/posix-qv/CMakeLists.txt new file mode 100644 index 00000000..242f1d17 --- /dev/null +++ b/ports/posix-qv/CMakeLists.txt @@ -0,0 +1,6 @@ +# ports/posix-qv +target_include_directories(qpcpp PUBLIC .) +target_sources(qpcpp PRIVATE + qf_port.cpp + $<$:${CMAKE_CURRENT_SOURCE_DIR}/qs_port.cpp> +) \ No newline at end of file diff --git a/ports/posix/CMakeLists.txt b/ports/posix/CMakeLists.txt new file mode 100644 index 00000000..2d8f2082 --- /dev/null +++ b/ports/posix/CMakeLists.txt @@ -0,0 +1,6 @@ +# ports/posix +target_include_directories(qpcpp PUBLIC .) +target_sources(qpcpp PRIVATE + qf_port.cpp + $<$:${CMAKE_CURRENT_SOURCE_DIR}/qs_port.cpp> +) \ No newline at end of file diff --git a/ports/qep-only/CMakeLists.txt b/ports/qep-only/CMakeLists.txt new file mode 100644 index 00000000..053d7d97 --- /dev/null +++ b/ports/qep-only/CMakeLists.txt @@ -0,0 +1,2 @@ +# ports/qep-only +target_include_directories(qpcpp PUBLIC .) diff --git a/ports/threadx/CMakeLists.txt b/ports/threadx/CMakeLists.txt new file mode 100644 index 00000000..1ffbce51 --- /dev/null +++ b/ports/threadx/CMakeLists.txt @@ -0,0 +1,3 @@ +# ports/os_xxx +target_include_directories(qpcpp PUBLIC .) +target_sources(qpcpp PRIVATE qf_port.cpp) diff --git a/ports/uc-os2/CMakeLists.txt b/ports/uc-os2/CMakeLists.txt new file mode 100644 index 00000000..ffb2e36b --- /dev/null +++ b/ports/uc-os2/CMakeLists.txt @@ -0,0 +1,3 @@ +# ports/uc-os2 +target_include_directories(qpcpp PUBLIC .) +target_sources(qpcpp PRIVATE qf_port.cpp) diff --git a/ports/win32-qutest/CMakeLists.txt b/ports/win32-qutest/CMakeLists.txt new file mode 100644 index 00000000..e0b6c6b5 --- /dev/null +++ b/ports/win32-qutest/CMakeLists.txt @@ -0,0 +1,5 @@ +# ports/win32-qutest +target_include_directories(qpcpp PUBLIC .) +target_sources(qpcpp PRIVATE + qutest_port.cpp +) \ No newline at end of file diff --git a/ports/win32-qv/CMakeLists.txt b/ports/win32-qv/CMakeLists.txt new file mode 100644 index 00000000..2130970a --- /dev/null +++ b/ports/win32-qv/CMakeLists.txt @@ -0,0 +1,7 @@ +# ports/win32-qv +target_include_directories(qpcpp PUBLIC .) +target_sources(qpcpp PRIVATE + qf_port.cpp + $<$:${CMAKE_CURRENT_SOURCE_DIR}/qwin_gui.c> + $<$:${CMAKE_CURRENT_SOURCE_DIR}/qs_port.cpp> +) diff --git a/ports/win32/CMakeLists.txt b/ports/win32/CMakeLists.txt new file mode 100644 index 00000000..2575ef8e --- /dev/null +++ b/ports/win32/CMakeLists.txt @@ -0,0 +1,7 @@ +# ports/win32 +target_include_directories(qpcpp PUBLIC .) +target_sources(qpcpp PRIVATE + qf_port.cpp + $<$:${CMAKE_CURRENT_SOURCE_DIR}/qwin_gui.c> + $<$:${CMAKE_CURRENT_SOURCE_DIR}/qs_port.cpp> +) diff --git a/qpcpp.md5 b/qpcpp.md5 index 0887c801..655bd5af 100644 --- a/qpcpp.md5 +++ b/qpcpp.md5 @@ -1,4 +1,4 @@ -ddd90780c6b874c0f8d27fe842e6005e *qpcpp.qm +27d2d0d96374af4853a6a31a25ac3ef8 *qpcpp.qm da3f0e1d1bc147b9e5ee801bc1fdd130 *include/qequeue.hpp fe1ff6084ff592ca8d14a6efffec296c *include/qk.hpp ebf2cb455c1471c2248bbde4b90ce634 *include/qmpool.hpp @@ -12,6 +12,7 @@ db4013ceefb33498f5d38e15d0cb9323 *include/qs_pkg.hpp e66cf5dd191fb0e7c1f8660fb477b860 *include/qstamp.hpp d42a19307ba3c0c5b890431767f35b42 *include/qv.hpp c0bc33e3823dde00803a301c4b85637d *include/qxk.hpp +ccc88dc7734a312ee0e33c437db7f3eb *src/qf/CMakeLists.txt 88c84e634597fafced2012faea838750 *src/qf/qep_hsm.cpp becbd953c6da010daddf4907784e9766 *src/qf/qep_msm.cpp 8b5c1ece58069ed5582864fd2dc58167 *src/qf/qf_act.cpp @@ -24,14 +25,18 @@ becbd953c6da010daddf4907784e9766 *src/qf/qep_msm.cpp 46f954811c55e933e016bb36ab22adcd *src/qf/qf_qeq.cpp 816dc7182f4014539f6f5304782ddb7b *src/qf/qf_qmact.cpp c49e1c15e6d6e035668d910c8d13a684 *src/qf/qf_time.cpp -6742057ed6d47ee15f171091a7d44afe *src/qk/qk.cpp +4dc7ca60248f4c13034e6f2481c7663d *src/qk/CMakeLists.txt +5670063d7e71927b7d5c98a6db38c351 *src/qk/qk.cpp +2557d617414f8cbdcbfeaab619d296bb *src/qs/CMakeLists.txt ecdd6f0f0a7dc56d8bb0c769e67b48fc *src/qs/qs.cpp a2ca20b2332d025067645839e4b25711 *src/qs/qs_64bit.cpp 8f6551c7786fdbb106c3d1bc7824c060 *src/qs/qs_fp.cpp 4af89f114491668f7a26af694ff11993 *src/qs/qs_rx.cpp 2655cd10d009075b71a84368fb6bf4d4 *src/qs/qstamp.cpp 180d454ecdbd08f522ff9a9c299de5df *src/qs/qutest.cpp -deac78388761a8e1d4d0e5c51d5b338b *src/qv/qv.cpp +cf2fae9b29aab50c5cd69d7d519cb0db *src/qv/CMakeLists.txt +80b65ecb456e0a8efaaa14f7f30aac81 *src/qv/qv.cpp +3c916b7d6a6ce58963153f51801858df *src/qxk/CMakeLists.txt 9a0b0803b84b7c4cf0fe1e34187371f8 *src/qxk/qxk.cpp efe0395b16911eaff880649a9968d6a3 *src/qxk/qxk_mutex.cpp ce5ff1926bd91dd8683e0232d3e1d471 *src/qxk/qxk_sema.cpp @@ -102,38 +107,47 @@ c40714b55d55e955163ba501bc76486b *ports/pic32/qv/xc32/qp_port.hpp f06c0d53c5c9918f08e99e01e20af046 *ports/pic32/qutest/xc32/qp_port.hpp 8769dc506ab52067b0a374e5765525d3 *ports/pic32/qutest/xc32/qs_port.hpp 77ee959e7ece547ca6d15ba753af987f *ports/config/qp_config.hpp +906dd67f13bf4cdfb83afc1c59c57ed2 *ports/embos/CMakeLists.txt c3bf7454d756ae63ee0b69fb9671478f *ports/embos/qf_port.cpp 0d7461d523df40ff7e33b0be5ae47048 *ports/embos/qp_port.hpp 5f098b1f50529ede0aff7e065d1234ef *ports/embos/qs_port.hpp +bb18f0378bf49ece5551b7631efc3229 *ports/freertos/CMakeLists.txt ce95f7bb92b80a759a69db63a535df80 *ports/freertos/qf_port.cpp 0c444889e3db0ba221db1421d7a48d64 *ports/freertos/qp_port.hpp f1d2ad95d14899edf65a236f1df4cfce *ports/freertos/qs_port.hpp +75e3906b6c068c7b59cf0c9a7a3c7454 *ports/threadx/CMakeLists.txt 79cdcd34a0393f77edee99ceb53709a5 *ports/threadx/qf_port.cpp 50f5bd76fc61e90edb546f2e11fc39e8 *ports/threadx/qp_port.hpp 5f098b1f50529ede0aff7e065d1234ef *ports/threadx/qs_port.hpp 23b496a982c574af2a47d01eb79e47f2 *ports/threadx/README.md +ae8b2f8b0649c8dfacbf6495fa560ad8 *ports/uc-os2/CMakeLists.txt 297438508fad9376be5cc20642b9bc80 *ports/uc-os2/qf_port.cpp f3c0b50eb1d3db891235d862dc398c18 *ports/uc-os2/qp_port.hpp 5f098b1f50529ede0aff7e065d1234ef *ports/uc-os2/qs_port.hpp +bb83d2a07ba0eb25a09bd64da602e3fa *ports/qep-only/CMakeLists.txt ec8563c61bcb8cb4682b7bc4ffc67d0a *ports/qep-only/qp_port.hpp 7955fc33c291eb6b8ebabaae0d6bd0da *ports/qep-only/safe_std.h +a29450c971859f6191f37c937b012eae *ports/posix/CMakeLists.txt a78cc40df8e511983e4f51b5233345d9 *ports/posix/qf_port.cpp 52e4d5e5d1113a3a0831aac6a44a3d21 *ports/posix/qp_port.hpp ae25ce9cf24260ec8affa08170f9d15a *ports/posix/qs_port.cpp dab4a85af98e1c67aa8de87b22e048c1 *ports/posix/qs_port.hpp f45c6f63edac95fd0b5d9cbeaa1f3926 *ports/posix/README.md 7955fc33c291eb6b8ebabaae0d6bd0da *ports/posix/safe_std.h +bbfb6bd8a58a8d5591f61b05b460cec5 *ports/posix-qv/CMakeLists.txt 3d1f2fa3662328387bbfa4cb974a7017 *ports/posix-qv/qf_port.cpp 221db06f9b4381533c738f1ca177f8cf *ports/posix-qv/qp_port.hpp ae25ce9cf24260ec8affa08170f9d15a *ports/posix-qv/qs_port.cpp dab4a85af98e1c67aa8de87b22e048c1 *ports/posix-qv/qs_port.hpp 72ee0355e2e9b6bd2a1e4c32480f361a *ports/posix-qv/README.md 7955fc33c291eb6b8ebabaae0d6bd0da *ports/posix-qv/safe_std.h +2171085568a15c190c72b106ea3c11b6 *ports/posix-qutest/CMakeLists.txt bc92f9570cafbe645318e54af34933e9 *ports/posix-qutest/qp_port.hpp e898e8f446a8fcfd84b5092144b21ef3 *ports/posix-qutest/qs_port.hpp 2b993b3de35967e54388740f67d4be2c *ports/posix-qutest/qutest_port.cpp 0ac7e3d28e684d07baacdcd0d3e65c4a *ports/posix-qutest/README.md 7955fc33c291eb6b8ebabaae0d6bd0da *ports/posix-qutest/safe_std.h +84541985a09da4e23055531452d74a02 *ports/win32/CMakeLists.txt ccec9e69c078e6b6889b7cba2e6195dd *ports/win32/Makefile b98e9825ffcbd8178145207316bf7910 *ports/win32/qf_port.cpp fc5a9085222501f994b6d517d6624a52 *ports/win32/qp_port.hpp @@ -143,6 +157,7 @@ a1c6143aa627599750360c58f4740129 *ports/win32/qwin_gui.c 64172552524a5e6449168adedfd858b0 *ports/win32/qwin_gui.h 84d25d92b6521b22736719d3ed33c289 *ports/win32/README.md 7955fc33c291eb6b8ebabaae0d6bd0da *ports/win32/safe_std.h +1f5c35a874db6752d1ec17f4b8ee4c19 *ports/win32-qv/CMakeLists.txt 7145fb32942db86db0dd6e7f090705a7 *ports/win32-qv/qf_port.cpp 38fbe14322593c37bdfe39c121e058fb *ports/win32-qv/qp_port.hpp b53aafe66b369a2e54344c792e481c1c *ports/win32-qv/qs_port.cpp @@ -151,6 +166,7 @@ a1c6143aa627599750360c58f4740129 *ports/win32-qv/qwin_gui.c 64172552524a5e6449168adedfd858b0 *ports/win32-qv/qwin_gui.h 4b910f53af0a91e12da39391840e396d *ports/win32-qv/README.md 7955fc33c291eb6b8ebabaae0d6bd0da *ports/win32-qv/safe_std.h +3d3f6d71f8afe29ec99b50b17fa84b65 *ports/win32-qutest/CMakeLists.txt c7cac095c6af24752bb87d63aba5beaf *ports/win32-qutest/qp_port.hpp 7fb4d8aa04a203af95a365f6a56f89b3 *ports/win32-qutest/qs_port.hpp c6f58183235c7dd685200b38808de610 *ports/win32-qutest/qutest_port.cpp diff --git a/qpcpp.qm b/qpcpp.qm index 715c0a74..987fa10c 100644 --- a/qpcpp.qm +++ b/qpcpp.qm @@ -4646,7 +4646,7 @@ if (ceiling > priv_.schedCeil) { // raising the scheduler ceiling? priv_.schedCeil = ceiling; #ifndef Q_UNSAFE - priv_.schedCeil_dis = static_cast<std::uint_fast16_t>(~ceiling); + priv_.schedCeil_dis = static_cast<std::uint_fast8_t>(~ceiling); #endif } QF_MEM_APP(); @@ -4671,7 +4671,7 @@ if (priv_.schedCeil != 0U) { // actually enabling the scheduler? priv_.schedCeil = 0U; #ifndef Q_UNSAFE - priv_.schedCeil_dis = ~static_cast<std::uint_fast16_t>(0U); + priv_.schedCeil_dis = ~static_cast<std::uint_fast8_t>(0U); #endif } QF_MEM_APP(); @@ -4690,7 +4690,7 @@ bzero_(&QActive::registry_[0], sizeof(QActive::registry_)); #ifndef Q_UNSAFE QV::priv_.readySet.update_(&QV::priv_.readySet_dis); -QV::priv_.schedCeil_dis = ~static_cast<std::uint_fast16_t>(0U); +QV::priv_.schedCeil_dis = ~static_cast<std::uint_fast8_t>(0U); #endif #ifdef QV_INIT @@ -4908,7 +4908,8 @@ QF_CRIT_ENTRY(); QF_MEM_SYS(); Q_REQUIRE_INCRIT(100, !QK_ISR_CONTEXT_()); -Q_REQUIRE_INCRIT(102, QK_priv_.lockCeil == ~QK_priv_.lockCeil_dis); +Q_REQUIRE_INCRIT(102, QK_priv_.lockCeil + == static_cast<std::uint_fast8_t>(~QK_priv_.lockCeil_dis)); // first store the previous lock prio QSchedStatus stat; @@ -4926,7 +4927,7 @@ if (ceiling > QK_priv_.lockCeil) { // raising the lock ceiling? // new status of the lock QK_priv_.lockCeil = ceiling; #ifndef Q_UNSAFE - QK_priv_.lockCeil_dis = ~ceiling; + QK_priv_.lockCeil_dis = static_cast<std::uint_fast8_t>(~ceiling); #endif } else { @@ -4949,7 +4950,8 @@ if (prevCeil != 0xFFU) { QF_CRIT_ENTRY(); QF_MEM_SYS(); - Q_REQUIRE_INCRIT(202, QK_priv_.lockCeil == ~QK_priv_.lockCeil_dis); + Q_REQUIRE_INCRIT(202, QK_priv_.lockCeil + == static_cast<std::uint_fast8_t>(~QK_priv_.lockCeil_dis)); Q_REQUIRE_INCRIT(210, (!QK_ISR_CONTEXT_()) && (QK_priv_.lockCeil > prevCeil)); @@ -4963,7 +4965,7 @@ if (prevCeil != 0xFFU) { // restore the previous lock ceiling QK_priv_.lockCeil = prevCeil; #ifndef Q_UNSAFE - QK_priv_.lockCeil_dis = ~prevCeil; + QK_priv_.lockCeil_dis = static_cast<std::uint_fast8_t>(~prevCeil); #endif // find if any AOs should be run after unlocking the scheduler @@ -4991,10 +4993,10 @@ QK_priv_.lockCeil = (QF_MAX_ACTIVE + 1U); // scheduler locked #ifndef Q_UNSAFE QK_priv_.readySet.update_(&QK_priv_.readySet_dis); -QK_priv_.actPrio_dis = ~QK_priv_.actPrio; -QK_priv_.nextPrio_dis = ~QK_priv_.nextPrio; -QK_priv_.actThre_dis = ~QK_priv_.actThre; -QK_priv_.lockCeil_dis = ~QK_priv_.lockCeil; +QK_priv_.actPrio_dis = static_cast<std::uint_fast8_t>(~QK_priv_.actPrio); +QK_priv_.nextPrio_dis = static_cast<std::uint_fast8_t>(~QK_priv_.nextPrio); +QK_priv_.actThre_dis = static_cast<std::uint_fast8_t>(~QK_priv_.actThre); +QK_priv_.lockCeil_dis = static_cast<std::uint_fast8_t>(~QK_priv_.lockCeil); #endif #ifdef QK_INIT @@ -5029,7 +5031,7 @@ QK_START(); // port-specific startup of the QK kernel QK_priv_.lockCeil = 0U; // unlock the QK scheduler #ifndef Q_UNSAFE -QK_priv_.lockCeil_dis = ~QK_priv_.lockCeil; +QK_priv_.lockCeil_dis = static_cast<std::uint_fast8_t>(~QK_priv_.lockCeil); #endif // activate AOs to process events posted so far @@ -5073,24 +5075,25 @@ QF_CRIT_ENTRY(); QF_MEM_SYS(); Q_REQUIRE_INCRIT(300, (!QK_ISR_CONTEXT_()) - && (stkSto == nullptr)); + && (stkSto == nullptr)); QF_MEM_APP(); QF_CRIT_EXIT(); -m_prio = static_cast<std::uint8_t>(prioSpec & 0xFFU); // QF-prio. +m_prio = static_cast<std::uint8_t>(prioSpec & 0xFFU); // QF-prio. m_pthre = static_cast<std::uint8_t>(prioSpec >> 8U); // preemption-thre. register_(); // make QF aware of this AO -m_eQueue.init(qSto, qLen); // initialize the built-in queue +m_eQueue.init(qSto, qLen); // init the built-in queue -this->init(par, m_prio); // top-most initial tran. (virtual call) +// top-most initial tran. (virtual call) +this->init(par, m_prio); QS_FLUSH(); // flush the trace buffer to the host -// See if this AO needs to be scheduled in case QK is already running +// See if this AO needs to be scheduled if QK is already running QF_CRIT_ENTRY(); QF_MEM_SYS(); -if (QK_sched_() != 0U) { // synchronous preemption needed? - QK_activate_(); // synchronously activate AOs +if (QK_sched_() != 0U) { // activation needed? + QK_activate_(); } QF_MEM_APP(); QF_CRIT_EXIT(); @@ -5142,27 +5145,28 @@ else { // find the highest-prio AO with non-empty event queue p = QK_priv_.readySet.findMax(); - Q_ASSERT_INCRIT(412, - QK_priv_.actThre == ~QK_priv_.actThre_dis); + Q_ASSERT_INCRIT(412, QK_priv_.actThre + == static_cast<std::uint_fast8_t>(~QK_priv_.actThre_dis)); // is the AO's prio. below the active preemption-threshold? if (p <= QK_priv_.actThre) { p = 0U; // no activation needed } else { - Q_ASSERT_INCRIT(422, - QK_priv_.lockCeil == ~QK_priv_.lockCeil_dis); + Q_ASSERT_INCRIT(422, QK_priv_.lockCeil + == static_cast<std::uint_fast8_t>(~QK_priv_.lockCeil_dis)); // is the AO's prio. below the lock-ceiling? if (p <= QK_priv_.lockCeil) { p = 0U; // no activation needed } else { - Q_ASSERT_INCRIT(432, - QK_priv_.nextPrio == ~QK_priv_.nextPrio_dis); + Q_ASSERT_INCRIT(432, QK_priv_.nextPrio + == static_cast<std::uint_fast8_t>(~QK_priv_.nextPrio_dis)); QK_priv_.nextPrio = p; // next AO to run #ifndef Q_UNSAFE - QK_priv_.nextPrio_dis = ~QK_priv_.nextPrio; + QK_priv_.nextPrio_dis + = static_cast<std::uint_fast8_t>(~QK_priv_.nextPrio); #endif } } @@ -5179,8 +5183,8 @@ std::uint_fast8_t const prio_in = QK_priv_.actPrio; // save initial prio. std::uint_fast8_t p = QK_priv_.nextPrio; // next prio to run Q_REQUIRE_INCRIT(502, - (prio_in == ~QK_priv_.actPrio_dis) - && (p == ~QK_priv_.nextPrio_dis)); + (prio_in == static_cast<std::uint_fast8_t>(~QK_priv_.actPrio_dis)) + && (p == static_cast<std::uint_fast8_t>(~QK_priv_.nextPrio_dis))); Q_REQUIRE_INCRIT(510, (prio_in <= QF_MAX_ACTIVE) && (0U < p) && (p <= QF_MAX_ACTIVE)); @@ -5190,7 +5194,7 @@ std::uint_fast8_t pprev = prio_in; QK_priv_.nextPrio = 0U; // clear for the next time #ifndef Q_UNSAFE -QK_priv_.nextPrio_dis = ~QK_priv_.nextPrio; +QK_priv_.nextPrio_dis = static_cast<std::uint_fast8_t>(~QK_priv_.nextPrio); #endif std::uint_fast8_t pthre_in; @@ -5220,8 +5224,8 @@ do { QK_priv_.actPrio = p; QK_priv_.actThre = pthre; #ifndef Q_UNSAFE - QK_priv_.actPrio_dis = ~p; - QK_priv_.actThre_dis = ~pthre; + QK_priv_.actPrio_dis = static_cast<std::uint_fast8_t>(~p); + QK_priv_.actThre_dis = static_cast<std::uint_fast8_t>(~pthre); #endif #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) @@ -5297,8 +5301,8 @@ do { QK_priv_.actPrio = prio_in; QK_priv_.actThre = pthre_in; #ifndef Q_UNSAFE -QK_priv_.actPrio_dis = ~QK_priv_.actPrio; -QK_priv_.actThre_dis = ~QK_priv_.actThre; +QK_priv_.actPrio_dis = static_cast<std::uint_fast8_t>(~QK_priv_.actPrio); +QK_priv_.actThre_dis = static_cast<std::uint_fast8_t>(~QK_priv_.actThre); #endif #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) diff --git a/qpcpp_sdk_init.cmake b/qpcpp_sdk_init.cmake new file mode 100644 index 00000000..7736a1fc --- /dev/null +++ b/qpcpp_sdk_init.cmake @@ -0,0 +1,49 @@ +# Pre-initialize the QPC SDK +# This file must be included prior to the project() call + +# Note: this file is perhaps named badly, as it provides a method qpc_sdk_init which +# the enclosing project calls LATER to actually "initialize" the SDK (by including the CMakeLists.txt from this +# same directory) + +if (NOT TARGET _qpcpp_sdk_pre_init_marker) + add_library(_qpcpp_sdk_pre_init_marker INTERFACE) + + function(qpcpp_is_top_level_project VAR) + string(TOLOWER ${CMAKE_CURRENT_LIST_DIR} __list_dir) + string(TOLOWER ${CMAKE_SOURCE_DIR} __source_dir) + if (__source_dir STREQUAL __list_dir) + set(${VAR} 1 PARENT_SCOPE) + else() + set(${VAR} 0 PARENT_SCOPE) + endif() + endfunction() + + function(qpcpp_message_debug MESSAGE) + # The log-level system was added in CMake 3.15. + if(${CMAKE_VERSION} VERSION_LESS "3.15.0") + message(${MESSAGE}) + else() + message(DEBUG ${MESSAGE}) + endif() + endfunction() + + if (NOT QPCPP_SDK_PATH) + set(QPCPP_SDK_PATH ${CMAKE_CURRENT_LIST_DIR}) + endif () + + file(REAL_PATH "${QPCPP_SDK_PATH}" QPCPP_SDK_PATH BASE_DIRECTORY "${CMAKE_BINARY_DIR}") + + set(QPCPP_SDK_PATH ${CMAKE_CURRENT_LIST_DIR} CACHE PATH "Path to the QP/C++ SDK" FORCE) + + list(APPEND CMAKE_MODULE_PATH ${QPCPP_SDK_PATH}/cmake) + + message("QPCPP_SDK_PATH is ${CMAKE_CURRENT_LIST_DIR}") + + function(qpcpp_sdk_init) + if (NOT CMAKE_PROJECT_NAME) + message(WARNING "qpcpp_sdk_init() should be called after the project is created (and languages added)") + endif() + + add_subdirectory(${QPCPP_SDK_PATH} qpcpp-sdk) + endfunction() +endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 00000000..24e53384 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,7 @@ +# qpcpp/src +add_subdirectory(qf) +add_subdirectory(qs) +if(${PORT} IN_LIST QPC_BAREMETAL_PORTS) + message(STATUS "adding subdir '${KERNEL}' for port '${PORT}'") + add_subdirectory(${KERNEL}) +endif() diff --git a/src/qf/CMakeLists.txt b/src/qf/CMakeLists.txt new file mode 100644 index 00000000..c231717f --- /dev/null +++ b/src/qf/CMakeLists.txt @@ -0,0 +1,25 @@ +# ./src/qf +target_sources(qpcpp PRIVATE + qep_hsm.cpp + qep_msm.cpp + qf_act.cpp + # qf_actq.cpp - see below + qf_defer.cpp + qf_dyn.cpp + # qf_mem.cpp - see below + qf_ps.cpp + qf_qact.cpp + qf_qeq.cpp + qf_qmact.cpp + qf_time.cpp +) +if(NOT (${QPCPP_CFG_PORT} IN_LIST QPCPP_RTOS_PORTS)) + target_sources(qpcpp PRIVATE + qf_actq.cpp + ) +endif() +if(NOT (${QPCPP_CFG_PORT} STREQUAL uc-os2)) + target_sources(qpcpp PRIVATE + qf_mem.cpp + ) +endif() \ No newline at end of file diff --git a/src/qk/CMakeLists.txt b/src/qk/CMakeLists.txt new file mode 100644 index 00000000..d5cc8080 --- /dev/null +++ b/src/qk/CMakeLists.txt @@ -0,0 +1,5 @@ +# ./src/qf +target_sources(qpcpp PRIVATE + qk.cpp +) + diff --git a/src/qk/qk.cpp b/src/qk/qk.cpp index 3c0cd222..7dd44be1 100644 --- a/src/qk/qk.cpp +++ b/src/qk/qk.cpp @@ -79,7 +79,8 @@ QSchedStatus schedLock(std::uint_fast8_t const ceiling) noexcept { QF_MEM_SYS(); Q_REQUIRE_INCRIT(100, !QK_ISR_CONTEXT_()); - Q_REQUIRE_INCRIT(102, QK_priv_.lockCeil == ~QK_priv_.lockCeil_dis); + Q_REQUIRE_INCRIT(102, QK_priv_.lockCeil + == static_cast(~QK_priv_.lockCeil_dis)); // first store the previous lock prio QSchedStatus stat; @@ -97,7 +98,7 @@ QSchedStatus schedLock(std::uint_fast8_t const ceiling) noexcept { // new status of the lock QK_priv_.lockCeil = ceiling; #ifndef Q_UNSAFE - QK_priv_.lockCeil_dis = ~ceiling; + QK_priv_.lockCeil_dis = static_cast(~ceiling); #endif } else { @@ -118,7 +119,8 @@ void schedUnlock(QSchedStatus const prevCeil) noexcept { QF_CRIT_ENTRY(); QF_MEM_SYS(); - Q_REQUIRE_INCRIT(202, QK_priv_.lockCeil == ~QK_priv_.lockCeil_dis); + Q_REQUIRE_INCRIT(202, QK_priv_.lockCeil + == static_cast(~QK_priv_.lockCeil_dis)); Q_REQUIRE_INCRIT(210, (!QK_ISR_CONTEXT_()) && (QK_priv_.lockCeil > prevCeil)); @@ -132,7 +134,7 @@ void schedUnlock(QSchedStatus const prevCeil) noexcept { // restore the previous lock ceiling QK_priv_.lockCeil = prevCeil; #ifndef Q_UNSAFE - QK_priv_.lockCeil_dis = ~prevCeil; + QK_priv_.lockCeil_dis = static_cast(~prevCeil); #endif // find if any AOs should be run after unlocking the scheduler @@ -170,27 +172,28 @@ std::uint_fast8_t QK_sched_() noexcept { // find the highest-prio AO with non-empty event queue p = QK_priv_.readySet.findMax(); - Q_ASSERT_INCRIT(412, - QK_priv_.actThre == ~QK_priv_.actThre_dis); + Q_ASSERT_INCRIT(412, QK_priv_.actThre + == static_cast(~QK_priv_.actThre_dis)); // is the AO's prio. below the active preemption-threshold? if (p <= QK_priv_.actThre) { p = 0U; // no activation needed } else { - Q_ASSERT_INCRIT(422, - QK_priv_.lockCeil == ~QK_priv_.lockCeil_dis); + Q_ASSERT_INCRIT(422, QK_priv_.lockCeil + == static_cast(~QK_priv_.lockCeil_dis)); // is the AO's prio. below the lock-ceiling? if (p <= QK_priv_.lockCeil) { p = 0U; // no activation needed } else { - Q_ASSERT_INCRIT(432, - QK_priv_.nextPrio == ~QK_priv_.nextPrio_dis); + Q_ASSERT_INCRIT(432, QK_priv_.nextPrio + == static_cast(~QK_priv_.nextPrio_dis)); QK_priv_.nextPrio = p; // next AO to run #ifndef Q_UNSAFE - QK_priv_.nextPrio_dis = ~QK_priv_.nextPrio; + QK_priv_.nextPrio_dis + = static_cast(~QK_priv_.nextPrio); #endif } } @@ -207,8 +210,8 @@ void QK_activate_() noexcept { std::uint_fast8_t p = QK_priv_.nextPrio; // next prio to run Q_REQUIRE_INCRIT(502, - (prio_in == ~QK_priv_.actPrio_dis) - && (p == ~QK_priv_.nextPrio_dis)); + (prio_in == static_cast(~QK_priv_.actPrio_dis)) + && (p == static_cast(~QK_priv_.nextPrio_dis))); Q_REQUIRE_INCRIT(510, (prio_in <= QF_MAX_ACTIVE) && (0U < p) && (p <= QF_MAX_ACTIVE)); @@ -218,7 +221,7 @@ void QK_activate_() noexcept { QK_priv_.nextPrio = 0U; // clear for the next time #ifndef Q_UNSAFE - QK_priv_.nextPrio_dis = ~QK_priv_.nextPrio; + QK_priv_.nextPrio_dis = static_cast(~QK_priv_.nextPrio); #endif std::uint_fast8_t pthre_in; @@ -248,8 +251,8 @@ void QK_activate_() noexcept { QK_priv_.actPrio = p; QK_priv_.actThre = pthre; #ifndef Q_UNSAFE - QK_priv_.actPrio_dis = ~p; - QK_priv_.actThre_dis = ~pthre; + QK_priv_.actPrio_dis = static_cast(~p); + QK_priv_.actThre_dis = static_cast(~pthre); #endif #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) @@ -325,8 +328,8 @@ void QK_activate_() noexcept { QK_priv_.actPrio = prio_in; QK_priv_.actThre = pthre_in; #ifndef Q_UNSAFE - QK_priv_.actPrio_dis = ~QK_priv_.actPrio; - QK_priv_.actThre_dis = ~QK_priv_.actThre; + QK_priv_.actPrio_dis = static_cast(~QK_priv_.actPrio); + QK_priv_.actThre_dis = static_cast(~QK_priv_.actThre); #endif #if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY) @@ -372,10 +375,10 @@ void init() { #ifndef Q_UNSAFE QK_priv_.readySet.update_(&QK_priv_.readySet_dis); - QK_priv_.actPrio_dis = ~QK_priv_.actPrio; - QK_priv_.nextPrio_dis = ~QK_priv_.nextPrio; - QK_priv_.actThre_dis = ~QK_priv_.actThre; - QK_priv_.lockCeil_dis = ~QK_priv_.lockCeil; + QK_priv_.actPrio_dis = static_cast(~QK_priv_.actPrio); + QK_priv_.nextPrio_dis = static_cast(~QK_priv_.nextPrio); + QK_priv_.actThre_dis = static_cast(~QK_priv_.actThre); + QK_priv_.lockCeil_dis = static_cast(~QK_priv_.lockCeil); #endif #ifdef QK_INIT @@ -412,7 +415,7 @@ int_t run() { QK_priv_.lockCeil = 0U; // unlock the QK scheduler #ifndef Q_UNSAFE - QK_priv_.lockCeil_dis = ~QK_priv_.lockCeil; + QK_priv_.lockCeil_dis = static_cast(~QK_priv_.lockCeil); #endif // activate AOs to process events posted so far @@ -458,24 +461,25 @@ void QActive::start( QF_MEM_SYS(); Q_REQUIRE_INCRIT(300, (!QK_ISR_CONTEXT_()) - && (stkSto == nullptr)); + && (stkSto == nullptr)); QF_MEM_APP(); QF_CRIT_EXIT(); - m_prio = static_cast(prioSpec & 0xFFU); // QF-prio. + m_prio = static_cast(prioSpec & 0xFFU); // QF-prio. m_pthre = static_cast(prioSpec >> 8U); // preemption-thre. register_(); // make QF aware of this AO - m_eQueue.init(qSto, qLen); // initialize the built-in queue + m_eQueue.init(qSto, qLen); // init the built-in queue - this->init(par, m_prio); // top-most initial tran. (virtual call) + // top-most initial tran. (virtual call) + this->init(par, m_prio); QS_FLUSH(); // flush the trace buffer to the host - // See if this AO needs to be scheduled in case QK is already running + // See if this AO needs to be scheduled if QK is already running QF_CRIT_ENTRY(); QF_MEM_SYS(); - if (QK_sched_() != 0U) { // synchronous preemption needed? - QK_activate_(); // synchronously activate AOs + if (QK_sched_() != 0U) { // activation needed? + QK_activate_(); } QF_MEM_APP(); QF_CRIT_EXIT(); diff --git a/src/qs/CMakeLists.txt b/src/qs/CMakeLists.txt new file mode 100644 index 00000000..9d9b96b0 --- /dev/null +++ b/src/qs/CMakeLists.txt @@ -0,0 +1,9 @@ +# ./src/qs +target_sources(qpcpp PRIVATE + "$<$:${CMAKE_CURRENT_SOURCE_DIR}/qs_64bit.cpp>" + "$<$:${CMAKE_CURRENT_SOURCE_DIR}/qs_fp.cpp>" + "$<$:${CMAKE_CURRENT_SOURCE_DIR}/qs_rx.cpp>" + "$<$:${CMAKE_CURRENT_SOURCE_DIR}/qstamp.cpp>" + "$<$:${CMAKE_CURRENT_SOURCE_DIR}/qs.cpp>" + "$<$,$>:${CMAKE_CURRENT_SOURCE_DIR}/qutest.cpp>" +) diff --git a/src/qv/CMakeLists.txt b/src/qv/CMakeLists.txt new file mode 100644 index 00000000..662436d8 --- /dev/null +++ b/src/qv/CMakeLists.txt @@ -0,0 +1,4 @@ +# ./src/qf +target_sources(qpcpp PRIVATE + qv.cpp +) diff --git a/src/qv/qv.cpp b/src/qv/qv.cpp index 45435d9d..5d2d4ff6 100644 --- a/src/qv/qv.cpp +++ b/src/qv/qv.cpp @@ -95,7 +95,7 @@ void schedDisable(std::uint_fast8_t const ceiling) { priv_.schedCeil = ceiling; #ifndef Q_UNSAFE - priv_.schedCeil_dis = static_cast(~ceiling); + priv_.schedCeil_dis = static_cast(~ceiling); #endif } QF_MEM_APP(); @@ -121,7 +121,7 @@ void schedEnable() { priv_.schedCeil = 0U; #ifndef Q_UNSAFE - priv_.schedCeil_dis = ~static_cast(0U); + priv_.schedCeil_dis = ~static_cast(0U); #endif } QF_MEM_APP(); @@ -144,7 +144,7 @@ void init() { #ifndef Q_UNSAFE QV::priv_.readySet.update_(&QV::priv_.readySet_dis); - QV::priv_.schedCeil_dis = ~static_cast(0U); + QV::priv_.schedCeil_dis = ~static_cast(0U); #endif #ifdef QV_INIT diff --git a/src/qxk/CMakeLists.txt b/src/qxk/CMakeLists.txt new file mode 100644 index 00000000..3939f6a6 --- /dev/null +++ b/src/qxk/CMakeLists.txt @@ -0,0 +1,7 @@ +# ./src/qf +target_sources(qpcpp PRIVATE + qxk_mutex.cpp + qxk_sema.cpp + qxk_xthr.cpp + qxk.cpp +)