Kinetis SDK v.1.2 API Reference Manual  Rev. 0
Freescale Semiconductor, Inc.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
Bare Metal Abstraction Layer

The Kinetis SDK provides the Bare Metal Abstraction Layer for synchronization, mutual exclusion, message queue, etc. More...

Overview

Data Structures

struct  semaphore_t
 Type for an semaphore. More...
 
struct  mutex_t
 Type for a mutex. More...
 
struct  event_t
 Type for an event object. More...
 
struct  task_control_block_t
 Task control block for bare metal. More...
 
struct  msg_queue_t
 Type for a message queue. More...
 

Macros

#define FSL_OSA_BM_TIMER_NONE   0U
 Bare Metal does not use timer. More...
 
#define FSL_OSA_BM_TIMER_LPTMER   1U
 Bare Metal uses LPTMR as timer. More...
 
#define FSL_OSA_BM_TIMER_CONFIG   FSL_OSA_BM_TIMER_LPTMER
 Configure what timer is used in Bare Metal. More...
 
#define OSA_WAIT_FOREVER   0xFFFFFFFFU
 Constant to pass as timeout value in order to wait indefinitely. More...
 
#define TASK_MAX_NUM   5
 How many tasks can the bare metal support. More...
 
#define FSL_OSA_TIME_RANGE   0xFFFFU
 OSA's time range in millisecond, OSA time wraps if exceeds this value. More...
 
#define OSA_DEFAULT_INT_HANDLER   ((osa_int_handler_t)(&DefaultISR))
 The default interrupt handler installed in vector table. More...
 

Typedefs

typedef uint32_t event_flags_t
 Type for an event flags group, bit 32 is reserved.
 
typedef void * task_param_t
 Type for task parameter.
 
typedef void(* task_t )(task_param_t param)
 Type for a task pointer.
 
typedef task_control_block_ttask_handler_t
 Type for a task handler, returned by the OSA_TaskCreate function.
 
typedef uint32_t task_stack_t
 Type for a task stack.
 
typedef msg_queue_tmsg_queue_handler_t
 Type for a message queue handler.
 

Functions

void DefaultISR (void)
 The default interrupt handler installed in vector table. More...
 

Thread management

void OSA_PollAllOtherTasks (void)
 Calls all task functions one time except for the current task. More...
 
#define OSA_TASK_DEFINE(task, stackSize)
 Defines a task. More...
 

Message queues

#define MSG_QUEUE_DECLARE(name, number, size)
 This macro statically reserves the memory required for the queue. More...
 

Bare Metal Abstraction Layer

Overview

When RTOSes are not used, bare metal abstraction layer provides semaphore, mutex, event, message queue and so on. Because bare metal does not have a task scheduler, it is necessary to exercise caution while using bare metal abstraction layer.

Bare Metal's Task Management

By contrast to RTOSes, bare metal abstraction layer uses a poll mechanism to simulate a task. All task functions are linked into a list and called one by one. Therefore, bare metal task function should not contains an infinite loop. It must return at a proper time to let the other tasks run.Bare metal task does not support priority, all tasks use the same priority. The macro TASK_MAX_NUM defines how many tasks applications could create. If it is set to 0, then applications could not use task APIs.

Bare Metal's Wait Functions

Bare metal wait functions, such as OSA_SemaWait and OSA_EventWait, return the kStatus_OSA_Idle if wait condition is not met and timeout has not occurred. Applications should catch this value and take proper actions. If the wait condition is set by the ISR, applications could wait in a loop:
void post_ISR(void)
{
//...
OSA_SemaPost(&my_sem);
//...
}
void wait_task(task_param_t param)
{
//...
do
{
status = OSA_SemaWait(&my_sem, 10);
} while(kStatus_OSA_Idle == status);
//...
}
In this example, if my_sem is not posted by post_ISR, but posted by a task post_task, then OSA_SemaWait in loop could never get my_sem within timeout, because post_task does not have chance to post my_sem. In this situation, applications could be implemented like this:
void post_task(task_param_t param)
{
//...
OSA_SemaPost(&my_sem);
//...
}
void wait_task(task_param_t param)
{
status = OSA_SemaWait(&my_sem, 10);
switch (status)
{
return;
// ...
break;
// ...
break;
// ...
break;
}
//...
}
Wait the semaphore at the start of the task, if kStatus_OSA_Idle is got, return and let other task run, then post_task has chance to post my_sem.
The other method is using function OSA_PollAllOtherTasks(). This function calls all other tasks one time, then post_task could post my_sem.
void post_task(task_param_t param)
{
//...
OSA_SemaPost(&my_sem);
//...
}
void wait_task(task_param_t param)
{
//...
status = OSA_SemaWait(&my_sem, 10);
while (kStatus_OSA_Idle == status)
{
status = OSA_SemaWait(&my_sem, 10);
}
//...
}
The limitation of this method is that only one task can use the OSA_PollAllOtherTasks() function. If both task_A and task_B call this function, then the stack overflow may occur, because the call stack is like this: task_A -> OSA_PollAllOtherTasks -> task_B -> OSA_PollAllOtherTasks -> task_A -> ...

Bare Metal Mutex

Bare matal OSA implements mutex as a binary semaphore, this is different from RTOSes mutex. Applications could choose to use it or not for bare metal.

Bare Metal Time management

Bare metal OSA implements two configurations for time management. The first one is using lowpower timer. The second one is empty, in other words, this configuration disables time management in bare metal OSA. To use different configurations, please set the macro FSL_OSA_BM_TIMER_CONFIG in file fsl_os_abstraction_bm.h.

Time management with LPTMR

To use lowpower timer in bare metal OSA, please define FSL_OSA_BM_TIMER_CONFIG as FSL_OSA_BM_TIMER_LPTMER.
Bare metal OSA maintains a system time by the lowpower timer module. Applications can get system time in milliseconds using the function OSA_TimeGetMsec(). At the same time, all wait functions such as OSA_SemaWait(), OSA_EventWait() depend on this system time. Lowpower timer module is set up in the function OSA_Init(). To use this time function, ensure that the OSA_Init() function is called. Please note that lowpower timer provides only 16-bit time count, it wraps every 65536ms. So take care to use these three kinds of functions:

  1. OSA_TimeDelay() cannot delay longer than 65536ms.
  2. Wait functions, such as OSA_SemaWait(), cannot set timeout longer than 65536ms, however, OSA_WAIT_FOREVER is allowed.
  3. OSA_TimeGetMsec() wraps every 65536ms, if it does not meet the requirement, please implement use other timer module in application.

Disable time management in BM OSA

To disable time management bare metal OSA, please define FSL_OSA_BM_TIMER_CONFIG as FSL_OSA_BM_TIMER_NONE.
With this configuration, LPTMR is not used by BM OSA, then the footprint is smaller. Time services such OSA_TimeGetMsec, OSA_TimeDelay could not be used any more. At the same time, the wait functions such as OSA_SemaWait(), OSA_EventWait() could only use 0 or OSA_WAIT_FOREVER as the parameter timeout.

User defined time management

Sometimes the LPTMR should be used for the other purpose, and also BM OSA should provide time services. In this situation, BM OSA must use other timers for the time services, please re-write these functions defined in fsl_os_abstraction_bm.c:
/* Initialize timer. */
void OSA_TimeInit(void);
/*
* Get time delta between time_start and time_end. This function
* should consider the timer counter overflow.
*/
uint32_t OSA_TimeDiff(uint32_t time_start, uint32_t time_end);
/* Get current time in milliseconds. */
uint32_t OSA_TimeGetMsec(void);
There are two methods to re-write these functions:

  1. Modify the functions in fsl_os_abstraction_bm.c directly.
  2. Define the functions in application, then the functions in fsl_os_abstraction_bm.c will be overridden.

Data Structure Documentation

struct semaphore_t

Data Fields

volatile bool isWaiting
 Is any task waiting for a timeout on this object.
 
volatile uint8_t semCount
 The count value of the object.
 
uint32_t time_start
 The time to start timeout.
 
uint32_t timeout
 Timeout to wait in milliseconds.
 
struct mutex_t

Data Fields

volatile bool isWaiting
 Is any task waiting for a timeout on this mutex.
 
volatile bool isLocked
 Is the object locked or not.
 
uint32_t time_start
 The time to start timeout.
 
uint32_t timeout
 Timeout to wait in milliseconds.
 
LWSEM_STRUCT sema
 The lwsem structure. More...
 
_task_id owner
 Task who locks this mutex. More...
 

Field Documentation

LWSEM_STRUCT mutex_t::sema
_task_id mutex_t::owner
struct event_t

Data Fields

volatile bool isWaiting
 Is any task waiting for a timeout on this event.
 
uint32_t time_start
 The time to start timeout.
 
uint32_t timeout
 Timeout to wait in milliseconds.
 
volatile event_flags_t flags
 The flags status.
 
osa_event_clear_mode_t clearMode
 Auto clear or manual clear.
 
struct task_control_block_t

Data Fields

task_t p_func
 Task's entry.
 
task_param_t param
 Task's parameter.
 
struct TaskControlBlock * next
 Pointer to next task control block.
 
struct TaskControlBlock * prev
 Pointer to previous task control block.
 
struct msg_queue_t

Data Fields

uint32_t * queueMem
 Points to the queue memory.
 
uint16_t number
 The number of messages in the queue.
 
uint16_t size
 The size in words of each message.
 
uint16_t head
 Index of the next message to be read.
 
uint16_t tail
 Index of the next place to write to.
 
semaphore_t queueSem
 Semaphore wakeup tasks waiting for msg.
 
volatile bool isEmpty
 Whether queue is empty.
 

Macro Definition Documentation

#define FSL_OSA_BM_TIMER_NONE   0U
#define FSL_OSA_BM_TIMER_LPTMER   1U
#define FSL_OSA_BM_TIMER_CONFIG   FSL_OSA_BM_TIMER_LPTMER
#define OSA_WAIT_FOREVER   0xFFFFFFFFU
#define TASK_MAX_NUM   5
#define FSL_OSA_TIME_RANGE   0xFFFFU
#define OSA_DEFAULT_INT_HANDLER   ((osa_int_handler_t)(&DefaultISR))
#define OSA_TASK_DEFINE (   task,
  stackSize 
)
Value:
task_stack_t* task##_stack = NULL; \
task_handler_t task##_task_handler
uint32_t task_stack_t
Type for a task stack.
Definition: fsl_os_abstraction_bm.h:104
task_control_block_t * task_handler_t
Type for a task handler, returned by the OSA_TaskCreate function.
Definition: fsl_os_abstraction_bm.h:101

This macro defines resources for a task statically. Then, the OSA_TaskCreate creates the task based-on these resources.

Parameters
taskThe task function.
stackSizeThe stack size this task needs in bytes.
#define MSG_QUEUE_DECLARE (   name,
  number,
  size 
)
Value:
uint32_t queueMem_##name[number * size]; \
msg_queue_t entity_##name = { \
.queueMem = queueMem_##name \
}; \
msg_queue_t *name = &(entity_##name)
xQueueHandle msg_queue_t
Type for a message queue declaration and creation.
Definition: fsl_os_abstraction_free_rtos.h:123
Parameters
nameIdentifier for the memory region.
numberNumber of elements in the queue.
sizeSize of every element in words.

Function Documentation

void DefaultISR ( void  )
void OSA_PollAllOtherTasks ( void  )

This function calls all other task functions one time. If current task is waiting for an event triggered by other tasks, this function could be used to trigger the event.

Note
There should be only one task calls this function, if more than one task call this function, stack overflow may occurs. Be careful to use this function.