1
0
mirror of https://github.com/azure-rtos/threadx synced 2025-01-30 08:02:57 +08:00

2847 lines
65 KiB
C
Raw Permalink Normal View History

2024-01-29 13:51:15 +08:00
/***************************************************************************
* Copyright (c) 2024 Microsoft Corporation
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
*
* SPDX-License-Identifier: MIT
**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** FreeRTOS compatibility Kit */
/** */
/**************************************************************************/
/**************************************************************************/
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
2021-10-14 00:51:26 +00:00
/* 10-15-2021 William E. Lamie Modified comment(s), and */
/* fixed compiler warnings, */
/* resulting in version 6.1.7 */
2022-01-29 00:24:03 +00:00
/* 01-31-2022 William E. Lamie Modified comment(s), and */
/* fixed compiler warnings, */
/* resulting in version 6.1.10 */
2022-07-26 02:04:40 +00:00
/* 07-29-2022 Cindy Deng Added simple static scheduler */
/* start flag, corrected stack */
/* allocation size, */
/* resulting in version 6.1.12 */
/* 12-31-2023 Xiuwen Cai Modified comment(s), and */
/* added check for overflow in */
/* queue size calculation, */
/* resulting in version 6.4.0 */
/* */
/**************************************************************************/
#include <stdint.h>
2022-07-26 02:04:40 +00:00
#include <limits.h>
#include <tx_api.h>
#include <tx_thread.h>
#include <tx_semaphore.h>
#include <tx_queue.h>
#include "FreeRTOS.h"
#if (INCLUDE_vTaskDelete == 1)
static TX_THREAD txfr_idle_task;
#ifdef TX_FREERTOS_IDLE_STACK
static UINT txfr_idle_stack[TX_FREERTOS_IDLE_STACK];
#else
static UINT txfr_idle_stack[configMINIMAL_STACK_SIZE];
#endif
static TX_SEMAPHORE txfr_idle_sem;
static txfr_task_t *p_delete_task_head;
#endif // #if (INCLUDE_vTaskDelete == 1)
UBaseType_t g_txfr_task_count;
#ifdef configTOTAL_HEAP_SIZE
static uint8_t txfr_heap_mem[configTOTAL_HEAP_SIZE];
static TX_BYTE_POOL txfr_heap;
#endif
static UINT txfr_heap_initialized;
#if (TX_FREERTOS_AUTO_INIT == 1)
static UINT txfr_initialized;
2022-07-26 02:04:40 +00:00
static UINT txfr_scheduler_started;
#endif // #if (TX_FREERTOS_AUTO_INIT == 1)
// TODO - do something with malloc.
void *txfr_malloc(size_t len)
{
void *p;
UINT ret;
if(txfr_heap_initialized == 1u) {
ret = tx_byte_allocate(&txfr_heap, &p, len, 0u);
if(ret != TX_SUCCESS) {
return NULL;
}
} else {
return NULL;
}
return p;
}
void txfr_free(void *p)
{
UINT ret;
if(txfr_heap_initialized == 1u) {
ret = tx_byte_release(p);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
}
}
return;
}
#if (INCLUDE_vTaskDelete == 1)
static void txfr_idle_task_entry(ULONG id)
{
txfr_task_t *p_task;
UINT ret;
TX_INTERRUPT_SAVE_AREA;
for(;;) {
ret = tx_semaphore_get(&txfr_idle_sem, TX_WAIT_FOREVER);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
}
TX_DISABLE;
p_task = p_delete_task_head;
if(p_task != NULL) {
p_delete_task_head = p_task->p_next;
}
g_txfr_task_count--;
TX_RESTORE;
if(p_task != NULL) {
// Make sure the task is terminated, which may return an error if that's already the case so the return value is ignored.
(void)tx_thread_terminate(&p_task->thread);
ret = tx_thread_delete(&p_task->thread);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
}
ret = tx_semaphore_delete(&p_task->notification_sem);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
}
if(p_task->allocated == 1u) {
txfr_free(p_task);
}
}
}
}
#endif // #if (INCLUDE_vTaskDelete == 1)
static uint32_t txfr_prio_fr_to_tx(uint32_t prio)
{
return TX_MAX_PRIORITIES - 1u - prio;
}
static uint32_t txfr_prio_tx_to_fr(uint32_t prio)
{
return TX_MAX_PRIORITIES - 1u - prio;
}
#if (TX_FREERTOS_AUTO_INIT == 1)
static void tx_freertos_auto_init(void)
{
UINT ret;
tx_kernel_enter();
ret = tx_freertos_init();
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return;
}
txfr_initialized = 1u;
}
#endif // #if (TX_FREERTOS_AUTO_INIT == 1)
#if (TX_FREERTOS_AUTO_INIT == 1)
VOID tx_application_define(VOID * first_unused_memory)
{
// Empty tx_application_define() to support auto initialization.
}
#endif // #if (TX_FREERTOS_AUTO_INIT == 1)
UINT tx_freertos_init(void)
{
UINT ret;
#ifdef configTOTAL_HEAP_SIZE
if(configTOTAL_HEAP_SIZE > 0u) {
ret = tx_byte_pool_create(&txfr_heap, "txfr_byte_pool", txfr_heap_mem, configTOTAL_HEAP_SIZE);
if(ret != TX_SUCCESS) {
return ret;
}
txfr_heap_initialized = 1u;
}
#endif
#if (INCLUDE_vTaskDelete == 1)
ret = tx_semaphore_create(&txfr_idle_sem, "txfr_idle_semaphore", 0u);
if(ret != TX_SUCCESS) {
return ret;
}
ret = tx_thread_create(&txfr_idle_task, "txfr_idle_task", txfr_idle_task_entry, 0u,
txfr_idle_stack, sizeof(txfr_idle_stack), TX_MAX_PRIORITIES - 1u, TX_MAX_PRIORITIES - 1u, 0u, TX_AUTO_START);
if(ret != TX_SUCCESS) {
return ret;
}
#endif // #if (INCLUDE_vTaskDelete == 1)
return TX_SUCCESS;
}
void txfr_thread_wrapper(ULONG id)
{
TX_THREAD *p_thread;
txfr_task_t *p_txfr_task;
p_thread = tx_thread_identify();
p_txfr_task = p_thread->txfr_thread_ptr;
p_txfr_task->p_task_func(p_txfr_task->p_task_arg);
#if (INCLUDE_vTaskDelete == 1)
vTaskDelete(NULL);
#else
// Returning from a task is not allowed when vTaskDelete is disabled.
TX_FREERTOS_ASSERT_FAIL();
#endif // #if (INCLUDE_vTaskDelete == 1)
}
void *pvPortMalloc(size_t xWantedSize)
{
return txfr_malloc(xWantedSize);
}
void vPortFree(void *pv)
{
txfr_free(pv);
return;
}
void vPortEnterCritical(void)
{
portDISABLE_INTERRUPTS();
_tx_thread_preempt_disable++;
}
void vPortExitCritical(void)
{
if(_tx_thread_preempt_disable == 0u) {
TX_FREERTOS_ASSERT_FAIL();
}
_tx_thread_preempt_disable--;
if(_tx_thread_preempt_disable == 0u) {
portENABLE_INTERRUPTS();
}
}
void vTaskStartScheduler(void)
{
#if (TX_FREERTOS_AUTO_INIT == 1)
2022-07-26 02:04:40 +00:00
txfr_scheduler_started = 1u;
_tx_thread_schedule();
#else
// Nothing to do, THREADX scheduler is already started.
#endif
}
BaseType_t xTaskGetSchedulerState(void)
{
2022-07-26 02:04:40 +00:00
#if (TX_FREERTOS_AUTO_INIT == 1)
if(txfr_scheduler_started == 0u) {
return taskSCHEDULER_NOT_STARTED;
}
#endif
if(_tx_thread_preempt_disable > 0u) {
return taskSCHEDULER_SUSPENDED;
} else {
return taskSCHEDULER_RUNNING;
}
}
void vTaskSuspendAll(void)
{
TX_INTERRUPT_SAVE_AREA;
TX_DISABLE;
_tx_thread_preempt_disable++;
TX_RESTORE;
}
BaseType_t xTaskResumeAll(void)
{
TX_INTERRUPT_SAVE_AREA;
TX_DISABLE;
_tx_thread_preempt_disable--;
TX_RESTORE;
return pdFALSE;
}
void vTaskDelay(const TickType_t xTicksToDelay)
{
tx_thread_sleep(xTicksToDelay);
}
TaskHandle_t xTaskCreateStatic(TaskFunction_t pxTaskCode,
const char *const pcName,
const configSTACK_DEPTH_TYPE ulStackDepth,
void *const pvParameters,
UBaseType_t uxPriority,
StackType_t *const puxStackBuffer,
StaticTask_t *const pxTaskBuffer)
{
UINT prio;
UINT ret;
2022-07-26 02:04:40 +00:00
ULONG stack_depth_bytes;
TX_INTERRUPT_SAVE_AREA;
configASSERT(pxTaskCode != NULL);
configASSERT(ulStackDepth >= configMINIMAL_STACK_SIZE);
configASSERT(uxPriority < configMAX_PRIORITIES);
configASSERT(puxStackBuffer != NULL);
configASSERT(pxTaskBuffer != NULL);
#if (TX_FREERTOS_AUTO_INIT == 1)
if(txfr_initialized != 1u) {
tx_freertos_auto_init();
}
#endif
2022-07-26 02:04:40 +00:00
if(ulStackDepth > (ULONG_MAX / sizeof(StackType_t))) {
/* Integer overflow in stack depth */
TX_FREERTOS_ASSERT_FAIL();
return NULL;
}
stack_depth_bytes = ulStackDepth * sizeof(StackType_t);
TX_MEMSET(pxTaskBuffer, 0, sizeof(*pxTaskBuffer));
pxTaskBuffer->p_task_arg = pvParameters;
pxTaskBuffer->p_task_func = pxTaskCode;
ret = tx_semaphore_create(&pxTaskBuffer->notification_sem, "", 0u);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return NULL;
}
prio = txfr_prio_fr_to_tx(uxPriority);
ret = tx_thread_create(&pxTaskBuffer->thread, (CHAR *)pcName, txfr_thread_wrapper, (ULONG)pvParameters,
2022-07-26 02:04:40 +00:00
puxStackBuffer, stack_depth_bytes, prio, prio, 0u, TX_DONT_START);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return NULL;
}
pxTaskBuffer->thread.txfr_thread_ptr = pxTaskBuffer;
ret = tx_thread_resume(&pxTaskBuffer->thread);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return NULL;
}
TX_DISABLE;
g_txfr_task_count++;
TX_RESTORE;
return pxTaskBuffer;
}
BaseType_t xTaskCreate(TaskFunction_t pvTaskCode,
const char * const pcName,
const configSTACK_DEPTH_TYPE usStackDepth,
void *pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask)
{
void *p_stack;
txfr_task_t *p_task;
UINT ret;
UINT prio;
2022-07-26 02:04:40 +00:00
ULONG stack_depth_bytes;
TX_INTERRUPT_SAVE_AREA;
configASSERT(pvTaskCode != NULL);
configASSERT(usStackDepth >= configMINIMAL_STACK_SIZE);
configASSERT(uxPriority < configMAX_PRIORITIES);
configASSERT(pxCreatedTask != NULL);
#if (TX_FREERTOS_AUTO_INIT == 1)
if(txfr_initialized != 1u) {
tx_freertos_auto_init();
}
#endif
2022-07-26 02:04:40 +00:00
if((usStackDepth > (SIZE_MAX / sizeof(StackType_t)))
|| (usStackDepth > (ULONG_MAX / sizeof(StackType_t)))) {
/* Integer overflow in stack depth */
return errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
}
stack_depth_bytes = usStackDepth * sizeof(StackType_t);
2022-07-26 02:04:40 +00:00
p_stack = txfr_malloc((size_t)stack_depth_bytes);
if(p_stack == NULL) {
return errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
}
p_task = txfr_malloc(sizeof(txfr_task_t));
if(p_task == NULL) {
txfr_free(p_stack);
return errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
}
*pxCreatedTask = p_task;
TX_MEMSET(p_task, 0, sizeof(*p_task));
p_task->allocated = 1u;
p_task->p_task_arg = pvParameters;
p_task->p_task_func = pvTaskCode;
ret = tx_semaphore_create(&p_task->notification_sem, "", 0u);
if(ret != TX_SUCCESS) {
txfr_free(p_stack);
txfr_free(p_task);
TX_FREERTOS_ASSERT_FAIL();
2021-10-14 00:51:26 +00:00
return (BaseType_t)NULL;
}
prio = txfr_prio_fr_to_tx(uxPriority);
ret = tx_thread_create(&p_task->thread, (CHAR *)pcName, txfr_thread_wrapper, (ULONG)pvParameters,
2022-07-26 02:04:40 +00:00
p_stack, stack_depth_bytes, prio, prio, 0u, TX_DONT_START);
if(ret != TX_SUCCESS) {
(void)tx_semaphore_delete(&p_task->notification_sem);
txfr_free(p_stack);
txfr_free(p_task);
TX_FREERTOS_ASSERT_FAIL();
2021-10-14 00:51:26 +00:00
return (BaseType_t)NULL;
}
p_task->thread.txfr_thread_ptr = p_task;
ret = tx_thread_resume(&p_task->thread);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
}
TX_DISABLE;
g_txfr_task_count++;
TX_RESTORE;
return pdPASS;
}
UBaseType_t uxTaskGetNumberOfTasks(void)
{
UBaseType_t count;
TX_INTERRUPT_SAVE_AREA;
TX_DISABLE;
count = g_txfr_task_count;
TX_RESTORE;
return count;
}
#if (INCLUDE_vTaskDelete == 1)
void vTaskDelete(TaskHandle_t xTask)
{
UINT ret;
TX_THREAD *p_thread;
txfr_task_t *p_txfr_thread;
TX_INTERRUPT_SAVE_AREA;
if(xTask == NULL) {
TX_THREAD_GET_CURRENT(p_thread);
p_txfr_thread = (txfr_task_t *)p_thread->txfr_thread_ptr;
} else {
p_txfr_thread = xTask;
p_thread = &xTask->thread;
}
TX_DISABLE;
p_txfr_thread->p_next = p_delete_task_head;
p_delete_task_head = p_txfr_thread;
_tx_thread_preempt_disable++;
ret = tx_semaphore_put(&txfr_idle_sem);
if(ret != TX_SUCCESS) {
_tx_thread_preempt_disable--;
TX_RESTORE;
TX_FREERTOS_ASSERT_FAIL();
return;
}
_tx_thread_preempt_disable--;
TX_RESTORE;
ret = tx_thread_terminate(p_thread);
if(ret != TX_SUCCESS) {
TX_RESTORE;
TX_FREERTOS_ASSERT_FAIL();
return;
}
return;
}
#endif
TaskHandle_t xTaskGetCurrentTaskHandle(void)
{
TX_THREAD *p_thread;
p_thread = tx_thread_identify();
return p_thread->txfr_thread_ptr;
}
void vTaskSuspend(TaskHandle_t xTaskToSuspend)
{
TX_THREAD *p_thread;
UINT ret;
if(xTaskToSuspend == NULL) {
p_thread = tx_thread_identify();
} else {
p_thread = &xTaskToSuspend->thread;
}
ret = tx_thread_suspend(p_thread);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return;
}
}
void vTaskResume(TaskHandle_t xTaskToResume)
{
UINT ret;
configASSERT(xTaskToResume != NULL);
ret = tx_thread_resume(&xTaskToResume->thread);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return;
}
}
BaseType_t xTaskResumeFromISR(TaskHandle_t xTaskToResume)
{
configASSERT(xTaskToResume != NULL);
vTaskResume(xTaskToResume);
return pdFALSE;
}
BaseType_t xTaskAbortDelay(TaskHandle_t xTask)
{
TX_THREAD *p_thread;
UINT ret;
configASSERT(xTask != NULL);
p_thread = &xTask->thread;
ret = tx_thread_wait_abort(p_thread);
if(ret != TX_SUCCESS) {
return pdFAIL;
}
return pdPASS;
}
UBaseType_t uxTaskPriorityGet(const TaskHandle_t xTask)
{
TX_THREAD *p_thread;
UINT priority;
UINT ret;
if(xTask == NULL) {
p_thread = tx_thread_identify();
} else {
p_thread = &xTask->thread;
}
ret = tx_thread_info_get(p_thread, NULL, NULL, NULL, &priority, NULL, NULL, NULL, NULL);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return 0;
}
priority = txfr_prio_tx_to_fr(priority);
return priority;
}
UBaseType_t uxTaskPriorityGetFromISR(const TaskHandle_t xTask)
{
return uxTaskPriorityGet(xTask);
}
void vTaskPrioritySet(TaskHandle_t xTask,
UBaseType_t uxNewPriority)
{
TX_THREAD *p_thread;
UINT priority;
UINT old_priority;
UINT ret;
configASSERT(uxNewPriority < configMAX_PRIORITIES);
if(xTask == NULL) {
p_thread = tx_thread_identify();
} else {
p_thread = &xTask->thread;
}
priority = uxNewPriority;
priority = txfr_prio_fr_to_tx(priority);
ret = tx_thread_priority_change(p_thread, priority, &old_priority);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return;
}
}
char *pcTaskGetName(TaskHandle_t xTaskToQuery)
{
TX_THREAD *p_thread;
char *p_task_name;
UINT ret;
if(xTaskToQuery == NULL) {
p_thread = tx_thread_identify();
} else {
p_thread = &xTaskToQuery->thread;
}
ret = tx_thread_info_get(p_thread, &p_task_name, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return 0;
}
return p_task_name;
}
eTaskState eTaskGetState(TaskHandle_t xTask)
{
UINT thread_state;
eTaskState ret_state;
TX_THREAD *p_thread;
TX_INTERRUPT_SAVE_AREA;
if(xTask == NULL) {
return eInvalid;
}
TX_DISABLE;
thread_state = xTask->thread.tx_thread_state;
p_thread = &xTask->thread;
TX_RESTORE;
if(p_thread == tx_thread_identify()) {
return eRunning;
}
switch(thread_state) {
case TX_READY:
ret_state = eReady;
break;
case TX_COMPLETED:
case TX_TERMINATED:
ret_state = eDeleted;
break;
case TX_SUSPENDED:
case TX_SLEEP:
ret_state = eSuspended;
break;
case TX_QUEUE_SUSP:
case TX_SEMAPHORE_SUSP:
case TX_EVENT_FLAG:
case TX_BLOCK_MEMORY:
case TX_BYTE_MEMORY:
case TX_IO_DRIVER:
case TX_FILE:
case TX_TCP_IP:
case TX_MUTEX_SUSP:
ret_state = eBlocked;
break;
default:
ret_state = eInvalid;
break;
}
return ret_state;
}
void vTaskDelayUntil(TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement)
{
TickType_t tick_cur;
tick_cur = (uint16_t)tx_time_get();
tx_thread_sleep(xTimeIncrement - (tick_cur - *pxPreviousWakeTime));
*pxPreviousWakeTime = *pxPreviousWakeTime + xTimeIncrement;
}
BaseType_t xTaskNotifyGive(TaskHandle_t xTaskToNotify)
{
configASSERT(xTaskToNotify != NULL);
return xTaskNotify(xTaskToNotify, 0u, eIncrement);
}
void vTaskNotifyGiveFromISR(TaskHandle_t xTaskToNotify,
BaseType_t *pxHigherPriorityTaskWoken)
{
configASSERT(xTaskToNotify != NULL);
(void)xTaskNotify(xTaskToNotify, 0u, eIncrement);
}
uint32_t ulTaskNotifyTake(BaseType_t xClearCountOnExit,
TickType_t xTicksToWait)
{
TX_THREAD *p_thread;
uint32_t val;
UINT ret;
UCHAR pend;
txfr_task_t *p_task;
UINT timeout;
if(xTicksToWait == portMAX_DELAY) {
timeout = TX_WAIT_FOREVER;
} else {
timeout = (UINT)xTicksToWait;
}
pend = TX_FALSE;
p_thread = tx_thread_identify();
p_task = p_thread->txfr_thread_ptr;
TX_INTERRUPT_SAVE_AREA;
TX_DISABLE;
ret = tx_semaphore_get(&p_task->notification_sem, 0u);
if(ret == TX_SUCCESS) {
val = p_task->task_notify_val;
p_task->p_notify_val_ret = NULL;
if(xClearCountOnExit != pdFALSE) {
p_task->task_notify_val = 0u;
} else {
p_task->task_notify_val--;
}
} else {
pend = TX_TRUE;
p_task->p_notify_val_ret = &val;
p_task->clear_on_pend = xClearCountOnExit;
p_task->clear_mask = (uint32_t)-1;
}
TX_RESTORE;
if(pend == TX_TRUE) {
ret = tx_semaphore_get(&p_task->notification_sem, timeout);
p_task->p_notify_val_ret = NULL;
if(ret != TX_SUCCESS) {
return 0u;
}
}
return val;
}
BaseType_t xTaskNotifyWait(uint32_t ulBitsToClearOnEntry,
uint32_t ulBitsToClearOnExit,
uint32_t *pulNotificationValue,
TickType_t xTicksToWait)
{
TX_INTERRUPT_SAVE_AREA;
TX_THREAD *p_thread;
uint32_t val;
BaseType_t ret_val;
UINT ret;
UCHAR pend;
txfr_task_t *p_task;
UINT timeout;
ret_val = pdPASS;
if(xTicksToWait == portMAX_DELAY) {
timeout = TX_WAIT_FOREVER;
} else {
timeout = (UINT)xTicksToWait;
}
pend = TX_FALSE;
p_thread = tx_thread_identify();
p_task = p_thread->txfr_thread_ptr;
TX_DISABLE;
ret = tx_semaphore_get(&p_task->notification_sem, 0u);
if(ret == TX_SUCCESS) {
val = p_task->task_notify_val;
p_task->p_notify_val_ret = NULL;
if(ulBitsToClearOnExit != 0u) {
p_task->task_notify_val &= ~ulBitsToClearOnExit;
}
} else {
pend = TX_TRUE;
p_task->p_notify_val_ret = &val;
p_task->clear_on_pend = 1u;
p_task->clear_mask = ulBitsToClearOnExit;
}
TX_RESTORE;
if(pend == TX_TRUE) {
ret = tx_semaphore_get(&p_task->notification_sem, timeout);
p_task->p_notify_val_ret = NULL;
if(ret != TX_SUCCESS) {
return 0u;
}
}
*pulNotificationValue = val;
return ret_val;
}
BaseType_t xTaskNotify(TaskHandle_t xTaskToNotify,
uint32_t ulValue,
eNotifyAction eAction)
{
configASSERT(TXFR_NOTIFYACTION_VALID(eAction));
return xTaskNotifyAndQuery(xTaskToNotify, ulValue, eAction, NULL);
}
BaseType_t xTaskNotifyFromISR(TaskHandle_t xTaskToNotify,
uint32_t ulValue,
eNotifyAction eAction,
BaseType_t *pxHigherPriorityTaskWoken)
{
configASSERT(xTaskToNotify != NULL);
configASSERT(TXFR_NOTIFYACTION_VALID(eAction));
return xTaskNotify(xTaskToNotify, ulValue, eAction);
}
BaseType_t xTaskNotifyAndQuery(TaskHandle_t xTaskToNotify,
uint32_t ulValue,
eNotifyAction eAction,
uint32_t *pulPreviousNotifyValue)
{
UINT ret;
UCHAR notified;
TX_INTERRUPT_SAVE_AREA;
BaseType_t ret_val;
UCHAR waiting;
configASSERT(xTaskToNotify != NULL);
configASSERT(TXFR_NOTIFYACTION_VALID(eAction));
TX_DISABLE;
if(pulPreviousNotifyValue != NULL) {
*pulPreviousNotifyValue = xTaskToNotify->task_notify_val;
}
waiting = TX_FALSE;
notified = TX_FALSE;
ret_val = pdPASS;
if(xTaskToNotify->notification_sem.tx_semaphore_suspended_count != 0u) {
waiting = TX_TRUE;
}
if(xTaskToNotify->notification_sem.tx_semaphore_count == 0u) {
_tx_thread_preempt_disable++;
ret = tx_semaphore_put(&xTaskToNotify->notification_sem);
_tx_thread_preempt_disable--;
if(ret != TX_SUCCESS) {
TX_RESTORE;
TX_FREERTOS_ASSERT_FAIL();
return pdFAIL;
}
xTaskToNotify->task_notify_val_pend = xTaskToNotify->task_notify_val;
notified = TX_TRUE;
}
switch (eAction) {
case eNoAction:
break;
case eSetBits:
xTaskToNotify->task_notify_val |= ulValue;
break;
case eIncrement:
xTaskToNotify->task_notify_val++;
break;
case eSetValueWithOverwrite:
xTaskToNotify->task_notify_val = ulValue;
break;
case eSetValueWithoutOverwrite:
if(notified == TX_TRUE) {
xTaskToNotify->task_notify_val = ulValue;
} else {
ret_val = pdFALSE;
}
break;
default:
TX_RESTORE;
return pdFAIL;
break;
}
if(waiting == TX_TRUE) {
*xTaskToNotify->p_notify_val_ret = xTaskToNotify->task_notify_val;
if(xTaskToNotify->clear_on_pend == TX_TRUE) {
xTaskToNotify->task_notify_val &= ~xTaskToNotify->clear_mask;
} else {
xTaskToNotify->task_notify_val--;
}
}
TX_RESTORE;
_tx_thread_system_preempt_check();
return ret_val;
}
BaseType_t xTaskNotifyAndQueryFromISR(TaskHandle_t xTaskToNotify,
uint32_t ulValue,
eNotifyAction eAction,
uint32_t *pulPreviousNotifyValue,
BaseType_t *pxHigherPriorityTaskWoken)
{
configASSERT(xTaskToNotify != NULL);
configASSERT(TXFR_NOTIFYACTION_VALID(eAction));
return xTaskNotifyAndQuery(xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue);
}
BaseType_t xTaskNotifyStateClear(TaskHandle_t xTask)
{
BaseType_t ret_val;
UINT ret;
TX_THREAD *p_thread;
txfr_task_t *p_task;
TX_INTERRUPT_SAVE_AREA;
if(xTask == NULL) {
p_thread = tx_thread_identify();
p_task = p_thread->txfr_thread_ptr;
} else {
p_thread = &xTask->thread;
p_task = xTask;
}
TX_DISABLE;
if(p_task->notification_sem.tx_semaphore_suspended_count != 0u) {
ret_val = pdTRUE;
} else {
ret_val = pdFALSE;
}
ret = tx_semaphore_get(&p_task->notification_sem, 0u);
if(ret != TX_SUCCESS) {
TX_RESTORE;
TX_FREERTOS_ASSERT_FAIL();
return pdFALSE;
}
TX_RESTORE;
return ret_val;
}
uint32_t ulTaskNotifyValueClear(TaskHandle_t xTask,
uint32_t ulBitsToClear)
{
BaseType_t ret_val;
TX_THREAD *p_thread;
txfr_task_t *p_task;
TX_INTERRUPT_SAVE_AREA;
if(xTask == NULL) {
p_thread = tx_thread_identify();
p_task = p_thread->txfr_thread_ptr;
} else {
p_thread = &xTask->thread;
p_task = xTask;
}
TX_DISABLE;
ret_val = p_task->task_notify_val;
p_task->task_notify_val &= ~ulBitsToClear;
TX_RESTORE;
return ret_val;
}
SemaphoreHandle_t xSemaphoreCreateCounting(UBaseType_t uxMaxCount,
UBaseType_t uxInitialCount)
{
txfr_sem_t *p_sem;
UINT ret;
configASSERT(uxMaxCount != 0u);
configASSERT(uxInitialCount <= uxMaxCount);
#if (TX_FREERTOS_AUTO_INIT == 1)
if(txfr_initialized != 1u) {
tx_freertos_auto_init();
}
#endif
p_sem = txfr_malloc(sizeof(txfr_sem_t));
if(p_sem == NULL) {
return NULL;
}
TX_MEMSET(p_sem, 0, sizeof(*p_sem));
p_sem->max_count = uxMaxCount;
p_sem->allocated = 1u;
p_sem->is_mutex = 0u;
ret = tx_semaphore_create(&p_sem->sem, "", uxInitialCount);
if(ret != TX_SUCCESS) {
txfr_free(p_sem);
return NULL;
}
return p_sem;
}
SemaphoreHandle_t xSemaphoreCreateCountingStatic(UBaseType_t uxMaxCount,
UBaseType_t uxInitialCount,
StaticSemaphore_t *pxSemaphoreBuffer)
{
UINT ret;
configASSERT(uxMaxCount != 0u);
configASSERT(uxInitialCount <= uxMaxCount);
configASSERT(pxSemaphoreBuffer != NULL);
#if (TX_FREERTOS_AUTO_INIT == 1)
if(txfr_initialized != 1u) {
tx_freertos_auto_init();
}
#endif
TX_MEMSET(pxSemaphoreBuffer, 0, sizeof(*pxSemaphoreBuffer));
pxSemaphoreBuffer->max_count = uxMaxCount;
pxSemaphoreBuffer->allocated = 0u;
pxSemaphoreBuffer->is_mutex = 0u;
ret = tx_semaphore_create(&pxSemaphoreBuffer->sem, "", uxInitialCount);
if(ret != TX_SUCCESS) {
return NULL;
}
return pxSemaphoreBuffer;
}
SemaphoreHandle_t xSemaphoreCreateBinary(void)
{
return xSemaphoreCreateCounting(1u, 0u);
}
SemaphoreHandle_t xSemaphoreCreateBinaryStatic(StaticSemaphore_t *pxSemaphoreBuffer)
{
configASSERT(pxSemaphoreBuffer != NULL);
return xSemaphoreCreateCountingStatic(1u, 0u, pxSemaphoreBuffer);
}
SemaphoreHandle_t xSemaphoreCreateMutex(void)
{
txfr_sem_t *p_sem;
UINT ret;
#if (TX_FREERTOS_AUTO_INIT == 1)
if(txfr_initialized != 1u) {
tx_freertos_auto_init();
}
#endif
p_sem = txfr_malloc(sizeof(txfr_sem_t));
if(p_sem == NULL) {
return NULL;
}
TX_MEMSET(p_sem, 0, sizeof(*p_sem));
p_sem->max_count = 1u;
p_sem->allocated = 1u;
p_sem->is_mutex = 1u;
ret = tx_mutex_create(&p_sem->mutex, "", TX_NO_INHERIT);
if(ret != TX_SUCCESS) {
txfr_free(p_sem);
return NULL;
}
return p_sem;
}
SemaphoreHandle_t xSemaphoreCreateMutexStatic(StaticSemaphore_t *pxMutexBuffer)
{
UINT ret;
configASSERT(pxMutexBuffer != NULL);
TX_MEMSET(pxMutexBuffer, 0, sizeof(*pxMutexBuffer));
pxMutexBuffer->max_count = 1u;
pxMutexBuffer->allocated = 0u;
pxMutexBuffer->is_mutex = 1u;
ret = tx_mutex_create(&pxMutexBuffer->mutex, "", TX_NO_INHERIT);
if(ret != TX_SUCCESS) {
return NULL;
}
return pxMutexBuffer;
}
SemaphoreHandle_t xSemaphoreCreateRecursiveMutex(void)
{
txfr_sem_t *p_sem;
UINT ret;
#if (TX_FREERTOS_AUTO_INIT == 1)
if(txfr_initialized != 1u) {
tx_freertos_auto_init();
}
#endif
p_sem = txfr_malloc(sizeof(txfr_sem_t));
if(p_sem == NULL) {
return NULL;
}
TX_MEMSET(p_sem, 0, sizeof(*p_sem));
p_sem->max_count = 1u;
p_sem->allocated = 1u;
p_sem->is_mutex = 1u;
ret = tx_mutex_create(&p_sem->mutex, "", TX_INHERIT);
if(ret != TX_SUCCESS) {
txfr_free(p_sem);
return NULL;
}
return p_sem;
}
SemaphoreHandle_t xSemaphoreCreateRecursiveMutexStatic(StaticSemaphore_t *pxMutexBuffer)
{
UINT ret;
configASSERT(pxMutexBuffer != NULL);
#if (TX_FREERTOS_AUTO_INIT == 1)
if(txfr_initialized != 1u) {
tx_freertos_auto_init();
}
#endif
TX_MEMSET(pxMutexBuffer, 0, sizeof(*pxMutexBuffer));
pxMutexBuffer->max_count = 1u;
pxMutexBuffer->allocated = 0u;
pxMutexBuffer->is_mutex = 1u;
ret = tx_mutex_create(&pxMutexBuffer->mutex, "", TX_INHERIT);
if(ret != TX_SUCCESS) {
return NULL;
}
return pxMutexBuffer;
}
void vSemaphoreDelete(SemaphoreHandle_t xSemaphore)
{
UINT ret;
configASSERT(xSemaphore != NULL);
if(xSemaphore->is_mutex == 0u) {
ret = tx_semaphore_delete(&xSemaphore->sem);
} else {
ret = tx_mutex_delete(&xSemaphore->mutex);
}
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return;
}
if(xSemaphore->allocated == 1u) {
vPortFree(xSemaphore);
}
}
BaseType_t xSemaphoreTake(SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait)
{
UINT timeout;
UINT ret;
configASSERT(xSemaphore != NULL);
if(xTicksToWait == portMAX_DELAY) {
timeout = TX_WAIT_FOREVER;
} else {
timeout = (UINT)xTicksToWait;
}
if(xSemaphore->is_mutex == 1u) {
if(xSemaphore->mutex.tx_mutex_owner == tx_thread_identify()) {
return pdFALSE;
}
ret = tx_mutex_get(&xSemaphore->mutex, timeout);
if(ret != TX_SUCCESS) {
return pdFALSE;
}
} else {
ret = tx_semaphore_get(&xSemaphore->sem, timeout);
if(ret != TX_SUCCESS) {
return pdFALSE;
}
}
return pdTRUE;
}
BaseType_t xSemaphoreTakeFromISR(SemaphoreHandle_t xSemaphore, BaseType_t *pxHigherPriorityTaskWoken)
{
UINT ret;
configASSERT(xSemaphore != NULL);
if(xSemaphore->is_mutex == 1u) {
return pdFALSE;
} else {
ret = tx_semaphore_get(&xSemaphore->sem, 0u);
if(ret != TX_SUCCESS) {
return pdFALSE;
}
}
return pdTRUE;
}
BaseType_t xSemaphoreTakeRecursive(SemaphoreHandle_t xMutex, TickType_t xTicksToWait)
{
UINT timeout;
UINT ret;
configASSERT(xMutex != NULL);
if(xTicksToWait == portMAX_DELAY) {
timeout = TX_WAIT_FOREVER;
} else {
timeout = (UINT)xTicksToWait;
}
if(xMutex->is_mutex == 1u) {
ret = tx_mutex_get(&xMutex->mutex, timeout);
if(ret != TX_SUCCESS) {
return pdFALSE;
}
} else {
ret = tx_semaphore_get(&xMutex->sem, timeout);
if(ret != TX_SUCCESS) {
return pdFALSE;
}
}
return pdTRUE;
}
BaseType_t xSemaphoreGive(SemaphoreHandle_t xSemaphore)
{
TX_INTERRUPT_SAVE_AREA
UINT ret;
configASSERT(xSemaphore != NULL);
if(xSemaphore->is_mutex == 1u) {
ret = tx_mutex_put(&xSemaphore->mutex);
if(ret != TX_SUCCESS) {
return pdFALSE;
}
2022-01-29 00:24:03 +00:00
return pdTRUE;
}
2022-01-29 00:24:03 +00:00
TX_DISABLE;
_tx_thread_preempt_disable++;
2022-01-29 00:24:03 +00:00
if(xSemaphore->sem.tx_semaphore_count >= xSemaphore->max_count) {
/* Maximum semaphore count reached return failure. */
_tx_thread_preempt_disable--;
TX_RESTORE
return pdFALSE;
}
2022-01-29 00:24:03 +00:00
ret = tx_semaphore_put(&xSemaphore->sem);
if(ret != TX_SUCCESS) {
_tx_thread_preempt_disable--;
TX_RESTORE;
return pdFALSE;
}
if(xSemaphore->p_set != NULL) {
// To prevent deadlocks don't wait when posting on a queue set.
ret = tx_queue_send(&xSemaphore->p_set->queue, &xSemaphore, TX_NO_WAIT);
if((ret != TX_SUCCESS) && (ret != TX_QUEUE_FULL)) {
// Fatal error, queue full errors are ignored on purpose to match the original behaviour.
_tx_thread_preempt_disable--;
TX_RESTORE;
TX_FREERTOS_ASSERT_FAIL();
return pdFALSE;
}
2022-01-29 00:24:03 +00:00
}
2022-01-29 00:24:03 +00:00
_tx_thread_preempt_disable--;
TX_RESTORE;
2022-01-29 00:24:03 +00:00
_tx_thread_system_preempt_check();
return pdTRUE;
}
BaseType_t xSemaphoreGiveFromISR(SemaphoreHandle_t xSemaphore, BaseType_t *pxHigherPriorityTaskWoken)
{
configASSERT(xSemaphore != NULL);
return xSemaphoreGive(xSemaphore);
}
BaseType_t xSemaphoreGiveRecursive(SemaphoreHandle_t xMutex)
{
configASSERT(xMutex != NULL);
return xSemaphoreGive(xMutex);
}
UBaseType_t uxSemaphoreGetCount(SemaphoreHandle_t xSemaphore)
{
UINT ret;
ULONG count;
configASSERT(xSemaphore != NULL);
ret = tx_semaphore_info_get(&xSemaphore->sem, NULL, &count, NULL, NULL, NULL);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return 0;
}
return count;
}
TaskHandle_t xSemaphoreGetMutexHolder(SemaphoreHandle_t xMutex)
{
configASSERT(xMutex != NULL);
return xMutex->mutex.tx_mutex_owner->txfr_thread_ptr;
}
TaskHandle_t xSemaphoreGetMutexHolderFromISR(SemaphoreHandle_t xMutex)
{
return xSemaphoreGetMutexHolder(xMutex);
}
TickType_t xTaskGetTickCount(void)
{
return tx_time_get();
}
TickType_t xTaskGetTickCountFromISR(void)
{
return tx_time_get();
}
QueueHandle_t xQueueCreateStatic(UBaseType_t uxQueueLength,
UBaseType_t uxItemSize,
uint8_t *pucQueueStorageBuffer,
StaticQueue_t *pxQueueBuffer)
{
UINT ret;
configASSERT(uxQueueLength != 0u);
configASSERT(uxItemSize >= sizeof(UINT));
configASSERT(pucQueueStorageBuffer != NULL);
configASSERT(pxQueueBuffer != NULL);
#if (TX_FREERTOS_AUTO_INIT == 1)
if(txfr_initialized != 1u) {
tx_freertos_auto_init();
}
#endif
TX_MEMSET(pucQueueStorageBuffer, 0, uxQueueLength * uxItemSize);
TX_MEMSET(pxQueueBuffer, 0, sizeof(*pxQueueBuffer));
pxQueueBuffer->allocated = 0u;
pxQueueBuffer->p_mem = pucQueueStorageBuffer;
pxQueueBuffer->id = TX_QUEUE_ID;
pxQueueBuffer->p_write = (uint8_t *)pucQueueStorageBuffer;
pxQueueBuffer->p_read = (uint8_t *)pucQueueStorageBuffer;
pxQueueBuffer->msg_size = uxItemSize;
pxQueueBuffer->queue_length = uxQueueLength;
ret = tx_semaphore_create(&pxQueueBuffer->read_sem, "", 0u);
if(ret != TX_SUCCESS) {
return NULL;
}
ret = tx_semaphore_create(&pxQueueBuffer->write_sem, "", uxQueueLength);
if(ret != TX_SUCCESS) {
return NULL;
}
return pxQueueBuffer;
}
QueueHandle_t xQueueCreate(UBaseType_t uxQueueLength, UBaseType_t uxItemSize)
{
txfr_queue_t *p_queue;
void *p_mem;
size_t mem_size;
UINT ret;
configASSERT(uxQueueLength != 0u);
configASSERT(uxItemSize >= sizeof(UINT));
#if (TX_FREERTOS_AUTO_INIT == 1)
if(txfr_initialized != 1u) {
tx_freertos_auto_init();
}
#endif
if ((uxQueueLength > (SIZE_MAX / uxItemSize)) ||
(uxQueueLength > (ULONG_MAX / uxItemSize))) {
/* Integer overflow in queue size */
return NULL;
}
p_queue = txfr_malloc(sizeof(txfr_queue_t));
if(p_queue == NULL) {
return NULL;
}
mem_size = uxQueueLength*(uxItemSize);
p_mem = txfr_malloc(mem_size);
if(p_mem == NULL) {
txfr_free(p_queue);
return NULL;
}
TX_MEMSET(p_mem, 0, mem_size);
TX_MEMSET(p_queue, 0, sizeof(*p_queue));
p_queue->allocated = 1u;
p_queue->p_mem = p_mem;
p_queue->id = TX_QUEUE_ID;
p_queue->p_write = (uint8_t *)p_mem;
p_queue->p_read = (uint8_t *)p_mem;
p_queue->msg_size = uxItemSize;
p_queue->queue_length = uxQueueLength;
ret = tx_semaphore_create(&p_queue->read_sem, "", 0u);
if(ret != TX_SUCCESS) {
return NULL;
}
ret = tx_semaphore_create(&p_queue->write_sem, "", uxQueueLength);
if(ret != TX_SUCCESS) {
return NULL;
}
return p_queue;
}
void vQueueDelete(QueueHandle_t xQueue)
{
UINT ret;
configASSERT(xQueue != NULL);
ret = tx_semaphore_delete(&xQueue->read_sem);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
}
ret = tx_semaphore_delete(&xQueue->write_sem);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
}
if(xQueue->allocated == 1u) {
vPortFree(xQueue->p_mem);
vPortFree(xQueue);
}
}
BaseType_t xQueueSend(QueueHandle_t xQueue,
const void *pvItemToQueue,
TickType_t xTicksToWait)
{
TX_INTERRUPT_SAVE_AREA;
UINT timeout;
UINT ret;
configASSERT(xQueue != NULL);
configASSERT(pvItemToQueue != NULL);
if(xTicksToWait == portMAX_DELAY) {
timeout = TX_WAIT_FOREVER;
} else {
timeout = (UINT)xTicksToWait;
}
// Wait for space to be available on the queue.
ret = tx_semaphore_get(&xQueue->write_sem, timeout);
if(ret != TX_SUCCESS) {
return pdFALSE;
}
// Enqueue the message.
TX_DISABLE;
memcpy(xQueue->p_write, pvItemToQueue, xQueue->msg_size);
if(xQueue->p_write >= (xQueue->p_mem + (xQueue->msg_size * (xQueue->queue_length - 1u)))) {
xQueue->p_write = xQueue->p_mem;
} else {
xQueue->p_write += xQueue->msg_size;
}
TX_RESTORE;
// Signal that there is an additional message available on the queue.
ret = tx_semaphore_put(&xQueue->read_sem);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return pdFALSE;
}
if(xQueue->p_set != NULL) {
// To prevent deadlocks don't wait when posting on a queue set.
ret = tx_queue_send(&xQueue->p_set->queue, &xQueue, TX_NO_WAIT);
if((ret != TX_SUCCESS) && (ret != TX_QUEUE_FULL)) {
// Fatal error, queue full errors are ignored on purpose to match the original behaviour.
TX_FREERTOS_ASSERT_FAIL();
return pdFALSE;
}
}
return pdPASS;
}
BaseType_t xQueueSendFromISR(QueueHandle_t xQueue,
const void * pvItemToQueue,
BaseType_t *pxHigherPriorityTaskWoken)
{
configASSERT(xQueue != NULL);
configASSERT(pvItemToQueue != NULL);
return xQueueSend(xQueue, pvItemToQueue, 0u);
}
BaseType_t xQueueSendToBack(QueueHandle_t xQueue,
const void * pvItemToQueue,
TickType_t xTicksToWait)
{
configASSERT(xQueue != NULL);
configASSERT(pvItemToQueue != NULL);
return xQueueSend(xQueue, pvItemToQueue, xTicksToWait);
}
BaseType_t xQueueSendToBackFromISR(QueueHandle_t xQueue,
const void * pvItemToQueue,
BaseType_t *pxHigherPriorityTaskWoken)
{
configASSERT(xQueue != NULL);
configASSERT(pvItemToQueue != NULL);
return xQueueSend(xQueue, pvItemToQueue, 0u);
}
BaseType_t xQueueSendToFront(QueueHandle_t xQueue,
const void *pvItemToQueue,
TickType_t xTicksToWait)
{
TX_INTERRUPT_SAVE_AREA;
UINT timeout;
UINT ret;
// TODO-
configASSERT(xQueue != NULL);
configASSERT(pvItemToQueue != NULL);
if(xTicksToWait == portMAX_DELAY) {
timeout = TX_WAIT_FOREVER;
} else {
timeout = (UINT)xTicksToWait;
}
if(xQueue->p_set != NULL) {
TX_DISABLE;
_tx_thread_preempt_disable++;
}
// Wait for space to be available on the queue.
ret = tx_semaphore_get(&xQueue->write_sem, timeout);
if(ret != TX_SUCCESS) {
return pdFALSE;
}
// Enqueue the message at the front.
TX_DISABLE;
// Push back the read pointer.
if(xQueue->p_read == xQueue->p_mem) {
xQueue->p_read = xQueue->p_mem + (xQueue->msg_size * (xQueue->queue_length - 1u));
} else {
xQueue->p_read -= xQueue->msg_size;
}
memcpy(xQueue->p_read, pvItemToQueue, xQueue->msg_size);
TX_RESTORE;
// Signal that there is an additional message available on the queue.
ret = tx_semaphore_put(&xQueue->read_sem);
if(ret != TX_SUCCESS) {
if(xQueue->p_set != NULL) {
_tx_thread_preempt_disable--;
TX_RESTORE;
}
TX_FREERTOS_ASSERT_FAIL();
return pdFALSE;
}
if(xQueue->p_set != NULL) {
// To prevent deadlocks don't wait when posting on a queue set.
ret = tx_queue_send(&xQueue->p_set->queue, &xQueue, TX_NO_WAIT);
if((ret != TX_SUCCESS) && (ret != TX_QUEUE_FULL)) {
// Fatal error, queue full errors are ignored on purpose to match the original behaviour.
_tx_thread_preempt_disable--;
TX_RESTORE;
TX_FREERTOS_ASSERT_FAIL();
return pdFALSE;
}
TX_RESTORE;
_tx_thread_preempt_disable--;
_tx_thread_system_preempt_check();
}
return pdPASS;
}
BaseType_t xQueueSendToFrontFromISR(QueueHandle_t xQueue,
const void * pvItemToQueue,
BaseType_t *pxHigherPriorityTaskWoken)
{
configASSERT(xQueue != NULL);
configASSERT(pvItemToQueue != NULL);
return xQueueSendToFront(xQueue, pvItemToQueue, 0u);
}
BaseType_t xQueueReceive(QueueHandle_t xQueue,
void *pvBuffer,
TickType_t xTicksToWait)
{
TX_INTERRUPT_SAVE_AREA;
UINT timeout;
UINT ret;
configASSERT(xQueue != NULL);
configASSERT(pvBuffer != NULL);
if(xTicksToWait == portMAX_DELAY) {
timeout = TX_WAIT_FOREVER;
} else {
timeout = (UINT)xTicksToWait;
}
// Wait for a message to be available on the queue.
ret = tx_semaphore_get(&xQueue->read_sem, timeout);
if(ret != TX_SUCCESS) {
return pdFAIL;
}
// Retrieve the message.
TX_DISABLE
memcpy(pvBuffer, xQueue->p_read, xQueue->msg_size);
if(xQueue->p_read >= (xQueue->p_mem + (xQueue->msg_size * (xQueue->queue_length - 1u)))) {
xQueue->p_read = xQueue->p_mem;
} else {
xQueue->p_read += xQueue->msg_size;
}
TX_RESTORE
// Signal that there's additional space available on the queue.
ret = tx_semaphore_put(&xQueue->write_sem);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return pdFALSE;
}
return pdPASS;
}
BaseType_t xQueueReceiveFromISR(QueueHandle_t xQueue,
void *pvBuffer,
BaseType_t *pxHigherPriorityTaskWoken)
{
BaseType_t ret;
configASSERT(xQueue != NULL);
configASSERT(pvBuffer != NULL);
ret = xQueueReceive(xQueue, pvBuffer, 0u);
return ret;
}
BaseType_t xQueuePeek(QueueHandle_t xQueue,
void *pvBuffer,
TickType_t xTicksToWait)
{
TX_INTERRUPT_SAVE_AREA;
UINT timeout;
UINT ret;
configASSERT(xQueue != NULL);
configASSERT(pvBuffer != NULL);
if(xTicksToWait == portMAX_DELAY) {
timeout = TX_WAIT_FOREVER;
} else {
timeout = (UINT)xTicksToWait;
}
// Wait for a message to be available on the queue.
ret = tx_semaphore_get(&xQueue->read_sem, timeout);
if(ret != TX_SUCCESS) {
return pdFAIL;
}
// Retrieve the message.
TX_DISABLE;
_tx_thread_preempt_disable++;
memcpy(pvBuffer, xQueue->p_read, xQueue->msg_size);
// Restore the original space on the queue.
ret = tx_semaphore_put(&xQueue->read_sem);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return pdFALSE;
}
_tx_thread_preempt_disable--;
TX_RESTORE;
return pdPASS;
}
BaseType_t xQueuePeekFromISR(QueueHandle_t xQueue,
void *pvBuffer)
{
configASSERT(xQueue != NULL);
configASSERT(pvBuffer != NULL);
return xQueuePeek(xQueue, pvBuffer, 0u);
}
UBaseType_t uxQueueMessagesWaiting(QueueHandle_t xQueue)
{
ULONG count;
UINT ret;
configASSERT(xQueue != NULL);
ret = tx_semaphore_info_get(&xQueue->read_sem, NULL, &count, NULL, NULL, NULL);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return 0;
}
return count;
}
UBaseType_t uxQueueMessagesWaitingFromISR(QueueHandle_t xQueue)
{
configASSERT(xQueue != NULL);
return uxQueueMessagesWaiting(xQueue);
}
UBaseType_t uxQueueSpacesAvailable(QueueHandle_t xQueue)
{
ULONG count;
UINT ret;
configASSERT(xQueue != NULL);
ret = tx_semaphore_info_get(&xQueue->write_sem, NULL, &count, NULL, NULL, NULL);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return 0;
}
return count;
}
BaseType_t xQueueIsQueueEmptyFromISR(const QueueHandle_t xQueue)
{
ULONG count;
UINT ret;
configASSERT(xQueue != NULL);
ret = tx_semaphore_info_get(&xQueue->read_sem, NULL, &count, NULL, NULL, NULL);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return 0;
}
if(count == 0u) {
return pdTRUE;
} else {
return pdFALSE;
}
}
BaseType_t xQueueIsQueueFullFromISR(const QueueHandle_t xQueue)
{
ULONG count;
UINT ret;
configASSERT(xQueue != NULL);
ret = tx_semaphore_info_get(&xQueue->write_sem, NULL, &count, NULL, NULL, NULL);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return 0;
}
if(count == 0u) {
return pdTRUE;
} else {
return pdFALSE;
}
}
BaseType_t xQueueReset(QueueHandle_t xQueue)
{
TX_INTERRUPT_SAVE_AREA;
UINT ret;
UINT write_post;
configASSERT(xQueue != NULL);
write_post = 0u;
TX_DISABLE;
_tx_thread_preempt_disable++;
// Reset pointers.
xQueue->p_write = xQueue->p_mem;
xQueue->p_read = xQueue->p_mem;
// Reset read semaphore.
xQueue->read_sem.tx_semaphore_count = 0u;
// Reset write semaphore.
if(xQueue->write_sem.tx_semaphore_count != xQueue->queue_length) {
write_post = 1u;
xQueue->write_sem.tx_semaphore_count = xQueue->queue_length - 1u;
}
_tx_thread_preempt_disable--;
TX_RESTORE;
if(write_post == 1u) {
// Signal that there's space available on the queue in case a writer was waiting before the reset.
ret = tx_semaphore_put(&xQueue->write_sem);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return pdFALSE;
}
} else {
_tx_thread_system_preempt_check();
}
return pdPASS;
}
BaseType_t xQueueOverwrite(QueueHandle_t xQueue,
const void * pvItemToQueue)
{
TX_INTERRUPT_SAVE_AREA;
UINT ret;
UINT read_post;
uint8_t *p_write_temp;
configASSERT(xQueue != NULL);
configASSERT(pvItemToQueue != NULL);
read_post = 0u;
TX_DISABLE;
if(xQueue->read_sem.tx_semaphore_count != 0u) {
// Go back one message.
p_write_temp = xQueue->p_write;
if(p_write_temp == xQueue->p_mem) {
p_write_temp = (xQueue->p_mem + (xQueue->msg_size * (xQueue->queue_length - 1u)));
} else {
p_write_temp -= xQueue->msg_size;
}
memcpy(p_write_temp, pvItemToQueue, xQueue->msg_size);
} else {
memcpy(xQueue->p_write, pvItemToQueue, xQueue->msg_size);
if(xQueue->p_write >= (xQueue->p_mem + (xQueue->msg_size * (xQueue->queue_length - 1u)))) {
xQueue->p_write = xQueue->p_mem;
} else {
xQueue->p_write += xQueue->msg_size;
}
read_post = 1u;
}
TX_RESTORE;
if(read_post == 1u) {
// Signal that there is an additional message available on the queue.
ret = tx_semaphore_put(&xQueue->read_sem);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return pdFALSE;
}
}
return pdPASS;
}
BaseType_t xQueueOverwriteFromISR(QueueHandle_t xQueue,
const void * pvItemToQueue,
BaseType_t *pxHigherPriorityTaskWoken)
{
configASSERT(xQueue != NULL);
configASSERT(pvItemToQueue != NULL);
return xQueueOverwrite(xQueue, pvItemToQueue);
}
EventGroupHandle_t xEventGroupCreate(void)
{
txfr_event_t *p_event;
UINT ret;
#if (TX_FREERTOS_AUTO_INIT == 1)
if(txfr_initialized != 1u) {
tx_freertos_auto_init();
}
#endif
p_event = txfr_malloc(sizeof(txfr_event_t));
if(p_event == NULL) {
return NULL;
}
TX_MEMSET(p_event, 0, sizeof(*p_event));
p_event->allocated = 1u;
ret = tx_event_flags_create(&p_event->event, "");
if(ret != TX_SUCCESS) {
txfr_free(p_event);
return NULL;
}
return p_event;
}
EventGroupHandle_t xEventGroupCreateStatic(StaticEventGroup_t *pxEventGroupBuffer)
{
UINT ret;
configASSERT(pxEventGroupBuffer != NULL);
#if (TX_FREERTOS_AUTO_INIT == 1)
if(txfr_initialized != 1u) {
tx_freertos_auto_init();
}
#endif
TX_MEMSET(pxEventGroupBuffer, 0, sizeof(*pxEventGroupBuffer));
pxEventGroupBuffer->allocated = 0u;
ret = tx_event_flags_create(&pxEventGroupBuffer->event, "");
if(ret != TX_SUCCESS) {
return NULL;
}
return pxEventGroupBuffer;
}
void vEventGroupDelete(EventGroupHandle_t xEventGroup)
{
UINT ret;
configASSERT(xEventGroup != NULL);
ret = tx_event_flags_delete(&xEventGroup->event);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return;
}
if(xEventGroup->allocated == 1u) {
vPortFree(xEventGroup);
}
}
EventBits_t xEventGroupWaitBits(const EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToWaitFor,
const BaseType_t xClearOnExit,
const BaseType_t xWaitForAllBits,
TickType_t xTicksToWait)
{
ULONG bits;
UINT timeout;
UINT ret;
UINT get_option;
configASSERT(xEventGroup != NULL);
if(xTicksToWait == portMAX_DELAY) {
timeout = TX_WAIT_FOREVER;
} else {
timeout = (UINT)xTicksToWait;
}
if(xWaitForAllBits == pdFALSE) {
if(xClearOnExit == pdFALSE) {
get_option = TX_OR;
} else {
get_option = TX_OR_CLEAR;
}
} else {
if(xClearOnExit == pdFALSE) {
get_option = TX_AND;
} else {
get_option = TX_AND_CLEAR;
}
}
ret = tx_event_flags_get(&xEventGroup->event, uxBitsToWaitFor, get_option, &bits, timeout);
if(ret != TX_SUCCESS) {
return 0;
}
return bits;
}
EventBits_t xEventGroupSetBits(EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet)
{
UINT ret;
ULONG bits;
configASSERT(xEventGroup != NULL);
ret = tx_event_flags_set(&xEventGroup->event, uxBitsToSet, TX_OR);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return 0u;
}
ret = tx_event_flags_info_get(&xEventGroup->event, NULL, &bits, NULL, NULL, NULL);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return 0u;
}
return bits;
}
BaseType_t xEventGroupSetBitsFromISR(EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToSet,
BaseType_t *pxHigherPriorityTaskWoken)
{
configASSERT(xEventGroup != NULL);
return xEventGroupSetBits(xEventGroup, uxBitsToSet);
}
EventBits_t xEventGroupClearBits(EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToClear)
{
UINT ret;
ULONG bits;
ULONG bits_before;
TX_INTERRUPT_SAVE_AREA;
configASSERT(xEventGroup != NULL);
TX_DISABLE;
ret = tx_event_flags_info_get(&xEventGroup->event, NULL, &bits_before, NULL, NULL, NULL);
if(ret != TX_SUCCESS) {
TX_RESTORE;
TX_FREERTOS_ASSERT_FAIL();
return 0u;
}
bits = uxBitsToClear;
ret = tx_event_flags_set(&xEventGroup->event, ~bits, TX_AND);
if(ret != TX_SUCCESS) {
TX_RESTORE;
TX_FREERTOS_ASSERT_FAIL();
return 0u;
}
TX_RESTORE;
return bits_before;
}
BaseType_t xEventGroupClearBitsFromISR(EventGroupHandle_t xEventGroup,
const EventBits_t uxBitsToClear)
{
configASSERT(xEventGroup != NULL);
return xEventGroupClearBits(xEventGroup, uxBitsToClear);
}
EventBits_t xEventGroupGetBits(EventGroupHandle_t xEventGroup)
{
UINT ret;
ULONG bits;
configASSERT(xEventGroup != NULL);
ret = tx_event_flags_info_get(&xEventGroup->event, NULL, &bits, NULL, NULL, NULL);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return 0u;
}
return bits;
}
EventBits_t xEventGroupGetBitsFromISR(EventGroupHandle_t xEventGroup)
{
configASSERT(xEventGroup != NULL);
return xEventGroupGetBits(xEventGroup);
}
void txfr_timer_callback_wrapper(ULONG id)
{
txfr_timer_t *p_timer;
p_timer = (txfr_timer_t *)id;
if(p_timer == NULL) {
TX_FREERTOS_ASSERT_FAIL();
}
p_timer->callback(p_timer);
}
TimerHandle_t xTimerCreate(const char * const pcTimerName,
const TickType_t xTimerPeriod,
const UBaseType_t uxAutoReload,
void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction)
{
txfr_timer_t *p_timer;
UINT ret;
ULONG resch_ticks;
configASSERT(xTimerPeriod != 0u);
configASSERT(pxCallbackFunction != NULL);
#if (TX_FREERTOS_AUTO_INIT == 1)
if(txfr_initialized != 1u) {
tx_freertos_auto_init();
}
#endif
p_timer = txfr_malloc(sizeof(txfr_timer_t));
if(p_timer == NULL) {
return NULL;
}
TX_MEMSET(p_timer, 0, sizeof(*p_timer));
p_timer->allocated = 1u;
p_timer->period = xTimerPeriod;
p_timer->id = pvTimerID;
p_timer->callback = pxCallbackFunction;
if(uxAutoReload != pdFALSE) {
resch_ticks = xTimerPeriod;
p_timer->one_shot = 1u;
} else {
p_timer->one_shot = 0u;
resch_ticks = 0u;
}
ret = tx_timer_create(&p_timer->timer, (char *)pcTimerName, txfr_timer_callback_wrapper, (ULONG)p_timer, xTimerPeriod, resch_ticks, TX_NO_ACTIVATE);
if(ret != TX_SUCCESS) {
txfr_free(p_timer);
return NULL;
}
return p_timer;
}
TimerHandle_t xTimerCreateStatic(const char * const pcTimerName,
const TickType_t xTimerPeriod,
const UBaseType_t uxAutoReload,
void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction,
StaticTimer_t *pxTimerBuffer)
{
UINT ret;
ULONG resch_ticks;
configASSERT(xTimerPeriod != 0u);
configASSERT(pxCallbackFunction != NULL);
configASSERT(pxTimerBuffer != NULL);
#if (TX_FREERTOS_AUTO_INIT == 1)
if(txfr_initialized != 1u) {
tx_freertos_auto_init();
}
#endif
TX_MEMSET(pxTimerBuffer, 0, sizeof(*pxTimerBuffer));
pxTimerBuffer->allocated = 0u;
pxTimerBuffer->period = xTimerPeriod;
pxTimerBuffer->id = pvTimerID;
pxTimerBuffer->callback = pxCallbackFunction;
if(uxAutoReload != pdFALSE) {
resch_ticks = xTimerPeriod;
} else {
resch_ticks = 0u;
}
ret = tx_timer_create(&pxTimerBuffer->timer, (char *)pcTimerName, txfr_timer_callback_wrapper, (ULONG)pxTimerBuffer, xTimerPeriod, resch_ticks, TX_NO_ACTIVATE);
if(ret != TX_SUCCESS) {
return NULL;
}
return pxTimerBuffer;
}
BaseType_t xTimerDelete(TimerHandle_t xTimer, TickType_t xBlockTime)
{
UINT ret;
configASSERT(xTimer != NULL);
ret = tx_timer_delete(&xTimer->timer);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return pdFAIL;
}
if(xTimer->allocated == 1u) {
vPortFree(xTimer);
}
return pdPASS;
}
BaseType_t xTimerIsTimerActive(TimerHandle_t xTimer)
{
UINT ret;
UINT is_active;
configASSERT(xTimer != NULL);
ret = tx_timer_info_get(&xTimer->timer, NULL, &is_active, NULL, NULL, NULL);
if(ret != TX_SUCCESS) {
return pdFALSE;
}
if(is_active == TX_TRUE) {
return pdTRUE;
} else {
return pdFALSE;
}
}
BaseType_t xTimerStart(TimerHandle_t xTimer,
TickType_t xBlockTime)
{
UINT ret;
configASSERT(xTimer != NULL);
ret = tx_timer_activate(&xTimer->timer);
if(ret != TX_SUCCESS) {
return pdFAIL;
}
return pdPASS;
}
BaseType_t xTimerStop(TimerHandle_t xTimer,
TickType_t xBlockTime)
{
UINT ret;
configASSERT(xTimer != NULL);
ret = tx_timer_deactivate(&xTimer->timer);
if(ret != TX_SUCCESS) {
return pdFAIL;
}
return pdPASS;
}
BaseType_t xTimerChangePeriod(TimerHandle_t xTimer,
TickType_t xNewPeriod,
TickType_t xBlockTime)
{
UINT ret;
TX_INTERRUPT_SAVE_AREA;
configASSERT(xTimer != NULL);
configASSERT(xNewPeriod != 0u);
TX_DISABLE;
ret = tx_timer_deactivate(&xTimer->timer);
if(ret != TX_SUCCESS) {
TX_RESTORE;
return pdFAIL;
}
if(xTimer->one_shot != 0u) {
ret = tx_timer_change(&xTimer->timer, xNewPeriod, xNewPeriod);
} else {
ret = tx_timer_change(&xTimer->timer, xNewPeriod, 0u);
}
if(ret != TX_SUCCESS) {
TX_RESTORE;
return pdFAIL;
}
ret = tx_timer_activate(&xTimer->timer);
if(ret != TX_SUCCESS) {
TX_RESTORE;
return pdFAIL;
}
TX_RESTORE;
return pdPASS;
}
BaseType_t xTimerReset(TimerHandle_t xTimer,
TickType_t xBlockTime)
{
UINT ret;
TX_INTERRUPT_SAVE_AREA;
configASSERT(xTimer != NULL);
TX_DISABLE;
ret = tx_timer_deactivate(&xTimer->timer);
if(ret != TX_SUCCESS) {
TX_RESTORE;
return pdFAIL;
}
if(xTimer->one_shot != 0u) {
ret = tx_timer_change(&xTimer->timer, xTimer->period, xTimer->period);
} else {
ret = tx_timer_change(&xTimer->timer, xTimer->period, 0u);
}
if(ret != TX_SUCCESS) {
TX_RESTORE;
return pdFAIL;
}
ret = tx_timer_activate(&xTimer->timer);
if(ret != TX_SUCCESS) {
TX_RESTORE;
return pdFAIL;
}
TX_RESTORE;
return pdPASS;
}
BaseType_t xTimerStartFromISR(TimerHandle_t xTimer,
BaseType_t *pxHigherPriorityTaskWoken)
{
configASSERT(xTimer != NULL);
return xTimerStart(xTimer, 0u);
}
BaseType_t xTimerStopFromISR(TimerHandle_t xTimer,
BaseType_t *pxHigherPriorityTaskWoken)
{
configASSERT(xTimer != NULL);
return xTimerStop(xTimer, 0u);
}
BaseType_t xTimerChangePeriodFromISR(TimerHandle_t xTimer,
TickType_t xNewPeriod,
BaseType_t *pxHigherPriorityTaskWoken)
{
configASSERT(xTimer != NULL);
configASSERT(xNewPeriod != 0u);
return xTimerChangePeriod(xTimer, xNewPeriod, 0u);
}
BaseType_t xTimerResetFromISR(TimerHandle_t xTimer,
BaseType_t *pxHigherPriorityTaskWoken)
{
configASSERT(xTimer != NULL);
return xTimerReset(xTimer, 0u);
}
void *pvTimerGetTimerID(TimerHandle_t xTimer)
{
TX_INTERRUPT_SAVE_AREA;
void *p_id;
configASSERT(xTimer != NULL);
TX_DISABLE;
p_id = xTimer->id;
TX_RESTORE;
return p_id;
}
void vTimerSetTimerID(TimerHandle_t xTimer, void *pvNewID)
{
TX_INTERRUPT_SAVE_AREA;
configASSERT(xTimer != NULL);
TX_DISABLE;
xTimer->id = pvNewID;
TX_RESTORE;
return;
}
void vTimerSetReloadMode(TimerHandle_t xTimer,
const UBaseType_t uxAutoReload)
{
UINT ret;
TX_INTERRUPT_SAVE_AREA;
ULONG left;
configASSERT(xTimer != NULL);
TX_DISABLE;
ret = tx_timer_deactivate(&xTimer->timer);
if(ret != TX_SUCCESS) {
TX_RESTORE;
return;
}
left = xTimer->timer.tx_timer_internal.tx_timer_internal_remaining_ticks;
if(uxAutoReload != pdFALSE) {
ret = tx_timer_change(&xTimer->timer, left, xTimer->period);
} else {
ret = tx_timer_change(&xTimer->timer, left, 0u);
}
if(ret != TX_SUCCESS) {
TX_RESTORE;
return;
}
ret = tx_timer_activate(&xTimer->timer);
if(ret != TX_SUCCESS) {
TX_RESTORE;
return;
}
TX_RESTORE;
return;
}
const char * pcTimerGetName(TimerHandle_t xTimer)
{
configASSERT(xTimer != NULL);
return (const char *)xTimer->timer.tx_timer_name;
}
TickType_t xTimerGetPeriod(TimerHandle_t xTimer)
{
TX_INTERRUPT_SAVE_AREA;
TickType_t period;
configASSERT(xTimer != NULL);
TX_DISABLE;
period = xTimer->period;
TX_RESTORE;
return period;
}
TickType_t xTimerGetExpiryTime(TimerHandle_t xTimer)
{
TX_INTERRUPT_SAVE_AREA;
ULONG time_tx;
TickType_t time;
UINT ret;
configASSERT(xTimer != NULL);
TX_DISABLE;
ret = tx_timer_info_get(&xTimer->timer, NULL, NULL, &time_tx, NULL, NULL);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return 0u;
}
time = (TickType_t)(tx_time_get() + time_tx);
TX_RESTORE;
return time;
}
UBaseType_t uxTimerGetReloadMode(TimerHandle_t xTimer)
{
TX_INTERRUPT_SAVE_AREA;
UBaseType_t type;
configASSERT(xTimer != NULL);
TX_DISABLE;
if(xTimer->one_shot == 0u) {
type = pdTRUE;
} else {
type = pdFALSE;
}
TX_RESTORE;
return type;
}
QueueSetHandle_t xQueueCreateSet(const UBaseType_t uxEventQueueLength)
{
txfr_queueset_t *p_set;
void *p_mem;
ULONG queue_size;
UINT ret;
configASSERT(uxEventQueueLength != 0u);
#if (TX_FREERTOS_AUTO_INIT == 1)
if(txfr_initialized != 1u) {
tx_freertos_auto_init();
}
#endif
if ((uxEventQueueLength > (SIZE_MAX / sizeof(void *))) ||
(uxEventQueueLength > (ULONG_MAX / sizeof(void *)))) {
/* Integer overflow in queue size */
return NULL;
}
p_set = txfr_malloc(sizeof(txfr_queueset_t));
if(p_set == NULL) {
return NULL;
}
queue_size = sizeof(void *) * uxEventQueueLength;
p_mem = txfr_malloc(queue_size);
if(p_mem == NULL) {
txfr_free(p_set);
return NULL;
}
ret = tx_queue_create(&p_set->queue, "", sizeof(void *) / sizeof(UINT), p_mem, queue_size);
if(ret != TX_SUCCESS) {
TX_FREERTOS_ASSERT_FAIL();
return NULL;
}
return p_set;
}
BaseType_t xQueueAddToSet(QueueSetMemberHandle_t xQueueOrSemaphore,
QueueSetHandle_t xQueueSet)
{
txfr_sem_t *p_sem;
txfr_queue_t *p_queue;
TX_INTERRUPT_SAVE_AREA;
configASSERT(xQueueOrSemaphore != NULL);
configASSERT(xQueueSet != NULL);
TX_DISABLE;
if(*((ULONG *)(xQueueOrSemaphore)) == TX_SEMAPHORE_ID) {
p_sem = (txfr_sem_t *)xQueueOrSemaphore;
if(p_sem->p_set != NULL) {
TX_RESTORE;
return pdFAIL;
}
p_sem->p_set = xQueueSet;
} else if(*((ULONG *)(xQueueOrSemaphore)) == TX_QUEUE_ID) {
p_queue = (txfr_queue_t *)xQueueOrSemaphore;
if(p_queue->p_set != NULL) {
TX_RESTORE;
return pdFAIL;
}
p_queue->p_set = xQueueSet;
} else {
TX_RESTORE;
configASSERT(0u);
return pdFAIL;
}
TX_RESTORE;
return pdPASS;
}
BaseType_t xQueueRemoveFromSet(QueueSetMemberHandle_t xQueueOrSemaphore,
QueueSetHandle_t xQueueSet)
{
txfr_sem_t *p_sem;
txfr_queue_t *p_queue;
TX_INTERRUPT_SAVE_AREA;
configASSERT(xQueueOrSemaphore != NULL);
configASSERT(xQueueSet != NULL);
TX_DISABLE;
if(*((ULONG *)(xQueueOrSemaphore)) == TX_SEMAPHORE_ID) {
p_sem = (txfr_sem_t *)xQueueOrSemaphore;
if(p_sem->p_set != xQueueSet) {
TX_RESTORE;
return pdFAIL;
} else {
p_sem->p_set = NULL;
}
} else if(*((ULONG *)(xQueueOrSemaphore)) == TX_QUEUE_ID) {
p_queue = (txfr_queue_t *)xQueueOrSemaphore;
if(p_queue->p_set != xQueueSet) {
TX_RESTORE;
return pdFAIL;
} else {
p_queue->p_set = NULL;
}
} else {
TX_RESTORE;
configASSERT(0u);
return pdFAIL;
}
TX_RESTORE;
return pdPASS;
}
QueueSetMemberHandle_t xQueueSelectFromSet(QueueSetHandle_t xQueueSet,
const TickType_t xTicksToWait)
{
void *p_ptr;
UINT ret;
UINT timeout;
configASSERT(xQueueSet != NULL);
if(xTicksToWait == portMAX_DELAY) {
timeout = TX_WAIT_FOREVER;
} else {
timeout = (UINT)xTicksToWait;
}
ret = tx_queue_receive(&xQueueSet->queue, &p_ptr, timeout);
if(ret != TX_SUCCESS) {
return NULL;
}
return p_ptr;
}
QueueSetMemberHandle_t xQueueSelectFromSetFromISR(QueueSetHandle_t xQueueSet)
{
return xQueueSelectFromSet(xQueueSet, 0u);
}