mirror of
https://github.com/QuantumLeaps/qpc.git
synced 2025-01-14 06:43:19 +08:00
7.3.4
updated QV, QK for MSP430 removed the unsupported esp-idf port Cmake support
This commit is contained in:
parent
fcea9943bb
commit
340b6bbd92
@ -1 +1 @@
|
||||
Subproject commit ebe4896f82bdb7b883f42f930307d243a4cd43d6
|
||||
Subproject commit db8b6155e6931d2c55315dfd55b0e1fac0f96e33
|
@ -132,36 +132,25 @@ add_subdirectory(src)
|
||||
add_subdirectory(ports)
|
||||
|
||||
# set general defines
|
||||
target_compile_definitions(qpc
|
||||
PRIVATE
|
||||
$<$<BOOL:${ADD_DEBUG_CODE}>:${ADD_DEBUG_CODE}>
|
||||
$<$<BOOL:${QPC_CFG_GUI}>:QWIN_GUI>
|
||||
$<$<CONFIG:Spy>:Q_SPY>
|
||||
$<$<AND:$<CONFIG:Spy>,$<BOOL:${QPC_CFG_UNIT_TEST}>>:Q_UTEST>
|
||||
target_compile_definitions(qpc PRIVATE
|
||||
$<$<BOOL:${ADD_DEBUG_CODE}>:${ADD_DEBUG_CODE}>
|
||||
$<$<BOOL:${QPC_CFG_GUI}>:QWIN_GUI>
|
||||
# $<$<CONFIG:Spy>:Q_SPY> # set via toolchain file
|
||||
$<$<AND:$<CONFIG:Spy>,$<BOOL:${QPC_CFG_UNIT_TEST}>>:Q_UTEST>
|
||||
)
|
||||
|
||||
target_compile_options(qpc
|
||||
PRIVATE
|
||||
$<$<BOOL:${QPC_CFG_VERBOSE}>:-v>
|
||||
target_compile_options(qpc PRIVATE
|
||||
$<$<BOOL:${QPC_CFG_VERBOSE}>:-v>
|
||||
)
|
||||
|
||||
target_link_options(qpc
|
||||
PRIVATE
|
||||
$<$<BOOL:${QPC_CFG_VERBOSE}>:-v>
|
||||
target_link_options(qpc PRIVATE
|
||||
$<$<BOOL:${QPC_CFG_VERBOSE}>:-v>
|
||||
)
|
||||
|
||||
target_link_libraries(qpc
|
||||
PUBLIC
|
||||
$<$<AND:$<CONFIG:Spy>,$<STREQUAL:win32,${PORT}>>:ws2_32>
|
||||
target_link_libraries(qpc PUBLIC
|
||||
$<$<AND:$<CONFIG:Spy>,$<STREQUAL:win32,${PORT}>>:ws2_32>
|
||||
)
|
||||
|
||||
# set position independent code compile/link parameters
|
||||
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14")
|
||||
include(CheckPIESupported)
|
||||
check_pie_supported()
|
||||
endif()
|
||||
set_property(TARGET qpc PROPERTY POSITION_INDEPENDENT_CODE FALSE)
|
||||
|
||||
# print configuration
|
||||
message(STATUS
|
||||
"========================================================
|
||||
|
2
examples
2
examples
@ -1 +1 @@
|
||||
Subproject commit 9c903f815f7690385c69e326fd8c1cc1f100ce4a
|
||||
Subproject commit 5b4edf6f7a1514169427fa42522d823fb31ee37c
|
@ -1,5 +1,4 @@
|
||||
# CMake the qpc libraries for different targets
|
||||
# target may be "Windows", "Posix", "TLE984x"
|
||||
set(PORT_DIR ${PORT})
|
||||
if((PORT STREQUAL win32) OR (PORT STREQUAL posix))
|
||||
if(QPC_CFG_UNIT_TEST)
|
||||
|
@ -15,8 +15,5 @@ else()
|
||||
target_include_directories(qpc PUBLIC ${KERNEL}/${_compiler_})
|
||||
endif()
|
||||
|
||||
if(EXISTS ${KERNEL}/config)
|
||||
target_include_directories(qpc PRIVATE ${KERNEL}/config)
|
||||
endif()
|
||||
target_sources(qpc PRIVATE ${KERNEL}/${_compiler_}/${qx_port_c})
|
||||
|
||||
|
@ -11,5 +11,4 @@ if(NOT KERNEL MATCHES "q[vk]")
|
||||
message(WARNING "Kernel ${KERNEL} is not supported! Falling back to QV kernel")
|
||||
set(KERNEL qv)
|
||||
endif()
|
||||
target_include_directories(qpc PUBLIC ${KERNEL}/${_compiler_} ${KERNEL}/config)
|
||||
|
||||
target_include_directories(qpc PUBLIC ${KERNEL}/${_compiler_})
|
||||
|
@ -1,3 +0,0 @@
|
||||
# ports/esp-idf
|
||||
target_include_directories(qpc PUBLIC .)
|
||||
target_sources(qpc PRIVATE qf_port.c)
|
@ -1,29 +0,0 @@
|
||||
This directory contains the "experimental" port to the [Espressif ESP-IDF][1]
|
||||
IoT Framework, which is loosely based on the [FreeRTOS kernel][2].
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
# About QP/C Port to ESP-IDF
|
||||
"Experimental" means that the port has not been thoroughly tested at
|
||||
Quantum Leaps and no working examples are provided.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
# About Espressif ESP-IDF
|
||||
|
||||
The [Espressif ESP-IDF][1] is based on a
|
||||
[significantly changed version of the FreeRTOS kernel][3]
|
||||
developed by Espressif to support the ESP32 multi-core CPUs (see [ESP-IDF][1]).
|
||||
|
||||
The Espressif version of FreeRTOS is __NOT__ compatible with the baseline [FreeRTOS][2]
|
||||
and it needs to be treated as a separate RTOS kernel. According to the comments
|
||||
in the Espressif source code, FreeRTOS-ESP-IDF is based on FreeRTOS V8.2.0, but
|
||||
apparently FreeRTOS-ESP32 has been updated with the newer features introduced to
|
||||
the original FreeRTOS in the later versions. For example, FreeRTOS-ESP-IDF supports
|
||||
the "static allocation", first introduced in baseline FreeRTOS V9.x. This QP port
|
||||
to FreeRTOS-ESP-IDF takes advantage of the "static allocation".
|
||||
|
||||
|
||||
[1]: https://www.espressif.com/en/products/sdks/esp-idf
|
||||
[2]: https://freertos.org
|
||||
[3]: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/freertos.html
|
@ -1,805 +0,0 @@
|
||||
//============================================================================
|
||||
// QP/C Real-Time Embedded Framework (RTEF)
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// 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: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
//
|
||||
// Redistributions in source code must retain this top-level comment block.
|
||||
// Plagiarizing this software to sidestep the license obligations is illegal.
|
||||
//
|
||||
// Contact information:
|
||||
// <www.state-machine.com>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2023-11-15
|
||||
//! @version Last updated for: @ref qpc_7_3_1
|
||||
//!
|
||||
//! @file
|
||||
//! @brief "Experimental" QF/C port to Espressif ESP-IDF (version 4.x)
|
||||
|
||||
#define QP_IMPL // this is QP implementation
|
||||
#include "qp_port.h" // QP port
|
||||
#include "qp_pkg.h" // QP package-level interface
|
||||
#include "qsafe.h" // QP Functional Safety (FuSa) Subsystem
|
||||
#ifdef Q_SPY // QS software tracing enabled?
|
||||
#include "qs_port.h" // QS port
|
||||
#include "qs_pkg.h" // QS package-scope internal interface
|
||||
#else
|
||||
#include "qs_dummy.h" // disable the QS software tracing
|
||||
#endif // Q_SPY
|
||||
|
||||
Q_DEFINE_THIS_MODULE("qf_port")
|
||||
|
||||
#if ( configSUPPORT_STATIC_ALLOCATION == 0 )
|
||||
#error "This QP/C port to FreeRTOS requires configSUPPORT_STATIC_ALLOCATION "
|
||||
#endif
|
||||
|
||||
#if ( configMAX_PRIORITIES < QF_MAX_ACTIVE )
|
||||
#error "FreeRTOS configMAX_PRIORITIES must not be less than QF_MAX_ACTIVE"
|
||||
#endif
|
||||
|
||||
// Global objects ----------------------------------------------------------
|
||||
PRIVILEGED_DATA portMUX_TYPE QF_esp32mux = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
// Local objects -----------------------------------------------------------
|
||||
static void task_function(void *pvParameters); // FreeRTOS task signature
|
||||
|
||||
// The following macro provides the number of free slots in the FreeRTOS
|
||||
// queue.
|
||||
//
|
||||
// NOTE1:
|
||||
// The official FreeRTOS API uxQueueSpacesAvailable() is not used
|
||||
// here, because that API uses task-level critical section internally.
|
||||
// Instead, the free slots calculation happens here in already
|
||||
// established critical section. Unfortunately, the bizarre "information
|
||||
// obfuscating" policy of FreeRTOS (incorrectly called "information
|
||||
// hiding") forces the use of the StaticQueue_t with "dummy" members.
|
||||
// This could potentially break in the future releases of FreeRTOS.
|
||||
//
|
||||
// Currently, the correspondence between xQUEUE and StaticQueue_t
|
||||
// is as follows (see queue.c and FreeRTOS.h, respectively):
|
||||
//
|
||||
// xQUEUE.uxMessagesWaiting == StaticQueue_t.uxDummy4[0];
|
||||
// xQUEUE.uxLength == StaticQueue_t.uxDummy4[1];
|
||||
//
|
||||
#define FREERTOS_QUEUE_GET_FREE(me_) \
|
||||
((me_)->osObject.uxDummy4[1] - (me_)->osObject.uxDummy4[0])
|
||||
|
||||
//============================================================================
|
||||
void QF_init(void) {
|
||||
// empty for ESP-IDF
|
||||
}
|
||||
//............................................................................
|
||||
int_t QF_run(void) {
|
||||
QF_onStartup(); // the startup callback (configure/enable interrupts)
|
||||
|
||||
// produce the QS_QF_RUN trace record
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
QS_BEGIN_PRE_(QS_QF_RUN, 0U)
|
||||
QS_END_PRE_()
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
return 0; // dummy return to make the compiler happy
|
||||
}
|
||||
//............................................................................
|
||||
void QF_stop(void) {
|
||||
QF_onCleanup(); // cleanup callback
|
||||
}
|
||||
|
||||
//............................................................................
|
||||
static void task_function(void *pvParameters) { // FreeRTOS task signature
|
||||
QActive *act = (QActive *)pvParameters;
|
||||
|
||||
#ifdef QACTIVE_CAN_STOP
|
||||
while (act->eQueue != (QueueHandle_t)0)
|
||||
#else
|
||||
for (;;) // for-ever
|
||||
#endif
|
||||
{
|
||||
QEvt const *e = QActive_get_(act); // wait for event
|
||||
QASM_DISPATCH(&act->super, e, act->prio); // dispatch to the SM
|
||||
QF_gc(e); // check if the event is garbage, and collect it if so
|
||||
}
|
||||
#ifdef QACTIVE_CAN_STOP
|
||||
QActive_unregister_(act); // remove this object from the framewrok
|
||||
vTaskDelete((TaskHandle_t)0); // delete this FreeRTOS task
|
||||
#endif
|
||||
}
|
||||
|
||||
//............................................................................
|
||||
void QActive_start_(QActive * const me,
|
||||
QPrioSpec const prioSpec,
|
||||
QEvt const * * const qSto,
|
||||
uint_fast16_t const qLen,
|
||||
void * const stkSto,
|
||||
uint_fast16_t const stkSize,
|
||||
void const * const par)
|
||||
{
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
// precondition:
|
||||
// - queue storage must be provided
|
||||
// - queue size must be provided
|
||||
// - stack storage must be provided
|
||||
// - stack size must be provided
|
||||
Q_REQUIRE_INCRIT(200,
|
||||
(qSto != (QEvt const **)0) && (qLen > 0U)
|
||||
&& (stkSto != (void *)0) && (stkSize > 0U));
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
// create FreeRTOS message queue
|
||||
me->eQueue = xQueueCreateStatic(
|
||||
(UBaseType_t)qLen, // length of the queue
|
||||
(UBaseType_t)sizeof(QEvt *), // element size
|
||||
(uint8_t *)qSto, // storage buffer
|
||||
&me->osObject); // static queue buffer
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ASSERT_INCRIT(210, me->eQueue != (QueueHandle_t)0);
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
me->prio = (uint8_t)(prioSpec & 0xFFU); // QF-priority of the AO
|
||||
me->pthre = 0U; // preemption-threshold (not used for AO registration)
|
||||
QActive_register_(me); // register this AO
|
||||
|
||||
// top-most initial tran. (virtual call)
|
||||
(*me->super.vptr->init)(&me->super, par, me->prio);
|
||||
QS_FLUSH(); // flush the QS trace buffer to the host
|
||||
|
||||
// task name provided by the user in QActive_setAttr() or default name
|
||||
char const *taskName = (me->thread.pxDummy1 != (void *)0)
|
||||
? (char const *)me->thread.pxDummy1
|
||||
: (char const *)"AO";
|
||||
|
||||
// The FreeRTOS priority of the AO thread can be specified in two ways:
|
||||
//
|
||||
// 1. Implictily based on the AO's priority (by the formula specified
|
||||
// in the macro FREERTOS_TASK_PRIO(), see qp_port.h). This option
|
||||
// is chosen, when the higher-byte of the prioSpec parameter is set
|
||||
// to zero.
|
||||
//
|
||||
// 2. Explicitly as the higher-byte of the prioSpec parameter.
|
||||
// This option is chosen when the prioSpec parameter is not-zero.
|
||||
// For example, Q_PRIO(10U, 5U) will explicitly specify AO priority
|
||||
// as 10 and FreeRTOS priority as 5.
|
||||
//
|
||||
// NOTE: The explicit FreeRTOS priority is NOT sanity-checked,
|
||||
// so it is the responsibility of the application to ensure that
|
||||
// it is consistent with the AO's priority. An example of
|
||||
// inconsistent setting would be assigning FreeRTOS priorities that
|
||||
// would result in a different relative priritization of AO's threads
|
||||
// than indicated by the AO priorities assigned.
|
||||
//
|
||||
UBaseType_t freertos_prio = (prioSpec >> 8U);
|
||||
if (freertos_prio == 0U) {
|
||||
freertos_prio = FREERTOS_TASK_PRIO(me->prio);
|
||||
}
|
||||
|
||||
// statically create the FreeRTOS task for the AO
|
||||
TaskHandle_t task = xTaskCreateStaticPinnedToCore(
|
||||
&task_function, // the task function
|
||||
taskName , // the name of the task
|
||||
stkSize/sizeof(portSTACK_TYPE), // stack length
|
||||
(void *)me, // the 'pvParameters' parameter
|
||||
freertos_prio, // FreeRTOS priority
|
||||
(StackType_t *)stkSto, // stack storage
|
||||
&me->thread, // task buffer
|
||||
QPC_CPU_NUM); // CPU number
|
||||
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ASSERT_INCRIT(220, task != (TaskHandle_t)0);
|
||||
QF_CRIT_EXIT();
|
||||
}
|
||||
//............................................................................
|
||||
#ifdef QACTIVE_CAN_STOP
|
||||
void QActive_stop(QActive * const me) {
|
||||
QActive_unsubscribeAll(me); // unsubscribe from all events
|
||||
me->eQueue = (QueueHandle_t)0; // stop the thread (see task_function())
|
||||
}
|
||||
#endif
|
||||
//............................................................................
|
||||
void QActive_setAttr(QActive *const me, uint32_t attr1, void const *attr2) {
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
// this function must be called before QACTIVE_START(),
|
||||
// which implies that me->thread.pxDummy1 must not be used yet;
|
||||
Q_REQUIRE_INCRIT(300, me->thread.pxDummy1 == (void *)0);
|
||||
switch (attr1) {
|
||||
case TASK_NAME_ATTR:
|
||||
// temporarily store the name, cast 'const' away
|
||||
me->thread.pxDummy1 = (void *)attr2;
|
||||
break;
|
||||
// ...
|
||||
}
|
||||
QF_CRIT_EXIT();
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
bool IRAM_ATTR QActive_post_(QActive * const me, QEvt const * const e,
|
||||
uint_fast16_t const margin, void const * const sender)
|
||||
{
|
||||
#ifndef Q_SPY
|
||||
Q_UNUSED_PAR(sender);
|
||||
#endif
|
||||
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
|
||||
// find the number of free slots available in the queue
|
||||
uint_fast16_t const nFree = (uint_fast16_t)FREERTOS_QUEUE_GET_FREE(me);
|
||||
|
||||
bool status;
|
||||
if (margin == QF_NO_MARGIN) {
|
||||
if (nFree > 0U) {
|
||||
status = true; // can post
|
||||
}
|
||||
else {
|
||||
status = false; // cannot post
|
||||
Q_ERROR_INCRIT(510); // must be able to post the event
|
||||
}
|
||||
}
|
||||
else if (nFree > margin) {
|
||||
status = true; // can post
|
||||
}
|
||||
else {
|
||||
status = false; // cannot post
|
||||
}
|
||||
|
||||
if (status) { // can post the event?
|
||||
|
||||
QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, me->prio)
|
||||
QS_TIME_PRE_(); // timestamp
|
||||
QS_OBJ_PRE_(sender); // the sender object
|
||||
QS_SIG_PRE_(e->sig); // the signal of the event
|
||||
QS_OBJ_PRE_(me); // this active object (recipient)
|
||||
QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr
|
||||
QS_EQC_PRE_((QEQueueCtr)nFree); // # free entries
|
||||
QS_EQC_PRE_(0U); // min # free entries (unknown)
|
||||
QS_END_PRE_()
|
||||
|
||||
if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event?
|
||||
QEvt_refCtr_inc_(e); // increment the reference counter
|
||||
}
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
BaseType_t err = xQueueSendToBack(
|
||||
me->eQueue, (void const *)&e, (TickType_t)0);
|
||||
|
||||
// posting to the FreeRTOS message queue must succeed, see NOTE3
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ASSERT_INCRIT(520, err == pdPASS);
|
||||
}
|
||||
else {
|
||||
|
||||
QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio)
|
||||
QS_TIME_PRE_(); // timestamp
|
||||
QS_OBJ_PRE_(sender); // the sender object
|
||||
QS_SIG_PRE_(e->sig); // the signal of the event
|
||||
QS_OBJ_PRE_(me); // this active object (recipient)
|
||||
QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr
|
||||
QS_EQC_PRE_((QEQueueCtr)nFree); // # free entries
|
||||
QS_EQC_PRE_(margin); // margin requested
|
||||
QS_END_PRE_()
|
||||
}
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
return status;
|
||||
}
|
||||
//............................................................................
|
||||
void IRAM_ATTR QActive_postLIFO_(QActive * const me, QEvt const * const e) {
|
||||
QF_CRIT_STAT
|
||||
QF_CRIT_ENTRY();
|
||||
|
||||
QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_LIFO, me->prio)
|
||||
QS_TIME_PRE_(); // timestamp
|
||||
QS_SIG_PRE_(e->sig); // the signal of this event
|
||||
QS_OBJ_PRE_(me); // this active object
|
||||
QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr
|
||||
QS_EQC_PRE_((QEQueueCtr)FREERTOS_QUEUE_GET_FREE(me)); // # free
|
||||
QS_EQC_PRE_(0U); // min # free entries (unknown)
|
||||
QS_END_PRE_()
|
||||
|
||||
if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event?
|
||||
QEvt_refCtr_inc_(e); // increment the reference counter
|
||||
}
|
||||
QF_CRIT_EXIT();
|
||||
|
||||
BaseType_t err = xQueueSendToFront(
|
||||
me->eQueue, (void const *)&e, (TickType_t)0);
|
||||
|
||||
// LIFO posting to the FreeRTOS queue must succeed, see NOTE3
|
||||
QF_CRIT_ENTRY();
|
||||
Q_ASSERT_INCRIT(610, err == pdPASS);
|
||||
QF_CRIT_EXIT();
|
||||
}
|
||||
//............................................................................
|
||||
QEvt const *QActive_get_(QActive * const me) {
|
||||
QEvt const *e;
|
||||
xQueueReceive(me->eQueue, (void *)&e, portMAX_DELAY);
|
||||
|
||||
QS_CRIT_STAT
|
||||
QS_CRIT_ENTRY();
|
||||
QS_BEGIN_PRE_(QS_QF_ACTIVE_GET, me->prio)
|
||||
QS_TIME_PRE_(); // timestamp
|
||||
QS_SIG_PRE_(e->sig); // the signal of this event
|
||||
QS_OBJ_PRE_(me); // this active object
|
||||
QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr
|
||||
QS_EQC_PRE_((QEQueueCtr)FREERTOS_QUEUE_GET_FREE(me)); // # free
|
||||
QS_END_PRE_()
|
||||
QS_CRIT_EXIT();
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
// The "FromISR" QP APIs for the FreeRTOS port...
|
||||
bool IRAM_ATTR QActive_postFromISR_(QActive * const me, QEvt const * const e,
|
||||
uint_fast16_t const margin,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken,
|
||||
void const * const sender)
|
||||
{
|
||||
portENTER_CRITICAL_ISR(&QF_esp32mux);
|
||||
|
||||
// find the number of free slots available in the queue
|
||||
uint_fast16_t const nFree = (uint_fast16_t)FREERTOS_QUEUE_GET_FREE(me);
|
||||
|
||||
bool status;
|
||||
if (margin == QF_NO_MARGIN) {
|
||||
if (nFree > 0U) {
|
||||
status = true; // can post
|
||||
}
|
||||
else {
|
||||
status = false; // cannot post
|
||||
Q_ERROR_INCRIT(810); // must be able to post the event
|
||||
}
|
||||
}
|
||||
else if (nFree > margin) {
|
||||
status = true; // can post
|
||||
}
|
||||
else {
|
||||
status = false; // cannot post
|
||||
}
|
||||
|
||||
if (status) { // can post the event?
|
||||
|
||||
QS_BEGIN_PRE_(QS_QF_ACTIVE_POST, me->prio)
|
||||
QS_TIME_PRE_(); // timestamp
|
||||
QS_OBJ_PRE_(sender); // the sender object
|
||||
QS_SIG_PRE_(e->sig); // the signal of the event
|
||||
QS_OBJ_PRE_(me); // this active object (recipient)
|
||||
QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr
|
||||
QS_EQC_PRE_(nFree); // # free entries available
|
||||
QS_EQC_PRE_(0U); // min # free entries (unknown)
|
||||
QS_END_PRE_()
|
||||
|
||||
if (QEvt_getPoolNum_(e) != 0U) { // is it a pool event?
|
||||
QEvt_refCtr_inc_(e); // increment the reference counter
|
||||
}
|
||||
portEXIT_CRITICAL_ISR(&QF_esp32mux);
|
||||
|
||||
BaseType_t err = xQueueSendToBackFromISR(me->eQueue,
|
||||
(void const *)&e,
|
||||
pxHigherPriorityTaskWoken);
|
||||
|
||||
// posting to the FreeRTOS message queue must succeed
|
||||
portENTER_CRITICAL_ISR(&QF_esp32mux);
|
||||
Q_ASSERT_INCRIT(820, err == pdPASS);
|
||||
portEXIT_CRITICAL_ISR(&QF_esp32mux);
|
||||
}
|
||||
else {
|
||||
|
||||
QS_BEGIN_PRE_(QS_QF_ACTIVE_POST_ATTEMPT, me->prio)
|
||||
QS_TIME_PRE_(); // timestamp
|
||||
QS_OBJ_PRE_(sender); // the sender object
|
||||
QS_SIG_PRE_(e->sig); // the signal of the event
|
||||
QS_OBJ_PRE_(me); // this active object (recipient)
|
||||
QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_); // poolNum & refCtr
|
||||
QS_EQC_PRE_(nFree); // # free entries available
|
||||
QS_EQC_PRE_(margin); // margin requested
|
||||
QS_END_PRE_()
|
||||
portEXIT_CRITICAL_ISR(&QF_esp32mux);
|
||||
|
||||
QF_gcFromISR(e); // recycle the event to avoid a leak
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
//............................................................................
|
||||
void IRAM_ATTR QActive_publishFromISR_(QEvt const * const e,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken,
|
||||
void const * const sender)
|
||||
{
|
||||
QSignal const sig = e->sig;
|
||||
|
||||
portENTER_CRITICAL_ISR(&QF_esp32mux);
|
||||
|
||||
//! @pre the published signal must be within the configured range
|
||||
Q_REQUIRE_INCRIT(500, sig < (QSignal)QActive_maxPubSignal_);
|
||||
Q_REQUIRE_INCRIT(502,
|
||||
QPSet_verify_(&QActive_subscrList_[sig].set,
|
||||
&QActive_subscrList_[sig].set_dis));
|
||||
|
||||
QS_BEGIN_PRE_(QS_QF_PUBLISH, 0U)
|
||||
QS_TIME_PRE_(); // the timestamp
|
||||
QS_OBJ_PRE_(sender); // the sender object
|
||||
QS_SIG_PRE_(sig); // the signal of the event
|
||||
QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_);// pool-Id & ref-Count
|
||||
QS_END_PRE_()
|
||||
|
||||
// is it a dynamic event?
|
||||
if (QEvt_getPoolNum_(e) != 0U) {
|
||||
// NOTE: The reference counter of a dynamic event is incremented to
|
||||
// prevent premature recycling of the event while the multicasting
|
||||
// is still in progress. At the end of the function, the garbage
|
||||
// collector step (QF_gcFromISR()) decrements the reference counter
|
||||
// and recycles the event if the counter drops to zero. This covers
|
||||
// the case when the event was published without any subscribers.
|
||||
QEvt_refCtr_inc_(e);
|
||||
}
|
||||
|
||||
// make a local, modifiable copy of the subscriber list
|
||||
QPSet subscrSet = QActive_subscrList_[sig].set;
|
||||
portEXIT_CRITICAL_ISR(&QF_esp32mux);
|
||||
|
||||
if (QPSet_notEmpty(&subscrSet)) { // any subscribers?
|
||||
// the highest-prio subscriber
|
||||
uint_fast8_t p = QPSet_findMax(&subscrSet);
|
||||
|
||||
// no need to lock the scheduler in the ISR context
|
||||
do { // loop over all subscribers
|
||||
// the prio of the AO must be registered with the framework
|
||||
portENTER_CRITICAL_ISR(&QF_esp32mux);
|
||||
Q_ASSERT_INCRIT(510, QActive_registry_[p] != (QActive *)0);
|
||||
portEXIT_CRITICAL_ISR(&QF_esp32mux);
|
||||
|
||||
// QACTIVE_POST_FROM_ISR() asserts if the queue overflows
|
||||
QACTIVE_POST_FROM_ISR(QActive_registry_[p], e,
|
||||
pxHigherPriorityTaskWoken, sender);
|
||||
|
||||
QPSet_remove(&subscrSet, p); // remove the handled subscriber
|
||||
if (QPSet_notEmpty(&subscrSet)) { // still more subscribers?
|
||||
p = QPSet_findMax(&subscrSet); // the highest-prio subscriber
|
||||
}
|
||||
else {
|
||||
p = 0U; // no more subscribers
|
||||
}
|
||||
} while (p != 0U);
|
||||
// no need to unlock the scheduler in the ISR context
|
||||
}
|
||||
|
||||
// The following garbage collection step decrements the reference counter
|
||||
// and recycles the event if the counter drops to zero. This covers both
|
||||
// cases when the event was published with or without any subscribers.
|
||||
QF_gcFromISR(e);
|
||||
}
|
||||
//............................................................................
|
||||
void IRAM_ATTR QTimeEvt_tickFromISR_(uint_fast8_t const tickRate,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken,
|
||||
void const * const sender)
|
||||
{
|
||||
portENTER_CRITICAL_ISR(&QF_esp32mux);
|
||||
|
||||
QTimeEvt *prev = &QTimeEvt_timeEvtHead_[tickRate];
|
||||
|
||||
QS_BEGIN_PRE_(QS_QF_TICK, 0U)
|
||||
++prev->ctr;
|
||||
QS_TEC_PRE_(prev->ctr); // tick ctr
|
||||
QS_U8_PRE_(tickRate); // tick rate
|
||||
QS_END_PRE_()
|
||||
|
||||
// scan the linked-list of time events at this rate...
|
||||
for (;;) {
|
||||
QTimeEvt *t = prev->next; // advance down the time evt. list
|
||||
|
||||
// end of the list?
|
||||
if (t == (QTimeEvt *)0) {
|
||||
|
||||
// any new time events armed since the last QTimeEvt_tick_()?
|
||||
if (QTimeEvt_timeEvtHead_[tickRate].act != (void *)0) {
|
||||
|
||||
// sanity check
|
||||
Q_ASSERT_INCRIT(610, prev != (QTimeEvt *)0);
|
||||
prev->next = (QTimeEvt *)QTimeEvt_timeEvtHead_[tickRate].act;
|
||||
QTimeEvt_timeEvtHead_[tickRate].act = (void *)0;
|
||||
t = prev->next; // switch to the new list
|
||||
}
|
||||
else {
|
||||
break; // all currently armed time evts. processed
|
||||
}
|
||||
}
|
||||
|
||||
// time event scheduled for removal?
|
||||
if (t->ctr == 0U) {
|
||||
prev->next = t->next;
|
||||
// mark time event 't' as NOT linked
|
||||
t->super.refCtr_ &= (uint8_t)(~QTE_IS_LINKED);
|
||||
// do NOT advance the prev pointer
|
||||
// exit crit. section to reduce latency
|
||||
portEXIT_CRITICAL_ISR(&QF_esp32mux);
|
||||
}
|
||||
else {
|
||||
--t->ctr;
|
||||
|
||||
// is time evt about to expire?
|
||||
if (t->ctr == 0U) {
|
||||
QActive *act = (QActive *)t->act; // temp. for volatile
|
||||
|
||||
// periodic time evt?
|
||||
if (t->interval != 0U) {
|
||||
t->ctr = t->interval; // rearm the time event
|
||||
prev = t; // advance to this time event
|
||||
}
|
||||
// one-shot time event: automatically disarm
|
||||
else {
|
||||
prev->next = t->next;
|
||||
// mark time event 't' as NOT linked
|
||||
t->super.refCtr_ &= (uint8_t)(~QTE_IS_LINKED);
|
||||
// do NOT advance the prev pointer
|
||||
|
||||
QS_BEGIN_PRE_(QS_QF_TIMEEVT_AUTO_DISARM, act->prio)
|
||||
QS_OBJ_PRE_(t); // this time event object
|
||||
QS_OBJ_PRE_(act); // the target AO
|
||||
QS_U8_PRE_(tickRate); // tick rate
|
||||
QS_END_PRE_()
|
||||
}
|
||||
|
||||
QS_BEGIN_PRE_(QS_QF_TIMEEVT_POST, act->prio)
|
||||
QS_TIME_PRE_(); // timestamp
|
||||
QS_OBJ_PRE_(t); // the time event object
|
||||
QS_SIG_PRE_(t->super.sig); // signal of time event
|
||||
QS_OBJ_PRE_(act); // the target AO
|
||||
QS_U8_PRE_(tickRate); // tick rate
|
||||
QS_END_PRE_()
|
||||
|
||||
// exit critical section before posting
|
||||
portEXIT_CRITICAL_ISR(&QF_esp32mux);
|
||||
|
||||
// QACTIVE_POST_FROM_ISR() asserts if the queue overflows
|
||||
QACTIVE_POST_FROM_ISR(act, &t->super,
|
||||
pxHigherPriorityTaskWoken,
|
||||
sender);
|
||||
}
|
||||
else {
|
||||
prev = t; // advance to this time event
|
||||
// exit crit. section to reduce latency
|
||||
portEXIT_CRITICAL_ISR(&QF_esp32mux);
|
||||
}
|
||||
}
|
||||
// re-enter crit. section to continue
|
||||
portENTER_CRITICAL_ISR(&QF_esp32mux);
|
||||
}
|
||||
portEXIT_CRITICAL_ISR(&QF_esp32mux);
|
||||
}
|
||||
//............................................................................
|
||||
QEvt IRAM_ATTR *QF_newXFromISR_(uint_fast16_t const evtSize,
|
||||
uint_fast16_t const margin, enum_t const sig)
|
||||
{
|
||||
// find the poolNum that fits the requested event size ...
|
||||
uint_fast8_t idx;
|
||||
for (idx = 0U; idx < QF_priv_.maxPool_; ++idx) {
|
||||
if (evtSize <= QF_EPOOL_EVENT_SIZE_(QF_priv_.ePool_[idx])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// cannot run out of registered pools
|
||||
portENTER_CRITICAL_ISR(&QF_esp32mux);
|
||||
Q_REQUIRE_INCRIT(700, idx < QF_priv_.maxPool_);
|
||||
portEXIT_CRITICAL_ISR(&QF_esp32mux);
|
||||
|
||||
// get e -- platform-dependent
|
||||
#ifdef Q_SPY
|
||||
QEvt *e = QMPool_getFromISR(&QF_priv_.ePool_[idx],
|
||||
((margin != QF_NO_MARGIN) ? margin : 0U),
|
||||
(uint_fast8_t)QS_EP_ID + idx + 1U);
|
||||
#else
|
||||
QEvt *e = QMPool_getFromISR(&QF_priv_.ePool_[idx],
|
||||
((margin != QF_NO_MARGIN) ? margin : 0U), 0U);
|
||||
#endif
|
||||
|
||||
// was e allocated correctly?
|
||||
if (e != (QEvt *)0) {
|
||||
e->sig = (QSignal)sig; // set the signal
|
||||
e->refCtr_ = 0U; // initialize the reference counter to 0
|
||||
e->evtTag_ = (uint8_t)(QEVT_MARKER | (idx + 1U)); // pool ID
|
||||
|
||||
#ifdef Q_SPY
|
||||
portENTER_CRITICAL_ISR(&QF_esp32mux);
|
||||
QS_BEGIN_PRE_(QS_QF_NEW,
|
||||
(uint_fast8_t)QS_EP_ID + idx + 1U)
|
||||
QS_TIME_PRE_(); // timestamp
|
||||
QS_EVS_PRE_(evtSize); // the size of the event
|
||||
QS_SIG_PRE_(sig); // the signal of the event
|
||||
QS_END_PRE_()
|
||||
portEXIT_CRITICAL_ISR(&QF_esp32mux);
|
||||
#endif // Q_SPY
|
||||
}
|
||||
else { // event cannot be allocated
|
||||
// must tolerate bad alloc.
|
||||
portENTER_CRITICAL_ISR(&QF_esp32mux);
|
||||
Q_ASSERT_INCRIT(720, margin != QF_NO_MARGIN);
|
||||
portEXIT_CRITICAL_ISR(&QF_esp32mux);
|
||||
|
||||
#ifdef Q_SPY
|
||||
portENTER_CRITICAL_ISR(&QF_esp32mux);
|
||||
QS_BEGIN_PRE_(QS_QF_NEW_ATTEMPT,
|
||||
(uint_fast8_t)QS_EP_ID + idx + 1U)
|
||||
QS_TIME_PRE_(); // timestamp
|
||||
QS_EVS_PRE_(evtSize); // the size of the event
|
||||
QS_SIG_PRE_(sig); // the signal of the event
|
||||
QS_END_PRE_()
|
||||
portEXIT_CRITICAL_ISR(&QF_esp32mux);
|
||||
#endif // Q_SPY
|
||||
}
|
||||
return e; // can't be NULL if we can't tolerate bad allocation
|
||||
}
|
||||
//............................................................................
|
||||
void IRAM_ATTR QF_gcFromISR(QEvt const * const e) {
|
||||
// is it a dynamic event?
|
||||
if (QEvt_getPoolNum_(e) != 0U) {
|
||||
portENTER_CRITICAL_ISR(&QF_esp32mux);
|
||||
|
||||
// isn't this the last ref?
|
||||
if (e->refCtr_ > 1U) {
|
||||
QEvt_refCtr_dec_(e); // decrement the ref counter
|
||||
|
||||
QS_BEGIN_PRE_(QS_QF_GC_ATTEMPT,
|
||||
(uint_fast8_t)QEvt_getPoolNum_(e))
|
||||
QS_TIME_PRE_(); // timestamp
|
||||
QS_SIG_PRE_(e->sig); // the signal of the event
|
||||
QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_);//pool-Id&ref-Count
|
||||
QS_END_PRE_()
|
||||
|
||||
portEXIT_CRITICAL_ISR(&QF_esp32mux);
|
||||
}
|
||||
// this is the last reference to this event, recycle it
|
||||
else {
|
||||
uint_fast8_t idx = (uint_fast8_t)QEvt_getPoolNum_(e) - 1U;
|
||||
|
||||
QS_BEGIN_PRE_(QS_QF_GC, (uint_fast8_t)QEvt_getPoolNum_(e))
|
||||
QS_TIME_PRE_(); // timestamp
|
||||
QS_SIG_PRE_(e->sig); // the signal of the event
|
||||
QS_2U8_PRE_(QEvt_getPoolNum_(e), e->refCtr_);//pool-Id&ref-Count
|
||||
QS_END_PRE_()
|
||||
|
||||
// pool ID must be in range
|
||||
Q_ASSERT_INCRIT(810, idx < QF_priv_.maxPool_);
|
||||
|
||||
portEXIT_CRITICAL_ISR(&QF_esp32mux);
|
||||
|
||||
#ifdef Q_SPY
|
||||
// cast 'const' away in (QEvt *)e is OK because it's a pool event
|
||||
QMPool_putFromISR(&QF_priv_.ePool_[idx], (QEvt *)e,
|
||||
(uint_fast8_t)QS_EP_ID + QEvt_getPoolNum_(e));
|
||||
#else
|
||||
QMPool_putFromISR(&QF_priv_.ePool_[idx], (QEvt *)e, 0U);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
//............................................................................
|
||||
void IRAM_ATTR QMPool_putFromISR(QMPool * const me, void *b,
|
||||
uint_fast8_t const qsId)
|
||||
{
|
||||
#ifndef Q_SPY
|
||||
Q_UNUSED_PAR(qsId);
|
||||
#endif
|
||||
|
||||
QFreeBlock * const fb = (QFreeBlock *)block;
|
||||
|
||||
portENTER_CRITICAL_ISR(&QF_esp32mux);
|
||||
|
||||
// precondition:
|
||||
// - # free blocks cannot exceed the total # blocks and
|
||||
// - the block pointer must be from this pool.
|
||||
Q_REQUIRE_INCRIT(900, (me->nFree < me->nTot)
|
||||
&& (me->start <= fb) && (fb <= me->end));
|
||||
|
||||
fb->next = me->free_head; // link into list
|
||||
#ifndef Q_UNSAFE
|
||||
fb->next_dis = (uintptr_t)(~Q_UINTPTR_CAST_(fb->next));
|
||||
#endif
|
||||
|
||||
me->free_head = block; // set as new head of the free list
|
||||
++me->nFree; // one more free block in this pool
|
||||
|
||||
QS_BEGIN_PRE_(QS_QF_MPOOL_PUT, qsId)
|
||||
QS_TIME_PRE_(); // timestamp
|
||||
QS_OBJ_PRE_(me); // this memory pool
|
||||
QS_MPC_PRE_(me->nFree); // the number of free blocks in the pool
|
||||
QS_END_PRE_()
|
||||
|
||||
portEXIT_CRITICAL_ISR(&QF_esp32mux);
|
||||
}
|
||||
//............................................................................
|
||||
void *QMPool_getFromISR(QMPool * const me, uint_fast16_t const margin,
|
||||
uint_fast8_t const qsId)
|
||||
{
|
||||
#ifndef Q_SPY
|
||||
Q_UNUSED_PAR(qsId);
|
||||
#endif
|
||||
|
||||
portENTER_CRITICAL_ISR(&QF_esp32mux);
|
||||
|
||||
// have more free blocks than the requested margin?
|
||||
QFreeBlock *fb;
|
||||
if (me->nFree > (QMPoolCtr)margin) {
|
||||
fb = me->free_head; // get a free block
|
||||
|
||||
// the pool has some free blocks, so a free block must be available
|
||||
Q_ASSERT_INCRIT(900, fb != (QFreeBlock *)0);
|
||||
|
||||
QFreeBlock * const fb_next = fb->next; // fast temporary to avoid UB
|
||||
|
||||
// the free block must have integrity (duplicate inverse storage)
|
||||
Q_ASSERT_INCRIT(902, Q_UINTPTR_CAST_(fb_next)
|
||||
== (uintptr_t)~fb->next_dis);
|
||||
|
||||
// is the pool becoming empty?
|
||||
--me->nFree; // one less free block
|
||||
if (me->nFree == 0U) {
|
||||
// pool is becoming empty, so the next free block must be NULL
|
||||
Q_ASSERT_INCRIT(920, fb_next == (QFreeBlock *)0);
|
||||
|
||||
me->nMin = 0U; // remember that the pool got empty
|
||||
}
|
||||
else {
|
||||
// invariant
|
||||
// The pool is not empty, so the next free-block pointer,
|
||||
// so the next free block must be in range.
|
||||
//
|
||||
// NOTE: The next free block pointer can fall out of range
|
||||
// when the client code writes past the memory block, thus
|
||||
// corrupting the next block.
|
||||
Q_ASSERT_INCRIT(930,
|
||||
(me->start <= fb_next) && (fb_next <= me->end));
|
||||
|
||||
// is the number of free blocks the new minimum so far?
|
||||
if (me->nMin > me->nFree) {
|
||||
me->nMin = me->nFree; // remember the new minimum
|
||||
}
|
||||
}
|
||||
|
||||
me->free_head = fb_next; // set the head to the next free block
|
||||
|
||||
QS_BEGIN_PRE_(QS_QF_MPOOL_GET, qsId)
|
||||
QS_TIME_PRE_(); // timestamp
|
||||
QS_OBJ_PRE_(me); // this memory pool
|
||||
QS_MPC_PRE_(me->nFree); // # free blocks in the pool
|
||||
QS_MPC_PRE_(me->nMin); // min # free blocks ever in the pool
|
||||
QS_END_PRE_()
|
||||
}
|
||||
else { // don't have enough free blocks at this point
|
||||
fb = (QFreeBlock *)0;
|
||||
|
||||
QS_BEGIN_PRE_(QS_QF_MPOOL_GET_ATTEMPT, qsId)
|
||||
QS_TIME_PRE_(); // timestamp
|
||||
QS_OBJ_PRE_(me); // this memory pool
|
||||
QS_MPC_PRE_(me->nFree); // # free blocks in the pool
|
||||
QS_MPC_PRE_(margin); // the requested margin
|
||||
QS_END_PRE_()
|
||||
}
|
||||
portEXIT_CRITICAL_ISR(&QF_esp32mux);
|
||||
|
||||
return fb; // return the block or NULL pointer to the caller
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
// NOTE3:
|
||||
// The event posting to FreeRTOS message queue occurs OUTSIDE critical section,
|
||||
// which means that the remaining margin of available slots in the queue
|
||||
// cannot be guaranteed. The problem is that interrupts and other tasks can
|
||||
// preempt the event posting after checking the margin, but before actually
|
||||
// posting the event to the queue.
|
||||
//
|
||||
|
@ -1,269 +0,0 @@
|
||||
//============================================================================
|
||||
// QP/C Real-Time Embedded Framework (RTEF)
|
||||
//
|
||||
// Q u a n t u m L e a P s
|
||||
// ------------------------
|
||||
// Modern Embedded Software
|
||||
//
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// 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: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
//
|
||||
// Redistributions in source code must retain this top-level comment block.
|
||||
// Plagiarizing this software to sidestep the license obligations is illegal.
|
||||
//
|
||||
// Contact information:
|
||||
// <www.state-machine.com>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2023-09-07
|
||||
//! @version Last updated for: @ref qpc_7_3_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QP/C port to Espressif ESP-IDF (version 4.x), Experimental, NOTE0
|
||||
//!
|
||||
#ifndef QP_PORT_H_
|
||||
#define QP_PORT_H_
|
||||
|
||||
#include <stdint.h> // Exact-width types. WG14/N843 C99 Standard
|
||||
#include <stdbool.h> // Boolean type. WG14/N843 C99 Standard
|
||||
|
||||
#ifdef QP_CONFIG
|
||||
#include "qp_config.h" // external QP configuration
|
||||
#endif
|
||||
|
||||
// no-return function specifier (C11 Standard)
|
||||
#define Q_NORETURN _Noreturn void
|
||||
|
||||
// QActive event queue and thread types for Espressif ESP-IDF
|
||||
#define QACTIVE_EQUEUE_TYPE QueueHandle_t
|
||||
#define QACTIVE_OS_OBJ_TYPE StaticQueue_t
|
||||
#define QACTIVE_THREAD_TYPE StaticTask_t
|
||||
|
||||
// FreeRTOS requires the "FromISR" API in QP/C++
|
||||
#define QF_ISR_API 1
|
||||
|
||||
// QF interrupt disabling for FreeRTOS-ESP32 (task level), see NOTE2
|
||||
#define QF_INT_DISABLE() portENTER_CRITICAL(&QF_esp32mux)
|
||||
#define QF_INT_ENABLE() portEXIT_CRITICAL(&QF_esp32mux)
|
||||
|
||||
// QF critical section for FreeRTOS-ESP32 (task level), see NOTE2
|
||||
#define QF_CRIT_STAT
|
||||
#define QF_CRIT_ENTRY() portENTER_CRITICAL(&QF_esp32mux)
|
||||
#define QF_CRIT_EXIT() portEXIT_CRITICAL(&QF_esp32mux)
|
||||
|
||||
// include files -------------------------------------------------------------
|
||||
#include "freertos/FreeRTOS.h" // FreeRTOS master include file, see NOTE3
|
||||
#include "freertos/task.h" // FreeRTOS task management
|
||||
#include "freertos/queue.h" // FreeRTOS queue management
|
||||
|
||||
#include "qequeue.h" // QP event queue (for deferring events)
|
||||
#include "qmpool.h" // QP memory pool (for event pools)
|
||||
#include "qp.h" // QP platform-independent public interface
|
||||
|
||||
// global spinlock "mutex" for all critical sections in QF (see NOTE4)
|
||||
extern PRIVILEGED_DATA portMUX_TYPE QF_esp32mux;
|
||||
|
||||
#if defined( CONFIG_QPC_PINNED_TO_CORE_0 )
|
||||
#define QPC_CPU_NUM PRO_CPU_NUM
|
||||
#elif defined( CONFIG_QPC_PINNED_TO_CORE_1 )
|
||||
#define QPC_CPU_NUM APP_CPU_NUM
|
||||
#else
|
||||
// Defaults to APP_CPU
|
||||
#define QPC_CPU_NUM APP_CPU_NUM
|
||||
#endif
|
||||
|
||||
// the "FromISR" versions of the QF APIs, see NOTE3
|
||||
#ifdef Q_SPY
|
||||
|
||||
#define QACTIVE_POST_FROM_ISR(me_, e_, pxHigherPrioTaskWoken_, sender_) \
|
||||
((void)QActive_postFromISR_((me_), (e_), QF_NO_MARGIN, \
|
||||
(pxHigherPrioTaskWoken_), (sender_)))
|
||||
|
||||
#define QACTIVE_POST_X_FROM_ISR(me_, e_, margin_, \
|
||||
pxHigherPrioTaskWoken_, sender_) \
|
||||
(QActive_postFromISR_((me_), (e_), (margin_), \
|
||||
(pxHigherPrioTaskWoken_), (sender_)))
|
||||
|
||||
#define QACTIVE_PUBLISH_FROM_ISR(e_, pxHigherPrioTaskWoken_, sender_) \
|
||||
(QActive_publishFromISR_((e_), (pxHigherPrioTaskWoken_), \
|
||||
(void const *)(sender_)))
|
||||
|
||||
#define QTIMEEVT_TICK_FROM_ISR(tickRate_, pxHigherPrioTaskWoken_, sender_) \
|
||||
(QTimeEvt_tickFromISR_((tickRate_), (pxHigherPrioTaskWoken_), (sender_)))
|
||||
|
||||
#else // ndef Q_SPY
|
||||
|
||||
#define QACTIVE_POST_FROM_ISR(me_, e_, pxHigherPrioTaskWoken_, dummy) \
|
||||
((void)QActive_postFromISR_((me_), (e_), QF_NO_MARGIN, \
|
||||
(pxHigherPrioTaskWoken_), (void *)0))
|
||||
|
||||
#define QACTIVE_POST_X_FROM_ISR(me_, e_, margin_, \
|
||||
pxHigherPrioTaskWoken_, dummy) \
|
||||
(QActive_postFromISR_((me_), (e_), (margin_), \
|
||||
(pxHigherPrioTaskWoken_), (void *)0))
|
||||
|
||||
#define QACTIVE_PUBLISH_FROM_ISR(e_, pxHigherPrioTaskWoken_, dummy) \
|
||||
(QActive_publishFromISR_((e_), (pxHigherPrioTaskWoken_), \
|
||||
(void *)0))
|
||||
|
||||
#define QTIMEEVT_TICK_FROM_ISR(tickRate_, pxHigherPrioTaskWoken_, dummy) \
|
||||
(QTimeEvt_tickFromISR_((tickRate_), (pxHigherPrioTaskWoken_), (void *)0))
|
||||
|
||||
#endif // Q_SPY
|
||||
|
||||
bool IRAM_ATTR QActive_postFromISR_(QActive * const me, QEvt const * const e,
|
||||
uint_fast16_t const margin,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken,
|
||||
void const * const sender);
|
||||
|
||||
void IRAM_ATTR QActive_publishFromISR_(QEvt const * const e,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken,
|
||||
void const * const sender);
|
||||
|
||||
void IRAM_ATTR QTimeEvt_tickFromISR_(uint_fast8_t const tickRate,
|
||||
BaseType_t * const pxHigherPriorityTaskWoken,
|
||||
void const * const sender);
|
||||
|
||||
#define QF_TICK_FROM_ISR(pxHigherPrioTaskWoken_, sender_) \
|
||||
QTIMEEVT_TICK_FROM_ISR(0U, pxHigherPrioTaskWoken_, sender_)
|
||||
|
||||
#ifdef QEVT_DYN_CTOR // Shall the ctor for the ::QEvt class be provided?
|
||||
|
||||
#define Q_NEW_FROM_ISR(evtT_, sig_, ...) \
|
||||
(evtT_##_ctor((evtT_ *)QF_newXFromISR_(sizeof(evtT_), \
|
||||
QF_NO_MARGIN, (sig_)), __VA_ARGS__))
|
||||
|
||||
#define Q_NEW_X_FROM_ISR(e_, evtT_, margin_, sig_, ...) do { \
|
||||
(e_) = (evtT_ *)QF_newXFromISR_(sizeof(evtT_), \
|
||||
(margin_), (sig_)); \
|
||||
if ((e_) != (evtT_ *)0) { \
|
||||
evtT_##_ctor((e_), __VA_ARGS__); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#else // no ::QEvt ctor
|
||||
|
||||
#define Q_NEW_FROM_ISR(evtT_, sig_) \
|
||||
((evtT_ *)QF_newXFromISR_((uint_fast16_t)sizeof(evtT_), \
|
||||
QF_NO_MARGIN, (sig_)))
|
||||
|
||||
#define Q_NEW_X_FROM_ISR(e_, evtT_, margin_, sig_) ((e_) = \
|
||||
(evtT_ *)QF_newXFromISR_((uint_fast16_t)sizeof(evtT_), \
|
||||
(margin_), (sig_)))
|
||||
|
||||
#endif // QEVT_DYN_CTOR
|
||||
|
||||
void QF_gcFromISR(QEvt const * const e);
|
||||
|
||||
QEvt *QF_newXFromISR_(uint_fast16_t const evtSize,
|
||||
uint_fast16_t const margin, enum_t const sig);
|
||||
|
||||
void *QMPool_getFromISR(QMPool * const me, uint_fast16_t const margin,
|
||||
uint_fast8_t const qsId);
|
||||
void QMPool_putFromISR(QMPool * const me, void *block,
|
||||
uint_fast8_t const qsId);
|
||||
|
||||
enum FreeRTOS_TaskAttrs {
|
||||
TASK_NAME_ATTR
|
||||
};
|
||||
|
||||
// FreeRTOS hooks prototypes (not provided by FreeRTOS)
|
||||
#if (configUSE_IDLE_HOOK > 0)
|
||||
void vApplicationIdleHook(void);
|
||||
#endif
|
||||
#if (configUSE_TICK_HOOK > 0)
|
||||
void vApplicationTickHook(void);
|
||||
#endif
|
||||
#if (configCHECK_FOR_STACK_OVERFLOW > 0)
|
||||
void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName);
|
||||
#endif
|
||||
#if (configSUPPORT_STATIC_ALLOCATION > 0)
|
||||
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
|
||||
StackType_t **ppxIdleTaskStackBuffer,
|
||||
uint32_t *pulIdleTaskStackSize);
|
||||
#endif
|
||||
|
||||
//============================================================================
|
||||
// interface used only inside QF, but not in applications
|
||||
|
||||
#ifdef QP_IMPL
|
||||
#define FREERTOS_TASK_PRIO(qp_prio_) \
|
||||
((UBaseType_t)((qp_prio_) + tskIDLE_PRIORITY))
|
||||
|
||||
// FreeRTOS scheduler locking for QF_publish_() (task context only)
|
||||
#define QF_SCHED_STAT_
|
||||
#define QF_SCHED_LOCK_(prio_) (vTaskSuspendAll())
|
||||
#define QF_SCHED_UNLOCK_() ((void)xTaskResumeAll())
|
||||
|
||||
// native QF event pool customization
|
||||
#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)
|
||||
#define QF_EPOOL_GET_(p_, e_, m_, qsId_) \
|
||||
((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qsId_)))
|
||||
#define QF_EPOOL_PUT_(p_, e_, qsId_) \
|
||||
(QMPool_put(&(p_), (e_), (qsId_)))
|
||||
|
||||
#endif // QP_IMPL
|
||||
|
||||
//============================================================================
|
||||
// NOTE0:
|
||||
// This is the "experimental" port to the [Espressif ESP-IDF][1]
|
||||
// IoT Framework, which is loosely based on the [FreeRTOS kernel][2].
|
||||
//
|
||||
// "Experimental" means that the port has not been thoroughly tested at
|
||||
// Quantum Leaps and no working examples are provided.
|
||||
//
|
||||
// The [Espressif ESP-IDF][1] is based on a significantly changed version
|
||||
// of the FreeRTOS kernel developed by Espressif to support the ESP32
|
||||
// multi-core CPUs (see [ESP-IDF][1]).
|
||||
//
|
||||
// The Espressif version of FreeRTOS is **NOT** compatible with the baseline
|
||||
// FreeRTOS and it needs to be treated as a separate RTOS kernel.
|
||||
// According to the comments in the Espressif source code, FreeRTOS-ESP-IDF
|
||||
// is based on FreeRTOS V8.2.0, but apparently FreeRTOS-ESP-IDF has been
|
||||
// updated with the newer features introduced to the original FreeRTOS in the
|
||||
// later versions. For example, FreeRTOS-ESP32 supports the "static allocation",
|
||||
// first introduced in baseline FreeRTOS V9.x. This QP port to FreeRTOS-ESP-IDF
|
||||
// takes advantage of the "static allocation".
|
||||
//
|
||||
// [1]: https://www.espressif.com/en/products/sdks/esp-idf
|
||||
// [2]: https://freertos.org
|
||||
//
|
||||
// NOTE1:
|
||||
// The maximum number of active objects QF_MAX_ACTIVE can be increased to 64,
|
||||
// inclusive, but it can be reduced to save some memory. Also, the number of
|
||||
// active objects cannot exceed the number of FreeRTOS task priorities,
|
||||
// because each QP active object requires a unique priority level.
|
||||
//
|
||||
// NOTE2:
|
||||
// The critical section definition applies only to the FreeRTOS "task level"
|
||||
// APIs. The "FromISR" APIs are defined separately.
|
||||
//
|
||||
// NOTE3:
|
||||
// The design of FreeRTOS requires using different APIs inside the ISRs
|
||||
// (the "FromISR" variant) than at the task level. Accordingly, this port
|
||||
// provides the "FromISR" variants for QP functions and "FROM_ISR" variants
|
||||
// for QP macros to be used inside ISRs. ONLY THESE "FROM_ISR" VARIANTS
|
||||
// ARE ALLOWED INSIDE ISRs AND CALLING THE TASK-LEVEL APIs IS AN ERROR.
|
||||
//
|
||||
// NOTE4:
|
||||
// This QF port to FreeRTOS-ESP32 uses the FreeRTOS-ESP32 spin lock "mutex",
|
||||
// similar to the internal implementation of FreeRTOS-ESP32 (see tasks.c).
|
||||
// However, the QF port uses its own "mutex" object QF_esp32mux.
|
||||
|
||||
#endif // QP_PORT_H_
|
||||
|
@ -1,56 +0,0 @@
|
||||
//============================================================================
|
||||
// QP/C Real-Time Embedded Framework (RTEF)
|
||||
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
|
||||
//
|
||||
// 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: <www.gnu.org/licenses/gpl-3.0>
|
||||
//
|
||||
// The terms of the closed source Quantum Leaps commercial licenses
|
||||
// can be found at: <www.state-machine.com/licensing>
|
||||
//
|
||||
// Redistributions in source code must retain this top-level comment block.
|
||||
// Plagiarizing this software to sidestep the license obligations is illegal.
|
||||
//
|
||||
// Contact information:
|
||||
// <www.state-machine.com>
|
||||
// <info@state-machine.com>
|
||||
//============================================================================
|
||||
//! @date Last updated on: 2023-08-16
|
||||
//! @version Last updated for: @ref qpc_7_3_0
|
||||
//!
|
||||
//! @file
|
||||
//! @brief QS/C port to a 32-bit CPU and a generic C11 compiler.
|
||||
|
||||
#ifndef QS_PORT_H_
|
||||
#define QS_PORT_H_
|
||||
|
||||
// QS time-stamp size in bytes
|
||||
#define QS_TIME_SIZE 4U
|
||||
|
||||
// object pointer size in bytes
|
||||
#define QS_OBJ_PTR_SIZE 4U
|
||||
|
||||
// function pointer size in bytes
|
||||
#define QS_FUN_PTR_SIZE 4U
|
||||
|
||||
//============================================================================
|
||||
// NOTE: QS might be used with or without other QP components, in which
|
||||
// case the separate definitions of the macros QF_CRIT_STAT, QF_CRIT_ENTRY(),
|
||||
// and QF_CRIT_EXIT() are needed. In this port QS is configured to be used
|
||||
// with the other QP component, by simply including "qp_port.h"
|
||||
//*before* "qs.h".
|
||||
#ifndef QP_PORT_H_
|
||||
#include "qp_port.h" // use QS with QF
|
||||
#endif
|
||||
|
||||
#include "qs.h" // QS platform-independent public interface
|
||||
|
||||
#endif // QS_PORT_H_
|
||||
|
@ -1,8 +1,10 @@
|
||||
# ports/msp430
|
||||
if(QPC_CFG_UNIT_TEST)
|
||||
target_include_directories(qpc PUBLIC qutest)
|
||||
elseif(NOT KERNEL MATCHES "q[vk]")
|
||||
message(WARNING "Kernel ${KERNEL} is not supported! Falling back to QV kernel")
|
||||
set(KERNEL qv)
|
||||
else()
|
||||
if(NOT KERNEL MATCHES "q[vk]")
|
||||
message(WARNING "Kernel ${KERNEL} is not supported! Falling back to QV kernel")
|
||||
set(KERNEL qv)
|
||||
endif()
|
||||
target_include_directories(qpc PUBLIC ${KERNEL})
|
||||
endif()
|
||||
target_include_directories(qpc PUBLIC ${KERNEL})
|
||||
|
@ -1,11 +1,15 @@
|
||||
# ports/pic32
|
||||
if(QPC_CFG_UNIT_TEST)
|
||||
target_include_directories(qpc PUBLIC qutest/xc32)
|
||||
elseif(NOT KERNEL MATCHES "q[vk]")
|
||||
message(WARNING "Kernel ${KERNEL} is not supported! Falling back to QV kernel")
|
||||
set(KERNEL qv)
|
||||
endif()
|
||||
target_include_directories(qpc PUBLIC ${KERNEL}/xc32)
|
||||
if(KERNEL STREQUAL qk)
|
||||
target_sources(qpc PRIVATE qk_port.c)
|
||||
endif()
|
||||
else()
|
||||
if(NOT KERNEL MATCHES "q[vk]")
|
||||
message(WARNING "Kernel ${KERNEL} is not supported! Falling back to QV kernel")
|
||||
set(KERNEL qv)
|
||||
endif()
|
||||
|
||||
set(KERNEL_PORT_C ${CMAKE_CURRENT_LIST_DIR}/${KERNEL}/xc32/${KERNEL}_port.c)
|
||||
if(EXISTS ${KERNEL_PORT_C})
|
||||
target_sources(qpc PRIVATE ${KERNEL_PORT_C})
|
||||
endif()
|
||||
target_include_directories(qpc PUBLIC ${KERNEL}/xc32)
|
||||
endif()
|
@ -1,7 +1,5 @@
|
||||
# ports/posix-qutest
|
||||
target_include_directories(qpc PUBLIC .)
|
||||
target_sources(
|
||||
qpc
|
||||
PRIVATE
|
||||
qutest_port.c
|
||||
target_sources(qpc PRIVATE
|
||||
qutest_port.c
|
||||
)
|
@ -1,8 +1,6 @@
|
||||
# ports/posix-qv
|
||||
target_include_directories(qpc PUBLIC .)
|
||||
target_sources(
|
||||
qpc
|
||||
PRIVATE
|
||||
qf_port.c
|
||||
$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qs_port.c>
|
||||
target_sources(qpc PRIVATE
|
||||
qf_port.c
|
||||
$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qs_port.c>
|
||||
)
|
@ -1,8 +1,6 @@
|
||||
# ports/posix
|
||||
target_include_directories(qpc PUBLIC .)
|
||||
target_sources(
|
||||
qpc
|
||||
PRIVATE
|
||||
qf_port.c
|
||||
$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qs_port.c>
|
||||
target_sources(qpc PRIVATE
|
||||
qf_port.c
|
||||
$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qs_port.c>
|
||||
)
|
@ -1,7 +1,5 @@
|
||||
# ports/win32-qutest
|
||||
target_include_directories(qpc PUBLIC .)
|
||||
target_sources(
|
||||
qpc
|
||||
PRIVATE
|
||||
qutest_port.c
|
||||
target_sources(qpc PRIVATE
|
||||
qutest_port.c
|
||||
)
|
@ -1,9 +1,7 @@
|
||||
# ports/win32-qv
|
||||
target_include_directories(qpc PUBLIC .)
|
||||
target_sources(
|
||||
qpc
|
||||
PRIVATE
|
||||
qf_port.c
|
||||
$<$<BOOL:${QPC_CFG_GUI}>:${CMAKE_CURRENT_SOURCE_DIR}/qwin_gui.c>
|
||||
$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qs_port.c>
|
||||
target_sources(qpc PRIVATE
|
||||
qf_port.c
|
||||
$<$<BOOL:${QPC_CFG_GUI}>:${CMAKE_CURRENT_SOURCE_DIR}/qwin_gui.c>
|
||||
$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qs_port.c>
|
||||
)
|
||||
|
@ -1,9 +1,7 @@
|
||||
# ports/win32
|
||||
target_include_directories(qpc PUBLIC .)
|
||||
target_sources(
|
||||
qpc
|
||||
PRIVATE
|
||||
qf_port.c
|
||||
$<$<BOOL:${QPC_CFG_GUI}>:${CMAKE_CURRENT_SOURCE_DIR}/qwin_gui.c>
|
||||
$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qs_port.c>
|
||||
target_sources(qpc PRIVATE
|
||||
qf_port.c
|
||||
$<$<BOOL:${QPC_CFG_GUI}>:${CMAKE_CURRENT_SOURCE_DIR}/qwin_gui.c>
|
||||
$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qs_port.c>
|
||||
)
|
||||
|
26
qpc.md5
26
qpc.md5
@ -1,4 +1,4 @@
|
||||
13078bbbcfe973eb8adb284ddccb74c7 *qpc.qm
|
||||
93ecf23cf720e5728920c20ee8d973e6 *qpc.qm
|
||||
f71fdc0261b7d7e1693f7cf92b269fc0 *include/qequeue.h
|
||||
57b1efebccde23a26f9d11e822ec379f *include/qk.h
|
||||
807f80a7a39be52083010803f76b4f05 *include/qmpool.h
|
||||
@ -25,18 +25,18 @@ bc3e5d7fcb172fee6881f993160502eb *src/qf/qf_mem.c
|
||||
a34020507dc261f49eaaaf2062dcb81d *src/qf/qf_qeq.c
|
||||
f9867335faa23f0b57c921c8882e7a52 *src/qf/qf_qmact.c
|
||||
b0531b1989555c6b7d128e112f4f3c39 *src/qf/qf_time.c
|
||||
a8fb5148cc628738ab7bf073e7fe2cdd *src/qk/CMakeLists.txt
|
||||
f5b5ef77f45d50a6450efd85995287c7 *src/qk/qk.c
|
||||
a9fac3a677755efae96fc84c15acd587 *src/qs/CMakeLists.txt
|
||||
ccd28413fc3a093ca99b03854cf7439b *src/qk/CMakeLists.txt
|
||||
aa27bde6715639754f8857a46c344442 *src/qk/qk.c
|
||||
27c155798720d7fb3b2f9cc38e311393 *src/qs/CMakeLists.txt
|
||||
e045ce8b2fc053d068ec3eb10c9f65bf *src/qs/qs.c
|
||||
9091ffd15f7ec791076091bb17eec5fc *src/qs/qs_64bit.c
|
||||
730d9bea159722e5d2c225e01b5c7875 *src/qs/qs_fp.c
|
||||
60453f6d2b1f915e6e477cca68cb7fee *src/qs/qs_rx.c
|
||||
80a31dfc0e24839342fe193779401e7b *src/qs/qstamp.c
|
||||
53ab2ae396c90e41045b019cdfea21b5 *src/qs/qutest.c
|
||||
f2661d91230a78b9c515f53a70dd81a4 *src/qv/CMakeLists.txt
|
||||
df8818b82672a7b9b2daa6a73e52036f *src/qv/qv.c
|
||||
893c91432ce0fcf195780e4827aeef25 *src/qxk/CMakeLists.txt
|
||||
cf8fa24441cb9577288f73bdb4effbff *src/qv/CMakeLists.txt
|
||||
bb08eae11dacb60099c7ff7a7b3700b3 *src/qv/qv.c
|
||||
3a9240f29676dea5ce3df8fed587ae52 *src/qxk/CMakeLists.txt
|
||||
8d2e28ffb1c8c670924de4c987fb35df *src/qxk/qxk.c
|
||||
f65131e2a680cc2f419f43437e1f873a *src/qxk/qxk_mutex.c
|
||||
214032bca5ddd45690cf3ca67f9f86c3 *src/qxk/qxk_sema.c
|
||||
@ -128,26 +128,26 @@ b9be2bca2c48d39a43e4b3d059376b6a *ports/uc-os2/qp_port.h
|
||||
281f9d70e7fb90b4457bee33b544c460 *ports/qep-only/CMakeLists.txt
|
||||
6ce09e456ded120d13d73a92e022fa3d *ports/qep-only/qp_port.h
|
||||
f26311a1912e214477781255c7c71834 *ports/qep-only/safe_std.h
|
||||
5de93f2758bcc03c99929af24dbf72c3 *ports/posix/CMakeLists.txt
|
||||
4577c2c64f7dbb0c81d1e99f20984888 *ports/posix/CMakeLists.txt
|
||||
0a9db5ee3129a97bd19c433e12f0442e *ports/posix/qf_port.c
|
||||
c1764d38614122b0a02a0172a21906d9 *ports/posix/qp_port.h
|
||||
5902d6c50e3d3e87c4cbeb66485c01c9 *ports/posix/qs_port.c
|
||||
306c23ae37e9b02f2f37f2d21331f28d *ports/posix/qs_port.h
|
||||
6690cf3899e6461ed7604dba13cf7520 *ports/posix/README.md
|
||||
f26311a1912e214477781255c7c71834 *ports/posix/safe_std.h
|
||||
7df4439ce695a959033556402136cbe8 *ports/posix-qv/CMakeLists.txt
|
||||
c36532b0e4b1956d9113f6ced25fb47b *ports/posix-qv/CMakeLists.txt
|
||||
044efad276cba04709c027cc66b7d356 *ports/posix-qv/qf_port.c
|
||||
46cd7f9bce31d6d519886f31f824fae0 *ports/posix-qv/qp_port.h
|
||||
94d91c859c62fd464f6ce61c9d4e82b1 *ports/posix-qv/qs_port.c
|
||||
306c23ae37e9b02f2f37f2d21331f28d *ports/posix-qv/qs_port.h
|
||||
a39965a1d1c41b224c8f328c9e28999b *ports/posix-qv/README.md
|
||||
f26311a1912e214477781255c7c71834 *ports/posix-qv/safe_std.h
|
||||
e980172aa95e2866309b92269548ce67 *ports/posix-qutest/CMakeLists.txt
|
||||
51ca57651ed492278fd728d3b94aba4d *ports/posix-qutest/CMakeLists.txt
|
||||
2ec8125e0cbaf03c06c679d698ec6a32 *ports/posix-qutest/qp_port.h
|
||||
306c23ae37e9b02f2f37f2d21331f28d *ports/posix-qutest/qs_port.h
|
||||
a7e763528627d662501e8a28ca6321c1 *ports/posix-qutest/qutest_port.c
|
||||
f26311a1912e214477781255c7c71834 *ports/posix-qutest/safe_std.h
|
||||
3bafe0c408101957b314362e1b22e81c *ports/win32/CMakeLists.txt
|
||||
5fa44dffb653cecb1d9ea41d154ce852 *ports/win32/CMakeLists.txt
|
||||
cd0040a8cc2c6051b2f8ea42f798d601 *ports/win32/Makefile
|
||||
20fc7e8b39e32f53aca8e3f08e372957 *ports/win32/qf_port.c
|
||||
dddd41fe592d8832b95179820de552d2 *ports/win32/qp_port.h
|
||||
@ -157,7 +157,7 @@ a46c047f83877a192b2de24f27238770 *ports/win32/qs_port.c
|
||||
a8f227294c6673a22b050e1165a911e3 *ports/win32/qwin_gui.h
|
||||
9af4450a3685e578e1774e5b707f6692 *ports/win32/README.md
|
||||
f26311a1912e214477781255c7c71834 *ports/win32/safe_std.h
|
||||
07088791b0937c530b7fc4a776fbd2de *ports/win32-qv/CMakeLists.txt
|
||||
c28c6dd7ad5899389e556c8cc61692ce *ports/win32-qv/CMakeLists.txt
|
||||
7d3aaf7289eb37ac9ef638d092f1d28f *ports/win32-qv/qf_port.c
|
||||
6e8a4ca279ced37f24ac45e4ff6d4157 *ports/win32-qv/qp_port.h
|
||||
a46c047f83877a192b2de24f27238770 *ports/win32-qv/qs_port.c
|
||||
@ -166,7 +166,7 @@ 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
|
||||
4eea94cb5efae4bd95187e496d40ad88 *ports/win32-qutest/CMakeLists.txt
|
||||
f62276b6a322c8fffce657cdb4998ed7 *ports/win32-qutest/CMakeLists.txt
|
||||
f9f1dfd9b7c2f0ce7b2c5928da09b123 *ports/win32-qutest/qp_port.h
|
||||
018ec5ae698a31c6fb0f2c002194c5bd *ports/win32-qutest/qs_port.h
|
||||
d8259b2bb16d1826806a636c6a3293f8 *ports/win32-qutest/qutest_port.c
|
||||
|
54
qpc.qm
54
qpc.qm
@ -4849,7 +4849,7 @@ if (ceiling > QV_priv_.schedCeil) { // raising the scheduler ceiling?
|
||||
|
||||
QV_priv_.schedCeil = ceiling;
|
||||
#ifndef Q_UNSAFE
|
||||
QV_priv_.schedCeil_dis = (uint_fast16_t)(~ceiling);
|
||||
QV_priv_.schedCeil_dis = (uint_fast8_t)(~ceiling);
|
||||
#endif
|
||||
}
|
||||
QF_MEM_APP();
|
||||
@ -4877,7 +4877,7 @@ if (QV_priv_.schedCeil != 0U) { // actually enabling the scheduler?
|
||||
|
||||
QV_priv_.schedCeil = 0U;
|
||||
#ifndef Q_UNSAFE
|
||||
QV_priv_.schedCeil_dis = (uint_fast16_t)(~0U);
|
||||
QV_priv_.schedCeil_dis = (uint_fast8_t)(~0U);
|
||||
#endif
|
||||
}
|
||||
QF_MEM_APP();
|
||||
@ -4903,7 +4903,7 @@ QF_bzero_(&QActive_registry_[0], sizeof(QActive_registry_));
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
QPSet_update_(&QV_priv_.readySet, &QV_priv_.readySet_dis);
|
||||
QV_priv_.schedCeil_dis = (uint_fast16_t)(~0U);
|
||||
QV_priv_.schedCeil_dis = (uint_fast8_t)(~0U);
|
||||
#endif
|
||||
|
||||
for (uint_fast8_t tickRate = 0U;
|
||||
@ -5199,7 +5199,8 @@ QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
Q_REQUIRE_INCRIT(100, !QK_ISR_CONTEXT_());
|
||||
Q_REQUIRE_INCRIT(102, QK_priv_.lockCeil == ~QK_priv_.lockCeil_dis);
|
||||
Q_REQUIRE_INCRIT(102, QK_priv_.lockCeil
|
||||
== (uint_fast8_t)(~QK_priv_.lockCeil_dis));
|
||||
|
||||
// first store the previous lock prio
|
||||
QSchedStatus stat;
|
||||
@ -5216,7 +5217,7 @@ if (ceiling > QK_priv_.lockCeil) { // raising the lock ceiling?
|
||||
// new status of the lock
|
||||
QK_priv_.lockCeil = ceiling;
|
||||
#ifndef Q_UNSAFE
|
||||
QK_priv_.lockCeil_dis = ~ceiling;
|
||||
QK_priv_.lockCeil_dis = (uint_fast8_t)(~ceiling);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
@ -5241,7 +5242,8 @@ if (prevCeil != 0xFFU) {
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
Q_REQUIRE_INCRIT(202, QK_priv_.lockCeil == ~QK_priv_.lockCeil_dis);
|
||||
Q_REQUIRE_INCRIT(202, QK_priv_.lockCeil
|
||||
== (uint_fast8_t)(~QK_priv_.lockCeil_dis));
|
||||
Q_REQUIRE_INCRIT(210, (!QK_ISR_CONTEXT_())
|
||||
&& (QK_priv_.lockCeil > prevCeil));
|
||||
|
||||
@ -5254,7 +5256,7 @@ if (prevCeil != 0xFFU) {
|
||||
// restore the previous lock ceiling
|
||||
QK_priv_.lockCeil = prevCeil;
|
||||
#ifndef Q_UNSAFE
|
||||
QK_priv_.lockCeil_dis = ~prevCeil;
|
||||
QK_priv_.lockCeil_dis = (uint_fast8_t)(~prevCeil);
|
||||
#endif
|
||||
|
||||
// find if any AOs should be run after unlocking the scheduler
|
||||
@ -5290,26 +5292,26 @@ else {
|
||||
p = QPSet_findMax(&QK_priv_.readySet);
|
||||
|
||||
Q_ASSERT_INCRIT(412,
|
||||
QK_priv_.actThre == ~QK_priv_.actThre_dis);
|
||||
QK_priv_.actThre == (uint_fast8_t)(~QK_priv_.actThre_dis));
|
||||
|
||||
// is the AO's prio. below the active preemption-threshold?
|
||||
if (p <= QK_priv_.actThre) {
|
||||
p = 0U; // no activation needed
|
||||
}
|
||||
else {
|
||||
Q_ASSERT_INCRIT(422,
|
||||
QK_priv_.lockCeil == ~QK_priv_.lockCeil_dis);
|
||||
Q_ASSERT_INCRIT(422, QK_priv_.lockCeil
|
||||
== (uint_fast8_t)(~QK_priv_.lockCeil_dis));
|
||||
|
||||
// is the AO's prio. below the lock-ceiling?
|
||||
if (p <= QK_priv_.lockCeil) {
|
||||
p = 0U; // no activation needed
|
||||
}
|
||||
else {
|
||||
Q_ASSERT_INCRIT(432,
|
||||
QK_priv_.nextPrio == ~QK_priv_.nextPrio_dis);
|
||||
Q_ASSERT_INCRIT(432, QK_priv_.nextPrio
|
||||
== (uint_fast8_t)(~QK_priv_.nextPrio_dis));
|
||||
QK_priv_.nextPrio = p; // next AO to run
|
||||
#ifndef Q_UNSAFE
|
||||
QK_priv_.nextPrio_dis = ~QK_priv_.nextPrio;
|
||||
QK_priv_.nextPrio_dis = (uint_fast8_t)(~QK_priv_.nextPrio);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -5328,8 +5330,8 @@ uint_fast8_t const prio_in = QK_priv_.actPrio; // save initial prio.
|
||||
uint_fast8_t p = QK_priv_.nextPrio; // next prio to run
|
||||
|
||||
Q_REQUIRE_INCRIT(502,
|
||||
(prio_in == ~QK_priv_.actPrio_dis)
|
||||
&& (p == ~QK_priv_.nextPrio_dis));
|
||||
(prio_in == (uint_fast8_t)(~QK_priv_.actPrio_dis))
|
||||
&& (p == (uint_fast8_t)(~QK_priv_.nextPrio_dis)));
|
||||
Q_REQUIRE_INCRIT(510, (prio_in <= QF_MAX_ACTIVE)
|
||||
&& (0U < p) && (p <= QF_MAX_ACTIVE));
|
||||
|
||||
@ -5368,8 +5370,8 @@ do {
|
||||
QK_priv_.actPrio = p;
|
||||
QK_priv_.actThre = pthre;
|
||||
#ifndef Q_UNSAFE
|
||||
QK_priv_.actPrio_dis = ~p;
|
||||
QK_priv_.actThre_dis = ~pthre;
|
||||
QK_priv_.actPrio_dis = (uint_fast8_t)(~p);
|
||||
QK_priv_.actThre_dis = (uint_fast8_t)(~pthre);
|
||||
#endif
|
||||
|
||||
#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
|
||||
@ -5427,8 +5429,8 @@ do {
|
||||
p = 0U; // no activation needed
|
||||
}
|
||||
else {
|
||||
Q_ASSERT_INCRIT(542,
|
||||
QK_priv_.lockCeil == ~QK_priv_.lockCeil_dis);
|
||||
Q_ASSERT_INCRIT(542, QK_priv_.lockCeil
|
||||
== (uint_fast8_t)(~QK_priv_.lockCeil_dis));
|
||||
|
||||
// is the AO's prio. below the lock preemption-threshold?
|
||||
if (p <= QK_priv_.lockCeil) {
|
||||
@ -5445,8 +5447,8 @@ do {
|
||||
QK_priv_.actPrio = prio_in;
|
||||
QK_priv_.actThre = pthre_in;
|
||||
#ifndef Q_UNSAFE
|
||||
QK_priv_.actPrio_dis = ~QK_priv_.actPrio;
|
||||
QK_priv_.actThre_dis = ~QK_priv_.actThre;
|
||||
QK_priv_.actPrio_dis = (uint_fast8_t)(~QK_priv_.actPrio);
|
||||
QK_priv_.actThre_dis = (uint_fast8_t)(~QK_priv_.actThre);
|
||||
#endif
|
||||
|
||||
#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
|
||||
@ -5491,10 +5493,10 @@ QK_priv_.lockCeil = (QF_MAX_ACTIVE + 1U); // scheduler locked
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
QPSet_update_(&QK_priv_.readySet, &QK_priv_.readySet_dis);
|
||||
QK_priv_.actPrio_dis = ~0U;
|
||||
QK_priv_.nextPrio_dis = ~0U;
|
||||
QK_priv_.actThre_dis = ~0U;
|
||||
QK_priv_.lockCeil_dis = ~QK_priv_.lockCeil;
|
||||
QK_priv_.actPrio_dis = (uint_fast8_t)(~0U);
|
||||
QK_priv_.nextPrio_dis = (uint_fast8_t)(~0U);
|
||||
QK_priv_.actThre_dis = (uint_fast8_t)(~0U);
|
||||
QK_priv_.lockCeil_dis = (uint_fast8_t)(~QK_priv_.lockCeil);
|
||||
#endif
|
||||
|
||||
for (uint_fast8_t tickRate = 0U;
|
||||
@ -5543,7 +5545,7 @@ QK_START(); // port-specific startup of the QK kernel
|
||||
|
||||
QK_priv_.lockCeil = 0U; // unlock the QK scheduler
|
||||
#ifndef Q_UNSAFE
|
||||
QK_priv_.lockCeil_dis = ~0U;
|
||||
QK_priv_.lockCeil_dis = (uint_fast8_t)(~0U);
|
||||
#endif
|
||||
|
||||
// activate AOs to process events posted so far
|
||||
|
@ -31,7 +31,7 @@ if (NOT TARGET _qpc_sdk_pre_init_marker)
|
||||
set(QPC_SDK_PATH ${CMAKE_CURRENT_LIST_DIR})
|
||||
endif ()
|
||||
|
||||
get_filename_component(QPC_SDK_PATH "${QPC_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
|
||||
file(REAL_PATH "${QPC_SDK_PATH}" QPC_SDK_PATH BASE_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||
|
||||
set(QPC_SDK_PATH ${CMAKE_CURRENT_LIST_DIR} CACHE PATH "Path to the QP/C SDK" FORCE)
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# qpc/src
|
||||
add_subdirectory(qf)
|
||||
add_subdirectory(qs)
|
||||
if(${PORT} MATCHES "^(arm-|pic32|risc-v)")
|
||||
if(${PORT} IN_LIST QPC_BAREMETAL_PORTS)
|
||||
message(STATUS "adding subdir '${KERNEL}' for port '${PORT}'")
|
||||
add_subdirectory(${KERNEL})
|
||||
endif()
|
||||
|
@ -1,7 +1,5 @@
|
||||
# ./src/qf
|
||||
target_sources(
|
||||
qpc
|
||||
PRIVATE
|
||||
qk.c
|
||||
target_sources(qpc PRIVATE
|
||||
qk.c
|
||||
)
|
||||
|
||||
|
48
src/qk/qk.c
48
src/qk/qk.c
@ -78,7 +78,8 @@ QSchedStatus QK_schedLock(uint_fast8_t const ceiling) {
|
||||
QF_MEM_SYS();
|
||||
|
||||
Q_REQUIRE_INCRIT(100, !QK_ISR_CONTEXT_());
|
||||
Q_REQUIRE_INCRIT(102, QK_priv_.lockCeil == ~QK_priv_.lockCeil_dis);
|
||||
Q_REQUIRE_INCRIT(102, QK_priv_.lockCeil
|
||||
== (uint_fast8_t)(~QK_priv_.lockCeil_dis));
|
||||
|
||||
// first store the previous lock prio
|
||||
QSchedStatus stat;
|
||||
@ -95,7 +96,7 @@ QSchedStatus QK_schedLock(uint_fast8_t const ceiling) {
|
||||
// new status of the lock
|
||||
QK_priv_.lockCeil = ceiling;
|
||||
#ifndef Q_UNSAFE
|
||||
QK_priv_.lockCeil_dis = ~ceiling;
|
||||
QK_priv_.lockCeil_dis = (uint_fast8_t)(~ceiling);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
@ -117,7 +118,8 @@ void QK_schedUnlock(QSchedStatus const prevCeil) {
|
||||
QF_CRIT_ENTRY();
|
||||
QF_MEM_SYS();
|
||||
|
||||
Q_REQUIRE_INCRIT(202, QK_priv_.lockCeil == ~QK_priv_.lockCeil_dis);
|
||||
Q_REQUIRE_INCRIT(202, QK_priv_.lockCeil
|
||||
== (uint_fast8_t)(~QK_priv_.lockCeil_dis));
|
||||
Q_REQUIRE_INCRIT(210, (!QK_ISR_CONTEXT_())
|
||||
&& (QK_priv_.lockCeil > prevCeil));
|
||||
|
||||
@ -130,7 +132,7 @@ void QK_schedUnlock(QSchedStatus const prevCeil) {
|
||||
// restore the previous lock ceiling
|
||||
QK_priv_.lockCeil = prevCeil;
|
||||
#ifndef Q_UNSAFE
|
||||
QK_priv_.lockCeil_dis = ~prevCeil;
|
||||
QK_priv_.lockCeil_dis = (uint_fast8_t)(~prevCeil);
|
||||
#endif
|
||||
|
||||
// find if any AOs should be run after unlocking the scheduler
|
||||
@ -159,26 +161,26 @@ uint_fast8_t QK_sched_(void) {
|
||||
p = QPSet_findMax(&QK_priv_.readySet);
|
||||
|
||||
Q_ASSERT_INCRIT(412,
|
||||
QK_priv_.actThre == ~QK_priv_.actThre_dis);
|
||||
QK_priv_.actThre == (uint_fast8_t)(~QK_priv_.actThre_dis));
|
||||
|
||||
// is the AO's prio. below the active preemption-threshold?
|
||||
if (p <= QK_priv_.actThre) {
|
||||
p = 0U; // no activation needed
|
||||
}
|
||||
else {
|
||||
Q_ASSERT_INCRIT(422,
|
||||
QK_priv_.lockCeil == ~QK_priv_.lockCeil_dis);
|
||||
Q_ASSERT_INCRIT(422, QK_priv_.lockCeil
|
||||
== (uint_fast8_t)(~QK_priv_.lockCeil_dis));
|
||||
|
||||
// is the AO's prio. below the lock-ceiling?
|
||||
if (p <= QK_priv_.lockCeil) {
|
||||
p = 0U; // no activation needed
|
||||
}
|
||||
else {
|
||||
Q_ASSERT_INCRIT(432,
|
||||
QK_priv_.nextPrio == ~QK_priv_.nextPrio_dis);
|
||||
Q_ASSERT_INCRIT(432, QK_priv_.nextPrio
|
||||
== (uint_fast8_t)(~QK_priv_.nextPrio_dis));
|
||||
QK_priv_.nextPrio = p; // next AO to run
|
||||
#ifndef Q_UNSAFE
|
||||
QK_priv_.nextPrio_dis = ~QK_priv_.nextPrio;
|
||||
QK_priv_.nextPrio_dis = (uint_fast8_t)(~QK_priv_.nextPrio);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -196,8 +198,8 @@ void QK_activate_(void) {
|
||||
uint_fast8_t p = QK_priv_.nextPrio; // next prio to run
|
||||
|
||||
Q_REQUIRE_INCRIT(502,
|
||||
(prio_in == ~QK_priv_.actPrio_dis)
|
||||
&& (p == ~QK_priv_.nextPrio_dis));
|
||||
(prio_in == (uint_fast8_t)(~QK_priv_.actPrio_dis))
|
||||
&& (p == (uint_fast8_t)(~QK_priv_.nextPrio_dis)));
|
||||
Q_REQUIRE_INCRIT(510, (prio_in <= QF_MAX_ACTIVE)
|
||||
&& (0U < p) && (p <= QF_MAX_ACTIVE));
|
||||
|
||||
@ -236,8 +238,8 @@ void QK_activate_(void) {
|
||||
QK_priv_.actPrio = p;
|
||||
QK_priv_.actThre = pthre;
|
||||
#ifndef Q_UNSAFE
|
||||
QK_priv_.actPrio_dis = ~p;
|
||||
QK_priv_.actThre_dis = ~pthre;
|
||||
QK_priv_.actPrio_dis = (uint_fast8_t)(~p);
|
||||
QK_priv_.actThre_dis = (uint_fast8_t)(~pthre);
|
||||
#endif
|
||||
|
||||
#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
|
||||
@ -295,8 +297,8 @@ void QK_activate_(void) {
|
||||
p = 0U; // no activation needed
|
||||
}
|
||||
else {
|
||||
Q_ASSERT_INCRIT(542,
|
||||
QK_priv_.lockCeil == ~QK_priv_.lockCeil_dis);
|
||||
Q_ASSERT_INCRIT(542, QK_priv_.lockCeil
|
||||
== (uint_fast8_t)(~QK_priv_.lockCeil_dis));
|
||||
|
||||
// is the AO's prio. below the lock preemption-threshold?
|
||||
if (p <= QK_priv_.lockCeil) {
|
||||
@ -313,8 +315,8 @@ void QK_activate_(void) {
|
||||
QK_priv_.actPrio = prio_in;
|
||||
QK_priv_.actThre = pthre_in;
|
||||
#ifndef Q_UNSAFE
|
||||
QK_priv_.actPrio_dis = ~QK_priv_.actPrio;
|
||||
QK_priv_.actThre_dis = ~QK_priv_.actThre;
|
||||
QK_priv_.actPrio_dis = (uint_fast8_t)(~QK_priv_.actPrio);
|
||||
QK_priv_.actThre_dis = (uint_fast8_t)(~QK_priv_.actThre);
|
||||
#endif
|
||||
|
||||
#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
|
||||
@ -358,10 +360,10 @@ void QF_init(void) {
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
QPSet_update_(&QK_priv_.readySet, &QK_priv_.readySet_dis);
|
||||
QK_priv_.actPrio_dis = ~0U;
|
||||
QK_priv_.nextPrio_dis = ~0U;
|
||||
QK_priv_.actThre_dis = ~0U;
|
||||
QK_priv_.lockCeil_dis = ~QK_priv_.lockCeil;
|
||||
QK_priv_.actPrio_dis = (uint_fast8_t)(~0U);
|
||||
QK_priv_.nextPrio_dis = (uint_fast8_t)(~0U);
|
||||
QK_priv_.actThre_dis = (uint_fast8_t)(~0U);
|
||||
QK_priv_.lockCeil_dis = (uint_fast8_t)(~QK_priv_.lockCeil);
|
||||
#endif
|
||||
|
||||
for (uint_fast8_t tickRate = 0U;
|
||||
@ -408,7 +410,7 @@ int_t QF_run(void) {
|
||||
|
||||
QK_priv_.lockCeil = 0U; // unlock the QK scheduler
|
||||
#ifndef Q_UNSAFE
|
||||
QK_priv_.lockCeil_dis = ~0U;
|
||||
QK_priv_.lockCeil_dis = (uint_fast8_t)(~0U);
|
||||
#endif
|
||||
|
||||
// activate AOs to process events posted so far
|
||||
|
@ -1,11 +1,9 @@
|
||||
# ./src/qs
|
||||
target_sources(
|
||||
qpc
|
||||
PRIVATE
|
||||
"$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qs_64bit.c>"
|
||||
"$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qs_fp.c>"
|
||||
"$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qs_rx.c>"
|
||||
"$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qstamp.c>"
|
||||
"$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qs.c>"
|
||||
"$<$<CONFIG:Spy>:$<$<BOOL:${QPC_CFG_UNIT_TEST}>:${CMAKE_CURRENT_SOURCE_DIR}/qutest.c>>"
|
||||
target_sources(qpc PRIVATE
|
||||
"$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qs_64bit.c>"
|
||||
"$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qs_fp.c>"
|
||||
"$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qs_rx.c>"
|
||||
"$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qstamp.c>"
|
||||
"$<$<CONFIG:Spy>:${CMAKE_CURRENT_SOURCE_DIR}/qs.c>"
|
||||
"$<$<AND:$<CONFIG:Spy>,$<BOOL:${QPC_CFG_UNIT_TEST}>>:${CMAKE_CURRENT_SOURCE_DIR}/qutest.c>"
|
||||
)
|
||||
|
@ -1,6 +1,4 @@
|
||||
# ./src/qf
|
||||
target_sources(
|
||||
qpc
|
||||
PRIVATE
|
||||
qv.c
|
||||
target_sources(qpc PRIVATE
|
||||
qv.c
|
||||
)
|
||||
|
@ -91,7 +91,7 @@ void QV_schedDisable(uint_fast8_t const ceiling) {
|
||||
|
||||
QV_priv_.schedCeil = ceiling;
|
||||
#ifndef Q_UNSAFE
|
||||
QV_priv_.schedCeil_dis = (uint_fast16_t)(~ceiling);
|
||||
QV_priv_.schedCeil_dis = (uint_fast8_t)(~ceiling);
|
||||
#endif
|
||||
}
|
||||
QF_MEM_APP();
|
||||
@ -118,7 +118,7 @@ void QV_schedEnable(void) {
|
||||
|
||||
QV_priv_.schedCeil = 0U;
|
||||
#ifndef Q_UNSAFE
|
||||
QV_priv_.schedCeil_dis = (uint_fast16_t)(~0U);
|
||||
QV_priv_.schedCeil_dis = (uint_fast8_t)(~0U);
|
||||
#endif
|
||||
}
|
||||
QF_MEM_APP();
|
||||
@ -137,7 +137,7 @@ void QF_init(void) {
|
||||
|
||||
#ifndef Q_UNSAFE
|
||||
QPSet_update_(&QV_priv_.readySet, &QV_priv_.readySet_dis);
|
||||
QV_priv_.schedCeil_dis = (uint_fast16_t)(~0U);
|
||||
QV_priv_.schedCeil_dis = (uint_fast8_t)(~0U);
|
||||
#endif
|
||||
|
||||
for (uint_fast8_t tickRate = 0U;
|
||||
|
@ -1,9 +1,7 @@
|
||||
# ./src/qf
|
||||
target_sources(
|
||||
qpc
|
||||
PRIVATE
|
||||
qxk_mutex.c
|
||||
qxk_sema.c
|
||||
qxk_xthr.c
|
||||
qxk.c
|
||||
target_sources(qpc PRIVATE
|
||||
qxk_mutex.c
|
||||
qxk_sema.c
|
||||
qxk_xthr.c
|
||||
qxk.c
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user