updated QV, QK for MSP430
Cmake support
This commit is contained in:
MMS 2024-02-27 17:45:11 -05:00
parent a2c05d3b05
commit 10441f7a03
31 changed files with 703 additions and 71 deletions

@ -1 +1 @@
Subproject commit ebe4896f82bdb7b883f42f930307d243a4cd43d6
Subproject commit db8b6155e6931d2c55315dfd55b0e1fac0f96e33

207
CMakeLists.txt Normal file
View File

@ -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
$<$<BOOL:${ADD_DEBUG_CODE}>:${ADD_DEBUG_CODE}>
$<$<BOOL:${QPCPP_CFG_GUI}>:QWIN_GUI>
# $<$<CONFIG:Spy>:Q_SPY> # set via toolchain file
$<$<AND:$<CONFIG:Spy>,$<BOOL:${QPCPP_CFG_UNIT_TEST}>>:Q_UTEST>
)
target_compile_options(qpcpp PRIVATE
$<$<BOOL:${QPCPP_CFG_VERBOSE}>:-v>
)
target_link_options(qpcpp PRIVATE
$<$<BOOL:${QPCPP_CFG_VERBOSE}>:-v>
)
target_link_libraries(qpcpp PUBLIC
$<$<AND:$<CONFIG:Spy>,$<STREQUAL:win32,${PORT}>>: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()

171
cmakeSupport.md Normal file
View File

@ -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 1<sup>st</sup> `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=<image>
# 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(<target>> 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 <build directory> --config=<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=<preset> .` from your project directory. The build then can be started with `cmake --build --preset=<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 <Build Directory> --config=<Debug|Release|Spy>`
To support this, the `cmake` variables
* `CMAKE_C_FLAGS_<CONFIGURATION>`
* `CMAKE_CXX_FLAGS_<CONFIGURATION>`
* `CMAKE_ASM_FLAGS_<CONFIGURATION>`
* `CMAKE_EXE_LINKER_FLAGS_<CONFIGURATION>`
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_<LANG>_FLAGS_<CONFIGURATION>` variables, also applies here.

@ -1 +1 @@
Subproject commit c89346fe6c765ac03d6d55d7ee0aa9c082bfa046
Subproject commit a4becf08ed700750fce0bfea22a8968349330e55

16
ports/CMakeLists.txt Normal file
View File

@ -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})

View File

@ -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})

View File

@ -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_})

View File

@ -0,0 +1,3 @@
# ports/embos
target_include_directories(qpcpp PUBLIC .)
target_sources(qpcpp PRIVATE qf_port.cpp)

View File

@ -0,0 +1,3 @@
# ports/freertos
target_include_directories(qpcpp PUBLIC .)
target_sources(qpcpp PRIVATE qf_port.cpp)

View File

@ -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()

View File

@ -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()

View File

@ -0,0 +1,5 @@
# ports/posix-qutest
target_include_directories(qpcpp PUBLIC .)
target_sources(qpcpp PRIVATE
qutest_port.cpp
)

View File

@ -0,0 +1,6 @@
# ports/posix-qv
target_include_directories(qpcpp PUBLIC .)
target_sources(qpcpp PRIVATE
qf_port.cpp
$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qs_port.cpp>
)

View File

@ -0,0 +1,6 @@
# ports/posix
target_include_directories(qpcpp PUBLIC .)
target_sources(qpcpp PRIVATE
qf_port.cpp
$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qs_port.cpp>
)

View File

@ -0,0 +1,2 @@
# ports/qep-only
target_include_directories(qpcpp PUBLIC .)

View File

@ -0,0 +1,3 @@
# ports/os_xxx
target_include_directories(qpcpp PUBLIC .)
target_sources(qpcpp PRIVATE qf_port.cpp)

View File

@ -0,0 +1,3 @@
# ports/uc-os2
target_include_directories(qpcpp PUBLIC .)
target_sources(qpcpp PRIVATE qf_port.cpp)

View File

@ -0,0 +1,5 @@
# ports/win32-qutest
target_include_directories(qpcpp PUBLIC .)
target_sources(qpcpp PRIVATE
qutest_port.cpp
)

View File

@ -0,0 +1,7 @@
# ports/win32-qv
target_include_directories(qpcpp PUBLIC .)
target_sources(qpcpp PRIVATE
qf_port.cpp
$<$<BOOL:${QPCPP_CFG_GUI}>:${CMAKE_CURRENT_SOURCE_DIR}/qwin_gui.c>
$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qs_port.cpp>
)

View File

@ -0,0 +1,7 @@
# ports/win32
target_include_directories(qpcpp PUBLIC .)
target_sources(qpcpp PRIVATE
qf_port.cpp
$<$<BOOL:${QPCPP_CFG_GUI}>:${CMAKE_CURRENT_SOURCE_DIR}/qwin_gui.c>
$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qs_port.cpp>
)

View File

@ -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

View File

@ -4646,7 +4646,7 @@ if (ceiling &gt; priv_.schedCeil) { // raising the scheduler ceiling?
priv_.schedCeil = ceiling;
#ifndef Q_UNSAFE
priv_.schedCeil_dis = static_cast&lt;std::uint_fast16_t&gt;(~ceiling);
priv_.schedCeil_dis = static_cast&lt;std::uint_fast8_t&gt;(~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&lt;std::uint_fast16_t&gt;(0U);
priv_.schedCeil_dis = ~static_cast&lt;std::uint_fast8_t&gt;(0U);
#endif
}
QF_MEM_APP();
@ -4690,7 +4690,7 @@ bzero_(&amp;QActive::registry_[0], sizeof(QActive::registry_));
#ifndef Q_UNSAFE
QV::priv_.readySet.update_(&amp;QV::priv_.readySet_dis);
QV::priv_.schedCeil_dis = ~static_cast&lt;std::uint_fast16_t&gt;(0U);
QV::priv_.schedCeil_dis = ~static_cast&lt;std::uint_fast8_t&gt;(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&lt;std::uint_fast8_t&gt;(~QK_priv_.lockCeil_dis));
// first store the previous lock prio
QSchedStatus stat;
@ -4926,7 +4927,7 @@ if (ceiling &gt; 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&lt;std::uint_fast8_t&gt;(~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&lt;std::uint_fast8_t&gt;(~QK_priv_.lockCeil_dis));
Q_REQUIRE_INCRIT(210, (!QK_ISR_CONTEXT_())
&amp;&amp; (QK_priv_.lockCeil &gt; 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&lt;std::uint_fast8_t&gt;(~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_(&amp;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&lt;std::uint_fast8_t&gt;(~QK_priv_.actPrio);
QK_priv_.nextPrio_dis = static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.nextPrio);
QK_priv_.actThre_dis = static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.actThre);
QK_priv_.lockCeil_dis = static_cast&lt;std::uint_fast8_t&gt;(~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&lt;std::uint_fast8_t&gt;(~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_())
&amp;&amp; (stkSto == nullptr));
&amp;&amp; (stkSto == nullptr));
QF_MEM_APP();
QF_CRIT_EXIT();
m_prio = static_cast&lt;std::uint8_t&gt;(prioSpec &amp; 0xFFU); // QF-prio.
m_prio = static_cast&lt;std::uint8_t&gt;(prioSpec &amp; 0xFFU); // QF-prio.
m_pthre = static_cast&lt;std::uint8_t&gt;(prioSpec &gt;&gt; 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-&gt;init(par, m_prio); // top-most initial tran. (virtual call)
// top-most initial tran. (virtual call)
this-&gt;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();</code>
@ -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&lt;std::uint_fast8_t&gt;(~QK_priv_.actThre_dis));
// is the AO's prio. below the active preemption-threshold?
if (p &lt;= 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&lt;std::uint_fast8_t&gt;(~QK_priv_.lockCeil_dis));
// is the AO's prio. below the lock-ceiling?
if (p &lt;= 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&lt;std::uint_fast8_t&gt;(~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&lt;std::uint_fast8_t&gt;(~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)
&amp;&amp; (p == ~QK_priv_.nextPrio_dis));
(prio_in == static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.actPrio_dis))
&amp;&amp; (p == static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.nextPrio_dis)));
Q_REQUIRE_INCRIT(510, (prio_in &lt;= QF_MAX_ACTIVE)
&amp;&amp; (0U &lt; p) &amp;&amp; (p &lt;= 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&lt;std::uint_fast8_t&gt;(~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&lt;std::uint_fast8_t&gt;(~p);
QK_priv_.actThre_dis = static_cast&lt;std::uint_fast8_t&gt;(~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&lt;std::uint_fast8_t&gt;(~QK_priv_.actPrio);
QK_priv_.actThre_dis = static_cast&lt;std::uint_fast8_t&gt;(~QK_priv_.actThre);
#endif
#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)

49
qpcpp_sdk_init.cmake Normal file
View File

@ -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()

7
src/CMakeLists.txt Normal file
View File

@ -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()

25
src/qf/CMakeLists.txt Normal file
View File

@ -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()

5
src/qk/CMakeLists.txt Normal file
View File

@ -0,0 +1,5 @@
# ./src/qf
target_sources(qpcpp PRIVATE
qk.cpp
)

View File

@ -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<std::uint_fast8_t>(~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<std::uint_fast8_t>(~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<std::uint_fast8_t>(~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<std::uint_fast8_t>(~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<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
}
}
@ -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<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));
@ -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<std::uint_fast8_t>(~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<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)
@ -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<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)
@ -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<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
@ -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<std::uint_fast8_t>(~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<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();

9
src/qs/CMakeLists.txt Normal file
View File

@ -0,0 +1,9 @@
# ./src/qs
target_sources(qpcpp PRIVATE
"$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qs_64bit.cpp>"
"$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qs_fp.cpp>"
"$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qs_rx.cpp>"
"$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qstamp.cpp>"
"$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qs.cpp>"
"$<$<AND:$<CONFIG:Spy>,$<BOOL:${QPCPP_CFG_UNIT_TEST}>>:${CMAKE_CURRENT_SOURCE_DIR}/qutest.cpp>"
)

4
src/qv/CMakeLists.txt Normal file
View File

@ -0,0 +1,4 @@
# ./src/qf
target_sources(qpcpp PRIVATE
qv.cpp
)

View File

@ -95,7 +95,7 @@ void schedDisable(std::uint_fast8_t const 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();
@ -121,7 +121,7 @@ void schedEnable() {
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();
@ -144,7 +144,7 @@ void init() {
#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

7
src/qxk/CMakeLists.txt Normal file
View File

@ -0,0 +1,7 @@
# ./src/qf
target_sources(qpcpp PRIVATE
qxk_mutex.cpp
qxk_sema.cpp
qxk_xthr.cpp
qxk.cpp
)