1253 lines
45 KiB
C
1253 lines
45 KiB
C
/*! *********************************************************************************
|
|
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
|
* Copyright 2016-2017, 2019 NXP
|
|
* All rights reserved.
|
|
*
|
|
*
|
|
* This is the source file for the OS Abstraction layer for freertos.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
********************************************************************************** */
|
|
|
|
/*! *********************************************************************************
|
|
*************************************************************************************
|
|
* Include
|
|
*************************************************************************************
|
|
********************************************************************************** */
|
|
#include "fsl_common.h"
|
|
#include "fsl_os_abstraction.h"
|
|
#include "fsl_os_abstraction_free_rtos.h"
|
|
#include <string.h>
|
|
#include "fsl_component_generic_list.h"
|
|
|
|
/*! *********************************************************************************
|
|
*************************************************************************************
|
|
* Private macros
|
|
*************************************************************************************
|
|
********************************************************************************** */
|
|
|
|
/* Weak function. */
|
|
#if defined(__GNUC__)
|
|
#define __WEAK_FUNC __attribute__((weak))
|
|
#elif defined(__ICCARM__)
|
|
#define __WEAK_FUNC __weak
|
|
#elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
|
|
#define __WEAK_FUNC __attribute__((weak))
|
|
#endif
|
|
|
|
#define millisecToTicks(millisec) (((millisec)*configTICK_RATE_HZ + 999U) / 1000U)
|
|
|
|
#ifdef DEBUG_ASSERT
|
|
#define OS_ASSERT(condition) \
|
|
if (!(condition)) \
|
|
while (1) \
|
|
;
|
|
#else
|
|
#define OS_ASSERT(condition) (void)(condition);
|
|
#endif
|
|
|
|
/*! @brief Converts milliseconds to ticks*/
|
|
#define MSEC_TO_TICK(msec) \
|
|
(((uint32_t)(msec) + 500uL / (uint32_t)configTICK_RATE_HZ) * (uint32_t)configTICK_RATE_HZ / 1000uL)
|
|
#define TICKS_TO_MSEC(tick) ((uint32_t)((uint64_t)(tick)*1000uL / (uint64_t)configTICK_RATE_HZ))
|
|
/************************************************************************************
|
|
*************************************************************************************
|
|
* Private type definitions
|
|
*************************************************************************************
|
|
************************************************************************************/
|
|
typedef struct osa_freertos_task
|
|
{
|
|
list_element_t link;
|
|
TaskHandle_t taskHandle;
|
|
} osa_freertos_task_t;
|
|
|
|
typedef struct _osa_event_struct
|
|
{
|
|
EventGroupHandle_t handle; /* The event handle */
|
|
uint8_t autoClear; /*!< Auto clear or manual clear */
|
|
} osa_event_struct_t;
|
|
|
|
/*! @brief State structure for bm osa manager. */
|
|
typedef struct _osa_state
|
|
{
|
|
#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
|
|
list_label_t taskList;
|
|
#if (defined(FSL_OSA_MAIN_FUNC_ENABLE) && (FSL_OSA_MAIN_FUNC_ENABLE > 0U))
|
|
OSA_TASK_HANDLE_DEFINE(mainTaskHandle);
|
|
#endif
|
|
#endif
|
|
uint32_t basePriority;
|
|
int32_t basePriorityNesting;
|
|
uint32_t interruptDisableCount;
|
|
} osa_state_t;
|
|
|
|
/*! *********************************************************************************
|
|
*************************************************************************************
|
|
* Private prototypes
|
|
*************************************************************************************
|
|
********************************************************************************** */
|
|
__WEAK_FUNC void main_task(void const *argument);
|
|
__WEAK_FUNC void main_task(void const *argument)
|
|
{
|
|
}
|
|
|
|
void startup_task(void *argument);
|
|
|
|
/*! *********************************************************************************
|
|
*************************************************************************************
|
|
* Public memory declarations
|
|
*************************************************************************************
|
|
********************************************************************************** */
|
|
const uint8_t gUseRtos_c = USE_RTOS; /* USE_RTOS = 0 for BareMetal and 1 for OS */
|
|
|
|
static osa_state_t s_osaState = {0};
|
|
/*! *********************************************************************************
|
|
*************************************************************************************
|
|
* Private memory declarations
|
|
*************************************************************************************
|
|
********************************************************************************** */
|
|
|
|
/*! *********************************************************************************
|
|
*************************************************************************************
|
|
* Public functions
|
|
*************************************************************************************
|
|
********************************************************************************** */
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_MemoryAllocate
|
|
* Description : Reserves the requested amount of memory in bytes.
|
|
*
|
|
*END**************************************************************************/
|
|
void *OSA_MemoryAllocate(uint32_t memLength)
|
|
{
|
|
void *p = (void *)pvPortMalloc(memLength);
|
|
|
|
if (NULL != p)
|
|
{
|
|
(void)memset(p, 0, memLength);
|
|
}
|
|
|
|
return p;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_MemoryFree
|
|
* Description : Frees the memory previously reserved.
|
|
*
|
|
*END**************************************************************************/
|
|
void OSA_MemoryFree(void *p)
|
|
{
|
|
vPortFree(p);
|
|
}
|
|
|
|
void OSA_EnterCritical(uint32_t *sr)
|
|
{
|
|
#if defined(__GIC_PRIO_BITS)
|
|
if ((__get_CPSR() & CPSR_M_Msk) == 0x13)
|
|
#else
|
|
if (0U != __get_IPSR())
|
|
#endif
|
|
{
|
|
*sr = portSET_INTERRUPT_MASK_FROM_ISR();
|
|
}
|
|
else
|
|
{
|
|
portENTER_CRITICAL();
|
|
}
|
|
}
|
|
|
|
void OSA_ExitCritical(uint32_t sr)
|
|
{
|
|
#if defined(__GIC_PRIO_BITS)
|
|
if ((__get_CPSR() & CPSR_M_Msk) == 0x13)
|
|
#else
|
|
if (0U != __get_IPSR())
|
|
#endif
|
|
{
|
|
portCLEAR_INTERRUPT_MASK_FROM_ISR(sr);
|
|
}
|
|
else
|
|
{
|
|
portEXIT_CRITICAL();
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : startup_task
|
|
* Description : Wrapper over main_task..
|
|
*
|
|
*END**************************************************************************/
|
|
void startup_task(void *argument)
|
|
{
|
|
main_task(argument);
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_TaskGetCurrentHandle
|
|
* Description : This function is used to get current active task's handler.
|
|
*
|
|
*END**************************************************************************/
|
|
#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
|
|
osa_task_handle_t OSA_TaskGetCurrentHandle(void)
|
|
{
|
|
list_element_handle_t list_element;
|
|
osa_freertos_task_t *ptask;
|
|
|
|
list_element = LIST_GetHead(&s_osaState.taskList);
|
|
while (NULL != list_element)
|
|
{
|
|
ptask = (osa_freertos_task_t *)(void *)list_element;
|
|
if (ptask->taskHandle == xTaskGetCurrentTaskHandle())
|
|
{
|
|
return (osa_task_handle_t)ptask;
|
|
}
|
|
list_element = LIST_GetNext(list_element);
|
|
}
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_TaskYield
|
|
* Description : When a task calls this function, it will give up CPU and put
|
|
* itself to the tail of ready list.
|
|
*
|
|
*END**************************************************************************/
|
|
#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
|
|
void OSA_TaskYield(void)
|
|
{
|
|
taskYIELD();
|
|
}
|
|
#endif
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_TaskGetPriority
|
|
* Description : This function returns task's priority by task handler.
|
|
*
|
|
*END**************************************************************************/
|
|
#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
|
|
osa_task_priority_t OSA_TaskGetPriority(osa_task_handle_t taskHandle)
|
|
{
|
|
assert(NULL != taskHandle);
|
|
osa_freertos_task_t *ptask = (osa_freertos_task_t *)taskHandle;
|
|
return (osa_task_priority_t)(PRIORITY_RTOS_TO_OSA((uxTaskPriorityGet(ptask->taskHandle))));
|
|
}
|
|
#endif
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_TaskSetPriority
|
|
* Description : This function sets task's priority by task handler.
|
|
*
|
|
*END**************************************************************************/
|
|
#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
|
|
osa_status_t OSA_TaskSetPriority(osa_task_handle_t taskHandle, osa_task_priority_t taskPriority)
|
|
{
|
|
assert(NULL != taskHandle);
|
|
osa_freertos_task_t *ptask = (osa_freertos_task_t *)taskHandle;
|
|
vTaskPrioritySet((task_handler_t)ptask->taskHandle, PRIORITY_OSA_TO_RTOS(((uint32_t)taskPriority)));
|
|
return KOSA_StatusSuccess;
|
|
}
|
|
#endif
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_TaskCreate
|
|
* Description : This function is used to create a task and make it ready.
|
|
* Param[in] : threadDef - Definition of the thread.
|
|
* task_param - Parameter to pass to the new thread.
|
|
* Return Thread handle of the new thread, or NULL if failed.
|
|
*
|
|
*END**************************************************************************/
|
|
#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
|
|
osa_status_t OSA_TaskCreate(osa_task_handle_t taskHandle, const osa_task_def_t *thread_def, osa_task_param_t task_param)
|
|
{
|
|
osa_status_t status = KOSA_StatusError;
|
|
#if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
|
|
!((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
|
|
assert((sizeof(osa_freertos_task_t) + sizeof(StaticTask_t)) <= OSA_TASK_HANDLE_SIZE);
|
|
#else
|
|
assert(sizeof(osa_freertos_task_t) == OSA_TASK_HANDLE_SIZE);
|
|
#endif
|
|
assert(NULL != taskHandle);
|
|
#if defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0)
|
|
TaskHandle_t pxCreatedTask;
|
|
#endif
|
|
osa_freertos_task_t *ptask = (osa_freertos_task_t *)taskHandle;
|
|
#if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
|
|
!((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
|
|
TaskHandle_t xHandle = NULL;
|
|
#endif
|
|
OSA_InterruptDisable();
|
|
#if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
|
|
!((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
|
|
xHandle = xTaskCreateStatic(
|
|
(TaskFunction_t)thread_def->pthread, /* pointer to the task */
|
|
(const char *)thread_def->tname, /* task name for kernel awareness debugging */
|
|
(uint32_t)((uint16_t)thread_def->stacksize / sizeof(portSTACK_TYPE)), /* task stack size */
|
|
(task_param_t)task_param, /* optional task startup argument */
|
|
PRIORITY_OSA_TO_RTOS((thread_def->tpriority)), /* initial priority */
|
|
thread_def->tstack, /*Array to use as the task's stack*/
|
|
(StaticTask_t *)((uint8_t *)(taskHandle) + sizeof(osa_freertos_task_t))/*Variable to hold the task's data structure*/
|
|
);
|
|
if(xHandle != NULL)
|
|
{
|
|
ptask->taskHandle = xHandle;
|
|
(void)LIST_AddTail(&s_osaState.taskList, (list_element_handle_t) & (ptask->link));
|
|
status = KOSA_StatusSuccess;
|
|
}
|
|
#else
|
|
if (xTaskCreate(
|
|
(TaskFunction_t)thread_def->pthread, /* pointer to the task */
|
|
(char const *)thread_def->tname, /* task name for kernel awareness debugging */
|
|
(configSTACK_DEPTH_TYPE)((uint16_t)thread_def->stacksize / sizeof(portSTACK_TYPE)), /* task stack size */
|
|
(task_param_t)task_param, /* optional task startup argument */
|
|
PRIORITY_OSA_TO_RTOS((thread_def->tpriority)), /* initial priority */
|
|
&pxCreatedTask /* optional task handle to create */
|
|
) == pdPASS)
|
|
{
|
|
ptask->taskHandle = pxCreatedTask;
|
|
|
|
(void)LIST_AddTail(&s_osaState.taskList, (list_element_handle_t) & (ptask->link));
|
|
|
|
status = KOSA_StatusSuccess;
|
|
}
|
|
#endif
|
|
OSA_InterruptEnable();
|
|
return status;
|
|
}
|
|
#endif
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_TaskDestroy
|
|
* Description : This function destroy a task.
|
|
* Param[in] :taskHandle - Thread handle.
|
|
* Return KOSA_StatusSuccess if the task is destroied, otherwise return KOSA_StatusError.
|
|
*
|
|
*END**************************************************************************/
|
|
#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
|
|
osa_status_t OSA_TaskDestroy(osa_task_handle_t taskHandle)
|
|
{
|
|
assert(NULL != taskHandle);
|
|
osa_freertos_task_t *ptask = (osa_freertos_task_t *)taskHandle;
|
|
osa_status_t status;
|
|
UBaseType_t oldPriority;
|
|
|
|
/*Change priority to avoid context switches*/
|
|
oldPriority = uxTaskPriorityGet(xTaskGetCurrentTaskHandle());
|
|
vTaskPrioritySet(xTaskGetCurrentTaskHandle(), (configMAX_PRIORITIES - 1));
|
|
#if INCLUDE_vTaskDelete /* vTaskDelete() enabled */
|
|
vTaskDelete((task_handler_t)ptask->taskHandle);
|
|
status = KOSA_StatusSuccess;
|
|
#else
|
|
status = KOSA_StatusError; /* vTaskDelete() not available */
|
|
#endif
|
|
vTaskPrioritySet(xTaskGetCurrentTaskHandle(), oldPriority);
|
|
OSA_InterruptDisable();
|
|
(void)LIST_RemoveElement(taskHandle);
|
|
OSA_InterruptEnable();
|
|
return status;
|
|
}
|
|
#endif
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_TimeDelay
|
|
* Description : This function is used to suspend the active thread for the given number of milliseconds.
|
|
*
|
|
*END**************************************************************************/
|
|
void OSA_TimeDelay(uint32_t millisec)
|
|
{
|
|
vTaskDelay(millisecToTicks(millisec));
|
|
}
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_TimeGetMsec
|
|
* Description : This function gets current time in milliseconds.
|
|
*
|
|
*END**************************************************************************/
|
|
uint32_t OSA_TimeGetMsec(void)
|
|
{
|
|
TickType_t ticks;
|
|
|
|
if (0U != __get_IPSR())
|
|
{
|
|
ticks = xTaskGetTickCountFromISR();
|
|
}
|
|
else
|
|
{
|
|
ticks = xTaskGetTickCount();
|
|
}
|
|
|
|
return TICKS_TO_MSEC(ticks);
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_SemaphorePrecreate
|
|
* Description : This function is used to pre-create a semaphore.
|
|
* Return : KOSA_StatusSuccess
|
|
*
|
|
*END**************************************************************************/
|
|
|
|
osa_status_t OSA_SemaphorePrecreate(osa_semaphore_handle_t semaphoreHandle, osa_task_ptr_t taskHandler)
|
|
{
|
|
semaphoreHandle = semaphoreHandle;
|
|
taskHandler = taskHandler;
|
|
return KOSA_StatusSuccess;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_SemaphoreCreate
|
|
* Description : This function is used to create a semaphore.
|
|
* Return : Semaphore handle of the new semaphore, or NULL if failed.
|
|
*
|
|
*END**************************************************************************/
|
|
osa_status_t OSA_SemaphoreCreate(osa_semaphore_handle_t semaphoreHandle, uint32_t initValue)
|
|
{
|
|
#if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
|
|
!((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
|
|
assert((sizeof(osa_semaphore_handle_t) + sizeof(StaticQueue_t)) == OSA_SEM_HANDLE_SIZE);
|
|
#else
|
|
assert(sizeof(osa_semaphore_handle_t) == OSA_SEM_HANDLE_SIZE);
|
|
#endif
|
|
assert(NULL != semaphoreHandle);
|
|
|
|
union
|
|
{
|
|
QueueHandle_t sem;
|
|
uint32_t semhandle;
|
|
} xSemaHandle;
|
|
#if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
|
|
!((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
|
|
xSemaHandle.sem = xSemaphoreCreateCountingStatic(0xFF, initValue, (StaticQueue_t *)(void *)((uint8_t *)semaphoreHandle + sizeof(osa_semaphore_handle_t)));
|
|
#else
|
|
xSemaHandle.sem = xSemaphoreCreateCounting(0xFF, initValue);
|
|
#endif
|
|
if (NULL != xSemaHandle.sem)
|
|
{
|
|
*(uint32_t *)semaphoreHandle = xSemaHandle.semhandle;
|
|
return KOSA_StatusSuccess;
|
|
}
|
|
return KOSA_StatusError;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_SemaphoreCreateBinary
|
|
* Description : This function is used to create a binary semaphore.
|
|
* Return : Semaphore handle of the new binary semaphore, or NULL if failed.
|
|
*
|
|
*END**************************************************************************/
|
|
osa_status_t OSA_SemaphoreCreateBinary(osa_semaphore_handle_t semaphoreHandle)
|
|
{
|
|
#if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
|
|
!((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
|
|
assert((sizeof(osa_semaphore_handle_t) + sizeof(StaticQueue_t)) == OSA_SEM_HANDLE_SIZE);
|
|
#else
|
|
assert(sizeof(osa_semaphore_handle_t) == OSA_SEM_HANDLE_SIZE);
|
|
#endif
|
|
assert(NULL != semaphoreHandle);
|
|
|
|
union
|
|
{
|
|
QueueHandle_t sem;
|
|
uint32_t semhandle;
|
|
} xSemaHandle;
|
|
#if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
|
|
!((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
|
|
xSemaHandle.sem = xSemaphoreCreateBinaryStatic((StaticQueue_t *)(void *)((uint8_t *)semaphoreHandle + sizeof(osa_semaphore_handle_t)));
|
|
#else
|
|
xSemaHandle.sem = xSemaphoreCreateBinary();
|
|
#endif
|
|
if (NULL != xSemaHandle.sem)
|
|
{
|
|
*(uint32_t *)semaphoreHandle = xSemaHandle.semhandle;
|
|
return KOSA_StatusSuccess;
|
|
}
|
|
return KOSA_StatusError;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_SemaphoreDestroy
|
|
* Description : This function is used to destroy a semaphore.
|
|
* Return : KOSA_StatusSuccess if the semaphore is destroyed successfully, otherwise return KOSA_StatusError.
|
|
*
|
|
*END**************************************************************************/
|
|
osa_status_t OSA_SemaphoreDestroy(osa_semaphore_handle_t semaphoreHandle)
|
|
{
|
|
assert(NULL != semaphoreHandle);
|
|
QueueHandle_t sem = (QueueHandle_t)(void *)(uint32_t *)(*(uint32_t *)semaphoreHandle);
|
|
|
|
vSemaphoreDelete(sem);
|
|
return KOSA_StatusSuccess;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_SemaphoreWait
|
|
* Description : This function checks the semaphore's counting value, if it is
|
|
* positive, decreases it and returns KOSA_StatusSuccess, otherwise, timeout
|
|
* will be used for wait. The parameter timeout indicates how long should wait
|
|
* in milliseconds. Pass osaWaitForever_c to wait indefinitely, pass 0 will
|
|
* return KOSA_StatusTimeout immediately if semaphore is not positive.
|
|
* This function returns KOSA_StatusSuccess if the semaphore is received, returns
|
|
* KOSA_StatusTimeout if the semaphore is not received within the specified
|
|
* 'timeout', returns KOSA_StatusError if any errors occur during waiting.
|
|
*
|
|
*END**************************************************************************/
|
|
osa_status_t OSA_SemaphoreWait(osa_semaphore_handle_t semaphoreHandle, uint32_t millisec)
|
|
{
|
|
uint32_t timeoutTicks;
|
|
assert(NULL != semaphoreHandle);
|
|
QueueHandle_t sem = (QueueHandle_t)(void *)(uint32_t *)(*(uint32_t *)semaphoreHandle);
|
|
|
|
/* Convert timeout from millisecond to tick. */
|
|
if (millisec == osaWaitForever_c)
|
|
{
|
|
timeoutTicks = portMAX_DELAY;
|
|
}
|
|
else
|
|
{
|
|
timeoutTicks = MSEC_TO_TICK(millisec);
|
|
}
|
|
|
|
if (((BaseType_t)0) == (BaseType_t)xSemaphoreTake(sem, timeoutTicks))
|
|
{
|
|
return KOSA_StatusTimeout; /* timeout */
|
|
}
|
|
else
|
|
{
|
|
return KOSA_StatusSuccess; /* semaphore taken */
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_SemaphorePost
|
|
* 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
|
|
* KOSA_StatusSuccess if the semaphre is post successfully, otherwise returns
|
|
* KOSA_StatusError.
|
|
*
|
|
*END**************************************************************************/
|
|
osa_status_t OSA_SemaphorePost(osa_semaphore_handle_t semaphoreHandle)
|
|
{
|
|
assert(NULL != semaphoreHandle);
|
|
osa_status_t status = KOSA_StatusError;
|
|
QueueHandle_t sem = (QueueHandle_t)(void *)(uint32_t *)(*(uint32_t *)semaphoreHandle);
|
|
|
|
if (0U != __get_IPSR())
|
|
{
|
|
portBASE_TYPE taskToWake = (portBASE_TYPE)pdFALSE;
|
|
|
|
if (((BaseType_t)1) == (BaseType_t)xSemaphoreGiveFromISR(sem, &taskToWake))
|
|
{
|
|
portYIELD_FROM_ISR(((bool)(taskToWake)));
|
|
status = KOSA_StatusSuccess;
|
|
}
|
|
else
|
|
{
|
|
status = KOSA_StatusError;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (((BaseType_t)1) == (BaseType_t)xSemaphoreGive(sem))
|
|
{
|
|
status = KOSA_StatusSuccess; /* sync object given */
|
|
}
|
|
else
|
|
{
|
|
status = KOSA_StatusError;
|
|
}
|
|
}
|
|
return status;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_MutexCreate
|
|
* Description : This function is used to create a mutex.
|
|
* Return : Mutex handle of the new mutex, or NULL if failed.
|
|
*
|
|
*END**************************************************************************/
|
|
osa_status_t OSA_MutexCreate(osa_mutex_handle_t mutexHandle)
|
|
{
|
|
#if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
|
|
!((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
|
|
assert((sizeof(osa_mutex_handle_t) + sizeof(StaticQueue_t)) == OSA_MUTEX_HANDLE_SIZE);
|
|
#else
|
|
assert(sizeof(osa_mutex_handle_t) == OSA_MUTEX_HANDLE_SIZE);
|
|
#endif
|
|
assert(NULL != mutexHandle);
|
|
|
|
union
|
|
{
|
|
QueueHandle_t mutex;
|
|
uint32_t pmutexHandle;
|
|
} xMutexHandle;
|
|
#if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
|
|
!((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
|
|
xMutexHandle.mutex = xSemaphoreCreateRecursiveMutexStatic((StaticQueue_t *)(void *)((uint8_t *)mutexHandle + sizeof(osa_mutex_handle_t)));
|
|
#else
|
|
xMutexHandle.mutex = xSemaphoreCreateRecursiveMutex();
|
|
#endif
|
|
if (NULL != xMutexHandle.mutex)
|
|
{
|
|
*(uint32_t *)mutexHandle = xMutexHandle.pmutexHandle;
|
|
return KOSA_StatusSuccess;
|
|
}
|
|
return KOSA_StatusError;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_MutexLock
|
|
* Description : This function checks the mutex's status, if it is unlocked,
|
|
* lock it and returns KOSA_StatusSuccess, otherwise, wait for the mutex.
|
|
* This function returns KOSA_StatusSuccess if the mutex is obtained, returns
|
|
* KOSA_StatusError if any errors occur during waiting. If the mutex has been
|
|
* locked, pass 0 as timeout will return KOSA_StatusTimeout immediately.
|
|
*
|
|
*END**************************************************************************/
|
|
osa_status_t OSA_MutexLock(osa_mutex_handle_t mutexHandle, uint32_t millisec)
|
|
{
|
|
assert(NULL != mutexHandle);
|
|
uint32_t timeoutTicks;
|
|
QueueHandle_t mutex = (QueueHandle_t)(void *)(uint32_t *)(*(uint32_t *)mutexHandle);
|
|
|
|
/* Convert timeout from millisecond to tick. */
|
|
if (millisec == osaWaitForever_c)
|
|
{
|
|
timeoutTicks = portMAX_DELAY;
|
|
}
|
|
else
|
|
{
|
|
timeoutTicks = MSEC_TO_TICK(millisec);
|
|
}
|
|
|
|
if (((BaseType_t)0) == (BaseType_t)xSemaphoreTakeRecursive(mutex, timeoutTicks))
|
|
{
|
|
return KOSA_StatusTimeout; /* timeout */
|
|
}
|
|
else
|
|
{
|
|
return KOSA_StatusSuccess; /* semaphore taken */
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_MutexUnlock
|
|
* Description : This function is used to unlock a mutex.
|
|
*
|
|
*END**************************************************************************/
|
|
osa_status_t OSA_MutexUnlock(osa_mutex_handle_t mutexHandle)
|
|
{
|
|
assert(NULL != mutexHandle);
|
|
QueueHandle_t mutex = (QueueHandle_t)(void *)(uint32_t *)(*(uint32_t *)mutexHandle);
|
|
|
|
if (((BaseType_t)0) == (BaseType_t)xSemaphoreGiveRecursive(mutex))
|
|
{
|
|
return KOSA_StatusError;
|
|
}
|
|
else
|
|
{
|
|
return KOSA_StatusSuccess;
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_MutexDestroy
|
|
* Description : This function is used to destroy a mutex.
|
|
* Return : KOSA_StatusSuccess if the lock object is destroyed successfully, otherwise return KOSA_StatusError.
|
|
*
|
|
*END**************************************************************************/
|
|
osa_status_t OSA_MutexDestroy(osa_mutex_handle_t mutexHandle)
|
|
{
|
|
assert(NULL != mutexHandle);
|
|
QueueHandle_t mutex = (QueueHandle_t)(void *)(uint32_t *)(*(uint32_t *)mutexHandle);
|
|
|
|
vSemaphoreDelete(mutex);
|
|
return KOSA_StatusSuccess;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_EventPrecreate
|
|
* Description : This function is used to pre-create a event.
|
|
* Return : KOSA_StatusSuccess
|
|
*
|
|
*END**************************************************************************/
|
|
|
|
osa_status_t OSA_EventPrecreate(osa_event_handle_t eventHandle, osa_task_ptr_t taskHandler)
|
|
{
|
|
eventHandle = eventHandle;
|
|
taskHandler = taskHandler;
|
|
return KOSA_StatusSuccess;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_EventCreate
|
|
* Description : This function is used to create a event object.
|
|
* Return : Event handle of the new event, or NULL if failed.
|
|
*
|
|
*END**************************************************************************/
|
|
osa_status_t OSA_EventCreate(osa_event_handle_t eventHandle, uint8_t autoClear)
|
|
{
|
|
assert(NULL != eventHandle);
|
|
#if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
|
|
!((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
|
|
assert((sizeof(osa_event_struct_t) + sizeof(StaticEventGroup_t)) <= OSA_EVENT_HANDLE_SIZE);
|
|
#else
|
|
assert(sizeof(osa_event_struct_t) == OSA_EVENT_HANDLE_SIZE);
|
|
#endif
|
|
osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
|
|
|
|
#if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
|
|
!((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
|
|
pEventStruct->handle = xEventGroupCreateStatic((StaticEventGroup_t *)(void *)((uint8_t *)(eventHandle) + sizeof(osa_event_struct_t)));
|
|
#else
|
|
pEventStruct->handle = xEventGroupCreate();
|
|
#endif
|
|
if (NULL != pEventStruct->handle)
|
|
{
|
|
pEventStruct->autoClear = autoClear;
|
|
}
|
|
else
|
|
{
|
|
return KOSA_StatusError;
|
|
}
|
|
return KOSA_StatusSuccess;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_EventSet
|
|
* Description : Set one or more event flags of an event object.
|
|
* Return : KOSA_StatusSuccess if set successfully, KOSA_StatusError if failed.
|
|
*
|
|
*END**************************************************************************/
|
|
osa_status_t OSA_EventSet(osa_event_handle_t eventHandle, osa_event_flags_t flagsToSet)
|
|
{
|
|
portBASE_TYPE taskToWake = (portBASE_TYPE)pdFALSE;
|
|
BaseType_t result;
|
|
assert(NULL != eventHandle);
|
|
osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
|
|
|
|
if (NULL == pEventStruct->handle)
|
|
{
|
|
return KOSA_StatusError;
|
|
}
|
|
if (0U != __get_IPSR())
|
|
{
|
|
#if (configUSE_TRACE_FACILITY == 1)
|
|
result = xEventGroupSetBitsFromISR(pEventStruct->handle, (event_flags_t)flagsToSet, &taskToWake);
|
|
#else
|
|
result = xEventGroupSetBitsFromISR((void *)pEventStruct->handle, (event_flags_t)flagsToSet, &taskToWake);
|
|
#endif
|
|
assert(pdPASS == result);
|
|
(void)result;
|
|
portYIELD_FROM_ISR(((bool)(taskToWake)));
|
|
}
|
|
else
|
|
{
|
|
(void)xEventGroupSetBits(pEventStruct->handle, (event_flags_t)flagsToSet);
|
|
}
|
|
|
|
(void)result;
|
|
return KOSA_StatusSuccess;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_EventClear
|
|
* Description : Clear one or more event flags of an event object.
|
|
* Return :KOSA_StatusSuccess if clear successfully, KOSA_StatusError if failed.
|
|
*
|
|
*END**************************************************************************/
|
|
osa_status_t OSA_EventClear(osa_event_handle_t eventHandle, osa_event_flags_t flagsToClear)
|
|
{
|
|
assert(NULL != eventHandle);
|
|
osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
|
|
|
|
if (NULL == pEventStruct->handle)
|
|
{
|
|
return KOSA_StatusError;
|
|
}
|
|
|
|
if (0U != __get_IPSR())
|
|
{
|
|
#if (configUSE_TRACE_FACILITY == 1)
|
|
(void)xEventGroupClearBitsFromISR(pEventStruct->handle, (event_flags_t)flagsToClear);
|
|
#else
|
|
(void)xEventGroupClearBitsFromISR((void *)pEventStruct->handle, (event_flags_t)flagsToClear);
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
(void)xEventGroupClearBits(pEventStruct->handle, (event_flags_t)flagsToClear);
|
|
}
|
|
return KOSA_StatusSuccess;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_EventGet
|
|
* Description : This function is used to get event's flags that specified by prameter
|
|
* flagsMask, and the flags (user specified) are obatianed by parameter pFlagsOfEvent. So
|
|
* you should pass the parameter 0xffffffff to specify you want to check all.
|
|
* Return :KOSA_StatusSuccess if event flags were successfully got, KOSA_StatusError if failed.
|
|
*
|
|
*END**************************************************************************/
|
|
osa_status_t OSA_EventGet(osa_event_handle_t eventHandle, osa_event_flags_t flagsMask, osa_event_flags_t *pFlagsOfEvent)
|
|
{
|
|
assert(NULL != eventHandle);
|
|
osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
|
|
EventBits_t eventFlags;
|
|
|
|
if (NULL == pEventStruct->handle)
|
|
{
|
|
return KOSA_StatusError;
|
|
}
|
|
|
|
if (NULL == pFlagsOfEvent)
|
|
{
|
|
return KOSA_StatusError;
|
|
}
|
|
|
|
if (0U != __get_IPSR())
|
|
{
|
|
eventFlags = xEventGroupGetBitsFromISR(pEventStruct->handle);
|
|
}
|
|
else
|
|
{
|
|
eventFlags = xEventGroupGetBits(pEventStruct->handle);
|
|
}
|
|
|
|
*pFlagsOfEvent = (osa_event_flags_t)eventFlags & flagsMask;
|
|
|
|
return KOSA_StatusSuccess;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_EventWait
|
|
* Description : This function checks the event's status, if it meets the wait
|
|
* condition, return KOSA_StatusSuccess, otherwise, timeout will be used for
|
|
* wait. The parameter timeout indicates how long should wait in milliseconds.
|
|
* Pass osaWaitForever_c to wait indefinitely, pass 0 will return the value
|
|
* KOSA_StatusTimeout 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 KOSA_StatusSuccess if wait condition is met, returns
|
|
* KOSA_StatusTimeout if wait condition is not met within the specified
|
|
* 'timeout', returns KOSA_StatusError if any errors occur during waiting.
|
|
*
|
|
*END**************************************************************************/
|
|
osa_status_t OSA_EventWait(osa_event_handle_t eventHandle,
|
|
osa_event_flags_t flagsToWait,
|
|
uint8_t waitAll,
|
|
uint32_t millisec,
|
|
osa_event_flags_t *pSetFlags)
|
|
{
|
|
assert(NULL != eventHandle);
|
|
BaseType_t clearMode;
|
|
uint32_t timeoutTicks;
|
|
event_flags_t flagsSave;
|
|
osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
|
|
|
|
/* Clean FreeRTOS cotrol flags */
|
|
flagsToWait = flagsToWait & 0x00FFFFFFU;
|
|
if (NULL == pEventStruct->handle)
|
|
{
|
|
return KOSA_StatusError;
|
|
}
|
|
|
|
/* Convert timeout from millisecond to tick. */
|
|
if (millisec == osaWaitForever_c)
|
|
{
|
|
timeoutTicks = portMAX_DELAY;
|
|
}
|
|
else
|
|
{
|
|
timeoutTicks = millisec / portTICK_PERIOD_MS;
|
|
}
|
|
|
|
clearMode = (pEventStruct->autoClear != 0U) ? pdTRUE : pdFALSE;
|
|
|
|
flagsSave = xEventGroupWaitBits(pEventStruct->handle, (event_flags_t)flagsToWait, clearMode, (BaseType_t)waitAll,
|
|
timeoutTicks);
|
|
|
|
flagsSave &= (event_flags_t)flagsToWait;
|
|
if (NULL != pSetFlags)
|
|
{
|
|
*pSetFlags = (osa_event_flags_t)flagsSave;
|
|
}
|
|
|
|
if (0U != flagsSave)
|
|
{
|
|
return KOSA_StatusSuccess;
|
|
}
|
|
else
|
|
{
|
|
return KOSA_StatusTimeout;
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_EventDestroy
|
|
* Description : This function is used to destroy a event object. Return
|
|
* KOSA_StatusSuccess if the event object is destroyed successfully, otherwise
|
|
* return KOSA_StatusError.
|
|
*
|
|
*END**************************************************************************/
|
|
osa_status_t OSA_EventDestroy(osa_event_handle_t eventHandle)
|
|
{
|
|
assert(NULL != eventHandle);
|
|
osa_event_struct_t *pEventStruct = (osa_event_struct_t *)eventHandle;
|
|
|
|
if (NULL == pEventStruct->handle)
|
|
{
|
|
return KOSA_StatusError;
|
|
}
|
|
vEventGroupDelete(pEventStruct->handle);
|
|
return KOSA_StatusSuccess;
|
|
}
|
|
|
|
/*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 NULL.
|
|
*
|
|
*END**************************************************************************/
|
|
osa_status_t OSA_MsgQCreate(osa_msgq_handle_t msgqHandle, uint32_t msgNo, uint32_t msgSize)
|
|
{
|
|
#if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
|
|
!((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
|
|
assert((sizeof(osa_msgq_handle_t) + sizeof(StaticQueue_t)) == OSA_MSGQ_HANDLE_SIZE);
|
|
#else
|
|
assert(sizeof(osa_msgq_handle_t) == OSA_MSGQ_HANDLE_SIZE);
|
|
#endif
|
|
assert(NULL != msgqHandle);
|
|
|
|
union
|
|
{
|
|
QueueHandle_t msgq;
|
|
uint32_t pmsgqHandle;
|
|
} xMsgqHandle;
|
|
|
|
/* Create the message queue where the number and size is specified by msgNo and msgSize */
|
|
#if (defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION > 0U)) && \
|
|
!((defined(configSUPPORT_DYNAMIC_ALLOCATION) && (configSUPPORT_DYNAMIC_ALLOCATION > 0U)))
|
|
xMsgqHandle.msgq = xQueueCreateStatic(msgNo, msgSize,
|
|
(uint8_t *)((uint8_t *)msgqHandle + sizeof(osa_msgq_handle_t) + sizeof(StaticQueue_t)),
|
|
(StaticQueue_t *)(void *)((uint8_t *)msgqHandle + sizeof(osa_msgq_handle_t)));
|
|
#else
|
|
xMsgqHandle.msgq = xQueueCreate(msgNo, msgSize);
|
|
#endif
|
|
if (NULL != xMsgqHandle.msgq)
|
|
{
|
|
*(uint32_t *)msgqHandle = xMsgqHandle.pmsgqHandle;
|
|
return KOSA_StatusSuccess;
|
|
}
|
|
return KOSA_StatusError;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_MsgQPut
|
|
* Description : This function is used to put a message to a message queue.
|
|
* Return : KOSA_StatusSuccess if the message is put successfully, otherwise return KOSA_StatusError.
|
|
*
|
|
*END**************************************************************************/
|
|
osa_status_t OSA_MsgQPut(osa_msgq_handle_t msgqHandle, osa_msg_handle_t pMessage)
|
|
{
|
|
osa_status_t osaStatus;
|
|
assert(NULL != msgqHandle);
|
|
portBASE_TYPE taskToWake = (portBASE_TYPE)pdFALSE;
|
|
QueueHandle_t handler = (QueueHandle_t)(void *)(uint32_t *)(*(uint32_t *)msgqHandle);
|
|
|
|
if (0U != __get_IPSR())
|
|
{
|
|
if (((BaseType_t)1) == (BaseType_t)xQueueSendToBackFromISR(handler, pMessage, &taskToWake))
|
|
{
|
|
portYIELD_FROM_ISR(((bool)(taskToWake)));
|
|
osaStatus = KOSA_StatusSuccess;
|
|
}
|
|
else
|
|
{
|
|
osaStatus = KOSA_StatusError;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
osaStatus = (xQueueSendToBack(handler, pMessage, 0) == pdPASS) ? (KOSA_StatusSuccess) : (KOSA_StatusError);
|
|
}
|
|
|
|
return osaStatus;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_MsgQGet
|
|
* Description : This function checks the queue's status, if it is not empty,
|
|
* get message from it and return KOSA_StatusSuccess, otherwise, timeout will
|
|
* be used for wait. The parameter timeout indicates how long should wait in
|
|
* milliseconds. Pass osaWaitForever_c to wait indefinitely, pass 0 will return
|
|
* KOSA_StatusTimeout immediately if queue is empty.
|
|
* This function returns KOSA_StatusSuccess if message is got successfully,
|
|
* returns KOSA_StatusTimeout if message queue is empty within the specified
|
|
* 'timeout', returns KOSA_StatusError if any errors occur during waiting.
|
|
*
|
|
*END**************************************************************************/
|
|
osa_status_t OSA_MsgQGet(osa_msgq_handle_t msgqHandle, osa_msg_handle_t pMessage, uint32_t millisec)
|
|
{
|
|
osa_status_t osaStatus;
|
|
assert(NULL != msgqHandle);
|
|
QueueHandle_t handler = (QueueHandle_t)(void *)(uint32_t *)(*(uint32_t *)msgqHandle);
|
|
|
|
uint32_t timeoutTicks;
|
|
|
|
if (millisec == osaWaitForever_c)
|
|
{
|
|
timeoutTicks = portMAX_DELAY;
|
|
}
|
|
else
|
|
{
|
|
timeoutTicks = MSEC_TO_TICK(millisec);
|
|
}
|
|
if (pdPASS != xQueueReceive(handler, pMessage, timeoutTicks))
|
|
{
|
|
osaStatus = KOSA_StatusTimeout; /* not able to send it to the queue? */
|
|
}
|
|
else
|
|
{
|
|
osaStatus = KOSA_StatusSuccess;
|
|
}
|
|
return osaStatus;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_MsgQAvailableMsgs
|
|
* Description : This function is used to get the available message.
|
|
* Return : Available message count
|
|
*
|
|
*END**************************************************************************/
|
|
int OSA_MsgQAvailableMsgs(osa_msgq_handle_t msgqHandle)
|
|
{
|
|
QueueHandle_t handler;
|
|
assert(NULL != msgqHandle);
|
|
handler = (QueueHandle_t)(void *)(uint32_t *)(*(uint32_t *)msgqHandle);
|
|
return (int)uxQueueMessagesWaiting((QueueHandle_t)handler);
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_MsgQDestroy
|
|
* Description : This function is used to destroy the message queue.
|
|
* Return : KOSA_StatusSuccess if the message queue is destroyed successfully, otherwise return KOSA_StatusError.
|
|
*
|
|
*END**************************************************************************/
|
|
osa_status_t OSA_MsgQDestroy(osa_msgq_handle_t msgqHandle)
|
|
{
|
|
assert(NULL != msgqHandle);
|
|
QueueHandle_t handler = (QueueHandle_t)(void *)(uint32_t *)(*(uint32_t *)msgqHandle);
|
|
|
|
vQueueDelete(handler);
|
|
return KOSA_StatusSuccess;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_InterruptEnable
|
|
* Description : self explanatory.
|
|
*
|
|
*END**************************************************************************/
|
|
void OSA_InterruptEnable(void)
|
|
{
|
|
if (0U != __get_IPSR())
|
|
{
|
|
if (1 == s_osaState.basePriorityNesting)
|
|
{
|
|
portCLEAR_INTERRUPT_MASK_FROM_ISR(s_osaState.basePriority);
|
|
}
|
|
|
|
if (s_osaState.basePriorityNesting > 0)
|
|
{
|
|
s_osaState.basePriorityNesting--;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
portEXIT_CRITICAL();
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_InterruptDisable
|
|
* Description : self explanatory.
|
|
*
|
|
*END**************************************************************************/
|
|
void OSA_InterruptDisable(void)
|
|
{
|
|
if (0U != __get_IPSR())
|
|
{
|
|
if (0 == s_osaState.basePriorityNesting)
|
|
{
|
|
s_osaState.basePriority = portSET_INTERRUPT_MASK_FROM_ISR();
|
|
}
|
|
s_osaState.basePriorityNesting++;
|
|
}
|
|
else
|
|
{
|
|
portENTER_CRITICAL();
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_EnableIRQGlobal
|
|
* Description : enable interrupts using PRIMASK register.
|
|
*
|
|
*END**************************************************************************/
|
|
void OSA_EnableIRQGlobal(void)
|
|
{
|
|
if (s_osaState.interruptDisableCount > 0U)
|
|
{
|
|
s_osaState.interruptDisableCount--;
|
|
|
|
if (0U == s_osaState.interruptDisableCount)
|
|
{
|
|
__enable_irq();
|
|
}
|
|
/* call core API to enable the global interrupt*/
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_DisableIRQGlobal
|
|
* Description : disable interrupts using PRIMASK register.
|
|
*
|
|
*END**************************************************************************/
|
|
void OSA_DisableIRQGlobal(void)
|
|
{
|
|
/* call core API to disable the global interrupt*/
|
|
__disable_irq();
|
|
|
|
/* update counter*/
|
|
s_osaState.interruptDisableCount++;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_DisableScheduler
|
|
* Description : Disable the scheduling of any task
|
|
* This function will disable the scheduling of any task
|
|
*
|
|
*END**************************************************************************/
|
|
void OSA_DisableScheduler(void)
|
|
{
|
|
vTaskSuspendAll();
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_EnableScheduler
|
|
* Description : Enable the scheduling of any task
|
|
* This function will enable the scheduling of any task
|
|
*
|
|
*END**************************************************************************/
|
|
void OSA_EnableScheduler(void)
|
|
{
|
|
(void)xTaskResumeAll();
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_InstallIntHandler
|
|
* Description : This function is used to install interrupt handler.
|
|
*
|
|
*END**************************************************************************/
|
|
void OSA_InstallIntHandler(uint32_t IRQNumber, void (*handler)(void))
|
|
{
|
|
#if defined(__IAR_SYSTEMS_ICC__)
|
|
_Pragma("diag_suppress = Pm138")
|
|
#endif
|
|
#if defined(ENABLE_RAM_VECTOR_TABLE)
|
|
(void) InstallIRQHandler((IRQn_Type)IRQNumber, (uint32_t)handler);
|
|
#endif /* ENABLE_RAM_VECTOR_TABLE. */
|
|
#if defined(__IAR_SYSTEMS_ICC__)
|
|
_Pragma("diag_remark = PM138")
|
|
#endif
|
|
}
|
|
|
|
/*!*********************************************************************************
|
|
*************************************************************************************
|
|
* Private functions
|
|
*************************************************************************************
|
|
********************************************************************************** */
|
|
#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
|
|
#if (defined(FSL_OSA_MAIN_FUNC_ENABLE) && (FSL_OSA_MAIN_FUNC_ENABLE > 0U))
|
|
static OSA_TASK_DEFINE(startup_task, gMainThreadPriority_c, 1, gMainThreadStackSize_c, 0);
|
|
|
|
int main(void)
|
|
{
|
|
extern void BOARD_InitHardware(void);
|
|
OSA_Init();
|
|
/* Initialize MCU clock */
|
|
BOARD_InitHardware();
|
|
|
|
(void)OSA_TaskCreate((osa_task_handle_t)s_osaState.mainTaskHandle, OSA_TASK(startup_task), NULL);
|
|
|
|
OSA_Start();
|
|
return 0;
|
|
}
|
|
#endif /*(defined(FSL_OSA_MAIN_FUNC_ENABLE) && (FSL_OSA_MAIN_FUNC_ENABLE > 0U))*/
|
|
#endif /* FSL_OSA_TASK_ENABLE */
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_Init
|
|
* Description : This function is used to setup the basic services, it should
|
|
* be called first in function main.
|
|
*
|
|
*END**************************************************************************/
|
|
#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
|
|
void OSA_Init(void)
|
|
{
|
|
LIST_Init((&s_osaState.taskList), 0);
|
|
s_osaState.basePriorityNesting = 0;
|
|
s_osaState.interruptDisableCount = 0;
|
|
}
|
|
#endif
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : OSA_Start
|
|
* Description : This function is used to start RTOS scheduler.
|
|
*
|
|
*END**************************************************************************/
|
|
#if (defined(FSL_OSA_TASK_ENABLE) && (FSL_OSA_TASK_ENABLE > 0U))
|
|
void OSA_Start(void)
|
|
{
|
|
vTaskStartScheduler();
|
|
}
|
|
#endif |