RKH
Porting

Prev: Home
Next: Configuration

This section describes how to adapt the RKH to various platforms, which is a process called porting. RKH contains a clearly defined abstraction layer, which encapsulates all the platform-specific code and cleanly separates it from platform-neutral code.

Porting RKH implies to create the a few platform-dependent files, rhhport.h, rkhport.c, rkht.h, which frequently defines the interrupt locking method, the critical section management, data types, among other things.

Note
It is recommended to start from a similar and existing port, properly copying and modifying its files (rkhport.c, rkhport.h and rkht.h) according to your needs and platform in question.

The RKH directories and files are described in detail in Installation section. The next sections listed below describes the aspects to be considered to port RKH.

  1. Platform-dependent files
  2. Data types definitions
  3. ROM allocator
  4. Active Object execution
  5. Dynamic event support
  6. Hook functions
  7. Interrupt locking mechanism
  8. Critical section
  9. Trace facility
  10. A port file example
  11. Extras

Platform-dependent files

Create a directory into source/fwk/portable within its platform dependent-files (rkhport.c, rkhport.h and rkht.h). Please, see RKH portable directory section.


Data types definitions

Create the data type file. The RKH uses a set of integer quantities. That maybe machine or compiler dependent. These types must be defined in rkht.h file. The following listing shows the required data type definitions:

/* ------------------------------- Data types ------------------------------ */
/*
* The RKH uses a set of integer quantities. That maybe machine or
* compiler dependent.
*/
typedef signed char ri8_t; /* Denotes a signed integer type with a */
/* width of exactly 8 bits */
typedef signed short ri16_t; /* Denotes a signed integer type with a */
/* width of exactly 16 bits */
typedef signed long ri32_t; /* Denotes a signed integer type with a */
/* width of exactly 32 bits */
typedef unsigned char rui8_t; /* Denotes a unsigned integer type with */
/* a width of exactly 8 bits */
typedef unsigned short rui16_t; /* Denotes a unsigned integer type with */
/* a width of exactly 16 bits */
typedef unsigned long rui32_t; /* Denotes a unsigned integer type with */
/* a width of exactly 32 bits */
/*
* The 'ruint' and 'rInt' will normally be the natural size for a
* particular machine. These types designates an integer type that is
* usually fastest to operate with among all integer types.
*/
typedef unsigned int ruint;
typedef signed int rInt;
/*
* Boolean data type and constants.
*
* \note
* The true (RKH_TRUE) and false (RKH_FALSE) values as defined as macro
* definitions in \c rkhdef.h file.
*/
typedef unsigned int rbool_t;

Please, see RKH portable directory section.


ROM allocator

For declaring an object that its value will not be changed and that will be stored in ROM, must be defined in rkhport.h the RKHROM macro. Example:

#define RKHROM const

Active Object execution

RKH works in conjunction with a traditional OS/RTOS? [ YES ] - [ NO ]


RKH works in conjunction with a traditional OS/RTOS?: YES
Is a multithreaded application? [ YES ] - [ NO ]


Is a multithreaded application?: YES
The RKH framework can work with virtually any traditional OS/RTOS. Combined with a conventional RTOS, RKH takes full advantage of the multitasking capabilities of the RTOS by executing each active object (SMA) in a separate task or thread.

  1. Define the macros RKH_CFGPORT_NATIVE_SCHEDULER_EN = RKH_DISABLED, RKH_CFGPORT_SMA_THREAD_EN = RKH_ENABLED, RKH_CFGPORT_REENTRANT_EN = RKH_ENABLED, within the rkhport.h file.
  2. Define the macros RKH_THREAD_TYPE, RKH_CFGPORT_SMA_STK_EN and RKH_THREAD_STK_TYPE in rkhport.h according to underlying OS/RTOS.
  3. Define the macro RKH_CFGPORT_SMA_STK_EN in rkhport.h according to OS/RTOS.
  4. Then, implement the platform-specific functions rkh_fwk_init(), rkh_fwk_enter(), rkh_fwk_exit(), rkh_sma_activate(), and rkh_sma_terminate() in rkhport.c, which are specified in source/fwk/inc/rkhfwk_sched.h and source/sma/inc/rkhsma.h respectively.

Example for ARM Cortex-M4 Kinetis, KDS, KSDK and uC/OS-III
Fragment of rkhport.h See source/portable/arm-cortex/ksdk_os/ucosiii/kds/rkhport.h

#define RKH_CFGPORT_NATIVE_SCHEDULER_EN RKH_DISABLED
#define RKH_CFGPORT_SMA_THREAD_EN RKH_ENABLED
#define RKH_CFGPORT_REENTRANT_EN RKH_ENABLED
#define RKH_THREAD_TYPE OS_TCB
#define RKH_THREAD_STK_TYPE rui8_t

Fragment of rkhport.c. See source/portable/arm-cortex/ksdk_os/ucosiii/kds/rkhport.c

void
{
osa_status_t status;
tick_cnt = RKH_TICKS_RATE;
status = OSA_Init();
OS_AppTimeTickHookPtr = rkh_isr_tick;
OS_AppIdleTaskHookPtr = idle_thread_function;
RKH_ENSURE(status == kStatus_OSA_Success);
}
void
{
osa_status_t status;
RKH_HOOK_START(); /* RKH start-up callback */
RKH_TR_FWK_OBJ(&rkh_isr_tick);
status = OSA_Start(); /* uC/OS-III start the multitasking */
RKH_TRC_CLOSE(); /* cleanup the trace session */
RKH_ENSURE(status == kStatus_OSA_Success); /* NEVER supposed to come */
/* back to this point */
}
void
{
RKH_HOOK_EXIT(); /* RKH cleanup callback */
}
void
void *stks, rui32_t stksize)
{
msg_queue_handler_t qh;
osa_status_t status;
task_handler_t th;
RKH_REQUIRE(qs != (const RKH_EVT_T **)0);
sma->equeue.msgs = (void *)qs;
qh = OSA_MsgQCreate(&sma->equeue, /* event message queue object */
(uint16_t)qsize, /* max. size of message queue */
/* allocate pointers */
(uint16_t)(sizeof(RKH_EVT_T *) / sizeof(uint32_t)));
RKH_ENSURE(qh != (msg_queue_handler_t)0);
th = &sma->thread;
status = OSA_TaskCreate(thread_function, /* function */
"uc_task", /* name */
(uint16_t)stksize, /* stack size */
(task_stack_t *)stks, /* stack base (low memory) */
(uint16_t)RKH_GET_PRIO(sma), /* priority */
sma, /* function argument */
false, /* usage of float register */
&th); /* task object */
RKH_ENSURE(status == kStatus_OSA_Success);
sma->running = (rbool_t)1;
}
void
{
osa_status_t status;
sma->running = (rbool_t)0;
status = OSA_MsgQDestroy(&sma->equeue);
RKH_ENSURE(status == kStatus_OSA_Success);
}
#define RKH_ENSURE(exp)
This macro checks the postcondition.
Definition: rkhassert.h:191
#define RKH_REQUIRE(exp)
This macro checks the precondition.
Definition: rkhassert.h:180
#define RKH_TRC_CLOSE()
Close the tracing session.
Definition: rkhtrc_out.h:138
void rkh_sma_terminate(RKH_SMA_T *me)
Terminate a state machine application (SMA) as known as active object.
void rkh_sma_activate(RKH_SMA_T *me, const RKH_EVT_T **qSto, RKH_QUENE_T qSize, void *stkSto, rui32_t stkSize)
Initializes and activates a previously created state machine application (SMA) as known as active obj...
void rkh_fwk_exit(void)
Exit the RKH framework.
void rkh_fwk_init(void)
Initializes the RKH framework.
void rkh_fwk_enter(void)
RKH framework is started.
void rkh_sm_init(RKH_SM_T *me)
Inits a previously created state machine calling its initializing action.
#define RKH_TR_FWK_EN()
Initializes the RKH framework.
#define RKH_TR_FWK_OBJ(obj_)
Entry symbol table for memory object.
#define RKH_TR_FWK_EX()
Exit the RKH framework.
#define RKH_SR_ALLOC()
RKH need to disable interrupts in order to access critical sections of code, and re-enable interrupts...
Definition: rkhitl.h:2051
rui8_t RKH_QUENE_T
This data type defines the maximum number of elements that any queue can contain.
Definition: rkhqueue.h:97
void rkh_sma_register(RKH_SMA_T *me)
Registers a state machine application (SMA) as known as active object into the framework,...
#define RKH_GET_PRIO(_ao)
Retrieves the priority number of an registered active object (SMA).
Definition: rkhsma.h:713
Represents events without parameters.
Definition: rkhevt.h:170
Describes the state machine.
Definition: rkhsm.h:1905
Describes the SMA (active object in UML).
Definition: rkhsma.h:772
rbool_t running
The Boolean loop variable determining if the thread routine of the SMA is running.
Definition: rkhsma.h:842
RKH_THREAD_TYPE thread
Virtual pointer.
Definition: rkhsma.h:805
RKH_EQ_TYPE equeue
Event queue of the SMA (a.k.a Active Object).
Definition: rkhsma.h:835

[ NEXT ]


Is a multithreaded application?: NO
It's frequently used for single thread applications that uses its own cooperative and non-preemptive scheduler, where RKH provides its own priority mechanism.

  1. Define the macros RKH_CFGPORT_NATIVE_SCHEDULER_EN = RKH_DISABLED, RKH_CFGPORT_SMA_THREAD_EN = RKH_DISABLED, RKH_CFGPORT_REENTRANT_EN = RKH_DISABLED, RKH_CFGPORT_SMA_STK_EN = RKH_DISABLED, within the rkhport.h file.
  2. Include the source/sma/inc/rkhsma_prio.h in rkhport.c.
  3. Implement the functions rkh_sma_block(), rkh_sma_setReady(), and rkh_sma_setUnready(), which are specified in source/sma/inc/rkhsma_sync.h, using the functions provided by source/sma/inc/rkhsma_prio.h

Example for Windows single-thread scheduling
Fragment of rkhport.c. See source/portable/80x86/win32_st/vc/rkhport.c

void
{
RKH_ASSERT(me->equeue.qty != 0);
}
void
{
SetEvent(sma_is_rdy);
}
void
{
}
#define RKH_ASSERT(exp)
The RKH_ASSERT() macro is used to check expressions that ought to be true as long as the program is r...
Definition: rkhassert.h:129
#define RKH_SMA_ACCESS_CONST(me_, member_)
Macro for accessing to members of state machine structure.
Definition: rkhsma.h:98
void rkh_smaPrio_setUnready(rui8_t prio)
Removing an active object from the ready list.
void rkh_smaPrio_setReady(rui8_t prio)
Making an active object ready-to-run inserting it into the ready list.
void rkh_sma_setUnready(RKH_SMA_T *const me)
Informs the underlying kernel that the active object's event queue is becoming empty....
void rkh_sma_block(RKH_SMA_T *const me)
Encapsulates the mechanism of blocking the native event queue.
void rkh_sma_setReady(RKH_SMA_T *const me)
Encapsulates the mechanism of signaling the thread waiting on the used native event queue....

[ NEXT ]


Are implemented the event queues with a message queue of the underlying OS/RTOS? [ YES ] - [ NO ]


Are implemented the event queues with a message queue of the underlying OS/RTOS?: YES

  1. Define the macro RKH_CFGPORT_NATIVE_EQUEUE_EN = RKH_DISABLED in rkhport.h
  2. Define the macro RKH_EQ_TYPE in rkhport.h according to OS/RTOS.
  3. Then, implement the platform-specific functions rkh_sma_post_fifo(), rkh_sma_post_lifo() and rkh_sma_get(), which are specified in source/sma/inc/rkhsma.h. All these functions are frequently placed in rkhport.c file.
  4. Define RKH_CFGPORT_SMA_THREAD_DATA_EN = RKH_DISABLED
  5. Define the macro RKH_CFGPORT_SMA_QSTO_EN in rkhport.h according to OS/RTOS.

Example for ARM Cortex-M4 Kinetis, KDS, KSDK and uC/OS-III
Fragment of rkhport.h See source/portable/arm-cortex/ksdk_os/ucosiii/kds/rkhport.h

#define RKH_EQ_TYPE msg_queue_t

Example for ARM Cortex-M4 Kinetis, KDS, KSDK and uC/OS-III
Fragment of rkhport.c See source/portable/arm-cortex/ksdk_os/ucosiii/kds/rkhport.c

void
{
osa_status_t status;
RKH_HOOK_SIGNAL(e);
RKH_ENTER_CRITICAL_();
RKH_INC_REF(e);
status = OSA_MsgQPut(&sma->equeue, /* event queue object */
(void *)&e); /* actual event posted */
RKH_ALLEGE(status == kStatus_OSA_Success);
RKH_TR_SMA_FIFO(sma, e, sender, e->pool, e->nref,
&sma->equeue.queue.MsgQ.NbrEntries, 0);
RKH_EXIT_CRITICAL_();
}
void
{
osa_status_t status;
RKH_HOOK_SIGNAL(e);
RKH_ENTER_CRITICAL_();
RKH_INC_REF(e);
status = OSA_MsgQPutLifo(&sma->equeue, /* event queue object */
(void *)&e); /* actual event posted */
RKH_ALLEGE(status == kStatus_OSA_Success);
RKH_TR_SMA_LIFO(sma, e, sender, e->pool, e->nref,
&sma->equeue.queue.MsgQ.NbrEntries, 0);
RKH_EXIT_CRITICAL_();
}
{
osa_status_t status;
status = OSA_MsgQGet(&sma->equeue, /* event queue object */
&e, /* received event message */
OSA_WAIT_FOREVER); /* wait indefinitely */
RKH_ENSURE(status == kStatus_OSA_Success);
/* To get the number of message currently in the queue and its */
/* minimum number of free elements is not a reliable manner in OSA */
/* Because the variables are obtained outside critical section could be */
/* a race condition */
/* Morever, OSA abstraction layer not implements the water mark in */
/* the queue */
RKH_TR_SMA_GET(sma, e, e->pool, e->nref,
&sma->equeue.queue.MsgQ.NbrEntries, 0);
return e;
}
#define RKH_ALLEGE(exp)
General purpose assertion that ALWAYS evaluates the exp argument and calls the RKH_ASSERT() macro if ...
Definition: rkhassert.h:151
void rkh_sma_post_lifo(RKH_SMA_T *me, const RKH_EVT_T *e, const void *const sender)
Send an event to a state machine application (SMA) as known as active object through a queue using th...
void rkh_sma_post_fifo(RKH_SMA_T *me, const RKH_EVT_T *e, const void *const sender)
Send an event to a state machine application (SMA) as known as active object through a queue using th...
RKH_EVT_T * rkh_sma_get(RKH_SMA_T *me)
Get an event from the event queue of an state machine application (SMA) as known as active object....
#define RKH_TR_SMA_FIFO(actObj_, evt_, sender_, poolID_, refCntr_, nElem_, nMin_)
Send an event to a state machine application (SMA) as known as active object through a queue using th...
#define RKH_TR_SMA_GET(actObj_, evt_, poolID_, refCntr_, nElem_, nMin_)
Get an event from the active object's queue.
#define RKH_TR_SMA_LIFO(actObj_, evt_, sender_, poolID_, refCntr_, nElem_, nMin_)
Send an event to a state machine application (SMA) as known as active object through a queue using th...
rui8_t nref
Attribute of dynamic events.
Definition: rkhevt.h:181
rui8_t pool
Attribute of dynamic events (0 for static event).
Definition: rkhevt.h:187

[ NEXT ]


Are implemented the event queues with a message queue of the underlying OS/RTOS?: NO

  1. Define the macro RKH_CFGPORT_NATIVE_EQUEUE_EN = RKH_ENABLED in rkhport.h
  2. Define the macro RKH_CFG_QUE_EN = RKH_ENABLED in rkhcfg.h
  3. Implement the platform-specific functions rkh_sma_block(), rkh_sma_setReady(), and rkh_sma_setUnready() in rkhport.c according to underlying OS/RTOS, which are specified in source/sma/inc/rkhsma_sync.h file.
  4. Define RKH_CFGPORT_SMA_THREAD_DATA_EN = RKH_ENABLED and RKH_OSSIGNAL_TYPE according to underlying OS/RTOS
  5. Define the macro RKH_CFGPORT_SMA_QSTO_EN = RKH_ENABLED in rkhport.h

Example for Windows multithreaded application
Fragment of rkhport.h. See source/portable/80x86/win32_mt/vc/rkhport.h

#define RKH_OSSIGNAL_TYPE void*

Fragment of rkhport.c. See source/portable/80x86/win32_mt/vc/rkhport.c

void
{
while (me->equeue.qty == 0)
{
rkhport_exit_critical();
(void)WaitForSingleObject(me->os_signal, (DWORD)INFINITE);
rkhport_enter_critical();
}
}
void
{
(void)SetEvent(me->os_signal);
}
void
{
(void)me;
}
RKH_OSSIGNAL_TYPE os_signal
OS-dependent object used to signal that an event has been queued.
Definition: rkhsma.h:827

[ NEXT ]


RKH works in conjunction with a traditional OS/RTOS?: NO

  1. Define the macros RKH_CFGPORT_NATIVE_SCHEDULER_EN = RKH_ENABLED, RKH_CFGPORT_SMA_THREAD_EN = RKH_DISABLED, RKH_CFGPORT_SMA_THREAD_DATA_EN = RKH_DISABLED, RKH_CFGPORT_SMA_STK_EN = RKH_DISABLED, RKH_CFGPORT_REENTRANT_EN = RKH_DISABLED in the rkhport.h file.
  2. Define the macro RKH_EQ_TYPE = RKH_QUEUE_T in rkhport.h

[ NEXT ]


Are implemented the event queues with the native queues? [ YES ] - [ NO ]


Are implemented the event queues with the native queues?: YES

  1. Define the macro RKH_CFGPORT_NATIVE_EQUEUE_EN = RKH_ENABLED and RKH_CFG_QUE_EN = RKH_ENABLED in rkhport.h and rkhcfg.h respectively.
  2. Define the macro RKH_CFGPORT_SMA_QSTO_EN = RKH_ENABLED in rkhport.h

[ NEXT ]


Are implemented the event queues with the native queues?: NO

  1. Define the macro RKH_CFGPORT_NATIVE_EQUEUE_EN = RKH_DISABLED in rkhport.h
  2. Define the macro RKH_EQ_TYPE in rkhport.h according to external queue module.
  3. Then, implement the platform-specific functions rkh_sma_post_fifo(), rkh_sma_post_lifo() and rkh_sma_get(), which are specified in source/sma/inc/rkhsma.h. All these functions are frequently placed in rkhport.c file. See section YES of q3.
  4. Define the macro RKH_CFGPORT_SMA_QSTO_EN in rkhport.h according to external queue module..

[ NEXT ]


Dynamic event support

Is required events with arguments? [ YES ] - [ NO ]


Is required events with arguments?: YES
If RKH works in conjunction with a traditional OS/RTOS, is implemented the dynamic memory support with a internal module of the underlying OS/RTOS? [ YES ] - [ NO ]


If RKH works in conjunction with a traditional OS/RTOS, is implemented the dynamic memory support with a internal module of the underlying OS/RTOS?: YES

  1. Define the macro RKH_CFG_FWK_DYN_EVT_EN = RKH_ENABLED in rkhcfg.h
  2. Define the macro RKH_CFGPORT_NATIVE_DYN_EVT_EN = RKH_DISABLED in rkhport.h
  3. Then, implement the platform-specific functions rkh_evtPool_init(), rkh_evtPool_getPool(), rkh_evtPool_getBlockSize(), rkh_evtPool_get(), rkh_evtPool_put(), rkh_evtPool_getNumUsed(), rkh_evtPool_getNumMin() and rkh_evtPool_getNumBlock(), which are specified in source/fwk/inc/rkhfwk_evtpool.h. All these functions are frequently placed in rkhport.c file.

Example for memory partitions of uC/OS-III

/* ---------------------------- Local data types --------------------------- */
struct RKHEvtPool
{
OS_MEM memPool;
rui8_t used;
};
/* ---------------------------- Global variables --------------------------- */
/* ---------------------------- Local variables ---------------------------- */
static RKHEvtPool evtPools[RKH_CFG_FWK_MAX_EVT_POOL];
/* ----------------------- Local function prototypes ----------------------- */
/* ---------------------------- Local functions ---------------------------- */
/* ---------------------------- Global functions --------------------------- */
void
{
rInt i;
RKHEvtPool *ep;
for (i = 0, ep = evtPools; i < RKH_CFG_FWK_MAX_EVT_POOL; ++i, ++ep)
{
ep->used = 0;
}
}
RKHEvtPool *
rkh_evtPool_getPool(void *stoStart, rui16_t stoSize, RKH_ES_T evtSize)
{
rInt i;
RKHEvtPool *ep;
OS_ERR err;
for (i = 0, ep = evtPools; i < RKH_CFG_FWK_MAX_EVT_POOL; ++i, ++ep)
{
if (ep->used == 0)
{
OSMemCreate((OS_MEM *)ep,
(CPU_CHAR *)"ep",
stoStart,
(OS_MEM_QTY )(stoSize / evtSize),
(OS_MEM_SIZE)evtSize,
&err);
/* Check 'err' */
return ep;
}
}
return (RKHEvtPool *)0;
}
rui8_t
rkh_evtPool_getBlockSize(RKHEvtPool *const me)
{
RKH_REQUIRE(me != (RKHEvtPool *)0);
return (rui8_t)((OS_MEM *)me)->BlkSize;
}
rkh_evtPool_get(RKHEvtPool *const me)
{
OS_ERR err;
RKH_REQUIRE(me != (RKHEvtPool *)0);
return (RKH_EVT_T *)OSMemGet((OS_MEM *)me, &err);
}
void
rkh_evtPool_put(RKHEvtPool *const me, RKH_EVT_T *evt)
{
OS_ERR err;
RKH_REQUIRE(me != (RKHEvtPool *)0);
rkh_memPool_put((OS_MEM *)me, (void *)evt, &err);
}
rui8_t
rkh_evtPool_getNumUsed(RKHEvtPool *const me)
{
RKH_REQUIRE(me != (RKHEvtPool *)0);
return (rui8_t)(((OS_MEM *)me)->NbrMax - ((OS_MEM *)me)->NbrFree);
}
rui8_t
rkh_evtPool_getNumMin(RKHEvtPool *const me)
{
RKH_REQUIRE(me != (RKHEvtPool *)0);
return (rui8_t)0; /* This operation is not supported for Micrium */
}
rui8_t
rkh_evtPool_getNumBlock(RKHEvtPool *const me)
{
RKH_REQUIRE(me != (RKHEvtPool *)0);
return (rui8_t)((OS_MEM *)me)->NbrMax;
}
void rkh_memPool_put(RKH_MEMPOOL_T *mp, void *blk)
When the application is done with the memory block, it must be returned to the appropiate memory pool...
#define RKH_CFG_FWK_MAX_EVT_POOL
If the dynamic event support is enabled (see RKH_CFG_FWK_DYN_EVT_EN) then the RKH_CFG_FWK_MAX_EVT_POO...
Definition: rkhcfg.h:114
rui8_t RKH_ES_T
Definition: rkhevt.h:116
void rkh_evtPool_init()
Encapsulates the initialization of event pool manager.
rui8_t rkh_evtPool_getBlockSize(RKHEvtPool *const me)
Encapsulates how RKH should obtain the block size of an event pool.
rui8_t rkh_evtPool_getNumMin(RKHEvtPool *const me)
Encapsulates how RKH should return the lowest number of free blocks ever present in the pool me....
RKH_EVT_T * rkh_evtPool_get(RKHEvtPool *const me)
Encapsulates how RKH should obtain an event evt from the event pool me.
rui8_t rkh_evtPool_getNumBlock(RKHEvtPool *const me)
Encapsulates how RKH should return the total number of blocks in the pool me.
rui8_t rkh_evtPool_getNumUsed(RKHEvtPool *const me)
Encapsulates how RKH should return the current number of memory blocks used in the pool me.
RKHEvtPool * rkh_evtPool_getPool(void *stoStart, rui16_t stoSize, RKH_ES_T evtSize)
Encapsulates the creation of an event pool.
void rkh_evtPool_put(RKHEvtPool *const me, RKH_EVT_T *evt)
Encapsulates how RKH should return an event evt to the event pool me.

[ NEXT ]


Is required events with arguments?: NO

  1. Define the macro RKH_CFG_FWK_DYN_EVT_EN = RKH_DISABLED in rkhcfg.h
  2. Define the macro RKH_CFGPORT_NATIVE_DYN_EVT_EN = RKH_DISABLED in rkhport.h

[ NEXT ]


If RKH works in conjunction with a traditional OS/RTOS, is implemented the dynamic memory support with a internal module of the underlying OS/RTOS?: NO

  1. Define the macro RKH_CFG_FWK_DYN_EVT_EN = RKH_ENABLED and RKH_CFG_MP_EN = RKH_ENABLED in rkhcfg.h
  2. Define the macro RKH_CFGPORT_NATIVE_DYN_EVT_EN = RKH_ENABLED in rkhport.h

[ NEXT ]


If the application code uses dynamic memory allocation, it's implemented with the native fixed-size memory block pool? [ YES ] - [ NO ]


If the application code uses dynamic memory allocation, it's implemented with the native fixed-size memory block pool?: YES

  1. Define the macro RKH_CFG_FWK_DYN_EVT_EN = RKH_ENABLED and RKH_CFG_MP_EN = RKH_ENABLED in rkhcfg.h
  2. Define the macro RKH_CFGPORT_NATIVE_DYN_EVT_EN = RKH_ENABLED in rkhport.h

[ NEXT ]


If the application code uses dynamic memory allocation, it's implemented with the native fixed-size memory block pool?: NO

  1. Define the macro RKH_CFG_FWK_DYN_EVT_EN = RKH_ENABLED in rkhcfg.h
  2. Define the macro RKH_CFGPORT_NATIVE_DYN_EVT_EN = RKH_DISABLED in rkhport.h
  3. Then, implement the platform-specific functions rkh_evtPool_init(), rkh_evtPool_getPool() and rkh_evtPool_getBlockSize(), rkh_evtPool_get(), rkh_evtPool_put(), rkh_evtPool_getNumUsed(), rkh_evtPool_getNumMin() and rkh_evtPool_getNumBlock() which are specified in source/fwk/inc/rkhfwk_evtpool.h. All these functions are frequently placed in rkhport.c file.

[ NEXT ]


Hook functions

A RKH port cannot and should not define all the functions that it calls, because this would render the port too inflexible. The functions that RKH calls but doesn't actually implement are referred to as callback or hook functions. All these functions in RKH are easily indentifiable by the "_hook_" key word used in the function name, rkh_hook_dispatch(), rkh_hook_signal(), rkh_hook_timeout(), rkh_hook_start(), rkh_hook_exit(), and rkh_hook_idle(). Please, see RKH_CFG_HOOK_DISPATCH_EN, RKH_CFG_HOOK_SIGNAL_EN, RKH_CFG_HOOK_TIMEOUT_EN, RKH_CFG_HOOK_START_EN, RKH_CFG_HOOK_EXIT_EN, RKH_CFG_HOOK_TIMETICK_EN, and RKH_CFG_HOOK_PUT_TRCEVT_EN options from the rkhcfg.h.

void rkh_hook_dispatch(RKH_SMA_T *me, RKH_EVT_T *e)
When dispatching an event to a SMA the dispatch hook function will be executed.
Type value Boolean
Range value
Default configuration: RKH_DISABLED
void rkh_hook_signal(RKH_EVT_T *e)
When the producer of an event directly posts the event to the event queue of the consumer SMA the rkh...
Type value Boolean
Range value
Default configuration: RKH_DISABLED
void rkh_hook_timeout(const void *t)
void rkh_hook_timeout(const void *t)
If a timer expires the rkh_hook_timeout() function is called just before the assigned event is direct...
Type value Boolean
Range value
Default configuration: RKH_DISABLED
void rkh_hook_start(void)
void rkh_hook_start(void)
This hook function is called just before the RKH takes over control of the application.
Type value Boolean
Range value
Default configuration: RKH_DISABLED
void rkh_hook_exit(void)
void rkh_hook_exit(void)
This hook function is called just before the RKH returns to the underlying OS/RTOS....
Type value Boolean
Range value
Default configuration: RKH_DISABLED
void rkh_hook_idle(void)
void rkh_hook_idle(void)
An idle hook function will only get executed (with interrupts LOCKED) when there are no SMAs of highe...

This makes the idle hook function an ideal place to put the processor into a low power state - providing an automatic power saving whenever there is no processing to be performed.

Note
The rkh_hook_idle() callback is called with interrupts locked, because the determination of the idle condition might change by any interrupt posting an event. This function must internally unlock interrupts, ideally atomically with putting the CPU to the power-saving mode.
Usage
void
rkh_hook_idle( void ) // NOTE: entered with interrupts DISABLED
{
RKH_ENA_INTERRUPT(); // must at least enable interrupts
...
}
#define RKH_ENA_INTERRUPT()
RKH need to disable interrupts in order to access critical sections of code, and re-enable interrupts...
Definition: rkhitl.h:1999
void rkh_hook_timetick(void)
This function is called by rkh_tmr_tick(), which is assumed to be called from an ISR....

Usually, the rkh_hook_timetick() allows to the application to extend the functionality of RKH, giving the port developer the opportunity to add code that will be called by rkh_tmr_tick(). Frequently, the rkh_hook_timetick() is called from the tick ISR and must not make any blocking calls and must execute as quickly as possible. When this is set the application must provide the hook function.

Type value Boolean
Range value
Default configuration: RKH_DISABLED

Interrupt locking mechanism

RKH need to disable interrupts in order to access critical sections of code, and re-enable interrupts when done. This allows RKH to protect critical code from being entered simultaneously. To hide the implementation method chosen by the processor, compiler, etc, RKH defines two macros to unconditionally disable and enable interrupts: RKH_DIS_INTERRUPT() and RKH_ENA_INTERRUPT() respectively. Obviously, they resides in rkhport.h file, which the user always need to provide.
Example for HCS08 CW6.3

#define RKH_DIS_INTERRUPT() DisableInterrupts
#define RKH_ENA_INTERRUPT() EnableInterrupts

Example for uC/OS-III and KSDK

#define RKH_DIS_INTERRUPT() INT_SYS_DisableIRQGlobal()
#define RKH_ENA_INTERRUPT() INT_SYS_EnableIRQGlobal()

Critical section

RKH need to disable interrupts in order to access critical sections of code, and re-enable interrupts when done. This allows RKH to protect critical code from being entered simultaneously from either multiple SMAs or ISRs. Every processor generally provide instructions to disable/enable interrupts and the C compiler must have a mechanism to perform these operations directly from C. Some compilers will allows to insert in-line assembly language statements in the C source code. This makes it quite easy to insert processor instructions to enable and disable interrupts. Other compilers will actually contain language extensions to enable and disable interrupts directly from C. To hide the implementation method chosen by the compiler manufacturer, RKH defines two macros to disable and enable interrupts: RKH_ENTER_CRITICAL() and RKH_EXIT_CRITICAL().

The RKH_ENTER_CRITICAL() macro saves the interrupt disable status onto the stack and then, disable interrupts. RKH_EXIT_CRITICAL() would simply be implemented by restoring the interrupt status from the stack. Using this scheme, if it's called a RKH service with either interrupts enabled or disabled then, the status would be preserved across the call. If calls a RKH service with interrupts disabled, is potentially extending the interrupt latency of application. The application can use RKH_ENTER_CRITICAL() and RKH_EXIT_CRITICAL() to also protect critical sections of code. As a general rule, should always call RKH services with interrupts enabled!.

Note
These macros are internal to RKH and the user application should not call it.

Example for x86, VC2008, and win32 single thread:

//#define RKH_CPUSR_TYPE
#define RKH_ENTER_CRITICAL(dummy) EnterCriticalSection(&csection)
#define RKH_EXIT_CRITICAL(dummy) LeaveCriticalSection(&csection)

Example for uC/OS-III and KSDK

//#define RKH_CPUSR_TYPE
#define RKH_ENTER_CRITICAL(dummy) \
OSA_EnterCritical(kCriticalDisableInt)
#define RKH_EXIT_CRITICAL(dummy) \
OSA_ExitCritical(kCriticalDisableInt)

Trace facility

When using the trace facility must be defined in rkhport.h the following configurations:

  1. RKH_CFGPORT_TRC_SIZEOF_PTR
    Specify the size of void pointer. The valid values [in bits] are 16 or 32. Default is 32. See RKH_TRC_SYM() macro.
    Type value Integer
    Range value [8, 16, 32]
    Default configuration: 32
  2. RKH_CFGPORT_TRC_SIZEOF_PTR
    Specify the size of function pointer. The valid values [in bits] are 16 or 32. Default is 32. See RKH_TUSR_FUN() and RKH_TRC_FUN() macros.
    Type value Integer
    Range value [8, 16, 32]
    Default configuration: 32
  3. RKH_CFGPORT_TRC_SIZEOF_TSTAMP
    Specify the number of bytes (size) used by the trace record timestamp. The valid values [in bits] are 8, 16 or 32. Default is 16.
    Type value Integer
    Range value [8, 16, 32]
    Default configuration: 16

    Example for ARM Cortex
    #define RKH_CFGPORT_TRC_SIZEOF_PTR 32u
    #define RKH_CFGPORT_TRC_SIZEOF_FUN_PTR 32u
    #define RKH_CFGPORT_TRC_SIZEOF_TSTAMP 32u

Example for S08 of NXP

#define RKH_CFGPORT_TRC_SIZEOF_PTR 16u
#define RKH_CFGPORT_TRC_SIZEOF_FUN_PTR 16u
#define RKH_CFGPORT_TRC_SIZEOF_TSTAMP 16u

A RKH port cannot and should not define all the functions that it calls, because this would render the port too inflexible. Therefore, the application-specific functions rkh_trc_open(), rkh_trc_close(), rkh_trc_flush(), and rkh_trc_getts() are application provided, which are specified in source/trc/inc/rkhtrc_out.h, typically in the board support package (bsp.c).

void rkh_trc_open(void)
void rkh_trc_open(void)
Open the tracing session.

This function is application-specific and the user needs to define it. At a minimum, this function must initialize and/or configure the trace stream by calling rkh_trc_init() and RKH_TRC_SEND_CFG() respectively.

Note
This function is internal to RKH and the user application should not call it. Instead, use RKH_TRC_OPEN() macro.
See also
rkhtrc.h file.
Usage
#define BSP_SIZEOF_TS 32u
#define BSP_TS_RATE_HZ CLOCK_PER_SEC
void
rkh_trc_open( void )
{
FTBIN_OPEN();
TCP_TRACE_OPEN();
RKH_TRC_SEND_CFG( BSP_SIZEOF_TS, BSP_TS_RATE_HZ );
if(( idle_thread = CreateThread( NULL, 1024,
&idle_thread_function, (void *)0,
CREATE_SUSPENDED, NULL )) == (HANDLE)0 )
fprintf( stderr, "Cannot create the thread: [%d]
line from %s "
"file\n", __LINE__, __FILE__ );
}
#define RKH_TRC_SEND_CFG(ts_hz)
Send the trace facility configuration to host application software Trazer.
Definition: rkhtrc_out.h:221
void rkh_trc_init(void)
Initializes the RKH's trace record service.


void rkh_trc_close(void)
void rkh_trc_close(void)
Close the tracing session.

This function is application-specific and the user needs to define it.

Note
This function is internal to RKH and the user application should not call it. Instead, use RKH_TRC_CLOSE() macro.
See also
rkhtrc.h file.
Usage
void
{
fclose( fdbg );
}


void rkh_trc_flush(void)
void rkh_trc_flush(void)
Platform-dependent macro flushing the trace stream.

This function is application-specific and the user needs to define it. When the RKH trace an event, all the information related to it has to be stored somewhere before it can be retrieved, in order to be analyzed. This place is a trace stream. Frequently, events traced are stored in the stream until it is flushed.

Note
This function is internal to RKH and the user application should not call it. Instead, use RKH_TRC_FLUSH() macro.
See also
rkhtrc.h file.
Usage
void
{
rui8_t *blk;
TRCQTY_T nbytes;
FOREVER
{
nbytes = (TRCQTY_T)1024;
RKH_ENTER_CRITICAL_();
blk = rkh_trc_get_block( &nbytes );
RKH_EXIT_CRITICAL_();
if((blk != (rui8_t *)0))
{
FTBIN_FLUSH( blk, nbytes );
TCP_TRACE_SEND_BLOCK( blk, nbytes );
}
else
break;
}
}
rui8_t * rkh_trc_get_block(TRCQTY_T *nget)
Retrieves a pointer to a contiguous block of data from the trace stream.

void rkh_trc_getts(void)
RKH_TS_T rkh_trc_getts(void)
Retrieves a timestamp to be placed in a trace event.
This function is application-specific and the user needs to define it. The data returned is defined in compile-time by means of RKH_SIZEOF_TSTAMP.
Returns
Timestamp (RKH_TS_T data type).
See also
rkhtrc.h file.
Usage
{
return ( RKH_TS_T )clock();
}
rui32_t RKH_TS_T
Defines the size of trace timestamp.


A port file example

rkhport.h for ARM Cortex-M3 and LPCXpresso, with native scheduler
See source/portable/arm-cortex/rkhs/arm_cm3/codered/rkhport.h file

/* --------------------------------- Module -------------------------------- */
#ifndef __RKHPORT_H__
#define __RKHPORT_H__
/* ----------------------------- Include files ----------------------------- */
#include "rkhtype.h"
#include "rkhqueue.h"
#include "rkhmempool.h"
#include "rkhsma_prio.h"
/* ---------------------- External C language linkage ---------------------- */
#ifdef __cplusplus
extern "C" {
#endif
/* --------------------------------- Macros -------------------------------- */
#define RKH_DIS_INTERRUPT() __asm volatile ("cpsid i")
#define RKH_ENA_INTERRUPT() __asm volatile ("cpsie i")
#define RKH_ENTER_CRITICAL( dummy ) rkhport_enter_critical()
#define RKH_EXIT_CRITICAL( dummy ) rkhport_exit_critical()
/* ------------------------------- Constants ------------------------------- */
#define KERNEL_IRQ_PRIO 6
#define HIGHEST_IRQ_PRI 5
#define RKH_CFGPORT_SMA_THREAD_EN RKH_DISABLED
#define RKH_CFGPORT_SMA_THREAD_DATA_EN RKH_DISABLED
#define RKH_CFGPORT_NATIVE_SCHEDULER_EN RKH_ENABLED
#define RKH_CFGPORT_NATIVE_EQUEUE_EN RKH_ENABLED
#define RKH_CFGPORT_NATIVE_DYN_EVT_EN RKH_ENABLED
#define RKH_CFGPORT_REENTRANT_EN RKH_DISABLED
#define RKH_CFGPORT_TRC_SIZEOF_PTR 32u
#define RKH_CFGPORT_TRC_SIZEOF_FUN_PTR 32u
#define RKH_CFGPORT_TRC_SIZEOF_TSTAMP 32u
#define RKH_CFGPORT_SMA_QSTO_EN RKH_ENABLED
#define RKH_CFGPORT_SMA_STK_EN RKH_DISABLED
#define RKHROM const
#define RKH_EQ_TYPE RKH_QUEUE_T
/* ------------------------------- Data types ------------------------------ */
/* -------------------------- External variables --------------------------- */
/* -------------------------- Function prototypes -------------------------- */
const char *rkhport_get_version(void);
const char *rkhport_get_desc(void);
void rkhport_enter_critical(void);
void rkhport_exit_critical(void);
/* -------------------- External C language linkage end -------------------- */
#ifdef __cplusplus
}
#endif
/* ------------------------------ Module end ------------------------------- */
#endif
/* ------------------------------ End of file ------------------------------ */
Specifies the interface of the fixed-size memory blocks facility.
Specifies the interface of the queue services.
Specifies the native priority mechanism for active object scheduling.
Defines the data types that uses RKH.

rkht.h for ARM Cortex-M3 and LPCXpresso
See source/portable/arm-cortex/rkhs/arm_cm3/codered/rkht.h file

/* --------------------------------- Module -------------------------------- */
#ifndef __RKHT_H__
#define __RKHT_H__
/* ----------------------------- Include files ----------------------------- */
/* ---------------------- External C language linkage ---------------------- */
#ifdef __cplusplus
extern "C" {
#endif
/* --------------------------------- Macros -------------------------------- */
/* -------------------------------- Constants ------------------------------ */
/* ------------------------------- Data types ------------------------------ */
typedef signed char ri8_t;
typedef signed short ri16_t;
typedef signed long ri32_t;
typedef unsigned char rui8_t;
typedef unsigned short rui16_t;
typedef unsigned long rui32_t;
typedef unsigned int ruint;
typedef signed int rInt;
typedef unsigned int rbool_t;
/* -------------------------- External variables --------------------------- */
/* -------------------------- Function prototypes -------------------------- */
/* -------------------- External C language linkage end -------------------- */
#ifdef __cplusplus
}
#endif
/* ------------------------------ Module end ------------------------------- */
#endif
/* ------------------------------ File footer ------------------------------ */

rkhport.c for ARM Cortex-M3 and LPCXpresso
See source/portable/arm-cortex/rkhs/arm_cm3/codered/rkhport.c file

/* --------------------------------- Notes --------------------------------- */
/* ----------------------------- Include files ----------------------------- */
#include "rkh.h"
#include "lpc17xx.h"
#include "bsp.h"
/* ----------------------------- Local macros ------------------------------ */
/* ------------------------------- Constants ------------------------------- */
RKH_MODULE_VERSION(rkhport, 1.00)
RKH_MODULE_DESC(rkhport, "ARM Cortex-M, LPCXpresso")
/* ---------------------------- Local data types --------------------------- */
/* ---------------------------- Global variables --------------------------- */
/* ---------------------------- Local variables ---------------------------- */
static ruint critical_nesting;
/* ----------------------- Local function prototypes ----------------------- */
/* ---------------------------- Local functions ---------------------------- */
/* ---------------------------- Global functions --------------------------- */
const char *
rkhport_get_version(void)
{
}
const char *
rkhport_get_desc(void)
{
}
void
rkhport_enter_critical(void)
{
__asm volatile
(
" mov r0, %0 \n"
" msr basepri, r0 \n"
::"i" (((HIGHEST_IRQ_PRI << (8 - __NVIC_PRIO_BITS)) & 0xFF)) : "r0"
);
critical_nesting++;
}
void
rkhport_exit_critical(void)
{
critical_nesting--;
if (critical_nesting != 0)
{
return;
}
__asm volatile
(
" mov r0, #0 \n"
" msr basepri, r0 \n"
::: "r0"
);
}
/* ------------------------------ File footer ------------------------------ */
#define RKH_MODULE_NAME(__fname)
This macro appears at the top of each C/C++ source file defining a name for that file.
RKH framwwork platform - independent interface.
#define RKH_MODULE_GET_DESC()
Get the module description.
Definition: rkhfwk_module.h:98
#define RKH_MODULE_GET_VERSION()
Get the module version.
Definition: rkhfwk_module.h:80
#define RKH_MODULE_DESC(__fname, __desc)
This macro appears at the top of each C/C++ source file defining the description string for that file...
Definition: rkhfwk_module.h:91
#define RKH_MODULE_VERSION(__fname, __version)
This macro appears at the top of each C/C++ source file defining the version string for that file (mo...
Definition: rkhfwk_module.h:73

Extras

In rkhport.h
See source/portable/arm-cortex/rkhs/arm_cm3/codered/rkhport.h file

const char *rkhport_get_version(void);
const char *rkhport_get_desc(void);

In rkhport.c
See source/portable/arm-cortex/rkhs/arm_cm3/codered/rkhport.c file

RKH_MODULE_VERSION(rkhport, 1.00)
RKH_MODULE_DESC(rkhport, "ARM Cortex-M, LPCXpresso")
const char *
rkhport_get_version(void)
{
}
const char *
rkhport_get_desc(void)
{
}