QP/C  6.6.0
qxthread.h File Reference

QXK/C eXtended (blocking) thread. More...

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  QXThread
 eXtended (blocking) thread of the QXK preemptive kernel More...
 
struct  QXSemaphore
 Counting Semaphore of the QXK preemptive kernel. More...
 
struct  QXMutex
 Blocking Mutex the QXK preemptive kernel. More...
 

Macros

#define QXTHREAD_START(me_, prio_, qSto_, qLen_, stkSto_, stkLen_, par_)
 Polymorphically start an extended thread. More...
 
#define QXTHREAD_POST_X(me_, e_, margin_, sender_)   QACTIVE_POST_X(&(me_)->super, (e_), (margin_), (sender_))
 
#define QXTHREAD_NO_TIMEOUT   ((uint_fast16_t)0)
 no-timeout special timeout value when blocking on queues or semaphores More...
 
#define Q_XTHREAD_CAST(handler_)   ((QXThreadHandler)(handler_))
 Perform cast to QXThreadHandler. More...
 

Typedefs

typedef QActiveVtable QXThreadVtable
 Virtual Table for the QXThread class (inherited from QActiveVtable) More...
 
typedef void(* QXThreadHandler) (QXThread *const me)
 Thread handler pointer-to-function. More...
 

Functions

void QXThread_ctor (QXThread *const me, QXThreadHandler handler, uint_fast8_t tickRate)
 constructor of an extended-thread More...
 
bool QXThread_delay (uint_fast16_t const nTicks)
 delay (block) the current extended thread for a specified # ticks More...
 
bool QXThread_delayCancel (QXThread *const me)
 cancel the delay More...
 
const QEvtQXThread_queueGet (uint_fast16_t const nTicks)
 obtain a message from the private message queue (block if no messages) More...
 
void QXSemaphore_init (QXSemaphore *const me, uint_fast16_t count, uint_fast16_t max_count)
 initialize the counting semaphore More...
 
bool QXSemaphore_wait (QXSemaphore *const me, uint_fast16_t const nTicks)
 wait (block) on the semaphore More...
 
bool QXSemaphore_tryWait (QXSemaphore *const me)
 try wait on the semaphore (non-blocking) More...
 
bool QXSemaphore_signal (QXSemaphore *const me)
 signal (unblock) the semaphore More...
 
void QXMutex_init (QXMutex *const me, uint_fast8_t ceiling)
 initialize the QXK priority-ceiling mutex QXMutex More...
 
bool QXMutex_lock (QXMutex *const me, uint_fast16_t const nTicks)
 lock the QXK priority-ceiling mutex QXMutex More...
 
bool QXMutex_tryLock (QXMutex *const me)
 try to lock the QXK priority-ceiling mutex QXMutex More...
 
void QXMutex_unlock (QXMutex *const me)
 unlock the QXK priority-ceiling mutex QXMutex More...
 

Detailed Description

QXK/C eXtended (blocking) thread.

Definition in file qxthread.h.


Data Structure Documentation

◆ QXThread

struct QXThread

eXtended (blocking) thread of the QXK preemptive kernel

Description
QXThread represents the eXtended (blocking) thread of the QXK preemptive kernel. Each extended thread in the application must be represented by the corresponding QXThread instance
Note
Typically, QXThread is instantiated directly in the application code. The customization of the thread occurs in the QXThread_ctor(), where you provide the thred-handler function as the parameter.
See also
Usage
The following example illustrates how to instantiate and use an extended thread in your application.
#include "qpc.h"
QXThread blinky; /* QXK extended-thread object */
uint32_t stack_blinky[80]; /* stack for the thread */
void main_blinky(QXThread * const me) { /* thread function */
while (1) {
uint32_t volatile i;
for (i = 1500U; i != 0U; --i) {
BSP_ledGreenOn();
BSP_ledGreenOff();
}
QXThread_delay(1U); /* block for 1 tick */
}
}
int main() {
. . .
/* initialize and start blinky thread */
QXThread_ctor(&blinky, &main_blinky, 0);
QXTHREAD_START(&blinky,
5U, /* priority */
(void *)0, 0, /* message queue (not used) */
stack_blinky, sizeof(stack_blinky), /* stack */
(void *)0); /* extra parameter (not used) */
. . .
return QF_run(); /* run the application */
}

Definition at line 71 of file qxthread.h.

Collaboration diagram for QXThread:
Collaboration graph
Data Fields
QActive super inherited QActive
QTimeEvt timeEvt time event to handle blocking timeouts

◆ QXSemaphore

struct QXSemaphore

Counting Semaphore of the QXK preemptive kernel.

Description
QXSemaphore is a blocking mechanism intended primarily for signaling extended threads. The semaphore is initialized with the maximum count (see QXSemaphore_init()), which allows you to create a binary semaphore (when the maximum count is 1) and counting semaphore when the maximum count is > 1.
See also
Usage
The following example illustrates how to instantiate and use the semaphore in your application.
QXSemaphore BTN_sema; /* semaphore to signal a button press */
int main() {
. . .
/* initialize the BTN_sema semaphore as binary, signaling semaphore */
QXSemaphore_init(&BTN_sema, /* pointer to semaphore to initialize */
0U, /* initial semaphore count (singaling semaphore) */
1U); /* maximum semaphore count (binary semaphore) */
. . .
}
void main_threadXYZ(QXThread * const me) {
while (1) {
. . .
QXSemaphore_wait(&BTN_sema, /* pointer to semaphore to wait on */
QXTHREAD_NO_TIMEOUT); /* timeout for waiting */
. . .
}
}
void GPIO_Handler(void) {
. . .
QXSemaphore_signal(&BTN_sema); /* pointer to semaphore to signal */
. . .
}

Definition at line 192 of file qxthread.h.

Collaboration diagram for QXSemaphore:
Collaboration graph
Data Fields
QPSet waitSet set of extended-threads waiting on this semaphore
uint16_t volatile count semaphore up-down counter
uint16_t max_count maximum value of the semaphore counter

◆ QXMutex

struct QXMutex

Blocking Mutex the QXK preemptive kernel.

Description
QXMutex is a blocking mutual exclusion mechanism that can also apply the priority ceiling protocol to avoid unbounded priority inversion (if initialized with a non-zero ceiling priority, see QXMutex_init()). In that case, QXMutex requires its own uinque QP priority level, which cannot be used by any thread or any other QXMutex. If initialzied with zero ceiling priority, QXMutex does not use the priority ceiling protocol and does not require a unique QP priority (see QXMutex_init()). QXMutex is recursive (reentrant), which means that it can be locked mutiliple times (up to 255 levels) by the same thread without causing deadlock. QXMutex is primarily intended for the extened (blocking) threads, but can also be used by the basic threads through the non-blocking QXMutex_tryLock() API.
Note
QXMutex should be used in situations when at least one of the extended threads contending for the mutex blocks while holding the mutex (between the QXMutex_lock() and QXMutex_unlock() operations). If no blocking is needed while holding the mutex, the more efficient non-blocking mechanism of selective QXK scheduler locking should be used instead. Selective scheduler locking is available for both basic threads and extendedthreads", so it is applicable to situations where resources are shared among all these threads.
See also
Usage
The following example illustrates how to instantiate and use the mutex in your application.
QXMutex l_rndMutex; /* mutex to protect the random number generator */
void BSP_randomSeed(uint32_t seed) {
QXMutex_init(&l_rndMutex, N_PHILO); /* <== initialize the mutex */
l_rnd = seed;
}
uint32_t BSP_random(void) { /* a very cheap pseudo-random-number generator */
uint32_t rnd;
QXMutex_lock(&l_rndMutex); /* <== lock the shared random seed */
/* "Super-Duper" Linear Congruential Generator (LCG) */
rnd = l_rnd * (3U*7U*11U*13U*23U);
l_rnd = rnd; /* set for the next time */
QXMutex_unlock(&l_rndMutex); /* <== unlock the shared random seed */
return rnd;
}

Definition at line 254 of file qxthread.h.

Collaboration diagram for QXMutex:
Collaboration graph
Data Fields
QPSet waitSet set of extended-threads waiting on this mutex
uint8_t volatile lockNest lock-nesting up-down counter
uint8_t volatile holderPrio priority of the lock holder thread
uint8_t ceiling prioirty ceiling of this mutex

Macro Definition Documentation

◆ QXTHREAD_START

#define QXTHREAD_START (   me_,
  prio_,
  qSto_,
  qLen_,
  stkSto_,
  stkLen_,
  par_ 
)
Value:
do {\
Q_ASSERT((me_)->super.super.vptr); \
((*((QActiveVtable const *)((me_)->super.super.vptr))->start)( \
&(me_)->super, (prio_), (QEvt const **)(qSto_), (qLen_), \
(stkSto_), (stkLen_), (par_))); \
} while (0)

Polymorphically start an extended thread.

Description
Starts execution of the thread and registers the thread with the framework.
Parameters
[in,out]me_pointer (see Object Orientation)
[in]prio_priority of the extended-thread
[in]qSto_pointer to the storage for the ring buffer of the message queue (possibly NULL)
[in]qLen_length of the message queue [events] (possibly 0)
[in]stkSto_pointer to the stack storage (required)
[in]stkSize_stack size [bytes]
[in]par_pointer to the additional port-specific parameter(s) (might be NULL).
Usage
#include "qpc.h"
int main() {
. . .
/* stack for the QXK's idle thread */
static uint64_t idleStackSto[32];
Test_ctor(); /* instantiate the Test "naked" thread */
QF_init(); /* initialize the framework */
BSP_init(); /* initialize the Board Support Package */
/* initialize QXK... */
QXK_init(idleStackSto, sizeof(idleStackSto));
/* initialize publish-subscribe... */
QF_psInit(subscrSto, Q_DIM(subscrSto));
/* initialize event pools... */
QF_poolInit(smlPoolSto, sizeof(smlPoolSto), sizeof(smlPoolSto[0]));
/* start the active objects (basic-threads)... */
QACTIVE_START(AO_Table, /* AO to start */
(uint_fast8_t)(N_PHILO + 2), /* QP priority of the AO */
tableQueueSto, /* event queue storage */
Q_DIM(tableQueueSto), /* queue length [events] */
tableStackSto, /* stack storage */
sizeof(tableStackSto), /* stack size [bytes] */
(QEvt *)0); /* initialization event */
. . .
/* start the extended-threads... */
QXTHREAD_START(XT_Test, /* Thread to start */
(uint_fast8_t)10U, /* QP priority of the thread */
testQueueSto, /* message queue storage */
Q_DIM(testQueueSto), /* message length [events] */
testStackSto, /* stack storage */
sizeof(testStackSto), /* stack size [bytes] */
(QEvt *)0); /* initialization event */
return QF_run(); /* run the QF application */
}

Definition at line 101 of file qxthread.h.

◆ QXTHREAD_POST_X

#define QXTHREAD_POST_X (   me_,
  e_,
  margin_,
  sender_ 
)    QACTIVE_POST_X(&(me_)->super, (e_), (margin_), (sender_))
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]e_pointer to the event to post
[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]sender_pointer to the sender object.
Returns
'true' if the posting succeeded, and 'false' if the posting failed due to insufficient margin of free slots available in the queue.
Note
The sender_ parameter is actually only used when QS tracing is enabled (macro Q_SPY is defined). When QS software tracing is disabled, the QXTHREAD_POST_X() macro does not pass the sender_ argument, so the overhead of passing this extra argument is entirely avoided.
The pointer to the sender object is not necessarily a pointer to an active object. In fact, if QXTHREAD_POST_X() is called from an interrupt or other context, you can create a unique object just to unambiguously identify the sender of the event.
Usage
extern QActive *AO_Table;
. . .
/* typically inside a state machine action */
TableEvt *pe;
Q_NEW_X(pe, TableEvt, 5U, HUNGRY_SIG); /* dynamic alloc, margin==5 */
if (pe != (TableEvt *)0) {
pe->philNum = me->num;
QACTIVE_POST_X(AO_Table, &pe->super, 3U, me); /* margin==3 */
}
. . .

Definition at line 147 of file qxthread.h.

◆ QXTHREAD_NO_TIMEOUT

#define QXTHREAD_NO_TIMEOUT   ((uint_fast16_t)0)

no-timeout special timeout value when blocking on queues or semaphores

Definition at line 160 of file qxthread.h.

◆ Q_XTHREAD_CAST

#define Q_XTHREAD_CAST (   handler_)    ((QXThreadHandler)(handler_))

Perform cast to QXThreadHandler.

Description
This macro encapsulates the cast of a specific thread handler function pointer to QXThreadHandler, which violates MISRA-C 2004 rule 11.4(adv). This macro helps to localize this deviation.

Definition at line 169 of file qxthread.h.

Typedef Documentation

◆ QXThreadVtable

Virtual Table for the QXThread class (inherited from QActiveVtable)

Note
QXThread inherits QActive without adding any new virtual functions and therefore, QXThreadVtable is typedef'ed as QActiveVtable.

Definition at line 82 of file qxthread.h.

◆ QXThreadHandler

typedef void(* QXThreadHandler) (QXThread *const me)

Thread handler pointer-to-function.

Definition at line 109 of file qxthread.h.

Function Documentation

◆ QXThread_ctor()

void QXThread_ctor ( QXThread *const  me,
QXThreadHandler  handler,
uint_fast8_t  tickRate 
)

constructor of an extended-thread

◆ QXThread_delay()

bool QXThread_delay ( uint_fast16_t const  nTicks)

delay (block) the current extended thread for a specified # ticks

◆ QXThread_delayCancel()

bool QXThread_delayCancel ( QXThread *const  me)

cancel the delay

◆ QXThread_queueGet()

const QEvt* QXThread_queueGet ( uint_fast16_t const  nTicks)

obtain a message from the private message queue (block if no messages)

◆ QXSemaphore_init()

void QXSemaphore_init ( QXSemaphore *const  me,
uint_fast16_t  count,
uint_fast16_t  max_count 
)

initialize the counting semaphore

◆ QXSemaphore_wait()

bool QXSemaphore_wait ( QXSemaphore *const  me,
uint_fast16_t const  nTicks 
)

wait (block) on the semaphore

◆ QXSemaphore_tryWait()

bool QXSemaphore_tryWait ( QXSemaphore *const  me)

try wait on the semaphore (non-blocking)

◆ QXSemaphore_signal()

bool QXSemaphore_signal ( QXSemaphore *const  me)

signal (unblock) the semaphore

◆ QXMutex_init()

void QXMutex_init ( QXMutex *const  me,
uint_fast8_t  ceiling 
)

initialize the QXK priority-ceiling mutex QXMutex

◆ QXMutex_lock()

bool QXMutex_lock ( QXMutex *const  me,
uint_fast16_t const  nTicks 
)

lock the QXK priority-ceiling mutex QXMutex

◆ QXMutex_tryLock()

bool QXMutex_tryLock ( QXMutex *const  me)

try to lock the QXK priority-ceiling mutex QXMutex

◆ QXMutex_unlock()

void QXMutex_unlock ( QXMutex *const  me)

unlock the QXK priority-ceiling mutex QXMutex

qpc.h
QP/C public interface including backwards-compatibility layer.
Q_DEFINE_THIS_FILE
#define Q_DEFINE_THIS_FILE
Define the file name (with __FILE__) for assertions in this file.
Definition: qassert.h:104
QXSemaphore
Counting Semaphore of the QXK preemptive kernel.
Definition: qxthread.h:192
QF_poolInit
void QF_poolInit(void *const poolSto, uint_fast32_t const poolSize, uint_fast16_t const evtSize)
Event pool initialization for dynamic allocation of events.
Definition: qf_dyn.c:112
QXThread_ctor
void QXThread_ctor(QXThread *const me, QXThreadHandler handler, uint_fast8_t tickRate)
constructor of an extended-thread
QXTHREAD_NO_TIMEOUT
#define QXTHREAD_NO_TIMEOUT
no-timeout special timeout value when blocking on queues or semaphores
Definition: qxthread.h:160
QXSemaphore_init
void QXSemaphore_init(QXSemaphore *const me, uint_fast16_t count, uint_fast16_t max_count)
initialize the counting semaphore
QActiveVtable
Virtual table for the QActive class.
Definition: qf.h:170
Q_NEW_X
#define Q_NEW_X(e_, evtT_, margin_, sig_)
Allocate a dynamic event (non-asserting version).
Definition: qf.h:736
QACTIVE_POST_X
#define QACTIVE_POST_X(me_, e_, margin_, sender_)
Polymorphically posts an event to an active object (FIFO) without delivery guarantee.
Definition: qf.h:285
QXThread_delay
bool QXThread_delay(uint_fast16_t const nTicks)
delay (block) the current extended thread for a specified # ticks
QEvt
Event structure.
Definition: qep.h:153
QF_run
int_t QF_run(void)
Transfers control to QF to run the application.
Definition: qutest.c:70
QXThread
eXtended (blocking) thread of the QXK preemptive kernel
Definition: qxthread.h:71
Q_DIM
#define Q_DIM(array_)
Helper macro to calculate static dimension of a 1-dim array_.
Definition: qassert.h:331
uint64_t
unsigned long long uint64_t
exact-width 64-bit unsigned int
Definition: stdint.h:32
QF_psInit
void QF_psInit(QSubscrList *const subscrSto, enum_t const maxSignal)
Publish-subscribe initialization.
Definition: qf_ps.c:86
QACTIVE_START
#define QACTIVE_START(me_, prio_, qSto_, qLen_, stkSto_, stkLen_, par_)
Polymorphically start an active object.
Definition: qf.h:215
QF_init
void QF_init(void)
QF initialization.
Definition: qutest.c:55
uint_fast8_t
unsigned int uint_fast8_t
fast at-least 8-bit unsigned int
Definition: stdint.h:36
QXSemaphore_signal
bool QXSemaphore_signal(QXSemaphore *const me)
signal (unblock) the semaphore
QXMutex_init
void QXMutex_init(QXMutex *const me, uint_fast8_t ceiling)
initialize the QXK priority-ceiling mutex QXMutex
QXTHREAD_START
#define QXTHREAD_START(me_, prio_, qSto_, qLen_, stkSto_, stkLen_, par_)
Polymorphically start an extended thread.
Definition: qxthread.h:101
QXMutex
Blocking Mutex the QXK preemptive kernel.
Definition: qxthread.h:254
QXMutex_unlock
void QXMutex_unlock(QXMutex *const me)
unlock the QXK priority-ceiling mutex QXMutex
QXSemaphore_wait
bool QXSemaphore_wait(QXSemaphore *const me, uint_fast16_t const nTicks)
wait (block) on the semaphore
uint32_t
unsigned long uint32_t
exact-width 32-bit unsigned int
Definition: stdint.h:31
QXMutex_lock
bool QXMutex_lock(QXMutex *const me, uint_fast16_t const nTicks)
lock the QXK priority-ceiling mutex QXMutex
QActive
Active Object (based on QHsm implementation)
Definition: qf.h:114