QP/C  7.2.2
Real-Time Embedded Framework
Loading...
Searching...
No Matches
QXThread Class Reference

eXtended (blocking) thread of the QXK preemptive kernel More...

#include "qxk.h"

Inheritance diagram for QXThread:
QActive QHsm

Public Member Functions

void QXThread_ctor (QXThread *const me, QXThreadHandler const handler, uint_fast8_t const tickRate)
 
bool QXThread_delayCancel (QXThread *const me)
 
- Public Member Functions inherited from QActive
void QActive_subscribe (QActive const *const me, enum_t const sig)
 
void QActive_unsubscribe (QActive const *const me, enum_t const sig)
 
void QActive_unsubscribeAll (QActive const *const me)
 
void QActive_setAttr (QActive *const me, uint32_t attr1, void const *attr2)
 
- Public Member Functions inherited from QHsm
bool QHsm_isIn (QHsm *const me, QStateHandler const state)
 
QStateHandler QHsm_childState (QHsm *const me, QStateHandler const parent)
 

Static Public Member Functions

bool QXThread_delay (uint_fast16_t const nTicks)
 
QEvt const * QXThread_queueGet (uint_fast16_t const nTicks)
 
- Static Public Member Functions inherited from QActive
void QActive_psInit (QSubscrList *const subscrSto, enum_t const maxSignal)
 
- Static Public Member Functions inherited from QHsm
static QStateHandler QHsm_state (QHsm *const me)
 

Public Attributes

QActive super
 
QTimeEvt timeEvt
 
- Public Attributes inherited from QActive
QHsm super
 

Private Member Functions

void QXThread_init_ (QHsm *const me, void const *const par, uint_fast8_t const qs_id)
 
void QXThread_dispatch_ (QHsm *const me, QEvt const *const e, uint_fast8_t const qs_id)
 
void QXThread_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)
 
bool QXThread_post_ (QActive *const me, QEvt const *const e, uint_fast16_t const margin, void const *const sender)
 
void QXThread_postLIFO_ (QActive *const me, QEvt const *const e)
 
void QXThread_block_ (QXThread const *const me)
 
void QXThread_unblock_ (QXThread const *const me)
 
void QXThread_teArm_ (QXThread *const me, enum_t const sig, uint_fast16_t const nTicks)
 
bool QXThread_teDisarm_ (QXThread *const me)
 
void QXK_threadExit_ (void)
 

Additional Inherited Members

- Protected Member Functions inherited from QActive
void QActive_ctor (QActive *const me, QStateHandler const initial)
 
void QActive_stop (QActive *const me)
 
bool QActive_defer (QActive const *const me, QEQueue *const eq, QEvt const *const e)
 
bool QActive_recall (QActive *const me, QEQueue *const eq)
 
uint_fast16_t QActive_flushDeferred (QActive const *const me, QEQueue *const eq)
 
void QActive_register_ (QActive *const me)
 
void QActive_unregister_ (QActive *const me)
 
- Protected Member Functions inherited from QHsm
void QHsm_ctor (QHsm *const me, QStateHandler const initial)
 
QState QHsm_top (QHsm const *const me, QEvt const *const e)
 
void QHsm_init_ (QHsm *const me, void const *const e, uint_fast8_t const qs_id)
 
void QHsm_dispatch_ (QHsm *const me, QEvt const *const e, uint_fast8_t const qs_id)
 

Detailed Description

QXThread represents the eXtended (blocking) thread of the QXK 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 thread-handler function as the parameter.
Usage
The following example illustrates how to instantiate and use an extended thread in your application.
#include "qpc.h"
Q_DEFINE_THIS_FILE
QXThread blinky; /* QXK extended-thread object */
void main_blinky(QXThread * const me) { /* thread function */
while (1) {
BSP_ledOn();
QXThread_delay(100U); /* BLOCK */
BSP_ledOff();
QXThread_delay(200U); /* BLOCK */
}
}
int main() {
. . .
/* initialize and start blinky thread */
QXThread_ctor(&blinky, &main_blinky, 0);
static uint64_t stack_blinky[40]; /* stack for the thread */
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 */
}
QP/C public interface including backwards-compatibility layer.
int_t QF_run(void)
Definition: qutest.c:190
#define QXTHREAD_START(me_, prioSpec_, qSto_, qLen_, stkSto_, stkSize_, par_)
Definition: qxk.h:934
eXtended (blocking) thread of the QXK preemptive kernel
Definition: qxk.h:289
bool QXThread_delay(uint_fast16_t const nTicks)
Definition: qxk_xthr.c:104
void QXThread_ctor(QXThread *const me, QXThreadHandler const handler, uint_fast8_t const tickRate)

Definition at line 289 of file qxk.h.

Member Function Documentation

◆ QXThread_ctor()

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

constructor of an extended-thread

Performs the first step of QXThread initialization by assigning the thread-handler function and the tick rate at which it will handle the timeouts.

Parameters
[in,out]mecurrent instance pointer (see oop)
[in]handlerthe thread-handler function
[in]tickRatethe ticking rate for timeouts in this thread (see QXThread_delay() and QTIMEEVT_TICK_X())
Note
Must be called only ONCE before QXTHREAD_START().
Usage
The following example illustrates how to invoke QXThread_ctor() in the main() function
#include "qpc.h"
Q_DEFINE_THIS_FILE
QXThread blinky; /* QXK extended-thread object */
void main_blinky(QXThread * const me) { /* thread function */
while (1) {
. . .
}
}
int main() {
. . .
/* instantiate and start blinky thread */
QXThread_ctor(&blinky, &main_blinky, 0); /* <--- ctor */
static uint32_t stack_blinky[80]; /* stack for the extended thread */
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 */
}

◆ QXThread_delay()

bool QXThread_delay ( uint_fast16_t const  nTicks)
static

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

Blocking delay for the number of clock tick at the associated tick rate.

Parameters
[in]nTicksnumber of clock ticks (at the associated rate) to wait for the event to arrive.
Returns
'true' if delay has expired, 'false' if it delay was canceled with QXThread_delayCancel().
Precondition qxk_xthr:800
  • must NOT be called from an ISR;
  • number of ticks cannot be zero
  • be called from an extended thread;
  • the thread must NOT be already blocked on any object.
Precondition qxk_xthr:801
  • the thread must NOT be holding a scheduler lock.
Note
For the delay to work, the QTIMEEVT_TICK_X() macro needs to be called periodically at the associated clock tick rate.
See also
QXThread_ctor()
QTIMEEVT_TICK_X()

Definition at line 104 of file qxk_xthr.c.

◆ QXThread_delayCancel()

bool QXThread_delayCancel ( QXThread *const  me)

cancel the delay

Cancel the blocking delay and cause return from the QXThread_delay() function.

Returns
"true" if the thread was actually blocked on QXThread_delay() and "false" otherwise.

Definition at line 138 of file qxk_xthr.c.

◆ QXThread_queueGet()

QEvt const * QXThread_queueGet ( uint_fast16_t const  nTicks)
static

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

The QXThread_queueGet() operation allows the calling extended thread to receive QP events directly into its own built-in event queue from an ISR, basic thread (AO), or another extended thread.

If QXThread_queueGet() is called when no events are present in the thread's private event queue, the operation blocks the current extended thread until either an event is received, or a user-specified timeout expires.

Parameters
[in]nTicksnumber of clock ticks (at the associated rate) to wait for the event to arrive. The value of QXTHREAD_NO_TIMEOUT indicates that no timeout will occur and the queue will block indefinitely.
Returns
A pointer to the event. If the pointer is not NULL, the event was delivered. Otherwise the event pointer of NULL indicates that the queue has timed out.
Precondition qxk_xthr:500
  • must NOT be called from an ISR;
  • be called from an extended thread;
  • the thread must NOT be already blocked on any object.
Precondition qxk_xthr:501
  • the thread must NOT be holding a scheduler lock.

Definition at line 157 of file qxk_xthr.c.

◆ QXThread_init_()

void QXThread_init_ ( QHsm *const  me,
void const *const  par,
uint_fast8_t const  qs_id 
)
private

Overrides QHsm_init_()

Definition at line 238 of file qxk_xthr.c.

◆ QXThread_dispatch_()

void QXThread_dispatch_ ( QHsm *const  me,
QEvt const *const  e,
uint_fast8_t const  qs_id 
)
private

Overrides QHsm_dispatch_()

Definition at line 252 of file qxk_xthr.c.

◆ QXThread_start_()

void QXThread_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 
)
private

start QXThread private implementation

Starts execution of an extended thread and registers it with the framework. The extended thread becomes ready-to-run immediately and is scheduled if the QXK is already running.

Parameters
[in,out]mecurrent instance pointer (see oop)
[in]prioQF-priority of the thread, but no preemption- threshold. See also QPrioSpec.
[in]qStopointer to the storage for the ring buffer of the event queue. This cold be NULL, if this extended thread does not use the built-in event queue.
[in]qLenlength of the event queue [in events], or zero if queue not used
[in]stkStopointer to the stack storage (must be provided)
[in]stkSizestack size [in bytes] (must not be zero)
[in]parpointer to an extra parameter (might be NULL).
Precondition qxk_xthr:200
  • must NOT be called from an ISR;
  • the stack storage must be provided;
  • the thread must be instantiated (see QXThread_ctor())
  • preemption-threshold is NOT provided (because QXK kernel does not support preemption-threshold scheduling)
Note
Currently, extended trheads in QXK do NOT support preemption-threshold. The prio must NOT provide preemption-threshold and this function will assert it in the precondition.
Usage
QXThread_start_() should NOT be called directly, only via the macro QXTHREAD_START(). The following example shows starting an extended thread:
#include "qpc.h"
Q_DEFINE_THIS_FILE
int main() {
. . .
QF_init(); /* initialize the framework */
BSP_init(); /* initialize the Board Support Package */
/* 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)~~~ */
Table_ctor(); /* instantiate the Table AO */
QACTIVE_START(AO_Table, /* AO to start */
n + 1U, /* QF-priority */
tableQueueSto, /* event queue storage */
Q_DIM(tableQueueSto), /* queue length [events] */
tableStackSto, /* stack storage */
sizeof(tableStackSto), /* stack size [bytes] */
(void *)0); /* initialization param */
. . .
/* start the extended-threads~~~ */
Test_ctor(); /* instantiate the Test extended thread */
QXTHREAD_START(XT_Test, /* Thread to start */
10U, /* QF-priority */
testQueueSto, /* message queue storage */
Q_DIM(testQueueSto), /* message length [events] */
testStackSto, /* stack storage */
sizeof(testStackSto), /* stack size [bytes] */
(void *)0); /* initialization param */
return QF_run(); /* run the QF application */
}
#define Q_DIM(array_)
Definition: qassert.h:424
#define QACTIVE_START(me_, prioSpec_, qSto_, qLen_, stkSto_, stkSize_, par_)
Definition: qf.h:1907
static void QF_psInit(QSubscrList *const subscrSto, enum_t const maxSignal)
Definition: qf.h:1482
void QF_init(void)
Definition: qutest.c:171

Definition at line 266 of file qxk_xthr.c.

◆ QXThread_post_()

bool QXThread_post_ ( QActive *const  me,
QEvt const *const  e,
uint_fast16_t const  margin,
void const *const  sender 
)
private

post to the QXThread event queue private implementation

Direct event posting is the simplest asynchronous communication method available in QF. The following example illustrates how the Philo active object posts directly the HUNGRY event to the Table active object.
The parameter margin specifies the minimum number of free slots in the queue that must be available for posting to succeed. The function returns 1 (success) if the posting succeeded (with the provided margin) and 0 (failure) when the posting fails.

Parameters
[in,out]mecurrent instance pointer (see oop)
[in]epointer to the event to be posted
[in]marginnumber of required free slots in the queue after posting the event. The special value QF_NO_MARGIN means that this function will assert if posting fails.
[in]senderpointer to a sender object (used only for QS tracing).
Returns
'true' (success) if the posting succeeded (with the provided margin) and 'false' (failure) when the posting fails.
Note
Should be called only via the macro QXTHREAD_POST_X().
The QF_NO_MARGIN value of the margin parameter is special and denotes situation when the post() operation is assumed to succeed (event delivery guarantee). An assertion fires, when the event cannot be delivered in this case.
For compatibility with the V-table from the superclass QActive, the me-pointer is typed as pointing to QActive. However, the me pointer here actually points to the QXThread subclass. Therefore the downcast (QXThread *)me is always correct.
Precondition
event pointer must be valid

Definition at line 314 of file qxk_xthr.c.

◆ QXThread_postLIFO_()

void QXThread_postLIFO_ ( QActive *const  me,
QEvt const *const  e 
)
private

post to the QXThread event queue (LIFO) private implementation

Last-In-First-Out (LIFO) policy is not supported for extened threads.

Parameters
[in]mecurrent instance pointer (see oop)
[in]epointer to the event to post to the queue
See also
QActive_postLIFO_()

Definition at line 457 of file qxk_xthr.c.

◆ QXThread_block_()

void QXThread_block_ ( QXThread const *const  me)
private

block QXThread private implementation

Internal implementation of blocking the given extended thread.

Precondition qxk_xthr:600
  • the thread holding the lock cannot block!
Note
Must be called from within a critical section

Definition at line 469 of file qxk_xthr.c.

◆ QXThread_unblock_()

void QXThread_unblock_ ( QXThread const *const  me)
private

unblock QXThread private implementation

Internal implementation of un-blocking the given extended thread.

Note
must be called from within a critical section

Definition at line 478 of file qxk_xthr.c.

◆ QXThread_teArm_()

void QXThread_teArm_ ( QXThread *const  me,
enum_t const  sig,
uint_fast16_t const  nTicks 
)
private

arm internal time event private implementation

Internal implementation of arming the private time event for a given timeout at a given system tick rate.

Precondition qxk_xthr:700
  • the time event must be unused
Note
Must be called from within a critical section

Definition at line 489 of file qxk_xthr.c.

◆ QXThread_teDisarm_()

bool QXThread_teDisarm_ ( QXThread *const  me)
private

disarm internal time event private implementation

Internal implementation of disarming the private time event.

Note
Must be called from within a critical section

Definition at line 530 of file qxk_xthr.c.

◆ QXK_threadExit_()

void QXK_threadExit_ ( void  )
private

called when QXThread exits

Called when the extended-thread handler function returns.

Precondition qxk:900
  • must NOT be called from an ISR;
  • must be called from an extended thread
Precondition qxk:901
  • the thread must NOT be holding a scheduler lock
Note
Most thread handler functions are structured as endless loops that never return. But it is also possible to structure threads as one-shot functions that perform their job and return. In that case this function peforms cleanup after the thread.

Definition at line 468 of file qxk.c.

Member Data Documentation

◆ super

QActive QXThread::super

Definition at line 291 of file qxk.h.

◆ timeEvt

QTimeEvt QXThread::timeEvt

time event to handle blocking timeouts

Definition at line 296 of file qxk.h.


The documentation for this class was generated from the following files: