Kinetis SDK v.1.3 API Reference Manual  Rev. 0
Freescale Semiconductor, Inc.
 All Data Structures 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 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 the post_ISR, but posted by a task post_task, then OSA_SemaWait in loop could never get my_sem within the timeout because the post_task does not have a chance to post my_sem. In this situation, applications could be implemented as follows:
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 received. Return and let other tasks run. Then, post_task has a chance to post my_sem.
The other method is using the function OSA_PollAllOtherTasks(). This function calls all other tasks one at a time and then post_task can 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 flows like this: task_A -> OSA_PollAllOtherTasks -> task_B -> OSA_PollAllOtherTasks -> task_A -> ...

Bare Metal Mutex

Bare metal OSA implements mutex as a binary semaphore, which is different than the RTOS mutex. Applications could choose whether to use if for the bare metal.

Bare Metal Time management

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

Time management with LPTMR

To use the low power timer in bare metal OSA, define the FSL_OSA_BM_TIMER_CONFIG as the FSL_OSA_BM_TIMER_LPTMER.
Bare metal OSA maintains a system time with the low power timer module. Applications can get the system time in milliseconds using the function OSA_TimeGetMsec(). At the same time, all wait functions, such as OSA_SemaWait() and OSA_EventWait(), depend on the system time. Low power timer module is set up in the function OSA_Init(). To use this timer function, ensure that the OSA_Init() function is called. Note that the low power timer provides only 16-bit time count and wraps every 65536 ms. Use these three functions:

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

Disable time management in bare metal OSA

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

User-defined time management

When the LPTMR is occupied by other tasks and bare metal OSA is used to provide time services, bare metal OSA must use other timers for the time services. In this case, customizeS these functions defined in fsl_os_abstraction_bm.c:
/* Initializes timer.
void OSA_TimeInit(void);
/*
* Gets the 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);
/* Gets current time in milliseconds.
uint32_t OSA_TimeGetMsec(void);
There are two methods to customize these functions:

  1. Modify the functions in fsl_os_abstraction_bm.c directly.
  2. Define the functions in the application, which means that the functions in fsl_os_abstraction_bm.c are 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.