diff --git a/3rd_party b/3rd_party index 054cd1ab..aca09a2e 160000 --- a/3rd_party +++ b/3rd_party @@ -1 +1 @@ -Subproject commit 054cd1abe4b4abef5e45f36b1ce8f2aff4575494 +Subproject commit aca09a2e3571adf97e5ce6cb5b1d645ba2418c1d diff --git a/examples b/examples index b11c80ef..4ecb703d 160000 --- a/examples +++ b/examples @@ -1 +1 @@ -Subproject commit b11c80ef242ca83d3f988b846ea28aedaa0ad2ce +Subproject commit 4ecb703d24102773d7f7e631d93e1b8b88da5a73 diff --git a/include/qp.h b/include/qp.h index 3678b035..f61cf18d 100644 --- a/include/qp.h +++ b/include/qp.h @@ -417,6 +417,7 @@ bool QMsm_isIn_( QAsm * const me, QStateHandler const state); +//! @private @memberof QMsm //! @deprecated instead use: QASM_IS_IN() bool QMsm_isInState(QMsm const * const me, QMState const * const stateObj); diff --git a/ports/embos/qf_port.c b/ports/embos/qf_port.c index 8b6cfe8d..9595e678 100644 --- a/ports/embos/qf_port.c +++ b/ports/embos/qf_port.c @@ -22,8 +22,8 @@ // // //============================================================================ -//! @date Last updated on: 2023-11-15 -//! @version Last updated for: @ref qpc_7_3_1 +//! @date Last updated on: 2024-06-11 +//! @version Last updated for: @ref qpc_7_4_0 //! //! @file //! @brief QF/C port to embOS RTOS kernel, generic C11 compiler diff --git a/ports/freertos/qf_port.c b/ports/freertos/qf_port.c index cef9685d..3c7285b2 100644 --- a/ports/freertos/qf_port.c +++ b/ports/freertos/qf_port.c @@ -22,8 +22,8 @@ // // //============================================================================ -//! @date Last updated on: 2023-11-15 -//! @version Last updated for: @ref qpc_7_3_1 +//! @date Last updated on: 2024-06-11 +//! @version Last updated for: @ref qpc_7_4_0 //! //! @file //! @brief QF/C port to FreeRTOS 10.x, generic C11 compiler diff --git a/ports/lint-plus/qpc.lnt b/ports/lint-plus/qpc.lnt index cb9681b8..930cb664 100644 --- a/ports/lint-plus/qpc.lnt +++ b/ports/lint-plus/qpc.lnt @@ -22,8 +22,8 @@ // // //============================================================================ -//! @date Last updated on: 2023-12-12 -//! @version Last updated for version: 7.3.1 +//! @date Last updated on: 2024-06-11 +//! @version Last updated for version: 7.4.0 //! //! @file //! @brief PC-Lint-Plus option file for analysing both **QP/C** @@ -69,8 +69,7 @@ //! PCLP definition of macro ends in semicolon //! @tr{DVP-QP-PCLP-823} -esym(823, - Q_DEFINE_THIS_MODULE, - Q_DEFINE_THIS_FILE) + Q_DEFINE_THIS_MODULE) //! BARR-C(R1.8b) parameter of function could be const -efunc(952, diff --git a/ports/posix-qutest/qp_port.h b/ports/posix-qutest/qp_port.h index 0f413313..7f0198ee 100644 --- a/ports/posix-qutest/qp_port.h +++ b/ports/posix-qutest/qp_port.h @@ -27,8 +27,8 @@ // // //============================================================================ -//! @date Last updated on: 2023-09-07 -//! @version Last updated for: @ref qpc_7_3_0 +//! @date Last updated on: 2024-06-10 +//! @version Last updated for: @ref qpc_7_4_0 //! //! @file //! @brief QP/C "port" for QUTEST unit test harness, generic C11 compiler @@ -52,13 +52,13 @@ // QACTIVE_THREAD_TYPE not used in this port // QF interrupt disable/enable -#define QF_INT_DISABLE() (++QS_tstPriv_.intLock) -#define QF_INT_ENABLE() (--QS_tstPriv_.intLock) +#define QF_INT_DISABLE() (QS_onIntDisable()) +#define QF_INT_ENABLE() (QS_onIntEnable()) // QF critical section #define QF_CRIT_STAT -#define QF_CRIT_ENTRY() QF_INT_DISABLE() -#define QF_CRIT_EXIT() QF_INT_ENABLE() +#define QF_CRIT_ENTRY() QF_INT_DISABLE() +#define QF_CRIT_EXIT() QF_INT_ENABLE() // QF_LOG2 not defined -- use the internal LOG2() implementation @@ -67,6 +67,9 @@ #include "qmpool.h" // QUTest port uses QMPool memory-pool #include "qp.h" // QP platform-independent public interface +void QS_onIntDisable(void); +void QS_onIntEnable(void); + //============================================================================ // interface used only inside QF implementation, but not in applications @@ -90,7 +93,7 @@ #endif // native QF event pool operations - #define QF_EPOOL_TYPE_ QMPool + #define QF_EPOOL_TYPE_ QMPool #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) diff --git a/ports/posix-qutest/qutest_port.c b/ports/posix-qutest/qutest_port.c index 326fe830..e8b79c7f 100644 --- a/ports/posix-qutest/qutest_port.c +++ b/ports/posix-qutest/qutest_port.c @@ -22,8 +22,8 @@ // // //============================================================================ -//! @date Last updated on: 2024-02-16 -//! @version Last updated for: @ref qpc_7_3_3 +//! @date Last updated on: 2024-06-11 +//! @version Last updated for: @ref qpc_7_4_0 //! //! @file //! @brief QS/C "port" to QUTest with POSIX @@ -61,7 +61,7 @@ #define INVALID_SOCKET -1 #define SOCKET_ERROR -1 -//Q_DEFINE_THIS_MODULE("qutest_port") +Q_DEFINE_THIS_MODULE("qutest_port") // local variables ........................................................... static int l_sock = INVALID_SOCKET; @@ -112,6 +112,8 @@ uint8_t QS_onStartup(void const *arg) { if (*src == ':') { serviceName = src + 1; } + //printf(" Connecting to QSPY on Host=%s:%s...\n", + // hostName, serviceName); memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; @@ -243,19 +245,20 @@ void QS_onFlush(void) { nBytes = QS_TX_CHUNK; } } + //............................................................................ void QS_onTestLoop() { fd_set readSet; FD_ZERO(&readSet); - struct timeval timeout = { - (long)0, (long)(QS_TIMEOUT_MS * 1000) - }; - QS_rxPriv_.inTestLoop = true; while (QS_rxPriv_.inTestLoop) { FD_SET(l_sock, &readSet); + struct timeval timeout = { + (long)0, (long)(QS_TIMEOUT_MS * 1000) + }; + // selective, timed blocking on the TCP/IP socket... timeout.tv_usec = (long)(QS_TIMEOUT_MS * 1000); int status = select(l_sock + 1, &readSet, @@ -270,7 +273,7 @@ void QS_onTestLoop() { (char *)QS_rxPriv_.buf, (int)QS_rxPriv_.end, 0); if (status > 0) { // any data received? QS_rxPriv_.tail = 0U; - QS_rxPriv_.head = status; // # bytes received + QS_rxPriv_.head = (QSCtr)status; // # bytes received QS_rxParse(); // parse all received bytes } } @@ -282,3 +285,17 @@ void QS_onTestLoop() { QS_rxPriv_.inTestLoop = true; } +//............................................................................ +void QS_onIntDisable(void) { + if (QS_tstPriv_.intLock != 0U) { + Q_onError(&Q_this_module_[0], 998); + } + ++QS_tstPriv_.intLock; +} +//............................................................................ +void QS_onIntEnable(void) { + --QS_tstPriv_.intLock; + if (QS_tstPriv_.intLock != 0U) { + Q_onError(&Q_this_module_[0], 999); + } +} diff --git a/ports/posix-qv/qf_port.c b/ports/posix-qv/qf_port.c index 0a0ae315..14c850ff 100644 --- a/ports/posix-qv/qf_port.c +++ b/ports/posix-qv/qf_port.c @@ -22,8 +22,8 @@ // // //============================================================================ -//! @date Last updated on: 2024-02-16 -//! @version Last updated for: @ref qpc_7_3_3 +//! @date Last updated on: 2024-06-11 +//! @version Last updated for: @ref qpc_7_4_0 //! //! @file //! @brief QF/C port to POSIX-QV (single-threaded) diff --git a/ports/posix-qv/qs_port.c b/ports/posix-qv/qs_port.c index 28c298fc..882860f6 100644 --- a/ports/posix-qv/qs_port.c +++ b/ports/posix-qv/qs_port.c @@ -22,8 +22,8 @@ // // //============================================================================ -//! @date Last updated on: 2023-12-13 -//! @version Last updated for: @ref qpc_7_3_2 +//! @date Last updated on: 2024-06-11 +//! @version Last updated for: @ref qpc_7_4_0 //! //! @file //! @brief QS/C port to POSIX diff --git a/ports/posix/qf_port.c b/ports/posix/qf_port.c index eb25d907..d947f090 100644 --- a/ports/posix/qf_port.c +++ b/ports/posix/qf_port.c @@ -22,8 +22,8 @@ // // //============================================================================ -//! @date Last updated on: 2024-02-16 -//! @version Last updated for: @ref qpc_7_3_3 +//! @date Last updated on: 2024-06-11 +//! @version Last updated for: @ref qpc_7_4_0 //! //! @file //! @brief QF/C port to POSIX (multithreaded with P-threads) diff --git a/ports/posix/qs_port.c b/ports/posix/qs_port.c index 5a48e1c6..7c5d3f77 100644 --- a/ports/posix/qs_port.c +++ b/ports/posix/qs_port.c @@ -22,8 +22,8 @@ // // //============================================================================ -//! @date Last updated on: 2023-12-13 -//! @version Last updated for: @ref qpc_7_3_0 +//! @date Last updated on: 2024-06-11 +//! @version Last updated for: @ref qpc_7_4_0 //! //! @file //! @brief QS/C port to POSIX diff --git a/ports/qube/qube.c b/ports/qube/qube.c index 7e2d3233..c1dd5785 100644 --- a/ports/qube/qube.c +++ b/ports/qube/qube.c @@ -22,8 +22,8 @@ // // //============================================================================ -//! @date Last updated on: 2023-12-13 -//! @version Last updated for: @ref qpc_7_3_2 +//! @date Last updated on: 2024-06-11 +//! @version Last updated for: @ref qpc_7_4_0 //! //! @file //! @brief Qube command-line QP execution environment diff --git a/ports/threadx/qf_port.c b/ports/threadx/qf_port.c index 82cf0cf1..b94297c9 100644 --- a/ports/threadx/qf_port.c +++ b/ports/threadx/qf_port.c @@ -22,8 +22,8 @@ // // //============================================================================ -//! @date Last updated on: 2023-08-22 -//! @version Last updated for: @ref qpc_7_3_0 +//! @date Last updated on: 2024-06-11 +//! @version Last updated for: @ref qpc_7_4_0 //! //! @file //! @brief QF/C, port to ThreadX diff --git a/ports/uc-os2/qf_port.c b/ports/uc-os2/qf_port.c index 4c8e993a..6084da7b 100644 --- a/ports/uc-os2/qf_port.c +++ b/ports/uc-os2/qf_port.c @@ -22,8 +22,8 @@ // // //============================================================================ -//! @date Last updated on: 2023-11-15 -//! @version Last updated for: @ref qpc_7_3_1 +//! @date Last updated on: 2024-06-11 +//! @version Last updated for: @ref qpc_7_4_0 //! //! @file //! @brief QP/C port to uC-OS2, generic C11 compiler diff --git a/ports/win32-qutest/qp_port.h b/ports/win32-qutest/qp_port.h index e800e2cc..e433c40b 100644 --- a/ports/win32-qutest/qp_port.h +++ b/ports/win32-qutest/qp_port.h @@ -27,11 +27,11 @@ // // //============================================================================ -//! @date Last updated on: 2023-09-07 -//! @version Last updated for: @ref qpc_7_3_0 +//! @date Last updated on: 2024-06-10 +//! @version Last updated for: @ref qpc_7_4_0 //! //! @file -//! @brief QP/C port to Win32-QUtest with GNU or Visual Studio C/C++ +//! @brief QP/C port to Win32-QUTest with GNU or Visual Studio C/C++ #ifndef QP_PORT_H_ #define QP_PORT_H_ @@ -80,8 +80,8 @@ // QACTIVE_THREAD_TYPE not used in this port // QF interrupt disable/enable -#define QF_INT_DISABLE() (++QS_tstPriv_.intLock) -#define QF_INT_ENABLE() (--QS_tstPriv_.intLock) +#define QF_INT_DISABLE() (QS_onIntDisable()) +#define QF_INT_ENABLE() (QS_onIntEnable()) // QF critical section #define QF_CRIT_STAT @@ -95,6 +95,9 @@ #include "qmpool.h" // QUTest port uses QMPool memory-pool #include "qp.h" // QP platform-independent public interface +void QS_onIntDisable(void); +void QS_onIntEnable(void); + #ifdef _MSC_VER #pragma warning (default: 4510 4512 4610) #endif diff --git a/ports/win32-qutest/qutest_port.c b/ports/win32-qutest/qutest_port.c index 2fadbf01..29645287 100644 --- a/ports/win32-qutest/qutest_port.c +++ b/ports/win32-qutest/qutest_port.c @@ -22,8 +22,8 @@ // // //============================================================================ -//! @date Last updated on: 2024-02-16 -//! @version Last updated for: @ref qpc_7_3_3 +//! @date Last updated on: 2024-06-11 +//! @version Last updated for: @ref qpc_7_4_0 //! //! @file //! @brief QS/C QUTest port for Win32 @@ -54,13 +54,13 @@ #include -//Q_DEFINE_THIS_MODULE("qutest_port") - #define QS_TX_SIZE (8*1024) #define QS_RX_SIZE (2*1024) #define QS_TX_CHUNK QS_TX_SIZE #define QS_TIMEOUT_MS 10U +Q_DEFINE_THIS_MODULE("qutest_port") + // local variables ......................................................... static SOCKET l_sock = INVALID_SOCKET; @@ -110,6 +110,8 @@ uint8_t QS_onStartup(void const *arg) { if (*src == ':') { serviceName = src + 1; } + //printf(" Connecting to QSPY on Host=%s:%s...\n", + // hostName, serviceName); memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; @@ -151,6 +153,7 @@ uint8_t QS_onStartup(void const *arg) { if (ioctlsocket(l_sock, FIONBIO, &ioctl_opt) != NO_ERROR) { FPRINTF_S(stderr, " ERROR %s WASErr=%d\n,", "Failed to set non-blocking socket", WSAGetLastError()); + QF_stop(); // <== stop and exit the application goto error; } @@ -237,29 +240,28 @@ void QS_onTestLoop() { fd_set readSet; FD_ZERO(&readSet); - struct timeval timeout = { - (long)0, (long)(QS_TIMEOUT_MS * 1000) - }; - QS_rxPriv_.inTestLoop = true; while (QS_rxPriv_.inTestLoop) { FD_SET(l_sock, &readSet); + struct timeval timeout = { + (long)0, (long)(QS_TIMEOUT_MS * 1000) + }; + // selective, timed blocking on the TCP/IP socket... int status = select(0, &readSet, (fd_set *)0, (fd_set *)0, &timeout); if (status == SOCKET_ERROR) { FPRINTF_S(stderr, " ERROR socket select,WSAErr=%d", WSAGetLastError()); - QS_onCleanup(); - exit(-2); + QF_stop(); // <== stop and exit the application } else if (FD_ISSET(l_sock, &readSet)) { // socket ready? status = recv(l_sock, (char *)QS_rxPriv_.buf, (int)QS_rxPriv_.end, 0); if (status > 0) { // any data received? QS_rxPriv_.tail = 0U; - QS_rxPriv_.head = status; // # bytes received + QS_rxPriv_.head = (QSCtr)status; // # bytes received QS_rxParse(); // parse all received bytes } } @@ -271,3 +273,17 @@ void QS_onTestLoop() { QS_rxPriv_.inTestLoop = true; } +//............................................................................ +void QS_onIntDisable(void) { + if (QS_tstPriv_.intLock != 0U) { + Q_onError(&Q_this_module_[0], 998); + } + ++QS_tstPriv_.intLock; +} +//............................................................................ +void QS_onIntEnable(void) { + --QS_tstPriv_.intLock; + if (QS_tstPriv_.intLock != 0U) { + Q_onError(&Q_this_module_[0], 999); + } +} diff --git a/ports/win32-qv/qf_port.c b/ports/win32-qv/qf_port.c index a2c3d245..68e097ac 100644 --- a/ports/win32-qv/qf_port.c +++ b/ports/win32-qv/qf_port.c @@ -22,8 +22,8 @@ // // //============================================================================ -//! @date Last updated on: 2024-02-15 -//! @version Last updated for: @ref qpc_7_3_3 +//! @date Last updated on: 2024-06-11 +//! @version Last updated for: @ref qpc_7_4_0 //! //! @file //! @brief QF/C port to Win32-QV (single-threaded) diff --git a/ports/win32-qv/qs_port.c b/ports/win32-qv/qs_port.c index 31ef3c57..344d8762 100644 --- a/ports/win32-qv/qs_port.c +++ b/ports/win32-qv/qs_port.c @@ -22,8 +22,8 @@ // // //============================================================================ -//! @date Last updated on: 2024-02-15 -//! @version Last updated for: @ref qpc_7_3_3 +//! @date Last updated on: 2024-06-11 +//! @version Last updated for: @ref qpc_7_4_0 //! //! @file //! @brief QS/C port for Win32 API diff --git a/ports/win32/qf_port.c b/ports/win32/qf_port.c index 119d2f0a..06406325 100644 --- a/ports/win32/qf_port.c +++ b/ports/win32/qf_port.c @@ -22,8 +22,8 @@ // // //============================================================================ -//! @date Last updated on: 2024-02-15 -//! @version Last updated for: @ref qpc_7_3_3 +//! @date Last updated on: 2024-06-11 +//! @version Last updated for: @ref qpc_7_4_0 //! //! @file //! @brief QF/C port to Win32 (multithreaded) diff --git a/ports/win32/qs_port.c b/ports/win32/qs_port.c index 31ef3c57..344d8762 100644 --- a/ports/win32/qs_port.c +++ b/ports/win32/qs_port.c @@ -22,8 +22,8 @@ // // //============================================================================ -//! @date Last updated on: 2024-02-15 -//! @version Last updated for: @ref qpc_7_3_3 +//! @date Last updated on: 2024-06-11 +//! @version Last updated for: @ref qpc_7_4_0 //! //! @file //! @brief QS/C port for Win32 API diff --git a/qpc.md5 b/qpc.md5 index 00a8e5c0..83fd992b 100644 --- a/qpc.md5 +++ b/qpc.md5 @@ -1,8 +1,8 @@ -ce2c6802e00361bbddbdf95a19746c97 *qpc.qm +428e1fb89d8905aaa5fc80ebef1bb0fd *qpc.qm f71fdc0261b7d7e1693f7cf92b269fc0 *include/qequeue.h 57b1efebccde23a26f9d11e822ec379f *include/qk.h 807f80a7a39be52083010803f76b4f05 *include/qmpool.h -452994196124e44d9db81c366f5c9057 *include/qp.h +b492f9909964e645db23a20da495c8e2 *include/qp.h e7b6c999b10d91f5c1adf1fde500e452 *include/qp_pkg.h 01e5748669bf110cd91d0bbe8eb5b206 *include/qpc.h 2f2ed281e63d5803738ab0c92a77171f *include/qs.h @@ -13,16 +13,16 @@ f59bf88705afe5b0acc999f8b47a6745 *include/qsafe.h 431c6e320c14f0b02dbc78e2d49f6431 *include/qv.h 7845e9391f7a94311fd849da56abd8a1 *include/qxk.h a25152f319178420b5b5140ca51ea4ae *src/qf/CMakeLists.txt -b4ade402584ddb981fe5967e1a4418c7 *src/qf/qep_hsm.c -72756ebffc4809e6b934b8189170852f *src/qf/qep_msm.c -762cba96738f7e3fe4ebd66659542b30 *src/qf/qf_act.c -091c7f1f25217df387119df63ee51dd1 *src/qf/qf_actq.c +d6db193ebc951f705c383d01b5ef2ee3 *src/qf/qep_hsm.c +95358d16fc2df768e95057c4400d141c *src/qf/qep_msm.c +14e37e53c5e0aec72ab8f35f94c1b96d *src/qf/qf_act.c +cbd76f4312137262c2fd3ec8a7836fea *src/qf/qf_actq.c 858f4abf264ab69734b4df56b0bfa739 *src/qf/qf_defer.c -29309e868460c232ef237a666b6d02b4 *src/qf/qf_dyn.c +d7bf54c7c065db78e2b9aea9dc972f13 *src/qf/qf_dyn.c 276a142fc226625a51fe678ded9ca642 *src/qf/qf_mem.c e090893c0f33678c6bf267c637c6cb48 *src/qf/qf_ps.c 5a1d0999864f48a688d34e9273868e8b *src/qf/qf_qact.c -0ce5878f6b86d0542503c63049083320 *src/qf/qf_qeq.c +0025254525a7065b35dbb781187cd1e1 *src/qf/qf_qeq.c f9867335faa23f0b57c921c8882e7a52 *src/qf/qf_qmact.c d457172637ab14cf42f99071bc7b8e7a *src/qf/qf_time.c ccd28413fc3a093ca99b03854cf7439b *src/qk/CMakeLists.txt @@ -33,7 +33,7 @@ af0330a6f55fe4cffc70f27fa95baebc *src/qk/qk.c 730d9bea159722e5d2c225e01b5c7875 *src/qs/qs_fp.c 60453f6d2b1f915e6e477cca68cb7fee *src/qs/qs_rx.c 80a31dfc0e24839342fe193779401e7b *src/qs/qstamp.c -53ab2ae396c90e41045b019cdfea21b5 *src/qs/qutest.c +9b60fe2d783f6cc18a9117e339b6ca5d *src/qs/qutest.c cf8fa24441cb9577288f73bdb4effbff *src/qv/CMakeLists.txt a428b106b6a95c80077a156ebe764622 *src/qv/qv.c 3a9240f29676dea5ce3df8fed587ae52 *src/qxk/CMakeLists.txt @@ -47,7 +47,7 @@ c72e1cc89263ebda9462ca6fb8b04326 *src/qxk/qxk_xthr.c 63418574679007d8ec13815cbff46f84 *ports/lint-plus/au-ql-c99.lnt be52f283a42b5b277097b5984181f204 *ports/lint-plus/options.lnt 02803e47d485980bdabc4a5d271288bd *ports/lint-plus/ql-style.lnt -7780e1ccc98afe4077689e31c639a862 *ports/lint-plus/qpc.lnt +77e3b47c56111ca18d91813c586fe126 *ports/lint-plus/qpc.lnt ecca2c20a6e0dc29a1f62aeb500ed165 *ports/lint-plus/std.lnt 8f1b876266fb274386670d94d0ba0fa2 *ports/arm-cm/qk/armclang/qk_port.c 5fcbb1d62dcc33ad8e0f38dfcf6f88a3 *ports/arm-cm/qk/armclang/qp_port.h @@ -109,72 +109,72 @@ d69a97a65c94b684ef56cef35faf73f0 *ports/pic32/qv/xc32/qs_port.h d69a97a65c94b684ef56cef35faf73f0 *ports/pic32/qutest/xc32/qs_port.h 7bd98101a1922e7dcf39107f2c07a7a4 *ports/config/qp_config.h d9a8f8c2b8ebdae309622841af4f80e7 *ports/embos/CMakeLists.txt -acf19d8d939b7e12fca90be762e7c377 *ports/embos/qf_port.c +287838f1571386f28c96de9f1bfd6cad *ports/embos/qf_port.c d5f7e75934bd283d4fa239afee096e78 *ports/embos/qp_port.h d69a97a65c94b684ef56cef35faf73f0 *ports/embos/qs_port.h 9d19cdfdd9eb682d6de7847bd0900f5a *ports/freertos/CMakeLists.txt -21610b5e0eaccb85d82c7edb74fc32dc *ports/freertos/qf_port.c +fe78898e3dbd64b18339adfc56c92826 *ports/freertos/qf_port.c 672615c0e1e9daab9aec12c300682f58 *ports/freertos/qp_port.h d69a97a65c94b684ef56cef35faf73f0 *ports/freertos/qs_port.h 04694f7224092a477cd4580aee7022fd *ports/threadx/CMakeLists.txt -b80df6c2ee6fc3ec6d7a4bf08963ec01 *ports/threadx/qf_port.c +b3d52f613f1c1da008ae5412029af0da *ports/threadx/qf_port.c 74570b4afbf0281af9638778781bda0b *ports/threadx/qp_port.h d69a97a65c94b684ef56cef35faf73f0 *ports/threadx/qs_port.h 97dbc9c6b8b0c2b46499b9070688dd3c *ports/threadx/README.md eec27f333c2787b6f3fdca5dbdd573b2 *ports/uc-os2/CMakeLists.txt -cc34f3f5ffa004831362473563cd345a *ports/uc-os2/qf_port.c +efff763f2b3a151b97cf6685599b0902 *ports/uc-os2/qf_port.c b9be2bca2c48d39a43e4b3d059376b6a *ports/uc-os2/qp_port.h d69a97a65c94b684ef56cef35faf73f0 *ports/uc-os2/qs_port.h 281f9d70e7fb90b4457bee33b544c460 *ports/qep-only/CMakeLists.txt 6ce09e456ded120d13d73a92e022fa3d *ports/qep-only/qp_port.h f26311a1912e214477781255c7c71834 *ports/qep-only/safe_std.h 4577c2c64f7dbb0c81d1e99f20984888 *ports/posix/CMakeLists.txt -0a9db5ee3129a97bd19c433e12f0442e *ports/posix/qf_port.c +ca2e05b42962f7f6e052ffd8775871e3 *ports/posix/qf_port.c c1764d38614122b0a02a0172a21906d9 *ports/posix/qp_port.h -5902d6c50e3d3e87c4cbeb66485c01c9 *ports/posix/qs_port.c +ec516e1c355eb1812937f5efafa6d7bc *ports/posix/qs_port.c a6c1ccba363f62079a579cd71ceccfe8 *ports/posix/qs_port.h 6690cf3899e6461ed7604dba13cf7520 *ports/posix/README.md f26311a1912e214477781255c7c71834 *ports/posix/safe_std.h c36532b0e4b1956d9113f6ced25fb47b *ports/posix-qv/CMakeLists.txt -044efad276cba04709c027cc66b7d356 *ports/posix-qv/qf_port.c +a846079b4b1c41d37399cbd1e2f55b5b *ports/posix-qv/qf_port.c 46cd7f9bce31d6d519886f31f824fae0 *ports/posix-qv/qp_port.h -94d91c859c62fd464f6ce61c9d4e82b1 *ports/posix-qv/qs_port.c +3f783ea4de87adaa1e051c7b7bb0a091 *ports/posix-qv/qs_port.c a6c1ccba363f62079a579cd71ceccfe8 *ports/posix-qv/qs_port.h a39965a1d1c41b224c8f328c9e28999b *ports/posix-qv/README.md f26311a1912e214477781255c7c71834 *ports/posix-qv/safe_std.h 51ca57651ed492278fd728d3b94aba4d *ports/posix-qutest/CMakeLists.txt -2ec8125e0cbaf03c06c679d698ec6a32 *ports/posix-qutest/qp_port.h +b5e1013ec0e5220b4162387de10c9195 *ports/posix-qutest/qp_port.h a6c1ccba363f62079a579cd71ceccfe8 *ports/posix-qutest/qs_port.h -a7e763528627d662501e8a28ca6321c1 *ports/posix-qutest/qutest_port.c +209bf23f8e9b4f5e213f947e8379b476 *ports/posix-qutest/qutest_port.c f26311a1912e214477781255c7c71834 *ports/posix-qutest/safe_std.h 5fa44dffb653cecb1d9ea41d154ce852 *ports/win32/CMakeLists.txt -20fc7e8b39e32f53aca8e3f08e372957 *ports/win32/qf_port.c +e1be9341bd19c34eb9be9df56a2491cc *ports/win32/qf_port.c dddd41fe592d8832b95179820de552d2 *ports/win32/qp_port.h -a46c047f83877a192b2de24f27238770 *ports/win32/qs_port.c +f1eb6964f5ea37db0fa4ba6ca0ff3f02 *ports/win32/qs_port.c 68809b0a38489524f2ed461e970a136c *ports/win32/qs_port.h 635a4a93c62e4b3501c5e3371a08cd65 *ports/win32/qwin_gui.c a8f227294c6673a22b050e1165a911e3 *ports/win32/qwin_gui.h 9af4450a3685e578e1774e5b707f6692 *ports/win32/README.md f26311a1912e214477781255c7c71834 *ports/win32/safe_std.h c28c6dd7ad5899389e556c8cc61692ce *ports/win32-qv/CMakeLists.txt -7d3aaf7289eb37ac9ef638d092f1d28f *ports/win32-qv/qf_port.c +58b63f82b35e14ff2ff1c2e913e743ea *ports/win32-qv/qf_port.c 6e8a4ca279ced37f24ac45e4ff6d4157 *ports/win32-qv/qp_port.h -a46c047f83877a192b2de24f27238770 *ports/win32-qv/qs_port.c +f1eb6964f5ea37db0fa4ba6ca0ff3f02 *ports/win32-qv/qs_port.c 68809b0a38489524f2ed461e970a136c *ports/win32-qv/qs_port.h c935dbe9f32dd4d0584d4b47bc734d19 *ports/win32-qv/qwin_gui.c 37499e3a99c8c38d52d9b61be19319b7 *ports/win32-qv/qwin_gui.h 4cb22092a4b28d1c1b2efc1e58900b99 *ports/win32-qv/README.md f26311a1912e214477781255c7c71834 *ports/win32-qv/safe_std.h f62276b6a322c8fffce657cdb4998ed7 *ports/win32-qutest/CMakeLists.txt -f9f1dfd9b7c2f0ce7b2c5928da09b123 *ports/win32-qutest/qp_port.h +7b72d04255c0da489b834dbf4bfaa599 *ports/win32-qutest/qp_port.h 68809b0a38489524f2ed461e970a136c *ports/win32-qutest/qs_port.h -d8259b2bb16d1826806a636c6a3293f8 *ports/win32-qutest/qutest_port.c +d0dc53c6e37871ccfc69fe32467c97a7 *ports/win32-qutest/qutest_port.c faed3388f63c9ec3dca2a5c6cf808a95 *ports/win32-qutest/README.md f26311a1912e214477781255c7c71834 *ports/win32-qutest/safe_std.h 2d72fa12f8a0c05bd23c0fc4fa41838c *zephyr/CMakeLists.txt 1c41081d80b88d187161f56605d1ea64 *zephyr/Kconfig 2140500a5b230057a2a6ed4b613f6353 *zephyr/module.yml -f167809c37f879a55cbc113e0e4d6ef6 *zephyr/qf_port.c +ae448b93666db2dc14bb169a7d47b321 *zephyr/qf_port.c 0076e0da63938ff838dd5736b6a309da *zephyr/qp-zephyr.jpg 4332e3b86722b1ccfed1dd134889fcac *zephyr/qp_port.h d69a97a65c94b684ef56cef35faf73f0 *zephyr/qs_port.h diff --git a/qpc.qm b/qpc.qm index ec55e767..98efe7ee 100644 --- a/qpc.qm +++ b/qpc.qm @@ -115,7 +115,7 @@ Contact information: - + Q_DEFINE_THIS_MODULE(__FILE__) @@ -893,6 +893,8 @@ do { #ifndef Q_UNSAFE me->super.temp.uint = ~me->super.state.uint; +#else +Q_UNUSED_PAR(isFound); #endif QF_CRIT_STAT @@ -1424,7 +1426,10 @@ return inState; const - //! @deprecated instead use: QASM_IS_IN() + //! @private @memberof QMsm +//! @deprecated instead use: QASM_IS_IN() + +//! @private @memberof QMsm bool inState = false; // assume that this SM is not in 'state' @@ -2233,7 +2238,9 @@ return (me->bits[0] == (QPSetBits)(~dis->bits[0])) - //! @static @private @memberof QActive + //! @static @private @memberof QActive + +//! @static @private @memberof QActive @@ -2404,8 +2411,10 @@ QF_CRIT_ENTRY(); QF_MEM_SYS(); #ifndef Q_UNSAFE +Q_REQUIRE_INCRIT(100, QEvt_verify_(e)); + uint8_t const pcopy = (uint8_t)(~me->prio_dis); -Q_INVARIANT_INCRIT(102, (QEvt_verify_(e)) && (me->prio == pcopy)); +Q_INVARIANT_INCRIT(102, me->prio == pcopy); #endif QEQueueCtr nFree = me->eQueue.nFree; // get volatile into temporary @@ -2461,7 +2470,13 @@ if (status) { // can post the event? // as producing the #QS_QF_ACTIVE_POST trace record, which are: // the local filter for this AO ('me->prio') is set if (QS_LOC_CHECK_(me->prio)) { + QF_MEM_APP(); + QF_CRIT_EXIT(); + QS_onTestPost(sender, me, e, status); + + QF_CRIT_ENTRY(); + QF_MEM_SYS(); } #endif @@ -2510,7 +2525,13 @@ else { // cannot post the event // as producing the #QS_QF_ACTIVE_POST trace record, which are: // the local filter for this AO ('me->prio') is set if (QS_LOC_CHECK_(me->prio)) { + QF_MEM_APP(); + QF_CRIT_EXIT(); + QS_onTestPost(sender, me, e, status); + + QF_CRIT_ENTRY(); + QF_MEM_SYS(); } #endif @@ -2545,8 +2566,10 @@ QF_CRIT_ENTRY(); QF_MEM_SYS(); #ifndef Q_UNSAFE +Q_REQUIRE_INCRIT(200, QEvt_verify_(e)); + uint8_t const pcopy = (uint8_t)(~me->prio_dis); -Q_INVARIANT_INCRIT(202, (QEvt_verify_(e)) && (me->prio == pcopy)); +Q_INVARIANT_INCRIT(202, me->prio == pcopy); #endif #ifdef QXK_H_ @@ -2587,7 +2610,13 @@ QS_END_PRE_() // as producing the #QS_QF_ACTIVE_POST trace record, which are: // the local filter for this AO ('me->prio') is set if (QS_LOC_CHECK_(me->prio)) { + QF_MEM_APP(); + QF_CRIT_EXIT(); + QS_onTestPost((QActive *)0, me, e, true); + + QF_CRIT_ENTRY(); + QF_MEM_SYS(); } #endif @@ -2622,6 +2651,8 @@ QACTIVE_EQUEUE_WAIT_(me); // wait for event to arrive directly // always remove event from the front QEvt const * const e = me->eQueue.frontEvt; +Q_INVARIANT_INCRIT(312, QEvt_verify_(e)); + QEQueueCtr const nFree = me->eQueue.nFree + 1U; // get volatile into tmp me->eQueue.nFree = nFree; // update the # free @@ -3701,7 +3732,7 @@ QF_CRIT_STAT QF_CRIT_ENTRY(); QF_MEM_SYS(); -Q_REQUIRE_INCRIT(200, e != (QEvt *)0); +Q_REQUIRE_INCRIT(200, QEvt_verify_(e)); QEQueueCtr nFree = me->nFree; // get volatile into temporary @@ -3782,9 +3813,10 @@ QF_CRIT_STAT QF_CRIT_ENTRY(); QF_MEM_SYS(); -QEQueueCtr nFree = me->nFree; // get volatile into temporary +Q_REQUIRE_INCRIT(300, QEvt_verify_(e)); -Q_REQUIRE_INCRIT(300, nFree != 0U); +QEQueueCtr nFree = me->nFree; // get volatile into temporary +Q_REQUIRE_INCRIT(301, nFree != 0U); if (QEvt_getPoolNum_(e) != 0U) { // is it a mutable event? QEvt_refCtr_inc_(e); // increment the reference counter @@ -3837,6 +3869,8 @@ QF_MEM_SYS(); QEvt const * const e = me->frontEvt; // always remove evt from the front if (e != (QEvt *)0) { // was the queue not empty? + Q_INVARIANT_INCRIT(412, QEvt_verify_(e)); + // use a temporary variable to increment me->nFree QEQueueCtr const nFree = me->nFree + 1U; me->nFree = nFree; // update the # free @@ -3861,7 +3895,7 @@ if (e != (QEvt *)0) { // was the queue not empty? me->frontEvt = (QEvt *)0; // queue becomes empty // all entries in the queue must be free (+1 for fronEvt) - Q_ASSERT_INCRIT(410, nFree == (me->end + 1U)); + Q_INVARIANT_INCRIT(420, nFree == (me->end + 1U)); QS_BEGIN_PRE_(QS_QF_EQUEUE_GET_LAST, qsId) QS_TIME_PRE_(); // timestamp @@ -4405,7 +4439,7 @@ return e; QF_CRIT_STAT QF_CRIT_ENTRY(); -Q_INVARIANT_INCRIT(402, QEvt_verify_(e)); +Q_REQUIRE_INCRIT(400, QEvt_verify_(e)); uint_fast8_t const poolNum = QEvt_getPoolNum_(e); @@ -4472,11 +4506,12 @@ Q_UNUSED_PAR(evtRef); QF_CRIT_STAT QF_CRIT_ENTRY(); -Q_INVARIANT_INCRIT(502, QEvt_verify_(e)); +Q_REQUIRE_INCRIT(500, QEvt_verify_(e)); uint_fast8_t const poolNum = QEvt_getPoolNum_(e); +Q_UNUSED_PAR(poolNum); // might be unused -Q_REQUIRE_INCRIT(500, (poolNum != 0U) +Q_REQUIRE_INCRIT(501, (poolNum != 0U) && (evtRef == (void *)0)); QEvt_refCtr_inc_(e); // increments the ref counter @@ -4501,11 +4536,11 @@ return e; //! @static @private @memberof QF - QEvt const * const e = (QEvt const *)evtRef; - -QF_CRIT_STAT + QF_CRIT_STAT QF_CRIT_ENTRY(); -Q_INVARIANT_INCRIT(602, QEvt_verify_(e)); + +QEvt const * const e = (QEvt const *)evtRef; +Q_REQUIRE_INCRIT(600, QEvt_verify_(e)); #ifdef Q_SPY uint_fast8_t const poolNum = QEvt_getPoolNum_(e); @@ -8102,15 +8137,15 @@ QPSet_update_(&QS_tstPriv_.readySet, &QS_tstPriv_.readySet_dis); //! QF_run() stub for QUTest - QS_CRIT_STAT -QS_CRIT_ENTRY(); -QS_MEM_SYS(); - -// function dictionaries for the standard API + // function dictionaries for the standard API QS_FUN_DICTIONARY(&QActive_post_); QS_FUN_DICTIONARY(&QActive_postLIFO_); QS_FUN_DICTIONARY(&QS_processTestEvts_); +QS_CRIT_STAT +QS_CRIT_ENTRY(); +QS_MEM_SYS(); + // produce the QS_QF_RUN trace record QS_BEGIN_PRE_(QS_QF_RUN, 0U) QS_END_PRE_() @@ -8448,14 +8483,15 @@ QS_BEGIN_PRE_(rec, me->prio) QS_EQC_PRE_(margin); // margin requested QS_END_PRE_() +QF_MEM_APP(); +QF_CRIT_EXIT(); + // callback to examine the posted event under the same conditions // as producing the #QS_QF_ACTIVE_POST trace record, which are: // the local filter for this AO ('me->prio') is set if (QS_LOC_CHECK_(me->prio)) { QS_onTestPost(sender, me, e, status); } -QF_MEM_APP(); -QF_CRIT_EXIT(); // recycle the event immediately, because it was not really posted #if (QF_MAX_EPOOL > 0U) @@ -8499,15 +8535,15 @@ QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio) QS_EQC_PRE_(0U); // min # free entries QS_END_PRE_() +QF_MEM_APP(); +QF_CRIT_EXIT(); + // callback to examine the posted event under the same conditions // as producing the #QS_QF_ACTIVE_POST trace record, which are: // the local filter for this AO ('me->prio') is set if (QS_LOC_CHECK_(me->prio)) { QS_onTestPost((QActive *)0, me, e, true); } -QF_MEM_APP(); -QF_CRIT_EXIT(); - // recycle the event immediately, because it was not really posted #if (QF_MAX_EPOOL > 0U) QF_gc(e); diff --git a/src/qf/qep_hsm.c b/src/qf/qep_hsm.c index 00d753ff..5f00590c 100644 --- a/src/qf/qep_hsm.c +++ b/src/qf/qep_hsm.c @@ -538,6 +538,8 @@ QStateHandler QHsm_childState(QHsm * const me, #ifndef Q_UNSAFE me->super.temp.uint = ~me->super.state.uint; + #else + Q_UNUSED_PAR(isFound); #endif QF_CRIT_STAT diff --git a/src/qf/qep_msm.c b/src/qf/qep_msm.c index 47f7805a..5ae1ee50 100644 --- a/src/qf/qep_msm.c +++ b/src/qf/qep_msm.c @@ -409,6 +409,7 @@ bool QMsm_isIn_( } //${QEP::QMsm::isInState} .................................................... +//! @private @memberof QMsm bool QMsm_isInState(QMsm const * const me, QMState const * const stateObj) { diff --git a/src/qf/qf_act.c b/src/qf/qf_act.c index a04c0cd6..8d795a9c 100644 --- a/src/qf/qf_act.c +++ b/src/qf/qf_act.c @@ -61,6 +61,7 @@ //$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //$define${QF::QActive::registry_[QF_MAX_ACTIVE + 1U]} vvvvvvvvvvvvvvvvvvvvvvv +//! @static @private @memberof QActive QActive * QActive_registry_[QF_MAX_ACTIVE + 1U]; //$enddef${QF::QActive::registry_[QF_MAX_ACTIVE + 1U]} ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/qf/qf_actq.c b/src/qf/qf_actq.c index 9ac61449..c1ea9a7a 100644 --- a/src/qf/qf_actq.c +++ b/src/qf/qf_actq.c @@ -87,8 +87,10 @@ bool QActive_post_(QActive * const me, QF_MEM_SYS(); #ifndef Q_UNSAFE + Q_REQUIRE_INCRIT(100, QEvt_verify_(e)); + uint8_t const pcopy = (uint8_t)(~me->prio_dis); - Q_INVARIANT_INCRIT(102, (QEvt_verify_(e)) && (me->prio == pcopy)); + Q_INVARIANT_INCRIT(102, me->prio == pcopy); #endif QEQueueCtr nFree = me->eQueue.nFree; // get volatile into temporary @@ -144,7 +146,13 @@ bool QActive_post_(QActive * const me, // as producing the #QS_QF_ACTIVE_POST trace record, which are: // the local filter for this AO ('me->prio') is set if (QS_LOC_CHECK_(me->prio)) { + QF_MEM_APP(); + QF_CRIT_EXIT(); + QS_onTestPost(sender, me, e, status); + + QF_CRIT_ENTRY(); + QF_MEM_SYS(); } #endif @@ -193,7 +201,13 @@ bool QActive_post_(QActive * const me, // as producing the #QS_QF_ACTIVE_POST trace record, which are: // the local filter for this AO ('me->prio') is set if (QS_LOC_CHECK_(me->prio)) { + QF_MEM_APP(); + QF_CRIT_EXIT(); + QS_onTestPost(sender, me, e, status); + + QF_CRIT_ENTRY(); + QF_MEM_SYS(); } #endif @@ -229,8 +243,10 @@ void QActive_postLIFO_(QActive * const me, QF_MEM_SYS(); #ifndef Q_UNSAFE + Q_REQUIRE_INCRIT(200, QEvt_verify_(e)); + uint8_t const pcopy = (uint8_t)(~me->prio_dis); - Q_INVARIANT_INCRIT(202, (QEvt_verify_(e)) && (me->prio == pcopy)); + Q_INVARIANT_INCRIT(202, me->prio == pcopy); #endif #ifdef QXK_H_ @@ -271,7 +287,13 @@ void QActive_postLIFO_(QActive * const me, // as producing the #QS_QF_ACTIVE_POST trace record, which are: // the local filter for this AO ('me->prio') is set if (QS_LOC_CHECK_(me->prio)) { + QF_MEM_APP(); + QF_CRIT_EXIT(); + QS_onTestPost((QActive *)0, me, e, true); + + QF_CRIT_ENTRY(); + QF_MEM_SYS(); } #endif @@ -307,6 +329,8 @@ QEvt const * QActive_get_(QActive * const me) { // always remove event from the front QEvt const * const e = me->eQueue.frontEvt; + Q_INVARIANT_INCRIT(312, QEvt_verify_(e)); + QEQueueCtr const nFree = me->eQueue.nFree + 1U; // get volatile into tmp me->eQueue.nFree = nFree; // update the # free diff --git a/src/qf/qf_dyn.c b/src/qf/qf_dyn.c index dd7934fe..8ec45266 100644 --- a/src/qf/qf_dyn.c +++ b/src/qf/qf_dyn.c @@ -218,7 +218,7 @@ QEvt * QF_newX_( void QF_gc(QEvt const * const e) { QF_CRIT_STAT QF_CRIT_ENTRY(); - Q_INVARIANT_INCRIT(402, QEvt_verify_(e)); + Q_REQUIRE_INCRIT(400, QEvt_verify_(e)); uint_fast8_t const poolNum = QEvt_getPoolNum_(e); @@ -283,11 +283,12 @@ QEvt const * QF_newRef_( QF_CRIT_STAT QF_CRIT_ENTRY(); - Q_INVARIANT_INCRIT(502, QEvt_verify_(e)); + Q_REQUIRE_INCRIT(500, QEvt_verify_(e)); uint_fast8_t const poolNum = QEvt_getPoolNum_(e); + Q_UNUSED_PAR(poolNum); // might be unused - Q_REQUIRE_INCRIT(500, (poolNum != 0U) + Q_REQUIRE_INCRIT(501, (poolNum != 0U) && (evtRef == (void *)0)); QEvt_refCtr_inc_(e); // increments the ref counter @@ -309,11 +310,11 @@ QEvt const * QF_newRef_( //${QF::QF-dyn::deleteRef_} .................................................. //! @static @private @memberof QF void QF_deleteRef_(void const * const evtRef) { - QEvt const * const e = (QEvt const *)evtRef; - QF_CRIT_STAT QF_CRIT_ENTRY(); - Q_INVARIANT_INCRIT(602, QEvt_verify_(e)); + + QEvt const * const e = (QEvt const *)evtRef; + Q_REQUIRE_INCRIT(600, QEvt_verify_(e)); #ifdef Q_SPY uint_fast8_t const poolNum = QEvt_getPoolNum_(e); diff --git a/src/qf/qf_qeq.c b/src/qf/qf_qeq.c index ff13f1e6..d7b1ad0a 100644 --- a/src/qf/qf_qeq.c +++ b/src/qf/qf_qeq.c @@ -108,7 +108,7 @@ bool QEQueue_post(QEQueue * const me, QF_CRIT_ENTRY(); QF_MEM_SYS(); - Q_REQUIRE_INCRIT(200, e != (QEvt *)0); + Q_REQUIRE_INCRIT(200, QEvt_verify_(e)); QEQueueCtr nFree = me->nFree; // get volatile into temporary @@ -187,9 +187,10 @@ void QEQueue_postLIFO(QEQueue * const me, QF_CRIT_ENTRY(); QF_MEM_SYS(); - QEQueueCtr nFree = me->nFree; // get volatile into temporary + Q_REQUIRE_INCRIT(300, QEvt_verify_(e)); - Q_REQUIRE_INCRIT(300, nFree != 0U); + QEQueueCtr nFree = me->nFree; // get volatile into temporary + Q_REQUIRE_INCRIT(301, nFree != 0U); if (QEvt_getPoolNum_(e) != 0U) { // is it a mutable event? QEvt_refCtr_inc_(e); // increment the reference counter @@ -241,6 +242,8 @@ struct QEvt const * QEQueue_get(QEQueue * const me, QEvt const * const e = me->frontEvt; // always remove evt from the front if (e != (QEvt *)0) { // was the queue not empty? + Q_INVARIANT_INCRIT(412, QEvt_verify_(e)); + // use a temporary variable to increment me->nFree QEQueueCtr const nFree = me->nFree + 1U; me->nFree = nFree; // update the # free @@ -265,7 +268,7 @@ struct QEvt const * QEQueue_get(QEQueue * const me, me->frontEvt = (QEvt *)0; // queue becomes empty // all entries in the queue must be free (+1 for fronEvt) - Q_ASSERT_INCRIT(410, nFree == (me->end + 1U)); + Q_INVARIANT_INCRIT(420, nFree == (me->end + 1U)); QS_BEGIN_PRE_(QS_QF_EQUEUE_GET_LAST, qsId) QS_TIME_PRE_(); // timestamp diff --git a/src/qs/qutest.c b/src/qs/qutest.c index 91f5b2d8..644fc6cf 100644 --- a/src/qs/qutest.c +++ b/src/qs/qutest.c @@ -189,15 +189,15 @@ void QF_stop(void) { //${QS::QUTest-stub::QF::run} ................................................ int_t QF_run(void) { - QS_CRIT_STAT - QS_CRIT_ENTRY(); - QS_MEM_SYS(); - // function dictionaries for the standard API QS_FUN_DICTIONARY(&QActive_post_); QS_FUN_DICTIONARY(&QActive_postLIFO_); QS_FUN_DICTIONARY(&QS_processTestEvts_); + QS_CRIT_STAT + QS_CRIT_ENTRY(); + QS_MEM_SYS(); + // produce the QS_QF_RUN trace record QS_BEGIN_PRE_(QS_QF_RUN, 0U) QS_END_PRE_() @@ -500,14 +500,15 @@ bool QActiveDummy_fakePost_( QS_EQC_PRE_(margin); // margin requested QS_END_PRE_() + QF_MEM_APP(); + QF_CRIT_EXIT(); + // callback to examine the posted event under the same conditions // as producing the #QS_QF_ACTIVE_POST trace record, which are: // the local filter for this AO ('me->prio') is set if (QS_LOC_CHECK_(me->prio)) { QS_onTestPost(sender, me, e, status); } - QF_MEM_APP(); - QF_CRIT_EXIT(); // recycle the event immediately, because it was not really posted #if (QF_MAX_EPOOL > 0U) @@ -549,15 +550,15 @@ void QActiveDummy_fakePostLIFO_( QS_EQC_PRE_(0U); // min # free entries QS_END_PRE_() + QF_MEM_APP(); + QF_CRIT_EXIT(); + // callback to examine the posted event under the same conditions // as producing the #QS_QF_ACTIVE_POST trace record, which are: // the local filter for this AO ('me->prio') is set if (QS_LOC_CHECK_(me->prio)) { QS_onTestPost((QActive *)0, me, e, true); } - QF_MEM_APP(); - QF_CRIT_EXIT(); - // recycle the event immediately, because it was not really posted #if (QF_MAX_EPOOL > 0U) QF_gc(e); diff --git a/test/qk/test_sched/bsp_efm32pg1b.c b/test/qk/test_sched/bsp_efm32pg1b.c index 4ab719cc..ec8eb486 100644 --- a/test/qk/test_sched/bsp_efm32pg1b.c +++ b/test/qk/test_sched/bsp_efm32pg1b.c @@ -40,7 +40,7 @@ #include "em_usart.h" // USART (SiLabs) // add other drivers if necessary... -Q_DEFINE_THIS_FILE +Q_DEFINE_THIS_FILE; // ISRs defined in this BSP ------------------------------------------------ void SysTick_Handler(void); diff --git a/test/qk/test_sched/bsp_nucleo-c031c6.c b/test/qk/test_sched/bsp_nucleo-c031c6.c index 54ae3559..ddcf94b8 100644 --- a/test/qk/test_sched/bsp_nucleo-c031c6.c +++ b/test/qk/test_sched/bsp_nucleo-c031c6.c @@ -1,34 +1,32 @@ //============================================================================ // Product: BSP for system-testing of QK kernel, NUCLEO-C031C6 board -// Last updated for version 7.3.0 -// Last updated on 2023-07-18 +// Last updated for version 7.4.0 +// Last updated on 2024-06-24 // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// Copyright (C) 2005 Quantum Leaps, LLC. // -// This program is open source software: you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published -// by the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// Alternatively, this program may be distributed and modified under the -// terms of Quantum Leaps commercial licenses, which expressly supersede -// the GNU General Public License and are specifically designed for -// licensees interested in retaining the proprietary status of their code. +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. // -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// The terms of the open source GNU General Public License version 3 +// can be found at: // -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. // // Contact information: -// +// // //============================================================================ #include "qpc.h" @@ -215,11 +213,11 @@ void BSP_init(void) { void BSP_terminate(int16_t result) { Q_UNUSED_PAR(result); } -//.......................................................................... +//............................................................................ void BSP_ledOn(void) { GPIOA->BSRR = (1U << LD4_PIN); // turn LD4 on } -//.......................................................................... +//............................................................................ void BSP_ledOff(void) { GPIOA->BSRR = (1U << (LD4_PIN + 16U)); // turn LD4 off } @@ -264,11 +262,11 @@ void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { *(uint32_t volatile *)(ram_base + offset) = value; } -//.......................................................................... +//============================================================================ +// QF callbacks... void QF_onStartup(void) { // NOTE: SystemInit() has been already called from the startup code // but SystemCoreClock needs to be updated - // SystemCoreClockUpdate(); // set up the SysTick timer to fire at BSP_TICKS_PER_SEC rate @@ -276,7 +274,6 @@ void QF_onStartup(void) { // assign all priority bits for preemption-prio. and none to sub-prio. // NOTE: this might have been changed by STM32Cube. - // NVIC_SetPriorityGrouping(0U); // set priorities of ALL ISRs used in the system @@ -288,7 +285,7 @@ void QF_onStartup(void) { // enable IRQs... NVIC_EnableIRQ(EXTI0_1_IRQn); } -//.......................................................................... +//............................................................................ void QF_onCleanup(void) { } //.......................................................................... @@ -302,7 +299,7 @@ void QF_onContextSw(QActive *prev, QActive *next) { } #endif // QF_ON_CONTEXT_SW -//.......................................................................... +//............................................................................ void QK_onIdle(void) { #ifdef Q_SPY QS_rxParse(); // parse all the received bytes @@ -316,10 +313,11 @@ void QK_onIdle(void) { #endif } -// QS callbacks ============================================================ +//============================================================================ +// QS callbacks... #ifdef Q_SPY -//.......................................................................... +//............................................................................ void QTimeEvt_tick1_( uint_fast8_t const tickRate, void const * const sender) @@ -331,6 +329,7 @@ void QTimeEvt_tick1_( } #endif // Q_SPY +//---------------------------------------------------------------------------- //============================================================================ // NOTE0: diff --git a/test/qk/test_sched/bsp_nucleo-u545re.c b/test/qk/test_sched/bsp_nucleo-u545re.c new file mode 100644 index 00000000..64e22485 --- /dev/null +++ b/test/qk/test_sched/bsp_nucleo-u545re.c @@ -0,0 +1,313 @@ +//============================================================================ +// Product: BSP for system-testing of QK kernel, NUCLEO-U545RE-Q board +// Last updated for version 7.4.0 +// Last updated on 2024-06-24 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "bsp.h" + +#include "stm32u545xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... + +Q_DEFINE_THIS_FILE // define the name of this file for assertions + +// Local-scope defines ----------------------------------------------------- +// LED pins available on the board (just one user LED LD2--Green on PA.5) +#define LD2_PIN 5U + +// Button pins available on the board (just one user Button B1 on PC.13) +#define B1_PIN 13U + +// macros from STM32Cube LL: +#define SET_BIT(REG, BIT) ((REG) |= (BIT)) +#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT)) +#define READ_BIT(REG, BIT) ((REG) & (BIT)) +#define CLEAR_REG(REG) ((REG) = (0x0)) +#define WRITE_REG(REG, VAL) ((REG) = (VAL)) +#define READ_REG(REG) ((REG)) +#define MODIFY_REG(REG, CLEARMASK, SETMASK) \ + WRITE_REG((REG), ((READ_REG(REG) & (~(CLEARMASK))) | (SETMASK))) + +#ifdef Q_SPY +// QSpy source IDs +static QSpyId const l_SysTick_Handler = { 100U }; +static QSpyId const l_test_ISR = { 101U }; + +enum AppRecords { // application-specific trace records + CONTEXT_SW = QS_USER1, + TRACE_MSG +}; + +#endif + +// ISRs used in this project ================================================= +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QK_ISR_ENTRY(); // inform QK kernel about entering an ISR + + // process time events for rate 0 + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); + + QK_ISR_EXIT(); // inform QK kernel about exiting an ISR +} +//.......................................................................... +void EXTI0_IRQHandler(void); // prototype +void EXTI0_IRQHandler(void) { // for testing, NOTE03 + QK_ISR_ENTRY(); // inform QXK kernel about entering an ISR + + // for testing... + static QEvt const t1 = QEVT_INITIALIZER(TEST1_SIG); + QACTIVE_PUBLISH(&t1, &l_test_ISR); + + QK_ISR_EXIT(); // inform QK kernel about exiting an ISR +} + +// BSP functions =========================================================== +static void STM32U545RE_MPU_setup(void) { + MPU->CTRL = 0U; // disable the MPU + + MPU->RNR = 0U; // region 0 (for ROM: read-only, can-execute) + MPU->RBAR = (0x08000000U & MPU_RBAR_BASE_Msk) | (0x3U << MPU_RBAR_AP_Pos); + MPU->RLAR = (0x08080000U & MPU_RLAR_LIMIT_Msk) | MPU_RLAR_EN_Msk; + + MPU->RNR = 1U; // region 1 (for RAM1: read-write, execute-never) + MPU->RBAR = (0x20000000U & MPU_RBAR_BASE_Msk) | (0x1U << MPU_RBAR_AP_Pos) + | MPU_RBAR_XN_Msk; + MPU->RLAR = (0x20040000U & MPU_RLAR_LIMIT_Msk) | MPU_RLAR_EN_Msk; + + MPU->RNR = 2U; // region 2 (for RAM2: read-write, execute-never) + MPU->RBAR = (0x28000000U & MPU_RBAR_BASE_Msk) | (0x1U << MPU_RBAR_AP_Pos) + | MPU_RBAR_XN_Msk; + MPU->RLAR = (0x28004000U & MPU_RLAR_LIMIT_Msk) | MPU_RLAR_EN_Msk; + + MPU->RNR = 7U; // region 7 (no access: for NULL pointer protection) + MPU->RBAR = (0x00000000U & MPU_RBAR_BASE_Msk) | MPU_RBAR_XN_Msk; + MPU->RLAR = (0x00080000U & MPU_RLAR_LIMIT_Msk) | MPU_RLAR_EN_Msk; + __DMB(); + + MPU->CTRL = MPU_CTRL_ENABLE_Msk | MPU_CTRL_PRIVDEFENA_Msk; + + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + + __DSB(); + __ISB(); +} +//.......................................................................... +void BSP_init(void) { + // setup the MPU... + STM32U545RE_MPU_setup(); + + // initialize I-CACHE + MODIFY_REG(ICACHE->CR, ICACHE_CR_WAYSEL, 0U); // 1-way + SET_BIT(ICACHE->CR, ICACHE_CR_EN); // enable + + // flash prefetch buffer enable + SET_BIT(FLASH->ACR, FLASH_ACR_PRFTEN); + + // enable PWR clock interface + SET_BIT(RCC->AHB3ENR, RCC_AHB3ENR_PWREN); + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + SystemCoreClockUpdate(); + + // enable GPIOA clock port for the LED LD4 + RCC->AHB2ENR1 |= RCC_AHB2ENR1_GPIOAEN; + + // set all used GPIOA pins as push-pull output, no pull-up, pull-down + MODIFY_REG(GPIOA->OSPEEDR, + GPIO_OSPEEDR_OSPEED0 << (LD2_PIN * GPIO_OSPEEDR_OSPEED1_Pos), + 1U << (LD2_PIN * GPIO_OSPEEDR_OSPEED1_Pos)); // speed==1 + MODIFY_REG(GPIOA->OTYPER, + 1U << LD2_PIN, + 0U << LD2_PIN); // output + MODIFY_REG(GPIOA->PUPDR, + GPIO_PUPDR_PUPD0 << (LD2_PIN * GPIO_PUPDR_PUPD1_Pos), + 0U << (LD2_PIN * GPIO_PUPDR_PUPD1_Pos)); // PUSHPULL + MODIFY_REG(GPIOA->MODER, + GPIO_MODER_MODE0 << (LD2_PIN * GPIO_MODER_MODE1_Pos), + 1U << (LD2_PIN * GPIO_MODER_MODE1_Pos)); // MODE_1 + + // enable GPIOC clock port for the Button B1 + RCC->AHB2ENR1 |= RCC_AHB2ENR1_GPIOCEN; + + // configure Button B1 pin on GPIOC as input, no pull-up, pull-down + MODIFY_REG(GPIOC->PUPDR, + GPIO_PUPDR_PUPD0 << (B1_PIN * GPIO_PUPDR_PUPD1_Pos), + 0U << (B1_PIN * GPIO_PUPDR_PUPD1_Pos)); // NO PULL + MODIFY_REG(GPIOC->MODER, + GPIO_MODER_MODE0 << (B1_PIN * GPIO_MODER_MODE1_Pos), + 0U << (B1_PIN * GPIO_MODER_MODE1_Pos)); // MODE_0 + + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_OBJ_DICTIONARY(&l_test_ISR); + + QS_USR_DICTIONARY(CONTEXT_SW); + QS_USR_DICTIONARY(TRACE_MSG); +} +//.......................................................................... +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} +//............................................................................ +void BSP_ledOn(void) { + GPIOA->BSRR = (1U << LD2_PIN); // turn LED on +} +//............................................................................ +void BSP_ledOff(void) { + GPIOA->BRR = (1U << LD2_PIN); // turn LED off +} +//.......................................................................... +void BSP_trigISR(void) { + NVIC_SetPendingIRQ(EXTI0_IRQn); +} +//.......................................................................... +void BSP_trace(QActive const *thr, char const *msg) { + QS_BEGIN_ID(TRACE_MSG, 0U) + QS_OBJ(thr); + QS_STR(msg); + QS_END() +} +//.......................................................................... +uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { + int32_t const rom_base = (fromEnd == 0U) + ? 0x08000000 + : 0x08080000 - 4; + return *(uint32_t volatile *)(rom_base + offset); +} +//.......................................................................... +void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { + int32_t const rom_base = (fromEnd == 0U) + ? 0x08000000 + : 0x08080000 - 4; + *(uint32_t volatile *)(rom_base + offset) = value; +} + +//.......................................................................... +uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { + int32_t const ram_base = (fromEnd == 0U) + ? 0x20000000 + : 0x20040000 - 4; + return *(uint32_t volatile *)(ram_base + offset); +} +//.......................................................................... +void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { + int32_t const ram_base = (fromEnd == 0U) + ? 0x20000000 + : 0x20040000 - 4; + *(uint32_t volatile *)(ram_base + offset) = value; +} + +//============================================================================ +// QF callbacks... +void QF_onStartup(void) { + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + SystemCoreClockUpdate(); + + //NOTE: don't start ticking for these tests + //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + // NOTE: this might have been changed by STM32Cube. + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(EXTI0_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // NOTE: priority of UART IRQ used for QS-RX is set in qutest_port.c + // ... + + // enable IRQs... + NVIC_EnableIRQ(EXTI0_IRQn); +} +//............................................................................ +void QF_onCleanup(void) { +} +//.......................................................................... +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//............................................................................ +void QK_onIdle(void) { +#ifdef Q_SPY + QS_rxParse(); // parse all the received bytes + QS_doOutput(); +#elif defined NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M3 MCU. + // + __WFI(); // Wait-For-Interrupt +#endif +} + +//============================================================================ +// QS callbacks... +#ifdef Q_SPY + +//............................................................................ +void QTimeEvt_tick1_( + uint_fast8_t const tickRate, + void const * const sender) +{ + QF_INT_DISABLE(); + // TODO pend the SysTick + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); + QF_INT_ENABLE(); +} + +#endif // Q_SPY +//---------------------------------------------------------------------------- + +//============================================================================ +// NOTE0: +// The MPU protection against NULL-pointer dereferencing sets up a no-access +// MPU region #7 around the NULL address (0x0). The size of this region is set +// to 2^(26+1)==0x0800'0000, because that is the address of Flash in STM32. +// +// REMARK: STM32 MCUs automatically relocate the Flash memory and the Vector +// Table in it to address 0x0800'0000 at startup. However, even though the +// region 0..0x0800'0000 is un-mapped after the relocation, the read access +// is still allowed and causes no CPU exception. Therefore setting up the MPU +// to protect that region is necessary. +// diff --git a/test/qk/test_sched/nucleo-u545re.mak b/test/qk/test_sched/nucleo-u545re.mak new file mode 100644 index 00000000..fb8d523a --- /dev/null +++ b/test/qk/test_sched/nucleo-u545re.mak @@ -0,0 +1,333 @@ +############################################################################## +# Product: Makefile for SYSTEM-Level tests of QP/C on NUCLEO-U545RE-Q, GNU-ARM +# Last Updated for Version: 7.4.0 +# Date of the Last Update: 2024-06-23 +# +# Q u a n t u m L e a P s +# ------------------------ +# Modern Embedded Software +# +# Copyright (C) 2005 Quantum Leaps, LLC. +# +# This program is open source software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Alternatively, this program may be distributed and modified under the +# terms of Quantum Leaps commercial licenses, which expressly supersede +# the GNU General Public License and are specifically designed for +# licensees interested in retaining the proprietary status of their code. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact information: +# +# +############################################################################## +# +# examples of invoking this Makefile: +# make -f nucleo-u545re.mak USB=g: # make, upload to USB drive, run the tests +# make -f nucleo-u545re.mak USB=g: TESTS=philo*.py # make and run the selected tests +# make -f nucleo-u545re.mak HOST=localhost:7705 # connect to host:port +# make -f nucleo-u545re.mak norun # only make but not run the tests +# make -f nucleo-u545re.mak clean # cleanup the build +# make -f nucleo-u545re.mak debug # only run tests in DEBUG mode +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the QTools collection for Windows, see: +# https://github.com/QuantumLeaps/qtools +# + +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../.. +endif + +#----------------------------------------------------------------------------- +# project name, target name, target directory: +# +PROJECT := test_sched +TARGET := nucleo-u545re +TARGET_DIR := $(QPC)/3rd_party/nucleo-u545re/qutest + +#----------------------------------------------------------------------------- +# project directories +# + +# QP port used in this project +QP_PORT_DIR := $(QPC)/ports/arm-cm/qk/gnu + +# make sure that QTOOLS env. variable is defined... +ifeq ("$(wildcard $(QTOOLS))","") +$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) +endif + + +# list of all source directories used by this project +VPATH := . \ + $(QPC)/src/qf \ + $(QPC)/src/qk \ + $(QPC)/src/qs \ + $(QP_PORT_DIR) \ + $(TARGET_DIR) \ + $(QPC)/3rd_party/nucleo-u545re \ + $(QPC)/3rd_party/nucleo-u545re/gnu + +# list of all include directories needed by this project +INCLUDES = -I. \ + -I$(QPC)/include \ + -I$(QP_PORT_DIR) \ + -I$(TARGET_DIR) \ + -I$(QPC)/3rd_party/CMSIS/Include \ + -I$(QPC)/3rd_party/nucleo-u545re + +#----------------------------------------------------------------------------- +# project files +# + +# assembler source files +ASM_SRCS := + +# C source files +C_SRCS := \ + test_sched.c \ + bsp_nucleo-u545re.c \ + system_stm32u5xx.c \ + startup_stm32u545retxq.c + +# C++ source files +CPP_SRCS := + +OUTPUT := $(PROJECT) +LD_SCRIPT := $(TARGET_DIR)/qutest.ld + +QP_SRCS := \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qk.c \ + qk_port.c \ + qs.c \ + qs_rx.c \ + qs_fp.c \ + qutest.c \ + qutest_port.c + +QP_ASMS := + +LIB_DIRS := +LIBS := + +# defines +DEFINES := -DSTM32U545xx \ + -DQP_API_VERSION=9999 \ + -DQF_ON_CONTEXT_SW + +# ARM CPU, ARCH, FPU, and Float-ABI types... +# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] +# ARM_FPU: [ | vfp] +# FLOAT_ABI: [ | soft | softfp | hard] +# +ARM_CPU := -mcpu=cortex-m33 +ARM_FPU := -mfpu=fpv5-sp-d16 +FLOAT_ABI := -mfloat-abi=hard -mthumb + +#----------------------------------------------------------------------------- +# GNU-ARM toolset (NOTE: You need to adjust to your machine) +# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads +# +ifeq ($(GNU_ARM),) +GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi +endif + +# make sure that the GNU-ARM toolset exists... +ifeq ("$(wildcard $(GNU_ARM))","") +$(error GNU_ARM toolset not found. Please adjust the Makefile) +endif + +CC := $(GNU_ARM)/bin/arm-none-eabi-gcc +CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ +AS := $(GNU_ARM)/bin/arm-none-eabi-as +LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc +BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy + +#----------------------------------------------------------------------------- +# NOTE: The symbol USB must be provided for the NUCLEO board +# has enumerated as USB drive f: +# +ifeq ($(USB),) +$(error USB drive not provided for the NUCLEO board.) +endif + +############################################################################## +# Typically you should not need to change anything below this line + +# basic utilities (included in QTools for Windows), see: +# https://www.state-machine.com/qtools + +MKDIR := mkdir +RM := rm +CP := cp +SLEEP := sleep + +#----------------------------------------------------------------------------- +# QUTest test script utilities (requires QTOOLS): +# +ifeq ("$(wildcard $(QUTEST))","") +QUTEST := python3 $(QTOOLS)/qutest/qutest.py +endif + +#----------------------------------------------------------------------------- +# build options +# + +# combine all the sources... +C_SRCS += $(QP_SRCS) +ASM_SRCS += $(QP_ASMS) + +BIN_DIR := build_$(TARGET) + +ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + + +# NOTE: +# Setting -DQ_UTEST=0 means that QUTest should be built WITHOUT +# the QP-stub for testing QP itself +# +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 + +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 + + +LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ + -specs=nosys.specs -specs=nano.specs \ + -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) + +ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) +C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) +CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) + +TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin +TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf +ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +.PHONY : run norun debug flash + +ifeq ($(MAKECMDGOALS),norun) +all : $(TARGET_BIN) +norun : all +else +all : $(TARGET_BIN) run +endif + +$(TARGET_BIN) : $(TARGET_ELF) + $(BIN) -O binary $< $@ + $(CP) $@ $(USB) + $(SLEEP) 2 + +$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +flash : + $(CP) $(TARGET_BIN) $(USB) + +run : $(TARGET_BIN) + $(QUTEST) -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.s + $(AS) $(ASFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +# create BIN_DIR and include dependencies only if needed +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) + ifneq ($(MAKECMDGOALS),debug) +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif + endif +endif + +debug : + $(QUTEST) -edebug -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) + +.PHONY : clean show + +clean : + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(BIN_DIR)/*.bin \ + $(BIN_DIR)/*.elf \ + $(BIN_DIR)/*.map + +show : + @echo PROJECT = $(PROJECT) + @echo MAKECMDGOALS = $(MAKECMDGOALS) + @echo TESTS = $(TESTS) + @echo TARGET_ELF = $(TARGET_ELF) + @echo CONF = $(CONF) + @echo VPATH = $(VPATH) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo ASM_SRCS = $(ASM_SRCS) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) + @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) + @echo LIB_DIRS = $(LIB_DIRS) + @echo LIBS = $(LIBS) + @echo DEFINES = $(DEFINES) + @echo QTOOLS = $(QTOOLS) + @echo HOST = $(HOST) + @echo QUTEST = $(QUTEST) + @echo TESTS = $(TESTS) + diff --git a/test/qk/test_sched/test_sched.py b/test/qk/test_sched/test_sched.py index bfc5e823..6d7e1263 100644 --- a/test/qk/test_sched/test_sched.py +++ b/test/qk/test_sched/test_sched.py @@ -1,7 +1,9 @@ # test-script for QUTest unit testing harness # see https://www.state-machine.com/qtools/qutest.html/qutest.html -tag('''@uid{TQP603} +required(VERSION >= 740, "QUTest VERSION >= 740 required") + +note('''@uid{TST-QP-QK_02} This test group verifies the preemption scenarios in the QK preemptive kernel ''') @@ -17,172 +19,205 @@ def on_reset(): def Q_PRIO(prio, pthre): return prio | (pthre << 8) -scenario("Scenario: ao->ao->ao (NO PTS)") -# given... -current_obj(OBJ_AP, "pspecB") -poke(0, 2, pack("2") -expect("@timestamp CONTEXT_SW NULL aoB[1]") -expect("@timestamp TRACE_MSG aoB[1] TEST0 1of2") -expect("@timestamp Sch-Next Pri=2->3") -expect("@timestamp CONTEXT_SW aoB[1] aoB[2]") -expect("@timestamp TRACE_MSG aoB[2] TEST1 1of2") -expect("@timestamp Sch-Lock Ceil=0->3") -expect("@timestamp Sch-Unlk Ceil=3->0") -expect("@timestamp TRACE_MSG aoB[2] TEST1 2of2") -expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") -expect("@timestamp Sch-Next Pri=3->2") -expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") -expect("@timestamp TRACE_MSG aoB[1] TEST0 2of2") -expect("@timestamp TRACE_MSG aoB[1] TEST1 1of2") -expect("@timestamp Sch-Lock Ceil=0->3") -expect("@timestamp Sch-Unlk Ceil=3->0") -expect("@timestamp Sch-Next Pri=2->3") -expect("@timestamp CONTEXT_SW aoB[1] aoB[2]") -expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") -expect("@timestamp Sch-Next Pri=3->2") -expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") -expect("@timestamp TRACE_MSG aoB[1] TEST1 2of2") -expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") -expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") -expect("@timestamp Sch-Next Pri=2->1") -expect("@timestamp CONTEXT_SW aoB[1] aoB[0]") -expect("@timestamp TRACE_MSG aoB[0] TEST1 1of2") -expect("@timestamp Sch-Lock Ceil=0->3") -expect("@timestamp Sch-Unlk Ceil=3->0") -expect("@timestamp Sch-Next Pri=1->3") -expect("@timestamp CONTEXT_SW aoB[0] aoB[2]") -expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") -expect("@timestamp Sch-Next Pri=3->2") -expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") -expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") -expect("@timestamp Sch-Next Pri=2->1") -expect("@timestamp CONTEXT_SW aoB[1] aoB[0]") -expect("@timestamp TRACE_MSG aoB[0] TEST1 2of2") -expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") -expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") -expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") -expect("@timestamp Sch-Idle Pri=1->0") -expect("@timestamp CONTEXT_SW aoB[0] NULL") -expect("@timestamp Trg-Done QS_RX_EVENT") +#------------------------------------------------------------------------------- +@scenario("Scenario: ao->ao->ao (NO PTS)") +def do(context): + context.prio = [Q_PRIO(1,0), Q_PRIO(2,0), Q_PRIO(3,0)] + return context + +@given("priorities: (1,0), (2,0), (3,0)") +def do(context): + current_obj(OBJ_AP, "pspecB") + poke(0, 2, pack("2") + expect("@timestamp CONTEXT_SW NULL aoB[1]") + expect("@timestamp TRACE_MSG aoB[1] TEST0 1of2") + expect("@timestamp Sch-Next Pri=2->3") + expect("@timestamp CONTEXT_SW aoB[1] aoB[2]") + expect("@timestamp TRACE_MSG aoB[2] TEST1 1of2") + expect("@timestamp Sch-Lock Ceil=0->3") + expect("@timestamp Sch-Unlk Ceil=3->0") + expect("@timestamp TRACE_MSG aoB[2] TEST1 2of2") + expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") + expect("@timestamp Sch-Next Pri=3->2") + expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") + expect("@timestamp TRACE_MSG aoB[1] TEST0 2of2") + expect("@timestamp TRACE_MSG aoB[1] TEST1 1of2") + expect("@timestamp Sch-Lock Ceil=0->3") + expect("@timestamp Sch-Unlk Ceil=3->0") + expect("@timestamp Sch-Next Pri=2->3") + expect("@timestamp CONTEXT_SW aoB[1] aoB[2]") + expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") + expect("@timestamp Sch-Next Pri=3->2") + expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") + expect("@timestamp TRACE_MSG aoB[1] TEST1 2of2") + expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") + expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") + expect("@timestamp Sch-Next Pri=2->1") + expect("@timestamp CONTEXT_SW aoB[1] aoB[0]") + expect("@timestamp TRACE_MSG aoB[0] TEST1 1of2") + expect("@timestamp Sch-Lock Ceil=0->3") + expect("@timestamp Sch-Unlk Ceil=3->0") + expect("@timestamp Sch-Next Pri=1->3") + expect("@timestamp CONTEXT_SW aoB[0] aoB[2]") + expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") + expect("@timestamp Sch-Next Pri=3->2") + expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") + expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") + expect("@timestamp Sch-Next Pri=2->1") + expect("@timestamp CONTEXT_SW aoB[1] aoB[0]") + expect("@timestamp TRACE_MSG aoB[0] TEST1 2of2") + expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") + expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") + expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") + expect("@timestamp Sch-Idle Pri=1->0") + expect("@timestamp CONTEXT_SW aoB[0] NULL") + expect("@timestamp Trg-Done QS_RX_EVENT") -scenario("ao->ao->ao (PTS1)") -# given... -current_obj(OBJ_AP, "pspecB") -poke(0, 2, pack("2") -expect("@timestamp CONTEXT_SW NULL aoB[1]") -expect("@timestamp TRACE_MSG aoB[1] TEST0 1of2") -expect("@timestamp TRACE_MSG aoB[1] TEST0 2of2") -expect("@timestamp Sch-Next Pri=2->3") -expect("@timestamp CONTEXT_SW aoB[1] aoB[2]") -expect("@timestamp TRACE_MSG aoB[2] TEST1 1of2") -expect("@timestamp Sch-Lock Ceil=0->3") -expect("@timestamp Sch-Unlk Ceil=3->0") -expect("@timestamp TRACE_MSG aoB[2] TEST1 2of2") -expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") -expect("@timestamp Sch-Next Pri=3->2") -expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") -expect("@timestamp TRACE_MSG aoB[1] TEST1 1of2") -expect("@timestamp Sch-Lock Ceil=0->3") -expect("@timestamp Sch-Unlk Ceil=3->0") -expect("@timestamp TRACE_MSG aoB[1] TEST1 2of2") -expect("@timestamp Sch-Next Pri=2->3") -expect("@timestamp CONTEXT_SW aoB[1] aoB[2]") -expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") -expect("@timestamp Sch-Next Pri=3->2") -expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") -expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") -expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") -expect("@timestamp Sch-Next Pri=2->1") -expect("@timestamp CONTEXT_SW aoB[1] aoB[0]") -expect("@timestamp TRACE_MSG aoB[0] TEST1 1of2") -expect("@timestamp Sch-Lock Ceil=0->3") -expect("@timestamp Sch-Unlk Ceil=3->0") -expect("@timestamp TRACE_MSG aoB[0] TEST1 2of2") -expect("@timestamp Sch-Next Pri=1->3") -expect("@timestamp CONTEXT_SW aoB[0] aoB[2]") -expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") -expect("@timestamp Sch-Next Pri=3->2") -expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") -expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") -expect("@timestamp Sch-Next Pri=2->1") -expect("@timestamp CONTEXT_SW aoB[1] aoB[0]") -expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") -expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") -expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") -expect("@timestamp Sch-Idle Pri=1->0") -expect("@timestamp CONTEXT_SW aoB[0] NULL") -expect("@timestamp Trg-Done QS_RX_EVENT") +#------------------------------------------------------------------------------- +@scenario("ao->ao->ao (PTS1)") +def do(context): + context.prio = [Q_PRIO(1,3), Q_PRIO(2,3), Q_PRIO(3,0)] + return context + +@given("priorities: (1,3), (2,3), (3,0)") +def do(context): + current_obj(OBJ_AP, "pspecB") + poke(0, 2, pack("2") + expect("@timestamp CONTEXT_SW NULL aoB[1]") + expect("@timestamp TRACE_MSG aoB[1] TEST0 1of2") + expect("@timestamp TRACE_MSG aoB[1] TEST0 2of2") + expect("@timestamp Sch-Next Pri=2->3") + expect("@timestamp CONTEXT_SW aoB[1] aoB[2]") + expect("@timestamp TRACE_MSG aoB[2] TEST1 1of2") + expect("@timestamp Sch-Lock Ceil=0->3") + expect("@timestamp Sch-Unlk Ceil=3->0") + expect("@timestamp TRACE_MSG aoB[2] TEST1 2of2") + expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") + expect("@timestamp Sch-Next Pri=3->2") + expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") + expect("@timestamp TRACE_MSG aoB[1] TEST1 1of2") + expect("@timestamp Sch-Lock Ceil=0->3") + expect("@timestamp Sch-Unlk Ceil=3->0") + expect("@timestamp TRACE_MSG aoB[1] TEST1 2of2") + expect("@timestamp Sch-Next Pri=2->3") + expect("@timestamp CONTEXT_SW aoB[1] aoB[2]") + expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") + expect("@timestamp Sch-Next Pri=3->2") + expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") + expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") + expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") + expect("@timestamp Sch-Next Pri=2->1") + expect("@timestamp CONTEXT_SW aoB[1] aoB[0]") + expect("@timestamp TRACE_MSG aoB[0] TEST1 1of2") + expect("@timestamp Sch-Lock Ceil=0->3") + expect("@timestamp Sch-Unlk Ceil=3->0") + expect("@timestamp TRACE_MSG aoB[0] TEST1 2of2") + expect("@timestamp Sch-Next Pri=1->3") + expect("@timestamp CONTEXT_SW aoB[0] aoB[2]") + expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") + expect("@timestamp Sch-Next Pri=3->2") + expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") + expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") + expect("@timestamp Sch-Next Pri=2->1") + expect("@timestamp CONTEXT_SW aoB[1] aoB[0]") + expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") + expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") + expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") + expect("@timestamp Sch-Idle Pri=1->0") + expect("@timestamp CONTEXT_SW aoB[0] NULL") + expect("@timestamp Trg-Done QS_RX_EVENT") -scenario("ao->ao->ao (PTS2)") -# given... -current_obj(OBJ_AP, "pspecB") -poke(0, 2, pack("2") -expect("@timestamp CONTEXT_SW NULL aoB[1]") -expect("@timestamp TRACE_MSG aoB[1] TEST0 1of2") -expect("@timestamp TRACE_MSG aoB[1] TEST0 2of2") -expect("@timestamp Sch-Next Pri=2->3") -expect("@timestamp CONTEXT_SW aoB[1] aoB[2]") -expect("@timestamp TRACE_MSG aoB[2] TEST1 1of2") -expect("@timestamp Sch-Lock Ceil=0->3") -expect("@timestamp Sch-Unlk Ceil=3->0") -expect("@timestamp TRACE_MSG aoB[2] TEST1 2of2") -expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") -expect("@timestamp Sch-Next Pri=3->2") -expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") -expect("@timestamp TRACE_MSG aoB[1] TEST1 1of2") -expect("@timestamp Sch-Lock Ceil=0->3") -expect("@timestamp Sch-Unlk Ceil=3->0") -expect("@timestamp TRACE_MSG aoB[1] TEST1 2of2") -expect("@timestamp Sch-Next Pri=2->3") -expect("@timestamp CONTEXT_SW aoB[1] aoB[2]") -expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") -expect("@timestamp Sch-Next Pri=3->2") -expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") -expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") -expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") -expect("@timestamp Sch-Next Pri=2->1") -expect("@timestamp CONTEXT_SW aoB[1] aoB[0]") -expect("@timestamp TRACE_MSG aoB[0] TEST1 1of2") -expect("@timestamp Sch-Lock Ceil=0->3") -expect("@timestamp Sch-Unlk Ceil=3->0") -expect("@timestamp Sch-Next Pri=1->3") -expect("@timestamp CONTEXT_SW aoB[0] aoB[2]") -expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") -expect("@timestamp Sch-Next Pri=3->2") -expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") -expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") -expect("@timestamp Sch-Next Pri=2->1") -expect("@timestamp CONTEXT_SW aoB[1] aoB[0]") -expect("@timestamp TRACE_MSG aoB[0] TEST1 2of2") -expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") -expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") -expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") -expect("@timestamp Sch-Idle Pri=1->0") -expect("@timestamp CONTEXT_SW aoB[0] NULL") -expect("@timestamp Trg-Done QS_RX_EVENT") +#------------------------------------------------------------------------------- +@scenario("ao->ao->ao (PTS2)") +def do(context): + context.prio = [Q_PRIO(1,0), Q_PRIO(2,3), Q_PRIO(3,0)] + return context + +@given("priorities: (1,0), (2,3), (3,0)") +def do(context): + current_obj(OBJ_AP, "pspecB") + poke(0, 2, pack("2") + expect("@timestamp CONTEXT_SW NULL aoB[1]") + expect("@timestamp TRACE_MSG aoB[1] TEST0 1of2") + expect("@timestamp TRACE_MSG aoB[1] TEST0 2of2") + expect("@timestamp Sch-Next Pri=2->3") + expect("@timestamp CONTEXT_SW aoB[1] aoB[2]") + expect("@timestamp TRACE_MSG aoB[2] TEST1 1of2") + expect("@timestamp Sch-Lock Ceil=0->3") + expect("@timestamp Sch-Unlk Ceil=3->0") + expect("@timestamp TRACE_MSG aoB[2] TEST1 2of2") + expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") + expect("@timestamp Sch-Next Pri=3->2") + expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") + expect("@timestamp TRACE_MSG aoB[1] TEST1 1of2") + expect("@timestamp Sch-Lock Ceil=0->3") + expect("@timestamp Sch-Unlk Ceil=3->0") + expect("@timestamp TRACE_MSG aoB[1] TEST1 2of2") + expect("@timestamp Sch-Next Pri=2->3") + expect("@timestamp CONTEXT_SW aoB[1] aoB[2]") + expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") + expect("@timestamp Sch-Next Pri=3->2") + expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") + expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") + expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") + expect("@timestamp Sch-Next Pri=2->1") + expect("@timestamp CONTEXT_SW aoB[1] aoB[0]") + expect("@timestamp TRACE_MSG aoB[0] TEST1 1of2") + expect("@timestamp Sch-Lock Ceil=0->3") + expect("@timestamp Sch-Unlk Ceil=3->0") + expect("@timestamp Sch-Next Pri=1->3") + expect("@timestamp CONTEXT_SW aoB[0] aoB[2]") + expect("@timestamp TRACE_MSG aoB[2] TEST2 1of1") + expect("@timestamp Sch-Next Pri=3->2") + expect("@timestamp CONTEXT_SW aoB[2] aoB[1]") + expect("@timestamp TRACE_MSG aoB[1] TEST2 1of1") + expect("@timestamp Sch-Next Pri=2->1") + expect("@timestamp CONTEXT_SW aoB[1] aoB[0]") + expect("@timestamp TRACE_MSG aoB[0] TEST1 2of2") + expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") + expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") + expect("@timestamp TRACE_MSG aoB[0] TEST2 1of1") + expect("@timestamp Sch-Idle Pri=1->0") + expect("@timestamp CONTEXT_SW aoB[0] NULL") + expect("@timestamp Trg-Done QS_RX_EVENT") diff --git a/test/qxk/test_sched/bsp_nucleo-c031c6.c b/test/qxk/test_sched/bsp_nucleo-c031c6.c index c4e4b6c6..9d7db3bb 100644 --- a/test/qxk/test_sched/bsp_nucleo-c031c6.c +++ b/test/qxk/test_sched/bsp_nucleo-c031c6.c @@ -1,34 +1,32 @@ //============================================================================ // Product: BSP for system-testing of QXK kernel, NUCLEO-C031C6 board -// Last updated for version 7.3.0 -// Last updated on 2023-07-18 +// Last updated for version 7.4.0 +// Last updated on 2024-06-24 // // Q u a n t u m L e a P s // ------------------------ // Modern Embedded Software // -// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +// Copyright (C) 2005 Quantum Leaps, LLC. // -// This program is open source software: you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published -// by the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // -// Alternatively, this program may be distributed and modified under the -// terms of Quantum Leaps commercial licenses, which expressly supersede -// the GNU General Public License and are specifically designed for -// licensees interested in retaining the proprietary status of their code. +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. // -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// The terms of the open source GNU General Public License version 3 +// can be found at: // -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. // // Contact information: -// +// // //============================================================================ #include "qpc.h" @@ -266,11 +264,11 @@ void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { *(uint32_t volatile *)(ram_base + offset) = value; } -//.......................................................................... +//============================================================================ +// QF callbacks... void QF_onStartup(void) { // NOTE: SystemInit() has been already called from the startup code // but SystemCoreClock needs to be updated - // SystemCoreClockUpdate(); //NOTE: don't start ticking for these tests @@ -317,7 +315,8 @@ void QXK_onIdle(void) { #endif } -// QS callbacks ============================================================ +//============================================================================ +// QS callbacks... #ifdef Q_SPY //.......................................................................... @@ -332,6 +331,7 @@ void QTimeEvt_tick1_( } #endif // Q_SPY +//---------------------------------------------------------------------------- //============================================================================ // NOTE0: diff --git a/test/qxk/test_sched/bsp_nucleo-u545re.c b/test/qxk/test_sched/bsp_nucleo-u545re.c new file mode 100644 index 00000000..9ca2278c --- /dev/null +++ b/test/qxk/test_sched/bsp_nucleo-u545re.c @@ -0,0 +1,313 @@ +//============================================================================ +// Product: BSP for system-testing of QXK kernel, NUCLEO-U545RE-Q board +// Last updated for version 7.4.0 +// Last updated on 2024-06-24 +// +// Q u a n t u m L e a P s +// ------------------------ +// Modern Embedded Software +// +// Copyright (C) 2005 Quantum Leaps, LLC. +// +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial +// +// This software is dual-licensed under the terms of the open source GNU +// General Public License version 3 (or any later version), or alternatively, +// under the terms of one of the closed source Quantum Leaps commercial +// licenses. +// +// The terms of the open source GNU General Public License version 3 +// can be found at: +// +// The terms of the closed source Quantum Leaps commercial licenses +// can be found at: +// +// Redistributions in source code must retain this top-level comment block. +// Plagiarizing this software to sidestep the license obligations is illegal. +// +// Contact information: +// +// +//============================================================================ +#include "qpc.h" +#include "bsp.h" + +#include "stm32u545xx.h" // CMSIS-compliant header file for the MCU used +// add other drivers if necessary... + +Q_DEFINE_THIS_FILE // define the name of this file for assertions + +// Local-scope defines ----------------------------------------------------- +// LED pins available on the board (just one user LED LD2--Green on PA.5) +#define LD2_PIN 5U + +// Button pins available on the board (just one user Button B1 on PC.13) +#define B1_PIN 13U + +// macros from STM32Cube LL: +#define SET_BIT(REG, BIT) ((REG) |= (BIT)) +#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT)) +#define READ_BIT(REG, BIT) ((REG) & (BIT)) +#define CLEAR_REG(REG) ((REG) = (0x0)) +#define WRITE_REG(REG, VAL) ((REG) = (VAL)) +#define READ_REG(REG) ((REG)) +#define MODIFY_REG(REG, CLEARMASK, SETMASK) \ + WRITE_REG((REG), ((READ_REG(REG) & (~(CLEARMASK))) | (SETMASK))) + +#ifdef Q_SPY +// QSpy source IDs +static QSpyId const l_SysTick_Handler = { 100U }; +static QSpyId const l_test_ISR = { 101U }; + +enum AppRecords { // application-specific trace records + CONTEXT_SW = QS_USER1, + TRACE_MSG +}; + +#endif + +// ISRs used in this project =============================================== +void SysTick_Handler(void); // prototype +void SysTick_Handler(void) { + QXK_ISR_ENTRY(); // inform QXK kernel about entering an ISR + + // process time events for rate 0 + QTIMEEVT_TICK_X(0U, &l_SysTick_Handler); + + QXK_ISR_EXIT(); // inform QXK kernel about exiting an ISR +} +//.......................................................................... +void EXTI0_IRQHandler(void); // prototype +void EXTI0_IRQHandler(void) { // for testing, NOTE03 + QXK_ISR_ENTRY(); // inform QXK kernel about entering an ISR + + // for testing... + static QEvt const t1 = QEVT_INITIALIZER(TEST1_SIG); + QACTIVE_PUBLISH(&t1, &l_test_ISR); + + QXK_ISR_EXIT(); // inform QXK kernel about exiting an ISR +} + +// BSP functions =========================================================== +static void STM32U545RE_MPU_setup(void) { + MPU->CTRL = 0U; // disable the MPU + + MPU->RNR = 0U; // region 0 (for ROM: read-only, can-execute) + MPU->RBAR = (0x08000000U & MPU_RBAR_BASE_Msk) | (0x3U << MPU_RBAR_AP_Pos); + MPU->RLAR = (0x08080000U & MPU_RLAR_LIMIT_Msk) | MPU_RLAR_EN_Msk; + + MPU->RNR = 1U; // region 1 (for RAM1: read-write, execute-never) + MPU->RBAR = (0x20000000U & MPU_RBAR_BASE_Msk) | (0x1U << MPU_RBAR_AP_Pos) + | MPU_RBAR_XN_Msk; + MPU->RLAR = (0x20040000U & MPU_RLAR_LIMIT_Msk) | MPU_RLAR_EN_Msk; + + MPU->RNR = 2U; // region 2 (for RAM2: read-write, execute-never) + MPU->RBAR = (0x28000000U & MPU_RBAR_BASE_Msk) | (0x1U << MPU_RBAR_AP_Pos) + | MPU_RBAR_XN_Msk; + MPU->RLAR = (0x28004000U & MPU_RLAR_LIMIT_Msk) | MPU_RLAR_EN_Msk; + + MPU->RNR = 7U; // region 7 (no access: for NULL pointer protection) + MPU->RBAR = (0x00000000U & MPU_RBAR_BASE_Msk) | MPU_RBAR_XN_Msk; + MPU->RLAR = (0x00080000U & MPU_RLAR_LIMIT_Msk) | MPU_RLAR_EN_Msk; + __DMB(); + + MPU->CTRL = MPU_CTRL_ENABLE_Msk | MPU_CTRL_PRIVDEFENA_Msk; + + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + + __DSB(); + __ISB(); +} +//.......................................................................... +void BSP_init(void) { + // setup the MPU... + STM32U545RE_MPU_setup(); + + // initialize I-CACHE + MODIFY_REG(ICACHE->CR, ICACHE_CR_WAYSEL, 0U); // 1-way + SET_BIT(ICACHE->CR, ICACHE_CR_EN); // enable + + // flash prefetch buffer enable + SET_BIT(FLASH->ACR, FLASH_ACR_PRFTEN); + + // enable PWR clock interface + SET_BIT(RCC->AHB3ENR, RCC_AHB3ENR_PWREN); + + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + SystemCoreClockUpdate(); + + // enable GPIOA clock port for the LED LD4 + RCC->AHB2ENR1 |= RCC_AHB2ENR1_GPIOAEN; + + // set all used GPIOA pins as push-pull output, no pull-up, pull-down + MODIFY_REG(GPIOA->OSPEEDR, + GPIO_OSPEEDR_OSPEED0 << (LD2_PIN * GPIO_OSPEEDR_OSPEED1_Pos), + 1U << (LD2_PIN * GPIO_OSPEEDR_OSPEED1_Pos)); // speed==1 + MODIFY_REG(GPIOA->OTYPER, + 1U << LD2_PIN, + 0U << LD2_PIN); // output + MODIFY_REG(GPIOA->PUPDR, + GPIO_PUPDR_PUPD0 << (LD2_PIN * GPIO_PUPDR_PUPD1_Pos), + 0U << (LD2_PIN * GPIO_PUPDR_PUPD1_Pos)); // PUSHPULL + MODIFY_REG(GPIOA->MODER, + GPIO_MODER_MODE0 << (LD2_PIN * GPIO_MODER_MODE1_Pos), + 1U << (LD2_PIN * GPIO_MODER_MODE1_Pos)); // MODE_1 + + // enable GPIOC clock port for the Button B1 + RCC->AHB2ENR1 |= RCC_AHB2ENR1_GPIOCEN; + + // configure Button B1 pin on GPIOC as input, no pull-up, pull-down + MODIFY_REG(GPIOC->PUPDR, + GPIO_PUPDR_PUPD0 << (B1_PIN * GPIO_PUPDR_PUPD1_Pos), + 0U << (B1_PIN * GPIO_PUPDR_PUPD1_Pos)); // NO PULL + MODIFY_REG(GPIOC->MODER, + GPIO_MODER_MODE0 << (B1_PIN * GPIO_MODER_MODE1_Pos), + 0U << (B1_PIN * GPIO_MODER_MODE1_Pos)); // MODE_0 + + // initialize the QS software tracing... + if (!QS_INIT((void *)0)) { + Q_ERROR(); + } + + // dictionaries... + QS_OBJ_DICTIONARY(&l_SysTick_Handler); + QS_OBJ_DICTIONARY(&l_test_ISR); + + QS_USR_DICTIONARY(CONTEXT_SW); + QS_USR_DICTIONARY(TRACE_MSG); +} +//.......................................................................... +void BSP_terminate(int16_t result) { + Q_UNUSED_PAR(result); +} +//............................................................................ +void BSP_ledOn(void) { + GPIOA->BSRR = (1U << LD2_PIN); // turn LED on +} +//............................................................................ +void BSP_ledOff(void) { + GPIOA->BRR = (1U << LD2_PIN); // turn LED off +} +//.......................................................................... +void BSP_trigISR(void) { + NVIC_SetPendingIRQ(EXTI0_IRQn); +} +//.......................................................................... +void BSP_trace(QActive const *thr, char const *msg) { + QS_BEGIN_ID(TRACE_MSG, 0U) + QS_OBJ(thr); + QS_STR(msg); + QS_END() +} +//.......................................................................... +uint32_t BSP_romRead(int32_t offset, uint32_t fromEnd) { + int32_t const rom_base = (fromEnd == 0U) + ? 0x08000000 + : 0x08080000 - 4; + return *(uint32_t volatile *)(rom_base + offset); +} +//.......................................................................... +void BSP_romWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { + int32_t const rom_base = (fromEnd == 0U) + ? 0x08000000 + : 0x08080000 - 4; + *(uint32_t volatile *)(rom_base + offset) = value; +} + +//.......................................................................... +uint32_t BSP_ramRead(int32_t offset, uint32_t fromEnd) { + int32_t const ram_base = (fromEnd == 0U) + ? 0x20000000 + : 0x20040000 - 4; + return *(uint32_t volatile *)(ram_base + offset); +} +//.......................................................................... +void BSP_ramWrite(int32_t offset, uint32_t fromEnd, uint32_t value) { + int32_t const ram_base = (fromEnd == 0U) + ? 0x20000000 + : 0x20040000 - 4; + *(uint32_t volatile *)(ram_base + offset) = value; +} + +//============================================================================ +// QF callbacks... +void QF_onStartup(void) { + // NOTE: SystemInit() has been already called from the startup code + // but SystemCoreClock needs to be updated + SystemCoreClockUpdate(); + + //NOTE: don't start ticking for these tests + //SysTick_Config(SystemCoreClock / BSP_TICKS_PER_SEC); + + // assign all priority bits for preemption-prio. and none to sub-prio. + // NOTE: this might have been changed by STM32Cube. + NVIC_SetPriorityGrouping(0U); + + // set priorities of ALL ISRs used in the system + NVIC_SetPriority(SysTick_IRQn, QF_AWARE_ISR_CMSIS_PRI + 0U); + NVIC_SetPriority(EXTI0_IRQn, QF_AWARE_ISR_CMSIS_PRI + 1U); + // NOTE: priority of UART IRQ used for QS-RX is set in qutest_port.c + // ... + + // enable IRQs... + NVIC_EnableIRQ(EXTI0_IRQn); +} +//............................................................................ +void QF_onCleanup(void) { +} +//.......................................................................... +#ifdef QF_ON_CONTEXT_SW +// NOTE: the context-switch callback is called with interrupts DISABLED +void QF_onContextSw(QActive *prev, QActive *next) { + QS_BEGIN_INCRIT(CONTEXT_SW, 0U) // in critical section! + QS_OBJ(prev); + QS_OBJ(next); + QS_END_INCRIT() +} +#endif // QF_ON_CONTEXT_SW + +//............................................................................ +void QXK_onIdle(void) { +#ifdef Q_SPY + QS_rxParse(); // parse all the received bytes + QS_doOutput(); +#elif defined NDEBUG + // Put the CPU and peripherals to the low-power mode. + // you might need to customize the clock management for your application, + // see the datasheet for your particular Cortex-M3 MCU. + // + __WFI(); // Wait-For-Interrupt +#endif +} + +//============================================================================ +// QS callbacks... +#ifdef Q_SPY + +//............................................................................ +void QTimeEvt_tick1_( + uint_fast8_t const tickRate, + void const * const sender) +{ + QF_INT_DISABLE(); + // TODO pend the SysTick + *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 26U); + QF_INT_ENABLE(); +} + +#endif // Q_SPY +//---------------------------------------------------------------------------- + +//============================================================================ +// NOTE0: +// The MPU protection against NULL-pointer dereferencing sets up a no-access +// MPU region #7 around the NULL address (0x0). The size of this region is set +// to 2^(26+1)==0x0800'0000, because that is the address of Flash in STM32. +// +// REMARK: STM32 MCUs automatically relocate the Flash memory and the Vector +// Table in it to address 0x0800'0000 at startup. However, even though the +// region 0..0x0800'0000 is un-mapped after the relocation, the read access +// is still allowed and causes no CPU exception. Therefore setting up the MPU +// to protect that region is necessary. +// diff --git a/test/qxk/test_sched/nucleo-c031c6.mak b/test/qxk/test_sched/nucleo-c031c6.mak index 05e84613..c432df06 100644 --- a/test/qxk/test_sched/nucleo-c031c6.mak +++ b/test/qxk/test_sched/nucleo-c031c6.mak @@ -7,7 +7,7 @@ # ------------------------ # Modern Embedded Software # -# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved. +# Copyright (C) 2005 Quantum Leaps, LLC. # # This program is open source software: you can redistribute it and/or # modify it under the terms of the GNU General Public License as published diff --git a/test/qxk/test_sched/nucleo-u545re.mak b/test/qxk/test_sched/nucleo-u545re.mak new file mode 100644 index 00000000..5d336fdd --- /dev/null +++ b/test/qxk/test_sched/nucleo-u545re.mak @@ -0,0 +1,337 @@ +############################################################################## +# Product: Makefile for SYSTEM-Level tests of QP/C on NUCLEO-U545RE-Q, GNU-ARM +# Last Updated for Version: 7.4.0 +# Date of the Last Update: 2024-06-23 +# +# Q u a n t u m L e a P s +# ------------------------ +# Modern Embedded Software +# +# Copyright (C) 2005 Quantum Leaps, LLC. +# +# This program is open source software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Alternatively, this program may be distributed and modified under the +# terms of Quantum Leaps commercial licenses, which expressly supersede +# the GNU General Public License and are specifically designed for +# licensees interested in retaining the proprietary status of their code. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Contact information: +# +# +############################################################################## +# +# examples of invoking this Makefile: +# make -f nucleo-u545re.mak USB=g: # make, upload to USB drive, run the tests +# make -f nucleo-u545re.mak USB=g: TESTS=philo*.py # make and run the selected tests +# make -f nucleo-u545re.mak HOST=localhost:7705 # connect to host:port +# make -f nucleo-u545re.mak norun # only make but not run the tests +# make -f nucleo-u545re.mak clean # cleanup the build +# make -f nucleo-u545re.mak debug # only run tests in DEBUG mode +# +# NOTE: +# To use this Makefile on Windows, you will need the GNU make utility, which +# is included in the QTools collection for Windows, see: +# https://github.com/QuantumLeaps/qtools +# + +# location of the QP/C framework (if not provided in an env. variable) +ifeq ($(QPC),) +QPC := ../../.. +endif + +#----------------------------------------------------------------------------- +# project name, target name, target directory: +# +PROJECT := test_sched +TARGET := nucleo-u545re +TARGET_DIR := $(QPC)/3rd_party/nucleo-u545re/qutest + +#----------------------------------------------------------------------------- +# project directories +# + +# QP port used in this project +QP_PORT_DIR := $(QPC)/ports/arm-cm/qxk/gnu + +# make sure that QTOOLS env. variable is defined... +ifeq ("$(wildcard $(QTOOLS))","") +$(error QTOOLS not found. Please install QTools and define QTOOLS env. variable) +endif + + +# list of all source directories used by this project +VPATH := . \ + $(QPC)/src/qf \ + $(QPC)/src/qxk \ + $(QPC)/src/qs \ + $(QP_PORT_DIR) \ + $(TARGET_DIR) \ + $(QPC)/3rd_party/nucleo-u545re \ + $(QPC)/3rd_party/nucleo-u545re/gnu + +# list of all include directories needed by this project +INCLUDES = -I. \ + -I$(QPC)/include \ + -I$(QP_PORT_DIR) \ + -I$(TARGET_DIR) \ + -I$(QPC)/3rd_party/CMSIS/Include \ + -I$(QPC)/3rd_party/nucleo-u545re + +#----------------------------------------------------------------------------- +# project files +# + +# assembler source files +ASM_SRCS := + +# C source files +C_SRCS := \ + test_sched.c \ + bsp_nucleo-u545re.c \ + system_stm32u5xx.c \ + startup_stm32u545retxq.c + +# C++ source files +CPP_SRCS := + +OUTPUT := $(PROJECT) +LD_SCRIPT := $(TARGET_DIR)/qutest.ld + +QP_SRCS := \ + qep_hsm.c \ + qep_msm.c \ + qf_act.c \ + qf_actq.c \ + qf_defer.c \ + qf_dyn.c \ + qf_mem.c \ + qf_ps.c \ + qf_qact.c \ + qf_qeq.c \ + qf_qmact.c \ + qf_time.c \ + qxk.c \ + qxk_xthr.c \ + qxk_sema.c \ + qxk_mutex.c \ + qxk_port.c \ + qs.c \ + qs_64bit.c \ + qs_rx.c \ + qs_fp.c \ + qutest.c \ + qutest_port.c + +QP_ASMS := + +LIB_DIRS := +LIBS := + +# defines +DEFINES := -DSTM32U545xx \ + -DQP_API_VERSION=9999 \ + -DQF_ON_CONTEXT_SW + +# ARM CPU, ARCH, FPU, and Float-ABI types... +# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4] +# ARM_FPU: [ | vfp] +# FLOAT_ABI: [ | soft | softfp | hard] +# +ARM_CPU := -mcpu=cortex-m33 +ARM_FPU := -mfpu=fpv5-sp-d16 +FLOAT_ABI := -mfloat-abi=hard -mthumb + +#----------------------------------------------------------------------------- +# GNU-ARM toolset (NOTE: You need to adjust to your machine) +# see https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads +# +ifeq ($(GNU_ARM),) +GNU_ARM := $(QTOOLS)/gnu_arm-none-eabi +endif + +# make sure that the GNU-ARM toolset exists... +ifeq ("$(wildcard $(GNU_ARM))","") +$(error GNU_ARM toolset not found. Please adjust the Makefile) +endif + +CC := $(GNU_ARM)/bin/arm-none-eabi-gcc +CPP := $(GNU_ARM)/bin/arm-none-eabi-g++ +AS := $(GNU_ARM)/bin/arm-none-eabi-as +LINK := $(GNU_ARM)/bin/arm-none-eabi-gcc +BIN := $(GNU_ARM)/bin/arm-none-eabi-objcopy + +#----------------------------------------------------------------------------- +# NOTE: The symbol USB must be provided for the NUCLEO board +# has enumerated as USB drive f: +# +ifeq ($(USB),) +$(error USB drive not provided for the NUCLEO board.) +endif + +############################################################################## +# Typically you should not need to change anything below this line + +# basic utilities (included in QTools for Windows), see: +# https://www.state-machine.com/qtools + +MKDIR := mkdir +RM := rm +CP := cp +SLEEP := sleep + +#----------------------------------------------------------------------------- +# QUTest test script utilities (requires QTOOLS): +# +ifeq ("$(wildcard $(QUTEST))","") +QUTEST := python3 $(QTOOLS)/qutest/qutest.py +endif + +#----------------------------------------------------------------------------- +# build options +# + +# combine all the sources... +C_SRCS += $(QP_SRCS) +ASM_SRCS += $(QP_ASMS) + +BIN_DIR := build_$(TARGET) + +ASFLAGS = -g $(ARM_CPU) $(ARM_FPU) $(ASM_CPU) $(ASM_FPU) + + +# NOTE: +# Setting -DQ_UTEST=0 means that QUTest should be built WITHOUT +# the QP-stub for testing QP itself +# +CFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 + +CPPFLAGS = -c -g $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb -Wall \ + -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions \ + -O $(INCLUDES) $(DEFINES) -DQ_SPY -DQ_UTEST=0 + + +LINKFLAGS = -T$(LD_SCRIPT) $(ARM_CPU) $(ARM_FPU) $(FLOAT_ABI) -mthumb \ + -specs=nosys.specs -specs=nano.specs \ + -Wl,-Map,$(BIN_DIR)/$(OUTPUT).map,--cref,--gc-sections $(LIB_DIRS) + +ASM_OBJS := $(patsubst %.s,%.o, $(notdir $(ASM_SRCS))) +C_OBJS := $(patsubst %.c,%.o, $(notdir $(C_SRCS))) +CPP_OBJS := $(patsubst %.cpp,%.o,$(notdir $(CPP_SRCS))) + +TARGET_BIN := $(BIN_DIR)/$(OUTPUT).bin +TARGET_ELF := $(BIN_DIR)/$(OUTPUT).elf +ASM_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(ASM_OBJS)) +C_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(C_OBJS)) +C_DEPS_EXT := $(patsubst %.o, %.d, $(C_OBJS_EXT)) +CPP_OBJS_EXT := $(addprefix $(BIN_DIR)/, $(CPP_OBJS)) +CPP_DEPS_EXT := $(patsubst %.o, %.d, $(CPP_OBJS_EXT)) + +# create $(BIN_DIR) if it does not exist +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif + +#----------------------------------------------------------------------------- +# rules +# + +.PHONY : run norun debug flash + +ifeq ($(MAKECMDGOALS),norun) +all : $(TARGET_BIN) +norun : all +else +all : $(TARGET_BIN) run +endif + +$(TARGET_BIN) : $(TARGET_ELF) + $(BIN) -O binary $< $@ + $(CP) $@ $(USB) + $(SLEEP) 2 + +$(TARGET_ELF) : $(ASM_OBJS_EXT) $(C_OBJS_EXT) $(CPP_OBJS_EXT) + $(CC) $(CFLAGS) $(QPC)/src/qs/qstamp.c -o $(BIN_DIR)/qstamp.o + $(LINK) $(LINKFLAGS) -o $@ $^ $(BIN_DIR)/qstamp.o $(LIBS) + +flash : + $(CP) $(TARGET_BIN) $(USB) + +run : $(TARGET_BIN) + $(QUTEST) -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) + +$(BIN_DIR)/%.d : %.c + $(CC) -MM -MT $(@:.d=.o) $(CFLAGS) $< > $@ + +$(BIN_DIR)/%.d : %.cpp + $(CPP) -MM -MT $(@:.d=.o) $(CPPFLAGS) $< > $@ + +$(BIN_DIR)/%.o : %.s + $(AS) $(ASFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.c + $(CC) $(CFLAGS) $< -o $@ + +$(BIN_DIR)/%.o : %.cpp + $(CPP) $(CPPFLAGS) $< -o $@ + +# create BIN_DIR and include dependencies only if needed +ifneq ($(MAKECMDGOALS),clean) + ifneq ($(MAKECMDGOALS),show) + ifneq ($(MAKECMDGOALS),debug) +ifeq ("$(wildcard $(BIN_DIR))","") +$(shell $(MKDIR) $(BIN_DIR)) +endif +-include $(C_DEPS_EXT) $(CPP_DEPS_EXT) + endif + endif +endif + +debug : + $(QUTEST) -edebug -q$(QSPY) -l$(LOG) -o$(OPT) -- $(TESTS) + +.PHONY : clean show + +clean : + -$(RM) $(BIN_DIR)/*.o \ + $(BIN_DIR)/*.d \ + $(BIN_DIR)/*.bin \ + $(BIN_DIR)/*.elf \ + $(BIN_DIR)/*.map + +show : + @echo PROJECT = $(PROJECT) + @echo MAKECMDGOALS = $(MAKECMDGOALS) + @echo TESTS = $(TESTS) + @echo TARGET_ELF = $(TARGET_ELF) + @echo CONF = $(CONF) + @echo VPATH = $(VPATH) + @echo C_SRCS = $(C_SRCS) + @echo CPP_SRCS = $(CPP_SRCS) + @echo ASM_SRCS = $(ASM_SRCS) + @echo C_DEPS_EXT = $(C_DEPS_EXT) + @echo C_OBJS_EXT = $(C_OBJS_EXT) + @echo CPP_DEPS_EXT = $(CPP_DEPS_EXT) + @echo CPP_OBJS_EXT = $(CPP_OBJS_EXT) + @echo ASM_OBJS_EXT = $(ASM_OBJS_EXT) + @echo LIB_DIRS = $(LIB_DIRS) + @echo LIBS = $(LIBS) + @echo DEFINES = $(DEFINES) + @echo QTOOLS = $(QTOOLS) + @echo HOST = $(HOST) + @echo QUTEST = $(QUTEST) + @echo TESTS = $(TESTS) + diff --git a/test/qxk/test_sched/test_sched.py b/test/qxk/test_sched/test_sched.py index 47385028..e0a84e19 100644 --- a/test/qxk/test_sched/test_sched.py +++ b/test/qxk/test_sched/test_sched.py @@ -2,7 +2,7 @@ # see https://www.state-machine.com/qtools/qutest.html/qutest.html note(''' -This test group verifies the preemption scenarios +This test group verifies the preemption tests in the QXK preemptive kernel ''') @@ -13,7 +13,7 @@ def on_reset(): # this will be done by the individual tests # after they poke the priorities of threads -scenario("extened->basic") +test("extened->basic") # given... current_obj(OBJ_AP, "pspecB") poke(0, 2, pack("extened->basic") +test("extended->extened->basic") # given... current_obj(OBJ_AP, "pspecB") poke(0, 2, pack("basic->extended") +test("extened->basic->extended") # given... current_obj(OBJ_AP, "pspecB") poke(0, 2, pack(" // //============================================================================ -//! @date Last updated on: 2024-01-03 -//! @version Last updated for: @ref qpc_7_3_2 +//! @date Last updated on: 2024-06-11 +//! @version Last updated for: @ref qpc_7_4_0 //! //! @file //! @brief QF/C port to Zephyr RTOS (v 3.1.99)