Update HAL-KSPDK files to 1.0 part 1

Everything except drivers and hal folder
pull/476/head
Sissors 2014-08-25 20:10:54 +02:00
parent 509a487cf6
commit db0a9b1f06
7 changed files with 1236 additions and 199 deletions

View File

@ -84,14 +84,6 @@ typedef enum _osa_critical_section_mode_t
#define USE_RTOS 1
#include "fsl_os_abstraction_ucosiii.h"
#elif defined (FSL_RTOS_CMSIS)
#define USE_RTOS 1
#include "fsl_os_abstraction_cmsis.h"
#elif defined (FSL_RTOS_MBED)
#define USE_RTOS 1
#include "fsl_os_abstraction_mbed.h"
#else
#define USE_RTOS 0
#include "fsl_os_abstraction_bm.h"

View File

@ -0,0 +1,185 @@
/*
* Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if !defined(__FSL_OS_ABSTRACTION_BM_H__)
#define __FSL_OS_ABSTRACTION_BM_H__
/*!
* @addtogroup os_abstraction_bm
* @{
*/
/*******************************************************************************
* Declarations
******************************************************************************/
/*! @brief Type for an semaphore */
typedef struct Semaphore
{
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 */
} semaphore_t;
/*! @brief Type for a mutex */
typedef struct Mutex
{
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 */
} mutex_t;
/*! @brief Type for an event flags group, bit 32 is reserved */
typedef uint32_t event_flags_t;
/*! @brief Type for an event object */
typedef struct Event
{
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 */
} event_t;
/*! @brief Type for task parameter */
typedef void* task_param_t;
/*! @brief Type for a task pointer */
typedef void (* task_t)(task_param_t param);
/*! @brief Task control block for bare metal. */
typedef struct TaskControlBlock
{
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 */
} task_control_block_t;
/*! @brief Type for a task handler, returned by the OSA_TaskCreate function */
typedef task_control_block_t* task_handler_t;
/*! @brief Type for a task stack */
typedef uint32_t task_stack_t;
/*! @brief Type for a message queue */
typedef struct MsgQueue
{
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 */
}msg_queue_t;
/*! @brief Type for a message queue handler */
typedef msg_queue_t* msg_queue_handler_t;
/*! @brief Constant to pass as timeout value in order to wait indefinitely. */
#define OSA_WAIT_FOREVER 0xFFFFFFFFU
/*! @brief How many tasks can the bare metal support. */
#define TASK_MAX_NUM 5
/*!
* @name Thread management
* @{
*/
/*!
* @brief Defines a task.
*
* This macro defines resources for a task statically. Then, the OSA_TaskCreate
* creates the task based-on these resources.
*
* @param task The task function.
* @param stackSize The stack size this task needs in bytes.
*/
#define OSA_TASK_DEFINE(task, stackSize) \
task_stack_t* task##_stack = NULL; \
task_handler_t task##_task_handler
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus*/
/*!
* @brief Calls all task functions one time except for the current task.
*
* 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.
*
*/
void OSA_PollAllOtherTasks(void);
#if defined(__cplusplus)
}
#endif /* __cplusplus*/
/* @} */
/*!
* @name Message queues
* @{
*/
/*!
* @brief This macro statically reserves the memory required for the queue.
*
* @param name Identifier for the memory region.
* @param number Number of elements in the queue.
* @param size Size of every element in words.
*/
#define MSG_QUEUE_DECLARE(name, number, size) uint32_t queueMem_##name[number * size]; \
msg_queue_t entity_##name = { \
.queueMem = queueMem_##name \
}; \
msg_queue_t *name = &(entity_##name)
/* @} */
/*! @}*/
#endif /* __FSL_OS_ABSTRACTION_BM_H__ */
/*******************************************************************************
* EOF
******************************************************************************/

View File

@ -0,0 +1,983 @@
/*
* Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include "fsl_os_abstraction.h"
#include "fsl_interrupt_manager.h"
#include "fsl_clock_manager.h"
#include "fsl_lptmr_hal.h"
#include "fsl_lptmr_features.h"
/* Include lptmr features to check wether lptimer module is available. */
/* Only one lptmr and always use it. */
#define BM_LPTMR_INSTANCE 0
#define BM_LPTMR_BASE LPTMR0_BASE
/*FUNCTION**********************************************************************
*
* Function Name : time_diff
* Description : This function gets the difference between two time stamp,
* time overflow is considered.
*
*END**************************************************************************/
static uint32_t time_diff(uint32_t time_start, uint32_t time_end)
{
if (time_end >= time_start)
{
return time_end - time_start;
}
else
{
/* lptmr count is 16 bits. */
return 0xFFFFU - time_start + time_end + 1;
}
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_SemaCreate
* Description : This function is used to create a semaphore. Return
* kStatus_OSA_Success if create successfully, otherwise return kStatus_OSA_Error.
*
*END**************************************************************************/
osa_status_t OSA_SemaCreate(semaphore_t *pSem, uint8_t initValue)
{
assert(pSem);
pSem->semCount = initValue;
pSem->isWaiting = false;
pSem->time_start = 0u;
pSem->timeout = 0u;
return kStatus_OSA_Success;
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_SemaWait
* Description : This function checks the semaphore's counting value, if it is
* positive, decreases it and returns kStatus_OSA_Success, otherwise, timeout
* will be used for wait. The parameter timeout indicates how long should wait
* in milliseconds. Pass OSA_WAIT_FOREVER to wait indefinitely, pass 0 will
* return kStatus_OSA_Timeout immediately if semaphore is not positive.
* This function returns kStatus_OSA_Success if the semaphore is received, returns
* kStatus_OSA_Timeout if the semaphore is not received within the specified
* 'timeout', returns kStatus_OSA_Error if any errors occur during waiting,
* returns kStatus_OSA_Idle if the semaphore is not available and 'timeout' is
* not exhausted, because wait functions should not block with bare metal.
*
*END**************************************************************************/
osa_status_t OSA_SemaWait(semaphore_t *pSem, uint32_t timeout)
{
uint32_t currentTime;
assert(pSem);
/* Check the sem count first. Deal with timeout only if not already set */
if (pSem->semCount)
{
INT_SYS_DisableIRQGlobal();
pSem->semCount --;
pSem->isWaiting = false;
INT_SYS_EnableIRQGlobal();
return kStatus_OSA_Success;
}
else
{
if (0 == timeout)
{
/* If timeout is 0 and semaphore is not available, return kStatus_OSA_Timeout. */
return kStatus_OSA_Timeout;
}
else if (pSem->isWaiting)
{
/* Check for timeout */
currentTime = OSA_TimeGetMsec();
if (pSem->timeout < time_diff(pSem->time_start, currentTime))
{
INT_SYS_DisableIRQGlobal();
pSem->isWaiting = false;
INT_SYS_EnableIRQGlobal();
return kStatus_OSA_Timeout;
}
}
else if (timeout != OSA_WAIT_FOREVER) /* If don't wait forever, start the timer */
{
/* Start the timeout counter */
INT_SYS_DisableIRQGlobal();
pSem->isWaiting = true;
INT_SYS_EnableIRQGlobal();
pSem->time_start = OSA_TimeGetMsec();
pSem->timeout = timeout;
}
}
return kStatus_OSA_Idle;
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_SemaPost
* Description : This function is used to wake up one task that wating on the
* semaphore. If no task is waiting, increase the semaphore. The function returns
* kStatus_OSA_Success if the semaphre is post successfully, otherwise returns
* kStatus_OSA_Error.
*
*END**************************************************************************/
osa_status_t OSA_SemaPost(semaphore_t *pSem)
{
assert(pSem);
/* The max value is 0xFF */
if (0xFF == pSem->semCount)
{
return kStatus_OSA_Error;
}
INT_SYS_DisableIRQGlobal();
++pSem->semCount;
INT_SYS_EnableIRQGlobal();
return kStatus_OSA_Success;
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_SemaDestroy
* Description : This function is used to destroy a semaphore.
* Return kStatus_OSA_Success if the semaphore is destroyed successfully, otherwise
* return kStatus_OSA_Error.
*
*END**************************************************************************/
osa_status_t OSA_SemaDestroy(semaphore_t *pSem)
{
assert(pSem);
return kStatus_OSA_Success;
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_MutexCreate
* Description : This function is used to create a mutex.
* Return kStatus_OSA_Success if create successfully, otherwise return kStatus_OSA_Error.
*
*END**************************************************************************/
osa_status_t OSA_MutexCreate(mutex_t *pMutex)
{
assert(pMutex);
pMutex->isLocked = false;
pMutex->isWaiting = false;
pMutex->time_start = 0u;
pMutex->timeout = 0u;
return kStatus_OSA_Success;
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_MutexLock
* Description : This function checks the mutex's status, if it is unlocked,
* lock it and returns kStatus_OSA_Success, otherwise, timeout will be used for
* wait. The parameter timeout indicates how long should wait in milliseconds.
* Pass OSA_WAIT_FOREVER to wait indefinitely, pass 0 will return the value
* kStatus_OSA_Timeout immediately if mutex is locked.
* This function returns kStatus_OSA_Success if the mutex is obtained, returns
* kStatus_OSA_Timeout if the mutex is not obtained within the specified
* 'timeout', returns kStatus_OSA_Error if any errors occur during waiting,
* returns kStatus_OSA_Idle if the mutex is not available and 'timeout' is
* not exhausted, because wait functions should not block with bare metal.
*
*END**************************************************************************/
osa_status_t OSA_MutexLock(mutex_t *pMutex, uint32_t timeout)
{
uint32_t currentTime;
assert(pMutex);
/* Always check first. Deal with timeout only if not available. */
if (pMutex->isLocked == false)
{
/* Get the lock and return success */
INT_SYS_DisableIRQGlobal();
pMutex->isLocked = true;
pMutex->isWaiting = false;
INT_SYS_EnableIRQGlobal();
return kStatus_OSA_Success;
}
else
{
if (0 == timeout)
{
/* If timeout is 0 and mutex is not available, return kStatus_OSA_Timeout. */
return kStatus_OSA_Timeout;
}
else if (pMutex->isWaiting)
{
/* Check for timeout */
currentTime = OSA_TimeGetMsec();
if (pMutex->timeout < time_diff(pMutex->time_start, currentTime))
{
INT_SYS_DisableIRQGlobal();
pMutex->isWaiting = false;
INT_SYS_EnableIRQGlobal();
return kStatus_OSA_Timeout;
}
}
else if (timeout != OSA_WAIT_FOREVER) /* If dont't wait forever, start timer. */
{
/* Start the timeout counter */
INT_SYS_DisableIRQGlobal();
pMutex->isWaiting = true;
INT_SYS_EnableIRQGlobal();
pMutex->time_start = OSA_TimeGetMsec();
pMutex->timeout = timeout;
}
}
return kStatus_OSA_Idle;
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_MutexUnlock
* Description : This function is used to unlock a mutex.
*
*END**************************************************************************/
osa_status_t OSA_MutexUnlock(mutex_t *pMutex)
{
assert(pMutex);
INT_SYS_DisableIRQGlobal();
pMutex->isLocked = false;
INT_SYS_EnableIRQGlobal();
return kStatus_OSA_Success;
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_MutexDestroy
* Description : This function is used to destroy a mutex.
* Return kStatus_OSA_Success if the lock object is destroyed successfully, otherwise
* return kStatus_OSA_Error.
*
*END**************************************************************************/
osa_status_t OSA_MutexDestroy(mutex_t *pMutex)
{
assert(pMutex);
return kStatus_OSA_Success;
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_EventCreate
* Description : This function is used to create a event object. Return
* kStatus_OSA_Success if create successfully, otherwise return kStatus_OSA_Error.
*
*END**************************************************************************/
osa_status_t OSA_EventCreate(event_t *pEvent, osa_event_clear_mode_t clearMode)
{
assert(pEvent);
pEvent->isWaiting = false;
pEvent->flags = 0;
pEvent->clearMode = clearMode;
pEvent->time_start = 0u;
pEvent->timeout = 0u;
return kStatus_OSA_Success;
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_EventWait
* Description : This function checks the event's status, if it meets the wait
* condition, return kStatus_OSA_Success, otherwise, timeout will be used for
* wait. The parameter timeout indicates how long should wait in milliseconds.
* Pass OSA_WAIT_FOREVER to wait indefinitely, pass 0 will return the value
* kStatus_OSA_Timeout immediately if wait condition is not met. The event flags
* will be cleared if the event is auto clear mode. Flags that wakeup waiting
* task could be obtained from the parameter setFlags.
* This function returns kStatus_OSA_Success if wait condition is met, returns
* kStatus_OSA_Timeout if wait condition is not met within the specified
* 'timeout', returns kStatus_OSA_Error if any errors occur during waiting,
* returns kStatus_OSA_Idle if wait condition is not met and 'timeout' is
* not exhausted, because wait functions should not block with bare metal.
*
*END**************************************************************************/
osa_status_t OSA_EventWait(event_t *pEvent,
event_flags_t flagsToWait,
bool waitAll,
uint32_t timeout,
event_flags_t *setFlags)
{
uint32_t currentTime;
assert(pEvent);
assert(setFlags);
osa_status_t retVal = kStatus_OSA_Idle;
*setFlags = pEvent->flags & flagsToWait;
/* Check the event flag first, if does not meet wait condition, deal with timeout. */
if ((((!waitAll) && (*setFlags))) || (*setFlags == flagsToWait))
{
INT_SYS_DisableIRQGlobal();
pEvent->isWaiting = false;
if(kEventAutoClear == pEvent->clearMode)
{
pEvent->flags &= ~flagsToWait;
}
INT_SYS_EnableIRQGlobal();
return kStatus_OSA_Success;
}
else
{
if (0 == timeout)
{
/* If timeout is 0 and wait condition is not met, return kStatus_OSA_Timeout. */
return kStatus_OSA_Timeout;
}
else if (pEvent->isWaiting)
{
/* Check for timeout */
currentTime = OSA_TimeGetMsec();
if (pEvent->timeout < time_diff(pEvent->time_start, currentTime))
{
INT_SYS_DisableIRQGlobal();
pEvent->isWaiting = false;
INT_SYS_EnableIRQGlobal();
retVal = kStatus_OSA_Timeout;
}
}
else if(timeout != OSA_WAIT_FOREVER) /* If no timeout, don't start the timer */
{
/* Start the timeout counter */
INT_SYS_DisableIRQGlobal();
pEvent->isWaiting = true;
INT_SYS_EnableIRQGlobal();
pEvent->time_start = OSA_TimeGetMsec();
pEvent->timeout = timeout;
}
}
return retVal;
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_EventSet
* Description : Set one or more event flags of an event object.
* Return kStatus_OSA_Success if set successfully, kStatus_OSA_Error if failed.
*
*END**************************************************************************/
osa_status_t OSA_EventSet(event_t *pEvent, event_flags_t flagsToSet)
{
assert(pEvent);
/* Set flags ensuring atomic operation */
INT_SYS_DisableIRQGlobal();
pEvent->flags |= flagsToSet;
INT_SYS_EnableIRQGlobal();
return kStatus_OSA_Success;
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_EventClear
* Description : Clear one or more event flags of an event object.
* Return kStatus_OSA_Success if clear successfully, kStatus_OSA_Error if failed.
*
*END**************************************************************************/
osa_status_t OSA_EventClear(event_t *pEvent, event_flags_t flagsToClear)
{
assert(pEvent);
/* Clear flags ensuring atomic operation */
INT_SYS_DisableIRQGlobal();
pEvent->flags &= ~flagsToClear;
INT_SYS_EnableIRQGlobal();
return kStatus_OSA_Success;
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_EventDestroy
* Description : This function is used to destroy a event object. Return
* kStatus_OSA_Success if the event object is destroyed successfully, otherwise
* return kStatus_OSA_Error.
*
*END**************************************************************************/
osa_status_t OSA_EventDestroy(event_t *pEvent)
{
assert(pEvent);
return kStatus_OSA_Success;
}
/* The task APIs are only available if TASK_MAX_NUM>0. */
#if (TASK_MAX_NUM > 0)
/* Global variales for task. */
static task_handler_t g_curTask; /* Current task. */
/*
* All task control blocks in g_taskControlBlockPool will be linked as a
* list, and the list is managed by the pointer g_freeTaskControlBlock.
*/
static task_control_block_t g_taskControlBlockPool[TASK_MAX_NUM];
/*
* Pointer to the free task control blocks. To create a task, we should get
* task control block from this pointer. When task is destroyed, the control
* block will be returned and managed by this pointer.
*/
static task_control_block_t *g_freeTaskControlBlock;
/* Head node of task list, all tasks will be linked to this head node. */
static task_control_block_t g_taskListHead;
/*FUNCTION**********************************************************************
*
* Function Name : task_init
* Description : This function is used to initialize bare metal's task system,
* it will prepare task control block pool and initialize corresponding
* structures. This function should be called before creating any tasks.
*
*END**************************************************************************/
void task_init(void)
{
int32_t i = TASK_MAX_NUM-1;
g_taskControlBlockPool[i].next = NULL;
while (i--)
{
/* Link all task control blocks to a list. */
g_taskControlBlockPool[i].next = &g_taskControlBlockPool[i+1];
}
g_freeTaskControlBlock = g_taskControlBlockPool;
/* Initialize task list. */
g_taskListHead.next = &g_taskListHead;
g_taskListHead.prev = &g_taskListHead;
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_TaskCreate
* Description : This function will register the task function and parameter
* to task list, so that the task functions can be called in turn. Return
* kStatus_OSA_Success if register successfully, otherwise return kStatus_OSA_Error;
*
*END**************************************************************************/
osa_status_t OSA_TaskCreate(task_t task,
uint8_t *name,
uint16_t stackSize,
task_stack_t *stackMem,
uint16_t priority,
task_param_t param,
bool usesFloat,
task_handler_t *handler)
{
task_control_block_t *p_newTaskControlBlock;
task_control_block_t *p_taskListTail;
if (!g_freeTaskControlBlock)
{
/* No more task control blocks can be got. */
return kStatus_OSA_Error;
}
else
{
/* Get new task control block from pool. */
p_newTaskControlBlock = g_freeTaskControlBlock;
g_freeTaskControlBlock = g_freeTaskControlBlock->next;
/* Set task entry and parameter.*/
p_newTaskControlBlock->p_func = task;
p_newTaskControlBlock->param = param;
/* Add p_newTaskControlBlock to the tail of task list. */
p_taskListTail = g_taskListHead.prev;
p_taskListTail->next = p_newTaskControlBlock;
p_newTaskControlBlock->next = &g_taskListHead;
g_taskListHead.prev = p_newTaskControlBlock;
p_newTaskControlBlock->prev = p_taskListTail;
/* Task handler is pointer of task control block. */
*handler = p_newTaskControlBlock;
return kStatus_OSA_Success;
}
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_TaskDestroy
* Description : This function will remove task control block from task list,
* so that the task functions will not called by anymore.
* Return kStatus_OSA_Success if successfully, otherwise return kStatus_OSA_Error;
*
*END**************************************************************************/
osa_status_t OSA_TaskDestroy(task_handler_t handler)
{
assert(handler);
/* Remove task control block from task list. */
handler->prev->next = handler->next;
handler->next->prev = handler->prev;
/*
* If current task is destroyed, then g_curTask will point to the previous
* task, so that the subsequent tasks could be called. Check the function
* OSA_Start for more details.
*/
if (handler == g_curTask)
{
g_curTask = handler->prev;
}
/* Put task control block back to pool. */
handler->prev = NULL;
handler->next = g_freeTaskControlBlock;
g_freeTaskControlBlock = handler;
return kStatus_OSA_Success;
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_TaskYield
* Description : This function is not implement with bare metal.
*
*END**************************************************************************/
osa_status_t OSA_TaskYield(void)
{
return kStatus_OSA_Success;
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_TaskGetHandler
* Description : This function is used to get current active task's handler.
*
*END**************************************************************************/
task_handler_t OSA_TaskGetHandler(void)
{
return g_curTask;
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_TaskGetPriority
* Description : This function is not implement with bare metal.
*
*END**************************************************************************/
uint16_t OSA_TaskGetPriority(task_handler_t handler)
{
return 0;
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_TaskSetPriority
* Description : This function is not implement with bare metal.
*
*END**************************************************************************/
osa_status_t OSA_TaskSetPriority(task_handler_t handler, uint16_t priority)
{
return kStatus_OSA_Success;
}
#endif
/*FUNCTION**********************************************************************
*
* Function Name : OSA_MsgQCreate
* Description : This function is used to create a message queue.
* Return the handle to the message queue if create successfully, otherwise
* return 0.
*
*END**************************************************************************/
msg_queue_handler_t OSA_MsgQCreate(msg_queue_t *queue,
uint16_t message_number,
uint16_t message_size)
{
assert(queue);
queue->number = message_number;
queue->size = message_size;
queue->head = 0;
queue->tail = 0;
queue->isEmpty = true;
if(kStatus_OSA_Success == OSA_SemaCreate(&queue->queueSem, 0))
{
return queue;
}
else
{
return NULL;
}
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_MsgQPut
* Description : This function is used to put a message to a message queue.
* Return kStatus_OSA_Success if the message is put successfully, otherwise
* return kStatus_OSA_Error.
*
*END**************************************************************************/
osa_status_t OSA_MsgQPut(msg_queue_handler_t handler, void* pMessage)
{
assert(handler);
uint32_t *from_ptr, *to_ptr;
uint16_t msgSize;
/* Check that there is room in the queue */
INT_SYS_DisableIRQGlobal();
if((handler->tail != handler->head) || (handler->isEmpty))
{
from_ptr = (uint32_t*)pMessage;
to_ptr = &handler->queueMem[handler->tail * handler->size];
/* Copy entire message into the queue, based on the size configured at creation */
msgSize = handler->size;
while(msgSize--)
{
*to_ptr++ = *from_ptr++;
}
/* Adjust tail pointer and wrap in case the end of the buffer is reached */
++handler->tail;
if(handler->tail == handler->number)
{
handler->tail = 0;
}
/* If queue was empty, clear the empty flag and signal that it is not empty anymore */
if(handler->isEmpty)
{
handler->isEmpty = false;
OSA_SemaPost(&handler->queueSem);
}
INT_SYS_EnableIRQGlobal();
return kStatus_OSA_Success;
}
else
{
INT_SYS_EnableIRQGlobal();
return kStatus_OSA_Error;
}
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_MsgQGet
* Description : This function checks the queue's status, if it is not empty,
* get message from it and return kStatus_OSA_Success, otherwise, timeout will
* be used for wait. The parameter timeout indicates how long should wait in
* milliseconds. Pass OSA_WAIT_FOREVER to wait indefinitely, pass 0 will return
* kStatus_OSA_Timeout immediately if queue is empty.
* This function returns kStatus_OSA_Success if message is got successfully,
* returns kStatus_OSA_Timeout if message queue is empty within the specified
* 'timeout', returns kStatus_OSA_Error if any errors occur during waiting,
* returns kStatus_OSA_Idle if message queue is empty and 'timeout' is
* not exhausted, because wait functions should not block with bare metal.
*
*END**************************************************************************/
osa_status_t OSA_MsgQGet(msg_queue_handler_t handler,
void *pMessage,
uint32_t timeout)
{
assert(handler);
osa_status_t retVal = kStatus_OSA_Error;
uint32_t *from_ptr, *to_ptr;
uint16_t msgSize;
INT_SYS_DisableIRQGlobal();
/* Check if the queue is not empty */
if(!handler->isEmpty)
{
from_ptr = &handler->queueMem[handler->head * handler->size];
to_ptr = (uint32_t*)(pMessage);
/* Copy entire message into the queue, based on the size configured at creation */
msgSize = handler->size;
while(msgSize--)
{
*to_ptr++ = *from_ptr++;
}
/* Adjust head pointer and wrap in case the end of the buffer is reached */
++handler->head;
if(handler->head == handler->number)
{
handler->head = 0;
}
/* If queue was empty, clear the empty flag and signal that it is not empty anymore */
if(handler->head == handler->tail)
{
handler->isEmpty = true;
/* Set semapohre to 0 because the queue is empty. */
(void)OSA_SemaWait(&handler->queueSem, 0);
}
INT_SYS_EnableIRQGlobal();
retVal = kStatus_OSA_Success;
}
else
{
INT_SYS_EnableIRQGlobal();
/* Wait for the semaphore if the queue was empty */
retVal = OSA_SemaWait(&handler->queueSem, timeout);
}
return retVal;
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_MsgQDestroy
* Description : This function is used to destroy the message queue.
* Return kStatus_OSA_Success if the message queue is destroyed successfully,
* otherwise return kStatus_OSA_Error.
*
*END**************************************************************************/
osa_status_t OSA_MsgQDestroy(msg_queue_handler_t handler)
{
assert(handler);
return OSA_SemaDestroy(&handler->queueSem);
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_MemAlloc
* Description : This function is used to allocate amount of memory in bytes.
* Return the pointer to the memory if success, otherwise return NULL;
*
*END**************************************************************************/
void * OSA_MemAlloc(size_t size)
{
return malloc(size);
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_MemAllocZero
* Description : This function is used to allocate amount of memory in bytes
* and initializes it to 0.
* Return the pointer to the memory if success, otherwise return NULL;
*
*END**************************************************************************/
void * OSA_MemAllocZero(size_t size)
{
return calloc(1, size);
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_MemFree
* Description : This function is used to free the memory previously allocated.
*
*END**************************************************************************/
osa_status_t OSA_MemFree(void *ptr)
{
free(ptr);
return kStatus_OSA_Success;
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_TimeDelay
* Description : This function is used to delay for a number of milliseconds.
*
*END**************************************************************************/
void OSA_TimeDelay(uint32_t delay)
{
uint32_t currTime, timeStart;
timeStart = OSA_TimeGetMsec();
do {
currTime = OSA_TimeGetMsec(); /* Get current time stamp */
} while (delay >= time_diff(timeStart, currTime));
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_TimeGetMsec
* Description : This function gets current time in milliseconds.
*
*END**************************************************************************/
uint32_t OSA_TimeGetMsec(void)
{
return LPTMR_HAL_GetCounterValue(BM_LPTMR_BASE);
}
/*FUNCTION**********************************************************************
*
* Function Name : interrupt_handler_register
* Description : This function is used to install interrupt handler.
* For bare metal, this function is empty.
*
*END**************************************************************************/
osa_status_t OSA_InstallIntHandler (int32_t IRQNumber,
void (*handler)(void))
{
INT_SYS_InstallHandler((IRQn_Type)IRQNumber, handler);
return kStatus_OSA_Success;
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_EnterCritical
* Description : This function is used to ensure some code will not be preempted.
*
*END**************************************************************************/
void OSA_EnterCritical(osa_critical_section_mode_t mode)
{
if (kCriticalDisableInt == mode)
{
INT_SYS_DisableIRQGlobal();
}
else
{
return;
}
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_ExitCritical
* Description : This function is used to exit critical section.
*
*END**************************************************************************/
void OSA_ExitCritical(osa_critical_section_mode_t mode)
{
if (kCriticalDisableInt == mode)
{
INT_SYS_EnableIRQGlobal();
}
else
{
return;
}
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_Init
* Description : This function is used to setup the basic services, it should
* be called first in function main. Return kStatus_OSA_Success if services
* are initialized successfully, otherwise return kStatus_OSA_Error.
*
*END**************************************************************************/
osa_status_t OSA_Init(void)
{
#if (TASK_MAX_NUM > 0)
task_init();
#endif
/*
* Setup LP Timer for timeout and delay.
* Use 1kHz LPO as clock source, disable prescaler, freerun mode.
*/
CLOCK_SYS_EnableLptimerClock(BM_LPTMR_INSTANCE);
LPTMR_HAL_SetTimerModeMode(BM_LPTMR_BASE, kLptmrTimerModeTimeCounter);
LPTMR_HAL_SetFreeRunningCmd(BM_LPTMR_BASE, true);
LPTMR_HAL_SetPrescalerCmd(BM_LPTMR_BASE, false);
LPTMR_HAL_SetPrescalerClockSourceMode(BM_LPTMR_BASE, kLptmrPrescalerClockSourceLpo);
LPTMR_HAL_SetIntCmd(BM_LPTMR_BASE,false);
LPTMR_HAL_Enable(BM_LPTMR_BASE);
return kStatus_OSA_Success;
}
/*FUNCTION**********************************************************************
*
* Function Name : OSA_Start
* Description : This function is used to start RTOS scheduler.
*
*END**************************************************************************/
osa_status_t OSA_Start(void)
{
#if (TASK_MAX_NUM > 0)
g_curTask = &g_taskListHead;
for(;;)
{
if (g_curTask->p_func)
{
g_curTask->p_func(g_curTask->param);
}
g_curTask = g_curTask->next;
}
#else
for(;;)
{
}
#endif
}
#if (TASK_MAX_NUM > 0)
/*FUNCTION**********************************************************************
*
* Function Name : OSA_PollAllOtherTasks
* Description : This function calls all task functions except current task
* one time. It is only for bare metal.
*
*END**************************************************************************/
void OSA_PollAllOtherTasks(void)
{
task_handler_t curTaskSave = g_curTask;
g_curTask = g_taskListHead.next;
while ((g_curTask->p_func) && (g_curTask!=curTaskSave))
{
g_curTask->p_func(g_curTask->param);
g_curTask = g_curTask->next;
}
g_curTask = curTaskSave;
}
#endif
/*******************************************************************************
* EOF
******************************************************************************/

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include "fsl_misc_utilities.h"
#if (defined(KEIL))
/*FUNCTION**********************************************************************
*
* Function Name : __aeabi_assert
* Description : called by assert in KEIL
* This function is called by the assert function in KEIL.
*
*END**************************************************************************/
void __aeabi_assert(const char *expr, const char *file, int line)
{
printf("assert failed:%s, file %s:%d\r\n",expr,file,line);
}
#elif (defined(KDS))
/*FUNCTION**********************************************************************
*
* Function Name : _isatty
* Description : used to enable the overwrite of the _write
* This function is used to enable the overwrite of the _write.
*
*END**************************************************************************/
int _isatty (int fd)
{
return 1;
}
#endif
/*******************************************************************************
* EOF
******************************************************************************/

View File

@ -1,191 +0,0 @@
/*
* Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if !defined(__SW_TIMER_H__)
#define __SW_TIMER_H__
#include <stdint.h>
#include <stdbool.h>
/*! @addtogroup sw_timer Software Timer
* @brief This module is used to interface with Abstract Timer HAL to generate periodical timeouts
* required through different modules of the AOA protocol. This block will be based on 1ms
* ticks for all the timeout calculations. The HAL Interface block used to communicate with
* this must have the same 1ms timeout configured. This module can generate different
* software timer channels based on the same 1ms.
*/
/*! @{*/
/*! Definition of the possible status of a software channel timer. */
typedef enum SwTimerChannelStatus
{
kSwTimerChannelExpired = 0x00, /*!< Indicates the timer channel has counted the given ms*/
kSwTimerChannelStillCounting = 0x01, /*!< Indicates the timeout of the channel has not expired
and the timer is still counting.*/
kSwTimerChannelIsDisable = 0x02, /*!< Indicates the timer channel is not reserved. */
kSwTimerChannelNotAvailable = 0xFF /*!< Indicates there are not available channels to reserve
or the requested channel is not available.*/
}sw_timer_channel_status_t;
/*! List of status and errors. */
enum _sw_timer_errors
{
kSwTimerStatusSuccess, /*!< The execution was successful.*/
kSwTimerStatusFail, /*!< The execution failed.*/
kSwTimerStatusInvalidChannel /*!< The given channel is not valid. Valid channels are 0 to
(SW_TIMER_NUMBER_CHANNELS - 1). */
};
/*!
* Data type of the counter of each timer channel. If it is an int8_t the counter will count
* up to 127ms, int16_t up to 32767ms and int32_t up to 2147483647ms.
*/
typedef int32_t time_counter_t;
/*! Max timeout value according to size of the time counter */
enum sw_timer_timeouts
{
kSwTimerMaxTimeout = 2147483647
};
/*!
* Data type of the free running counter. This data type should be unsigned and will count up to
* 255ms if it is uint8_t, 65535ms for uint16_t and 4294967295ms for uint32_t.
*/
typedef uint32_t time_free_counter_t;
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus*/
/*!
* @brief Initializes the software timer module. Prepares variables and HAL layer to provide timer
* services. Starts the free running counter which will be available to get its value any
* time while the service is running; it is useful whenever a module wants to keep track of
* time, but do not wants to reserve a channel.
*
* @return status_t Returns software timer status after initialization.
* @retval kSwTimerStatusSuccess The initialization was successful and the software timer is ready
* to provide services.
* @retval kSwTimerStatusFail The initialization failed.
*/
uint32_t sw_timer_init_service(void);
/*!
* @brief Deinitializes the software timer module. Shutdown HAL layer, so no timer service can be
* provided after the execution of this function.
*
* @return void
*/
void sw_timer_shutdown_service(void);
/*!
* @brief Reserves a free timer channel to be used by any module and returns its identifier.
*
* @return uint8_t Returns the number of the channel that was reserved.
* @retval Any value between 0 and SW_TIMER_NUMBER_CHANNELS is a valid channel. It indicates the
* channel was reserved and can be used.
* @retval kSwTimerChannelNotAvailable If there is not any available channel, because all
* channels are already reserved.
*/
uint8_t sw_timer_reserve_channel(void);
/*!
* @brief Returns the actual status of the given timer channel. The timer has to be previously
* started to return a valid status.
*
* @param timerChannel [in] Indicates the timer channel which status is going to be returned.
*
* @return sw_timer_channel_status_t Current status of the given timer channel.
* @retval kSwTimerChannelExpired Indicates the timer channel has counted the given ms.
* @retval kSwTimerChannelStillCounting Indicates the timeout of the channel has not expired and
the timer is still counting.
* @retval kSwTimerChannelIsDisable Indicates the timer channel is not reserved.
* @retval kSwTimerChannelNotAvailable Indicates the timer channel is invalid.
*/
sw_timer_channel_status_t sw_timer_get_channel_status(uint8_t timerChannel);
/*!
* @brief Starts the count down of the given timer channel. The timer channel has to be previously
* reserved.
*
* @param timerChannel [in] Indicates the timer channel that is going to be started.
* @param timeout [in] Time in ms that the timer channel will count. The timeout should be
a multiple of count unit of the timer, otherwise it will be taken
the integer part of the division and the exact count will not be
achieved
*
* @return status_t Reports failures in the execution of the function.
* @retval kSwTimerStatusSuccess A channel was started successfully.
* @retval kSwTimerStatusInvalidChannel The timer channel is invalid, it does not exist.
*/
uint32_t sw_timer_start_channel(uint8_t timerChannel, time_counter_t timeout);
/*!
* @brief Releases the given timer channel, so it can be used by someone else.
*
* @param timerChannel [in] Identifier of the timer channel.
*
* @return status_t Reports failures in the execution of the function.
* @retval kSwTimerStatusSuccess A channel was released successfully.
* @retval kSwTimerStatusInvalidChannel The timer channel is invalid, it does not exist.
*/
uint32_t sw_timer_release_channel(uint8_t timerChannel);
/*!
* @brief Gets the current value of the free running counter. Any module can keep track of the time
* by reading this counter and calculates time difference. No reservation of timer channel
* is needed. Consider for calculations that when the counter overflows it will start from
* 0 again.
*
* @return time_free_counter_t Returns current count of the free running counter.
*/
time_free_counter_t sw_timer_get_free_counter(void);
/*!
* @brief This function is called every 1ms by the interruption and update count down values of all
* timer channels.
*
* @return void
*/
void sw_timer_update_counters(void);
#if defined(__cplusplus)
}
#endif /* __cplusplus*/
/*! @}*/
/*Group sw_timer*/
#endif /* __SW_TIMER_H__ */
/*******************************************************************************
* EOF
******************************************************************************/