summaryrefslogtreecommitdiff
path: root/utility/rtos_compatibility_layers/FreeRTOS/tx_freertos.c
diff options
context:
space:
mode:
Diffstat (limited to 'utility/rtos_compatibility_layers/FreeRTOS/tx_freertos.c')
-rw-r--r--utility/rtos_compatibility_layers/FreeRTOS/tx_freertos.c2809
1 files changed, 2809 insertions, 0 deletions
diff --git a/utility/rtos_compatibility_layers/FreeRTOS/tx_freertos.c b/utility/rtos_compatibility_layers/FreeRTOS/tx_freertos.c
new file mode 100644
index 00000000..132e9036
--- /dev/null
+++ b/utility/rtos_compatibility_layers/FreeRTOS/tx_freertos.c
@@ -0,0 +1,2809 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) Microsoft Corporation. All rights reserved. */
+/* */
+/* This software is licensed under the Microsoft Software License */
+/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+/* and in the root directory of this software. */
+/* */
+/**************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** FreeRTOS compatibility Kit */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 09-30-2020 William E. Lamie Initial Version 6.1 */
+/* */
+/**************************************************************************/
+
+#include <stdint.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;
+#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)
+ _tx_thread_schedule();
+#else
+ // Nothing to do, THREADX scheduler is already started.
+#endif
+}
+
+
+BaseType_t xTaskGetSchedulerState(void)
+{
+ 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;
+ 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
+
+ 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,
+ puxStackBuffer, ulStackDepth, 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;
+ 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
+
+ p_stack = txfr_malloc(usStackDepth);
+ 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();
+ return NULL;
+ }
+
+ prio = txfr_prio_fr_to_tx(uxPriority);
+
+ ret = tx_thread_create(&p_task->thread, (CHAR *)pcName, txfr_thread_wrapper, (ULONG)pvParameters,
+ p_stack, usStackDepth, 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();
+ return 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->p_set != NULL) {
+ TX_DISABLE;
+ _tx_thread_preempt_disable++;
+ }
+
+ if(xSemaphore->is_mutex == 1u) {
+ ret = tx_mutex_put(&xSemaphore->mutex);
+ if(ret != TX_SUCCESS) {
+ return pdFALSE;
+ }
+ } else {
+ if(xSemaphore->p_set == NULL) {
+ TX_DISABLE;
+ _tx_thread_preempt_disable++;
+ }
+
+ if(xSemaphore->sem.tx_semaphore_count >= xSemaphore->max_count) {
+ /* Maximum semaphore count reached return failure. */
+ _tx_thread_preempt_disable--;
+ TX_RESTORE
+ return pdFALSE;
+ }
+
+ ret = tx_semaphore_put(&xSemaphore->sem);
+ if(ret != TX_SUCCESS) {
+ _tx_thread_preempt_disable--;
+ TX_RESTORE;
+ return pdFALSE;
+ }
+
+ if(xSemaphore->p_set == NULL) {
+ _tx_thread_preempt_disable--;
+ TX_RESTORE;
+
+ _tx_thread_system_preempt_check();
+ }
+ }
+
+ 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;
+ }
+
+ _tx_thread_preempt_disable--;
+ TX_RESTORE;
+
+ _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
+
+ 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
+
+ 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);
+}