QP-nano  6.9.0
Real-Time Embedded Framework
qfn.h File Reference

Public QF-nano interface. More...

Go to the source code of this file.

Data Structures

struct  QTimer
 
struct  QActive
 
struct  QActiveVtable
 
struct  QActiveCB
 

Macros

#define QF_MAX_TICK_RATE   1U
 
#define QF_NO_MARGIN   ((uint_fast8_t)0xFF)
 
#define QACTIVE_POST(me_, sig_, par_)
 
#define QACTIVE_POST_X(me_, margin_, sig_, par_)
 
#define QACTIVE_POST_ISR(me_, sig_, par_)
 
#define QACTIVE_POST_X_ISR(me_, margin_, sig_, par_)
 
#define QF_ROM_QUEUE_AT_(ao_, i_)   (((QEvt *)Q_ROM_PTR((ao_)->queue))[(i_)])
 
#define QF_ROM_ACTIVE_GET_(p_)   ((QActive *)Q_ROM_PTR(QF_active[(p_)].act))
 
#define QF_ACTIVE_CAST(a_)   ((QActive *)(a_))
 

Typedefs

typedef uint16_t QTimeEvtCtr
 

Functions

void QActive_ctor (QActive *const me, QStateHandler initial)
 
void QF_tickXISR (uint_fast8_t const tickRate)
 
void QF_init (uint_fast8_t maxActive)
 
void QF_stop (void)
 
void QF_onStartup (void)
 
int_t QF_run (void)
 

Variables

QActiveCB const Q_ROM QF_active []
 active object control blocks More...
 
uint_fast8_t QF_maxActive_
 
uint_fast8_t volatile QF_readySet_
 
uint8_t const Q_ROM QF_log2Lkup [16]
 
uint_fast8_t volatile QF_timerSetX_ [QF_MAX_TICK_RATE]
 
uint8_t const Q_ROM QF_invPow2Lkup [9]
 

Data Structure Documentation

◆ QTimer

struct QTimer

Timer structure the active objects

Definition at line 84 of file qfn.h.

Data Fields
QTimeEvtCtr nTicks

timer tick counter

QTimeEvtCtr interval

timer interval

◆ QActiveCB

struct QActiveCB

QActive Control Block

QActiveCB represents the read-only information that the QF-nano needs to manage the active object. QActiveCB objects are grouped in the array QF_active[], which typically can be placed in ROM.

Usage
The following example illustrates how to allocate and initialize the QActive control blocks in the array QF_active[].
#include "qpn.h" /* QP-nano API */
#include "bsp.h" /* Board Support Package (BSP) */
#include "pelican.h" /* Application interface */
/*..........................................................................*/
static QEvt l_pelicanQueue[2];
static QEvt l_pedQueue[1];
/* QF_active[] array defines all active object control blocks --------------*/
{ (QActive *)0, (QEvt *)0, 0 },
{ (QActive *)&AO_Pelican, l_pelicanQueue, Q_DIM(l_pelicanQueue) },
{ (QActive *)&AO_Ped, l_pedQueue, Q_DIM(l_pedQueue) }
};
/*..........................................................................*/
int_t main (void) {
Pelican_ctor(); /* instantiate the Pelican AO */
Ped_ctor(); /* instantiate the Ped AO */
QF_init(Q_DIM(QF_active)); /* initialize the QF-nano framework */
BSP_init(); /* initialize the Board Support Package */
return QF_run(); /* transfer control to QF-nano */
}
#define Q_ROM
Definition: qassert.h:90
int int_t
Definition: qassert.h:86
#define Q_DIM(array_)
Definition: qassert.h:342
Definition: qepn.h:131
QActiveCB const Q_ROM QF_active[]
active object control blocks
void QF_init(uint_fast8_t maxActive)
Definition: qfn.c:315
int_t QF_run(void)
Definition: qkn.c:121
Definition: qfn.h:397
QP-nano public interface including backwards-compatibility layer.
Definition: qfn.h:122

Definition at line 397 of file qfn.h.

Data Fields
QActive * act

pointer to the active object structure

QEvt * queue

pointer to the event queue buffer

uint8_t qlen

the length of the queue ring buffer

Macro Definition Documentation

◆ QF_MAX_TICK_RATE

#define QF_MAX_TICK_RATE   1U

Default value of the macro configurable value in qpn_port.h

Definition at line 94 of file qfn.h.

◆ QF_NO_MARGIN

#define QF_NO_MARGIN   ((uint_fast8_t)0xFF)

special value of margin that causes asserting failure in case event posting fails.

Definition at line 181 of file qfn.h.

◆ QACTIVE_POST

#define QACTIVE_POST (   me_,
  sig_,
  par_ 
)
Value:
do { \
QActive * const ao_ = QF_ACTIVE_CAST((me_)); \
((void)(*((QActiveVtable const *)(ao_->super.vptr))->post)( \
ao_, QF_NO_MARGIN, (enum_t)(sig_), (QParam)(par_)));\
} while (false)
uint16_t QParam
Definition: qepn.h:103
int enum_t
Definition: qepn.h:76
#define QF_NO_MARGIN
Definition: qfn.h:181
#define QF_ACTIVE_CAST(a_)
Definition: qfn.h:456

Polymorphically posts an event to an active object (FIFO) with delivery guarantee (task context).

Description
This macro asserts if the queue overflows and cannot accept the event.
Parameters
[in,out]me_pointer (see Object Orientation)
[in]sig_signal of the event to post
[in]par_parameter of the event to post.
See also
QACTIVE_POST_X(), QActive_postX_(), QACTIVE_POST_ISR(), QActive_postXISR_().
Usage
/* event posting from the interrupt context (QACTIVE_POST_ISR()) ... */
#pragma vector=TIMER0_A0_VECTOR
__interrupt void TIMER0_A0_ISR(void) {
QK_ISR_ENTRY(); /* infrom QK-nano about entering an ISR */
QF_tickXISR(0U); /* process time events for rate 0 */
/* post TIME_TICK events to all interested active objects... */
QACTIVE_POST_ISR((QActive *)&AO_Tunnel, TIME_TICK_SIG, 0U);
QACTIVE_POST_ISR((QActive *)&AO_Ship, TIME_TICK_SIG, 0U);
QACTIVE_POST_ISR((QActive *)&AO_Missile, TIME_TICK_SIG, 0U);
QK_ISR_EXIT(); /* infrom QK-nano about exiting an ISR */
}
/* event posting from the task context (QACTIVE_POST())... */
static QState Ship_flying(Ship * const me) {
QState status_;
switch (Q_SIG(me)) {
case TIME_TICK_SIG: {
. . .
if ((me->score % 10) == 0) { /* is the score "round"? */
QACTIVE_POST((QActive *)&AO_Tunnel,
SCORE_SIG, me->score); /* signal and parameter */
}
status_ = Q_HANDLED();
break;
}
. . .
}
return status_;
}
#define Q_HANDLED()
Definition: qepn.h:370
#define Q_SIG(me_)
Definition: qepn.h:143
uint_fast8_t QState
Definition: qepn.h:155
void QF_tickXISR(uint_fast8_t const tickRate)
Definition: qfn.c:398
#define QACTIVE_POST(me_, sig_, par_)
Definition: qfn.h:201
#define QACTIVE_POST_ISR(me_, sig_, par_)
Definition: qfn.h:250

Definition at line 201 of file qfn.h.

◆ QACTIVE_POST_X

#define QACTIVE_POST_X (   me_,
  margin_,
  sig_,
  par_ 
)
Value:
((*((QActiveVtable const *)((me_)->super.vptr))->post)( \
(me_), (margin_), (enum_t)(sig_), (QParam)(par_)))

Polymorphically posts an event to an active object (FIFO) without delivery guarantee (task context).

Description
This macro does not assert if the queue overflows and cannot accept the event with the specified margin of free slots remaining.
Parameters
[in,out]me_pointer (see Object Orientation)
[in]margin_the minimum free slots in the queue, which must still be available after posting the event. The special value QF_NO_MARGIN causes asserting failure in case event allocation fails.
[in]sig_signal of the event to post
[in]par_parameter of the event to post.
Returns
'true' if the posting succeeded, and 'false' if the posting failed due to insufficient margin of free slots available in the queue.
Usage
/* "extended" event posting from the interrupt context (QACTIVE_POST_X_ISR) */
void SysTick_Handler(void) {
. . .
if (!QACTIVE_POST_X_ISR((QActive *)&AO_Cruncher,
5U, /* margin of free slots in the queue */
ECHO_SIG, 0U)) /* signal and parameter */
{
/* event posting failed... */
}
}
/* "extended" event posting from the task context (QACTIVE_POST_X())... */
static QState Ship_flying(Ship * const me) {
QState status_;
switch (Q_SIG(me)) {
case TIME_TICK_SIG: {
. . .
if ((me->score % 10) == 0) { /* is the score "round"? */
if (!QACTIVE_POST_X((QActive *)&AO_Tunnel,
4U, /* margin of free slots in the queue */
SCORE_SIG, me->score)) /* signal and parameter */
{
/* event posting failed... */
}
}
status_ = Q_HANDLED();
break;
}
. . .
}
return status_;
}
#define QACTIVE_POST_X(me_, margin_, sig_, par_)
Definition: qfn.h:230
#define QACTIVE_POST_X_ISR(me_, margin_, sig_, par_)
Definition: qfn.h:279

Definition at line 230 of file qfn.h.

◆ QACTIVE_POST_ISR

#define QACTIVE_POST_ISR (   me_,
  sig_,
  par_ 
)
Value:
do { \
QActive * const ao_ = QF_ACTIVE_CAST((me_)); \
((void)(*((QActiveVtable const *)(ao_->super.vptr))->postISR)( \
ao_, QF_NO_MARGIN, (enum_t)(sig_), (QParam)(par_))); \
} while (false)

Polymorphically posts an event to an active object (FIFO) with delivery guarantee (ISR context).

Description
This macro asserts if the queue overflows and cannot accept the event.
Parameters
[in,out]me_pointer (see Object Orientation)
[in]sig_signal of the event to post
[in]par_parameter of the event to post.
See also
QACTIVE_POST_X(), QActive_postX_().
Usage
/* event posting from the interrupt context (QACTIVE_POST_ISR()) ... */
#pragma vector=TIMER0_A0_VECTOR
__interrupt void TIMER0_A0_ISR(void) {
QK_ISR_ENTRY(); /* infrom QK-nano about entering an ISR */
QF_tickXISR(0U); /* process time events for rate 0 */
/* post TIME_TICK events to all interested active objects... */
QACTIVE_POST_ISR((QActive *)&AO_Tunnel, TIME_TICK_SIG, 0U);
QACTIVE_POST_ISR((QActive *)&AO_Ship, TIME_TICK_SIG, 0U);
QACTIVE_POST_ISR((QActive *)&AO_Missile, TIME_TICK_SIG, 0U);
QK_ISR_EXIT(); /* infrom QK-nano about exiting an ISR */
}
/* event posting from the task context (QACTIVE_POST())... */
static QState Ship_flying(Ship * const me) {
QState status_;
switch (Q_SIG(me)) {
case TIME_TICK_SIG: {
. . .
if ((me->score % 10) == 0) { /* is the score "round"? */
QACTIVE_POST((QActive *)&AO_Tunnel,
SCORE_SIG, me->score); /* signal and parameter */
}
status_ = Q_HANDLED();
break;
}
. . .
}
return status_;
}

Definition at line 250 of file qfn.h.

◆ QACTIVE_POST_X_ISR

#define QACTIVE_POST_X_ISR (   me_,
  margin_,
  sig_,
  par_ 
)
Value:
((*((QActiveVtable const *)( \
QF_ACTIVE_CAST((me_))->super.vptr))->postISR)( \
QF_ACTIVE_CAST((me_)), (margin_), \
(enum_t)(sig_), (QParam)(par_)))

Polymorphically posts an event to an active object (FIFO) without delivery guarantee (ISR context).

Description
This macro does not assert if the queue overflows and cannot accept the event with the specified margin of free slots remaining.
Parameters
[in,out]me_pointer (see Object Orientation)
[in]margin_the minimum free slots in the queue, which must still be available after posting the event. The special value QF_NO_MARGIN causes asserting failure in case event allocation fails.
[in]sig_signal of the event to post
[in]par_parameter of the event to post.
Returns
'true' if the posting succeeded, and 'false' if the posting failed due to insufficient margin of free slots available in the queue.
Usage
/* "extended" event posting from the interrupt context (QACTIVE_POST_X_ISR) */
void SysTick_Handler(void) {
. . .
if (!QACTIVE_POST_X_ISR((QActive *)&AO_Cruncher,
5U, /* margin of free slots in the queue */
ECHO_SIG, 0U)) /* signal and parameter */
{
/* event posting failed... */
}
}
/* "extended" event posting from the task context (QACTIVE_POST_X())... */
static QState Ship_flying(Ship * const me) {
QState status_;
switch (Q_SIG(me)) {
case TIME_TICK_SIG: {
. . .
if ((me->score % 10) == 0) { /* is the score "round"? */
if (!QACTIVE_POST_X((QActive *)&AO_Tunnel,
4U, /* margin of free slots in the queue */
SCORE_SIG, me->score)) /* signal and parameter */
{
/* event posting failed... */
}
}
status_ = Q_HANDLED();
break;
}
. . .
}
return status_;
}

Definition at line 279 of file qfn.h.

◆ QF_ROM_QUEUE_AT_

#define QF_ROM_QUEUE_AT_ (   ao_,
  i_ 
)    (((QEvt *)Q_ROM_PTR((ao_)->queue))[(i_)])

This macro encapsulates accessing the active object queue at a given index, which violates MISRA-C 2004 rules 17.4(req) and 11.4(adv). This macro helps to localize this deviation.

Definition at line 442 of file qfn.h.

◆ QF_ROM_ACTIVE_GET_

#define QF_ROM_ACTIVE_GET_ (   p_)    ((QActive *)Q_ROM_PTR(QF_active[(p_)].act))

This macro encapsulates accessing the active object control block, which violates MISRA-C 2004 rule 11.4(adv). This macro helps to localize this deviation.

Definition at line 448 of file qfn.h.

◆ QF_ACTIVE_CAST

#define QF_ACTIVE_CAST (   a_)    ((QActive *)(a_))

This macro encapsulates the upcast to QActive*

This macro encapsulates up-casting a pointer to a subclass of QActive to the base class QActive, which violates MISRA-C 2004 rule 11.4(adv). This macro helps to localize this deviation.

Definition at line 456 of file qfn.h.

Typedef Documentation

◆ QTimeEvtCtr

typedef uint16_t QTimeEvtCtr
Description
This header file must be included in all modules that use QP-nano. Typically, this header file is included indirectly through the header file qpn_port.h.

type of the Time Event counter, which determines the dynamic range of the time delays measured in clock ticks.

Description
This typedef is configurable via the preprocessor switch #QF_TIMEEVT_CTR_SIZE. The other possible values of this type are as follows:
none when (QF_TIMEEVT_CTR_SIZE not defined or == 0U),
uint8_t when (QF_TIMEEVT_CTR_SIZE == 1U);
uint16_t when (QF_TIMEEVT_CTR_SIZE == 2U); and
uint32_t when (QF_TIMEEVT_CTR_SIZE == 4U).

Definition at line 75 of file qfn.h.

Function Documentation

◆ QActive_ctor()

void QActive_ctor ( QActive *const  me,
QStateHandler  initial 
)

protected "constructor" of an QActive active object.

◆ QF_tickXISR()

void QF_tickXISR ( uint_fast8_t const  tickRate)

Processes all armed time events at every clock tick.

Description
This function must be called periodically from a time-tick ISR or from an ISR so that QF-nano can manage the timeout events assigned to the given system clock tick rate.
Parameters
[in]tickRatesystem clock tick rate serviced in this call.
Note
Each system tick rate posts timeout events with a different signal as follows:
tickRate==0 Q_TIMEOUT_SIG
tickRate==1 Q_TIMEOUT1_SIG
tickRate==2 Q_TIMEOUT2_SIG
tickRate==3 Q_TIMEOUT3_SIG
The calls to QF_tickXISR() with different tick rate parameter can preempt each other. For example, higher clock tick rates might be serviced from interrupts that can preempt lower-priority interrupts.

Definition at line 398 of file qfn.c.

◆ QF_init()

void QF_init ( uint_fast8_t  maxActive)

QF-nano initialization.

Description
The function QF_init() initializes the number of active objects to be managed by the framework and clears the internal QF-nano variables as well as all registered active objects to zero, which is needed in case when the startup code does not clear the uninitialized data (in violation of the C Standard).
Note
The intended use of the function is to call as follows: QF_init(Q_DIM(QF_active));
Precondition
the number of active objects must be in range

Definition at line 315 of file qfn.c.

◆ QF_stop()

void QF_stop ( void  )

QF-nano termination.

Description
This function terminates QF and performs any necessary cleanup. In QF-nano this function is defined in the BSP. Many QF ports might not require implementing QF_stop() at all, because many embedded applications don't have anything to exit to.

◆ QF_onStartup()

void QF_onStartup ( void  )

Startup QF-nano callback.

Description
The time line for calling QF_onStartup() depends on the particular QF port. In most cases, QF_onStartup() is called from QF_run(), right before starting any multitasking kernel or the background loop.
See also
QF initialization example for QActiveCB.

◆ QF_run()

int_t QF_run ( void  )

Transfers control to QF-nano to run the application.

Description
QF_run() is typically called from your startup code after you initialize the QF and start at least one active object with QActive_start(). This implementation of QF_run() is for the preemptive QK-nano kernel.
Returns
In QK-nano QF_run() does not return.
Description
QF_run() is typically called from your startup code after you initialize the QF and start at least one active object with QActive_start(). This implementation of QF_run() is for the cooperative Vanilla kernel.
Returns
QF_run() typically does not return in embedded applications. However, when QP runs on top of an operating system, QF_run() might return and in this case the return represents the error code (0 for success). Typically the value returned from QF_run() is subsequently passed on as return from main().
Precondition
the number of active objects must be initialized by calling: QF_init(Q_DIM(QF_active));

Definition at line 121 of file qkn.c.

Variable Documentation

◆ QF_active

QActiveCB const Q_ROM QF_active[]
extern

◆ QF_maxActive_

uint_fast8_t QF_maxActive_
extern

number of active objects in the application (# elements in QF_active[])

Description
This variable stores the number of active objects in the application. This is the number of elements (dimension of) the QF_active[] array.

Definition at line 53 of file qfn.c.

◆ QF_readySet_

uint_fast8_t volatile QF_readySet_
extern

Ready set of QF-nano.

Description
The QF-nano ready set keeps track of active objects that are ready to run. The ready set represents each active object as a bit, with the bits assigned according to priorities of the active objects. The bit is set if the corresponding active object is ready to run (i.e., has one or more events in its event queue) and zero if the event queue is empty. The QF-nano ready set is one byte-wide, which corresponds to 8 active objects maximum.

Definition at line 65 of file qfn.c.

◆ QF_log2Lkup

uint8_t const Q_ROM QF_log2Lkup[16]
extern

Lookup table for (log2(n) + 1), where n is the index into the table. This lookup delivers the 1-based number of the most significant 1-bit of a nibble.

Definition at line 89 of file qfn.c.

◆ QF_timerSetX_

uint_fast8_t volatile QF_timerSetX_[QF_MAX_TICK_RATE]
extern

Timer set of QF-nano.

Description
The QF-nano timer set keeps track of the armed time events. The timer set represents the timeout down-counter of each active object as a bit, with the bits assigned according to priorities of the active objects. The bit is set if the corresponding timeout down-counter is not zero (i.e., is counting down) and zero if the down-counter is zero. The QF-nano time event set is one byte-wide, which corresponds to 8 active objects maximum.

The main use of the QF_timerSetX_ is to quickly determine that all time events are disarmed by testing (QF_timerSetX_[tickRate] == 0). If so, the CPU can go to longer sleep mode, in which the system clock tick ISR is turned off.
Note
The test (QF_timerSet_[tickRate] == 0) must be always performed inside a CRITICAL SECTION.

Definition at line 85 of file qfn.c.

◆ QF_invPow2Lkup

uint8_t const Q_ROM QF_invPow2Lkup[9]
extern

Lookup table for ~(1 << (n - 1)), where n is the index into the table.