QP/C++ Real-Time Event Framework 8.1.5
Loading...
Searching...
No Matches
qp_port.hpp
Go to the documentation of this file.
1/*! @file
2@code_uid{qp_port.hpp, Sample @QPX port}
3@code_litem{Details}
4This is just an example of a QF port for a generic C11 compiler.
5Other specific QF ports will define the QF facilities differently.
6@endcode_uid
7*/
8
9#ifndef QP_PORT_HPP_
10#define QP_PORT_HPP_
11
12#include <cstdint> // Exact-width types. C++11 Standard
13
14/*!
15@code_uid{#Q_NORETURN, No-return specifier for the Q_onError() callback function.}
16@code_litem{Details}
17Per the Software Safety Requirement @ref SREQ_QP_FDM_03, the Custom Error Handler Q_onError() should never return. Starting with the C99 Standard, the no-return specification can be provided at the language level, which may allow the compiler to apply optimizations (e.g., for impossible code paths downstream of Q_onError()). Also, the no-return specification is immensely valuable for static analysis tools.
18@note
19If the `Q_NORETURN` macro is not defined in the QP port (`qf_port.h`), the default will be the C99 specifier `_Noreturn` applied in `qsafe.h`.
20@code_bw_trace{brief}
21- @tr{SREQ_QP_FDM_03}: <i>@QPX fault management shall be based on the <u>Crash-Only model</u>.</i>
22@code_fw_trace
23@endcode_uid
24*/
25#define Q_NORETURN [[ noreturn ]] void
26
27// QF configuration for the data members of the QActive class ----------------
28/*!
29@code_uid{QACTIVE_EQUEUE_TYPE, Port-specific ::QActive event queue type.}
30@code_fw_trace
31@endcode_uid
32*/
33#define QACTIVE_EQUEUE_TYPE QEQueue
34
35/*!
36@code_uid{QACTIVE_OS_OBJ_TYPE, Port-specific ::QActive "OS-object" type.}
37@code_fw_trace
38@endcode_uid
39*/
40#define QACTIVE_OS_OBJ_TYPE void*
41
42/*!
43@code_uid{QACTIVE_THREAD_TYPE, Port-specific ::QActive thread type.}
44@code_fw_trace
45@endcode_uid
46*/
47#define QACTIVE_THREAD_TYPE void const *
48
49// interrupt disabling mechanism ---------------------------------------------
50/*!
51@code_uid{QF_INT_DISABLE(), Port-specific interrupt disable}
52@code_fw_trace
53- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
54@endcode_uid
55*/
56#define QF_INT_DISABLE() intDisable()
57
58/*!
59@code_uid{QF_INT_ENABLE(), Port-specific interrupt enable}
60@code_fw_trace
61- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
62@endcode_uid
63*/
64#define QF_INT_ENABLE() intEnable()
65
66// QF critical section mechanism ---------------------------------------------
67/*!
68@code_uid{#QF_CRIT_STAT, Define the critical section status that was present before entering the critical section.}
69@code_litem{Details}
70For critical sections that are allowed to nest, the critical section status must be saved and restored at the end. This macro provides the storage for saving the status.
71@note
72This macro might be empty, in which case, the critical section status is not saved or restored. Such critical sections won't be able to nest. Also, note that the macro should be invoked without the closing semicolon.
73@code_fw_trace
74@endcode_uid
75*/
76#define QF_CRIT_STAT crit_stat_t crit_stat_;
77
78/*!
79@code_uid{QF_CRIT_ENTRY(), Port-specific critical section entry}
80@code_litem{Details}
81If the critical section status is provided, the macro saves the critical section status from before entering the critical section. Otherwise, the macro just unconditionally enters the critical section without saving the status.
82@code_fw_trace
83- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
84@endcode_uid
85*/
86#define QF_CRIT_ENTRY() (crit_stat_ = critEntry())
87
88/*!
89@code_uid{QF_CRIT_EXIT(), Port-specific critical section exit}
90@code_litem{Details}
91If the critical section status is provided, the macro restores the critical section status saved by QF_CRIT_ENTRY(). Otherwise, the macro just unconditionally exits the critical section.
92@code_fw_trace
93- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
94@endcode_uid
95*/
96#define QF_CRIT_EXIT() critExit(crit_stat_)
97
98/*!
99@code_uid{QF_CRIT_EXIT_NOP(), No-operation for exiting a critical section}
100@code_litem{Details}
101In some QF ports, the critical section exit takes effect only on the next machine instruction. If this next instruction is another entry to a critical section, the critical section won't be exited, but rather the two adjacent critical sections would be _merged_. The QF_CRIT_EXIT_NOP() macro contains minimal code required to prevent such merging of critical sections in QF ports.
102@code_fw_trace
103- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
104@endcode_uid
105*/
106#define QF_CRIT_EXIT_NOP() __asm volatile ("isb" ::: "memory")
107
108/*!
109@code_uid{QF_CRIT_EST(), Port-specific establishing a critical section (without saving the status)}
110@code_litem{Details}
111This port-specific macro only establishes a critical section (to later call Q_onError() error handler), but since Q_onError() never returns, there is no need to exit such established critical section.
112@code_fw_trace
113- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
114@endcode_uid
115*/
116#define QF_CRIT_EST() (static_cast<void>(critEntry()))
117
118/*!
119@code_uid{QF_LOG2(), Port-specific integer log-base-2 of a 32-bit bitmask}
120@code_litem{Details}
121Calculate integer log-base-2 of a given bitmask (1-based) used to quickly determine the higest-number 1-bit in the bitmask. This operation is used frequently during task scheduling and publish-subscribe.
122@param[in] bitmask_ 32-bit bitmask
123@returns 1-based integer log-base-2 of the provided bitmask. Examples:
124- QF_LOG2(0x00000000U) == 0U
125- QF_LOG2(0x00000001U) == 1U
126- QF_LOG2(0x00000002U) == 2U
127- QF_LOG2(0x00000004U) == 3U
128- QF_LOG2(0x00000008U) == 4U
129- QF_LOG2(0x00000010U) == 5U
130...
131- QF_LOG2(0x80000010U) == 32U
132
133@note
134This operation is performed frequently in time-critical parts of the code. Some CPUs provide such calculation in hardware (e.g., as a machine instruction). For example, ARMv7 and higher architectures support the related CLZ (count leading zeroes) instruction, with the following relationship:
135QF_LOG2(bitmask_) == 32U - CLZ(bitmask_).
136@code_fw_trace
137- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
138@endcode_uid
139*/
140#define QF_LOG2(bitmask_) QF_qlog2(static_cast<std::uint32_t>(bitmask_))
141
142extern "C" {
143 //void intDisable(void);
144 //void intEnable(void);
145 //std::uint32_t critEntry(void);
146 //void critExit(std::uint32_t stat);
147 //std::uint32_t QK_get_IPSR(void);
148} // extern "C"
149
150
151#ifdef QF_MEM_ISOLATE
152 /*!
153 @code_uid{QF_ON_CONTEXT_SW, Enable memory isolation requires the context-switch}
154 @code_bw_trace{brief}
155 - @tr{ARCH_QP_FFI_PM}: <i>Architectural view: Memory isolation programming model.</i>
156 - @tr{AOU_QA_MI_00}: <i>@QPX Application should apply <u>memory isolation mechanisms</u> provided in @QPX Framework.</i>
157 @code_fw_trace
158 @endcode_uid
159 */
160 #define QF_ON_CONTEXT_SW 1U
161
162 /*!
163 @code_uid{QF_MEM_SYS(), Port-specific establishing _System Context_ for memory protection}
164 @code_bw_trace{brief}
165 - @tr{ARCH_QP_FFI_PM}: <i>Architectural view: Memory isolation programming model.</i>
166 - @tr{AOU_QA_MI_00}: <i>@QPX Application should apply <u>memory isolation mechanisms</u> provided in @QPX Framework.</i>
167 @code_fw_trace
168 - @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
169 @endcode_uid
170 */
171 #define QF_MEM_SYS() QF_onMemSys()
172
173 /*!
174 @code_uid{QF_MEM_APP(), Port-specific establishing _Application Context_ for memory protection}
175 @code_bw_trace{brief}
176 - @tr{ARCH_QP_FFI_PM}: <i>Architectural view: Memory isolation programming model.</i>
177 - @tr{AOU_QA_MI_00}: <i>@QPX Application should apply <u>memory isolation mechanisms</u> provided in @QPX Framework.</i>
178 @code_fw_trace
179 - @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
180 @endcode_uid
181 */
182 #define QF_MEM_APP() QF_onMemApp()
183
184#ifdef Q_SPY
185 /*!
186 @code_uid{QS_MEM_SYS(), Port-specific establishing _System Context_ for memory protection in conditional QS software tracing code.}
187 @code_bw_trace{brief}
188 - @tr{ARCH_QP_FFI_PM}: <i>Architectural view: Memory isolation programming model.</i>
189 - @tr{AOU_QA_MI_00}: <i>@QPX Application should apply <u>memory isolation mechanisms</u> provided in @QPX Framework.</i>
190 @code_fw_trace
191 - @tr{DVR_QS_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
192 @endcode_uid
193 */
194 #define QS_MEM_SYS() QF_MEM_SYS()
195
196 /*!
197 @code_uid{QS_MEM_APP(), Port-specific establishing _Application Context_ for memory protection in conditional QS software tracing code.}
198 @code_bw_trace{brief}
199 - @tr{ARCH_QP_FFI_PM}: <i>Architectural view: Memory isolation programming model.</i>
200 - @tr{AOU_QA_MI_00}: <i>@QPX Application should apply <u>memory isolation mechanisms</u> provided in @QPX Framework.</i>
201 @code_fw_trace
202 - @tr{DVR_QS_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
203 @endcode_uid
204 */
205 #define QS_MEM_APP() QF_MEM_APP()
206#endif
207
208#endif // QF_MEM_ISOLATE
209
210// QV-specific ---------------------------------------------------------------
211/*!
212@code_uid{QV_CPU_SLEEP(), Port-specific method to put the CPU to sleep __safely__ in the non-preemptive QV kernel (to be called from QV::QV_onIdle()).}
213@code_fw_trace
214@endcode_uid
215*/
216#define QV_CPU_SLEEP() \
217do { \
218 __disable_interrupt(); \
219 QF_INT_ENABLE(); \
220 __WFI(); \
221 __enable_interrupt(); \
222} while (false)
223
224
225// QK-specific ---------------------------------------------------------------
226/*!
227@code_uid{QK_ISR_CONTEXT_(), Port-specific method to check if the QK kernel executes in the ISR context (used internally in QK only).}
228@returns `true` if the caller executes in the ISR context and `false` otherwise
229@code_fw_trace
230- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
231@endcode_uid
232*/
233#define QK_ISR_CONTEXT_() (QK_priv_.intNest != 0U)
234
235/*!
236@code_uid{QK_ISR_ENTRY(), Port-specific method to inform QK kernel about the ISR entry.}
237@code_fw_trace
238- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
239@endcode_uid
240*/
241#define QK_ISR_ENTRY() \
242do { \
243 QF_INT_DISABLE(); \
244 ++QK::priv_.intNest; \
245 QF_QS_ISR_ENTRY(QK::priv_.intNest, QK_currPrio_);\
246 QF_INT_ENABLE(); \
247} while (false)
248
249/*!
250@code_uid{QK_ISR_EXIT(), Port-specific method to inform QK kernel about the ISR exit.}
251@code_fw_trace
252- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
253@endcode_uid
254*/
255#define QK_ISR_EXIT() \
256do { \
257 QF_INT_DISABLE(); \
258 --QP::QK::priv_.intNest; \
259 if (QP::QK::priv_.intNest == 0U) {\
260 if (QP::QK::sched_() != 0U) { \
261 QP::QK::activate_(); \
262 } \
263 } \
264 QF_INT_ENABLE(); \
265} while (false)
266
267// QXK-specific --------------------------------------------------------------
268/*!
269@code_uid{QXK_ISR_CONTEXT_(), Port-specific method to check if the QXK kernel executes in the ISR context (used internally in QXK only).}
270@returns `true` if the caller executes in the ISR context and `false` otherwise
271@code_fw_trace
272- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
273@endcode_uid
274*/
275#define QXK_ISR_CONTEXT_() (QXK_get_IPSR() != 0U)
276
277/*!
278@code_uid{QXK_CONTEXT_SWITCH_(), Port-specific method to trigger context switch (used internally in QXK only).}
279@code_fw_trace
280- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
281@endcode_uid
282*/
283#define QXK_CONTEXT_SWITCH_() (trigPendSV())
284
285/*!
286@code_uid{QXK_ISR_ENTRY(), Port-specific method to inform QXK kernel about the ISR entry.}
287@code_fw_trace
288- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
289@endcode_uid
290*/
291#define QXK_ISR_ENTRY() ((void)0)
292
293/*!
294@code_uid{QXK_ISR_EXIT(), Port-specific method to inform QXK kernel about the ISR exit.}
295@code_fw_trace
296- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
297@endcode_uid
298*/
299#define QXK_ISR_EXIT() do { \
300 QF_INT_DISABLE(); \
301 if (QP::QXK::sched_() != 0U) { \
302 *Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = (1U << 28U);\
303 } \
304 QF_INT_ENABLE(); \
305 QXK_ARM_ERRATUM_838869(); \
306} while (false)
307
308// Scheduling locking port interface (example) -------------------------------
309/*!
310@code_uid{QF_SCHED_STAT_, Port-specific type of the scheduler lock status (for internal use in QF only).}
311@code_fw_trace
312@endcode_uid
313*/
314#define QF_SCHED_STAT_ QSchedStatus lockStat_;
315
316/*!
317@code_uid{QF_SCHED_LOCK_(), Port-specific method to lock the scheduler (for internal use in QF only).}
318@param[in] ceil_ priority-ceiling up to which the scheduler should be locked
319@code_fw_trace
320- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
321@endcode_uid
322*/
323#define QF_SCHED_LOCK_(ceil_) do { \
324 if (QK_ISR_CONTEXT_()) { \
325 lockStat_ = 0xFFU; \
326 } else { \
327 lockStat_ = QK::schedLock((ceil_)); \
328 } \
329} while (false)
330
331/*!
332@code_uid{QF_SCHED_UNLOCK_(), Port-specific method to unlock the scheduler (for internal use in QF only).}
333@code_fw_trace
334- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
335@endcode_uid
336*/
337#define QF_SCHED_UNLOCK_() do { \
338 if (lockStat_ != 0xFFU) { \
339 QP::QK::schedUnlock(lockStat_); \
340 } \
341} while (false)
342
343// Event-Queue port interface (example) --------------------------------------
344// QActive event queue customization...
345/*!
346@code_uid{QACTIVE_EQUEUE_WAIT_(), Port-specific method to wait on an empty Active Object event queue (for internal use only).}
347@param[in,out] me_ current instance pointer
348@code_fw_trace
349- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
350@endcode_uid
351*/
352#define QACTIVE_EQUEUE_WAIT_(me_) (static_cast<void>(0))
353
354/*!
355@code_uid{QACTIVE_EQUEUE_SIGNAL_(), Port-specific method to signal Active Object event queue (for internal use only).}
356@param[in,out] me_ current instance pointer
357@code_fw_trace
358- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
359@endcode_uid
360*/
361#define QACTIVE_EQUEUE_SIGNAL_(me_) do { \
362 QP::QK::priv_.readySet.insert( \
363 static_cast<std::uint_fast8_t>((me_)->m_prio)); \
364 if (!QP::QK_ISR_CONTEXT_()) { \
365 if (QP::QK::sched_() != 0U) { \
366 QP::QK::activate_(); \
367 } \
368 } \
369} while (false)
370
371/*!
372@code_uid{QXTHREAD_EQUEUE_SIGNAL_(), Port-specific method to signal eXtended thread event queue (for internal use only).}
373@param[in,out] me_ current instance pointer
374@code_fw_trace
375- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
376@endcode_uid
377*/
378#define QXTHREAD_EQUEUE_SIGNAL_(me_) do { \
379 if ((me_)->m_temp.obj == QXK::qmstate_cast_(&(me_)->m_eQueue)) { \
380 static_cast<void>(static_cast<QP::QXThread *>(me_)->teDisarm_()); \
381 QXK_priv_.readySet.insert( \
382 static_cast<std::uint_fast8_t>((me_)->m_prio)); \
383 QXK_priv_.readySet.update_(&QXK_priv_.readySet_dis); \
384 if (!QXK_ISR_CONTEXT_()) { \
385 static_cast<void>(QXK::sched_()); \
386 } \
387 } \
388} while (false)
389
390// Event-Pool port interface (example) ---------------------------------------
391/*!
392@code_uid{QF_EPOOL_TYPE_, Port-specific type of the event pool (for internal use in QF only).}
393@code_fw_trace
394@endcode_uid
395*/
396#define QF_EPOOL_TYPE_ QMPool
397
398/*!
399@code_uid{QF_EPOOL_INIT_(), Port-specific event pool initialization (for internal use in QF only).}
400@param[in,out] p_ event pool pointer
401@param[in] poolSto_ storage for the pool (pointer to the pool buffer)
402@param[in] poolSize_ size of the pool storage in [bytes]
403@param[in] evtSize_ event size of this pool in [bytes]
404@code_fw_trace
405- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
406@endcode_uid
407*/
408#define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \
409 (p_).init((poolSto_), (poolSize_), (evtSize_))
410
411/*!
412@code_uid{QF_EPOOL_EVENT_SIZE_(), Port-specific event pool block-size() operation (for internal use in QF only).}
413@param[in,out] p_ event pool pointer
414@code_fw_trace
415- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
416@endcode_uid
417*/
418#define QF_EPOOL_EVENT_SIZE_(p_) ((p_).getBlockSize())
419
420/*!
421@code_uid{QF_EPOOL_GET_(), Port-specific event pool get() operation (for internal use in QF only).}
422@param[in,out] p_ event pool pointer
423@param[out] e_ event pointer to be assigned the obtained event
424@param[in] m_ margin (# free events that must still remain in the pool)
425@param[in] qsId_ QS ID for the QS local filter
426@code_fw_trace
427- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
428@endcode_uid
429*/
430#define QF_EPOOL_GET_(p_, e_, m_, qsId_) \
431 ((e_) = static_cast<QEvt *>((p_).get((m_), (qsId_))))
432
433/*!
434@code_uid{QF_EPOOL_PUT_(), Port-specific event pool put() operation (for internal use in QF only).}
435@param[in,out] p_ event pool pointer
436@param[out] e_ event pointer to return to the pool
437@param[in] qsId_ QS ID for the QS local filter
438@code_fw_trace
439- @tr{DVR_QP_MP2_R8_2_3}: <i>Rule 8.2.3(Required): A cast shall not remove any 'const' or 'volatile' qualification from the type pointer to by a pointer or by reference</i>
440- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
441@endcode_uid
442*/
443#define QF_EPOOL_PUT_(p_, e_, qsId_) ((p_).put((e_), (qsId_)))
444
445/*!
446@code_uid{QF_EPOOL_USE_(), Port-specific event pool # used events operation (for internal use in QF only).}
447@param[in] ePool_ event pool pointer
448@returns # used events in the pool at this moment (allocated and not returned yet)
449@code_fw_trace
450- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
451@endcode_uid
452*/
453#define QF_EPOOL_USE_(ePool_) ((ePool_)->getUse())
454
455/*!
456@code_uid{QF_EPOOL_FREE_(), Port-specific event pool # free events operation (for internal use in QF only).}
457@param[in] ePool_ event pool pointer
458@returns # free events in the pool at this moment (available to allocate)
459@code_fw_trace
460- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
461@endcode_uid
462*/
463#define QF_EPOOL_FREE_(ePool_) ((ePool_)->getFree())
464
465/*!
466@code_uid{QF_EPOOL_MIN_(), Port-specific event pool minimum # events since initialization (for internal use in QF only).}
467@param[in] ePool_ event pool pointer
468@returns minimal # free events in the pool since initialization
469@code_fw_trace
470- @tr{DVR_QP_MP2_R19_0_2}: <i>Rule 19.0.2(Required): Function-like macros shall not be defined</i>
471@endcode_uid
472*/
473#define QF_EPOOL_MIN_(ePool_) ((ePool_)->getMin())
474
475#ifdef QF_MEM_ISOLATE
476
477/*!
478@code_uid{QF_onMemSys(), Port-specific callback to establish the <u>System</u> Memory Protection Mode.}
479@qualifier crit-sect
480@code_litem{Usage}
481This callback is enabled by defining the macro #QF_MEM_ISOLATE.
482
483@attention
484QF_onMemSys() uses "C" linkage (extern "C") and is invoked with interrupts **disabled** and must also return with interrupts **disabled**.
485
486@code{cpp}
487#ifdef QF_MEM_ISOLATE
488extern "C" void QF_onMemSys(void) {
489 // Enable MPU with background region (SYS mode)
490 MPU->CTRL = MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_ENABLE_Msk;
491 __DSB();
492 __ISB();
493}
494#endif // QF_MEM_ISOLATE
495@endcode
496@code_fw_trace
497@endcode_uid
498*/
499void QF_onMemSys(void);
500
501/*!
502@code_uid{QF_onMemApp(), Port-specific callback to establish the <u>Application</u> Memory Protection Mode.}
503@qualifier crit-sect
504@code_litem{Usage}
505This callback is enabled by defining the macro #QF_MEM_ISOLATE.
506
507@attention
508QF_onMemApp() uses "C" linkage (extern "C") and is invoked with interrupts **disabled** and must also return with interrupts **disabled**.
509
510@code{cpp}
511#ifdef QF_MEM_ISOLATE
512extern "C" void QF_onMemApp(void) {
513 // Enable MPU WITHOUT background region (APP mode)
514 MPU->CTRL = MPU_CTRL_ENABLE_Msk;
515 __DSB();
516 __ISB();
517}
518#endif // QF_MEM_ISOLATE
519@endcode
520@code_fw_trace
521@endcode_uid
522*/
523void QF_onMemApp(void);
524
525#endif // QF_MEM_ISOLATE
526
527// include files -------------------------------------------------------------
528#include "qequeue.hpp" // QK kernel uses the native QP event queue
529#include "qmpool.hpp" // QK kernel uses the native QP memory pool
530#include "qp.hpp" // QP framework
531#include "qk.hpp" // QK kernel
532
533#endif // QP_PORT_HPP_
QP native platform-independent QEQueue event queue interface.
QK (preemptive non-blocking kernel) platform-independent public interface.
QP/C++ native platform-independent memory pool QP::QMPool interface.
QP/C++ Framework platform-independent public interface.