Files
arcs/arcs-sdk/modules/rtos_al/rtos_al.c
2026-08-13 16:50:52 +08:00

971 lines
25 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
****************************************************************************************
*
* @file rtos_al.c
*
* @brief Implementation of the FreeRTOS abstraction layer.
*
* Copyright (C) ListenAI 2024-2025
*
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include <stdio.h>
#include <string.h>
#include <FreeRTOSConfig.h>
#include "rtos_def.h"
#include "rtos_al.h"
#include "semphr.h"
#include "dbg_assert.h"
#include "arcs_ap.h"
#include "timers.h"
//AP/CP两个工程依赖的heap头文件不一致
#include "sysheap.h"
#include "esp_heap_caps.h"
#include "assert.h"
#if NX_TRACE
#define TRACE_FILE_ID (0xFFFFFF >> TRACE_FILE_ID_OFT)
/// conversion table between task handles and task ID (for trace purpose)
static rtos_task_handle task_table[MAX_TASK];
/// ID of the task that is currently being created.
/// (Needed as traceTASK_CREATE hook is called before task_table is update)
static enum rtos_task_id creating_task_id = UNDEF_TASK;
#endif
// #if configAPPLICATION_ALLOCATED_HEAP
// #define __MHEAP __attribute__ ((section("MHEAP")))
// uint8_t ucHeap[ configTOTAL_HEAP_SIZE ] __MHEAP;
// #endif
static bool __os_started = false;
rtos_stack_type wpa_task_stack_buf[1024];
rtos_static_task_tcb wpa_task_control;
/*
* FUNCTIONS
****************************************************************************************
*/
/**
****************************************************************************************
* @brief get task name by handle
*
* @param[in] ptr pointer of taskhandle
* @return task name
*
***************************************************************************************
*/
char *rtos_get_name_by_handle(TaskHandle_t ptr)
{
return pcTaskGetName(ptr);
}
/**
****************************************************************************************
* @brief Convert ms to ticks
*
* @param[in] timeout_ms Timeout value in ms (use -1 for no timeout).
* @return number of ticks for the specified timeout value.
*
****************************************************************************************
*/
__STATIC_INLINE TickType_t rtos_timeout_2_tickcount(int timeout_ms)
{
if (timeout_ms < 0)
{
return portMAX_DELAY;
}
else
{
return pdMS_TO_TICKS(timeout_ms);
}
}
uint32_t rtos_now(bool isr)
{
if (isr)
{
return xTaskGetTickCountFromISR();
}
else
{
return xTaskGetTickCount();
}
}
void rtos_delay(uint32_t duration_ms)
{
vTaskDelay(pdMS_TO_TICKS(duration_ms));
}
void *rtos_malloc(uint32_t size)
{
void *res = exram_malloc(32, size);
return res;
}
void *rtos_calloc(uint32_t nb_elt, uint32_t size)
{
void *res = exram_calloc(32, nb_elt, size);
assert(res != NULL);
return res;
}
void *rtos_realloc(void *ptr, uint32_t new_size)
{
return exram_realloc(ptr, new_size);
}
void rtos_free(void *ptr)
{
exram_free(ptr);
}
// void *_malloc_r(struct _reent *reent, size_t size)
// {
// return rtos_malloc(size);
// }
// void *_calloc_r(struct _reent *reent, size_t num, size_t size)
// {
// return rtos_calloc(num, size);
// }
// void *_realloc_r(struct _reent *reent, void *ptr, size_t new_size)
// {
// return rtos_realloc(ptr, new_size);
// }
// void _free_r(struct _reent *reent, void *ptr)
// {
// rtos_free(ptr);
// }
void *rtos_aligned_malloc(uint32_t size, uint32_t alignment)
{
void *res = exram_malloc(alignment, size);
assert(res != NULL);
return res;
}
void rtos_aligned_free(void *ptr)
{
if (ptr)
{
exram_free(ptr);
}
}
void rtos_heap_info(int *total_size, int *free_size, int *min_free_size)
{
multi_heap_info_t heap_info;
heap_caps_get_info(&heap_info, MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM);
*total_size = heap_info.total_free_bytes + heap_info.total_allocated_bytes;
*free_size = heap_info.total_free_bytes;
*min_free_size = heap_info.minimum_free_bytes;
}
int rtos_task_create(rtos_task_fct func,
const char * const name,
enum rtos_task_id task_id,
const uint16_t stack_depth,
void * const params,
rtos_prio prio,
rtos_task_handle * const task_handle)
{
BaseType_t res;
rtos_task_handle handle;
#if NX_TRACE
creating_task_id = task_id;
#endif
// 临时 * 4避免栈溢出
res = xTaskCreate(func, name, stack_depth * 4, params, prio, &handle);
if (res == pdFAIL){
assert(0);
return 1;
}
#if ( configUSE_TRACE_FACILITY == 1 )
vTaskSetTaskNumber(handle, task_id);
#endif
if (task_handle) {
*task_handle = handle;
}
return 0;
}
void rtos_task_delete(rtos_task_handle task_handle)
{
if (!task_handle)
task_handle = xTaskGetCurrentTaskHandle();
if (eTaskGetState(task_handle) != eDeleted)
vTaskDelete(task_handle);
}
int rtos_task_create_static(rtos_task_fct func,
const char * const name,
enum rtos_task_id task_id,
const uint16_t stack_depth,
void * const params,
rtos_prio prio,
rtos_task_handle * const task_handle,
rtos_stack_type * task_stack_buf,
rtos_static_task_tcb * task_stask_tcb)
{
rtos_task_handle handle;
#if NX_TRACE
creating_task_id = task_id;
#endif
handle = xTaskCreateStatic(func, name, stack_depth, params, prio, task_stack_buf, task_stask_tcb);
if (handle == NULL){
assert(0);
return 1;
}
#if ( configUSE_TRACE_FACILITY == 1 )
vTaskSetTaskNumber(handle, task_id);
#endif
if (task_handle) {
*task_handle = handle;
}
return 0;
}
void rtos_task_suspend(int duration)
{
if (duration <= 0)
return;
vTaskDelay(pdMS_TO_TICKS(duration));
}
int rtos_task_init_notification(rtos_task_handle task)
{
return 0;
}
int rtos_task_wait_notification(int timeout)
{
return ulTaskNotifyTake(pdTRUE, rtos_timeout_2_tickcount(timeout));
}
void rtos_task_notify(rtos_task_handle task, bool isr)
{
if (isr)
{
BaseType_t task_woken = pdFALSE;
vTaskNotifyGiveFromISR(task, &task_woken);
portYIELD_FROM_ISR(task_woken);
}
else
{
xTaskNotifyGive(task);
}
}
int rtos_queue_create(int elt_size, int nb_elt, rtos_queue *queue)
{
*queue = xQueueCreate(nb_elt, elt_size);
assert(*queue != NULL);
if ( *queue == NULL )
return -1;
return 0;
}
void rtos_queue_delete(rtos_queue queue)
{
vQueueDelete(queue);
}
bool rtos_queue_is_empty(rtos_queue queue)
{
BaseType_t res;
GLOBAL_INT_DISABLE();
res = xQueueIsQueueEmptyFromISR(queue);
GLOBAL_INT_RESTORE();
return (res == pdTRUE);
}
bool rtos_queue_is_full(rtos_queue queue)
{
BaseType_t res;
GLOBAL_INT_DISABLE();
res = xQueueIsQueueFullFromISR(queue);
GLOBAL_INT_RESTORE();
return (res == pdTRUE);
}
int rtos_queue_cnt(rtos_queue queue)
{
UBaseType_t res;
GLOBAL_INT_DISABLE();
res = uxQueueMessagesWaitingFromISR(queue);
GLOBAL_INT_RESTORE();
return ((int)res);
}
int rtos_queue_write(rtos_queue queue, void *msg, int timeout, bool isr)
{
BaseType_t res;
if (isr)
{
BaseType_t task_woken = pdFALSE;
res = xQueueSendToBackFromISR(queue, msg, &task_woken);
portYIELD_FROM_ISR(task_woken);
}
else
{
res = xQueueSendToBack(queue, msg, rtos_timeout_2_tickcount(timeout));
}
return (res == errQUEUE_FULL);
}
int rtos_queue_read(rtos_queue queue, void *msg, int timeout, bool isr)
{
BaseType_t res = pdPASS;
if (isr)
{
BaseType_t task_woken = pdFALSE;
res = xQueueReceiveFromISR(queue, msg, &task_woken);
portYIELD_FROM_ISR(task_woken);
}
else
{
res = xQueueReceive(queue, msg, rtos_timeout_2_tickcount(timeout));
}
return (res == errQUEUE_EMPTY);
}
int rtos_semaphore_create(rtos_semaphore *semaphore, int max_count, int init_count)
{
int res = -1;
if (max_count == 1)
{
*semaphore = xSemaphoreCreateBinary();
assert(*semaphore != NULL);
if (*semaphore != 0)
{
if (init_count)
{
xSemaphoreGive(*semaphore);
}
res = 0;
}
}
else
{
*semaphore = xSemaphoreCreateCounting(max_count, init_count);
assert(*semaphore != NULL);
if (*semaphore != 0)
{
res = 0;
}
}
return res;
}
void rtos_semaphore_delete(rtos_semaphore semaphore)
{
vSemaphoreDelete(semaphore);
}
int rtos_semaphore_get_count(rtos_semaphore semaphore)
{
return uxSemaphoreGetCount(semaphore);
}
int rtos_semaphore_wait(rtos_semaphore semaphore, int timeout)
{
BaseType_t res = pdPASS;
res = xSemaphoreTake(semaphore, rtos_timeout_2_tickcount(timeout));
return (res == errQUEUE_EMPTY);
}
int rtos_semaphore_signal(rtos_semaphore semaphore, bool isr)
{
BaseType_t res;
if (isr)
{
BaseType_t task_woken = pdFALSE;
res = xSemaphoreGiveFromISR(semaphore, &task_woken);
portYIELD_FROM_ISR(task_woken);
}
else
{
res = xSemaphoreGive(semaphore);
}
return (res == errQUEUE_FULL);
}
int rtos_mutex_create(rtos_mutex *mutex)
{
int res = -1;
*mutex = xSemaphoreCreateMutex();
assert(*mutex != NULL);
if (*mutex != 0)
{
res = 0;
}
return res;
}
void rtos_mutex_delete(rtos_mutex mutex)
{
#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) )
ASSERT_ERR(xSemaphoreGetMutexHolder(mutex) == NULL);
#endif
vSemaphoreDelete(mutex);
}
void rtos_mutex_lock(rtos_mutex mutex)
{
xSemaphoreTake(mutex, portMAX_DELAY);
}
void rtos_mutex_unlock(rtos_mutex mutex)
{
xSemaphoreGive(mutex);
}
uint32_t rtos_protect(void)
{
taskENTER_CRITICAL();
return 1;
}
void rtos_unprotect(uint32_t protect)
{
(void) protect;
taskEXIT_CRITICAL();
}
void rtos_start_scheduler(void)
{
__os_started = true;
vTaskStartScheduler();
}
bool rtos_os_started(void)
{
return __os_started;
}
int rtos_init(void)
{
#if NX_TRACE
memset(task_table, 0, sizeof(task_table));
#endif
return 0;
}
#if NX_TRACE
/**
****************************************************************************************
* @brief Get task id from task handle
*
* @param[in] task Task handle. If NULL use curretn task handle
* @return id of the task within @ref rtos_task_id.
****************************************************************************************
*/
__STATIC_INLINE int rtos_trace_task_id(void *task)
{
if (!task)
task = xTaskGetCurrentTaskHandle();
int i;
for (i = 0; i < MAX_TASK; i++)
{
if (task == task_table[i])
{
return i;
}
}
return UNDEF_TASK;
}
#endif
rtos_task_handle rtos_get_task_handle()
{
return xTaskGetCurrentTaskHandle();
}
void rtos_trace_task(int id, void *task)
{
#if NX_TRACE
enum rtos_task_id task_id = rtos_trace_task_id(task);
if (id == RTOS_TRACE_SWITCH_IN)
{
TRACE_RTOS(SWITCH_IN, "Enter Task %rT", task_id);
}
else if (id == RTOS_TRACE_SWITCH_OUT)
{
TRACE_RTOS(SWITCH_OUT, "Exit Task %rT", task_id);
}
else if (id == RTOS_TRACE_DELETE)
{
TRACE_RTOS(CREATE, "Delete task %rT", task_id);
}
else if (id == RTOS_TRACE_SUSPEND)
{
TRACE_RTOS(SUSPEND, "Suspend task %rT", task_id);
}
else if (id == RTOS_TRACE_RESUME)
{
TRACE_RTOS(SUSPEND, "Resume task %rT", task_id);
}
else if (id == RTOS_TRACE_RESUME_FROM_ISR)
{
TRACE_RTOS(SUSPEND, "Resume from ISR task %rT", task_id);
}
else if (id == RTOS_TRACE_CREATE)
{
if ((creating_task_id == UNDEF_TASK) &&
(task_table[IDLE_TASK] == NULL)
#if( configSUPPORT_STATIC_ALLOCATION == 0 )
&& (task == xTaskGetIdleTaskHandle())
#endif
)
{
task_table[IDLE_TASK] = task;
creating_task_id = IDLE_TASK;
}
else if (creating_task_id < MAX_TASK)
{
task_table[creating_task_id] = task;
}
TRACE_RTOS(CREATE, "Create task %rT", creating_task_id);
creating_task_id = UNDEF_TASK;
}
#endif
}
void rtos_trace_mem(int id, void *ptr, int size, int free_size)
{
#if NX_TRACE
enum rtos_task_id task_id = rtos_trace_task_id(NULL);
if (id == RTOS_TRACE_ALLOC)
{
if (ptr == NULL)
{
TRACE_RTOS(ERR, "[%rT] Failed to allocate %d bytes. (free_size = %d)",
task_id, size, free_size);
}
#if RTOS_MALLOC_TRACE_LEVEL > 0
else
{
TRACE_RTOS(ALLOC, "[%rT] Allocate %d bytes at %p. (free_size = %d)",
task_id, size, TR_PTR(ptr), free_size);
}
#endif
}
else if (id == RTOS_TRACE_FREE)
{
TRACE_RTOS(FREE, "[%rT] Free %d bytes at %p. (free_size = %d)",
task_id, size, TR_PTR(ptr), free_size);
}
#endif
}
void rtos_priority_set(rtos_task_handle handle, rtos_prio priority)
{
vTaskPrioritySet(handle, priority);
}
uint32_t rtos_get_time(void)
{
return ( xTaskGetTickCount( ) * 1000 / configTICK_RATE_HZ );
}
bool rtos_time_past(uint32_t timestamp_ms, uint32_t timeout_ms)
{
uint32_t cur_ms = rtos_get_time();
uint32_t timepast_ms;
if (cur_ms < timestamp_ms)
{
timepast_ms = cur_ms + (portMAX_DELAY - timestamp_ms) + 1;
}
else
{
timepast_ms = cur_ms - timestamp_ms;
}
if (timepast_ms >= timeout_ms)
{
return true;
}
return false;
}
#ifndef SYS_TIMER_FREQ
#define SYS_TIMER_FREQ (1000000UL)
#endif
int32_t rtos_get_sys_time(enum time_origin_t origin, uint32_t *sec, uint32_t *usec)
{
uint64_t count;
count = SysTimer_GetLoadValue();
if (sec)
*sec = count / SYS_TIMER_FREQ;
if (usec)
*usec = (count % SYS_TIMER_FREQ);
return 0;
}
uint64_t rtos_get_sys_us(void)
{
return SysTimer_GetLoadValue();
}
int32_t rtos_event_create(rtos_event *evt)
{
*evt = xEventGroupCreate();
assert(*evt != NULL);
return 0;
}
rtos_event_bit rtos_event_wait(rtos_event evt, rtos_event_bit bit, TickType_t timeout_ms)
{
return xEventGroupWaitBits(evt, bit, pdTRUE, pdFALSE, timeout_ms);
}
int32_t rtos_event_clear(rtos_event evt, rtos_event_bit bit)
{
xEventGroupClearBits(evt, bit);
return 0;
}
int32_t rtos_event_set(rtos_event evt, rtos_event_bit bit, bool isr)
{
rtos_base_type xHigherPriorityTaskWoken = pdFALSE;
if (isr)
xEventGroupSetBitsFromISR(evt, bit, &xHigherPriorityTaskWoken);
else
xEventGroupSetBits(evt, bit);
return 0;
}
void rtos_event_delete(rtos_event evt)
{
vEventGroupDelete(evt);
}
rtos_timer rtos_timer_create(void *id, bool reload, uint32_t period_ms, rtos_timer_callback cb)
{
rtos_timer timer = xTimerCreate(NULL, pdMS_TO_TICKS(period_ms), reload, id, cb);
assert(timer != NULL);
return timer;
}
int32_t rtos_timer_start(rtos_timer timer)
{
if (xTimerStart(timer, 0) != pdPASS)
return -1;
else
return 0;
}
int32_t rtos_timer_stop(rtos_timer timer)
{
return xTimerStop(timer, 0);
}
int32_t rtos_timer_delete(rtos_timer timer)
{
return xTimerDelete(timer, 0);
}
int32_t rtos_timer_reload(rtos_timer timer)
{
return xTimerReset(timer, 0);
}
void rtos_timer_schedule(rtos_timer timer, uint32_t period_ms)
{
xTimerChangePeriod(timer, period_ms, 0);
}
void rtos_timer_id_set(rtos_timer timer, void *id)
{
vTimerSetTimerID(timer, id);
}
void *rtos_timer_id_get(rtos_timer timer)
{
return pvTimerGetTimerID(timer);
}
uint32_t rtos_timer_get_period(rtos_timer timer)
{
return xTimerGetPeriod(timer);
}
void rtos_timer_set_reload_mode(rtos_timer timer, bool reload)
{
vTimerSetReloadMode(timer, reload);
}
int32_t rtos_timer_is_active(rtos_timer timer)
{
return xTimerIsTimerActive(timer);
}
#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configUSE_TRACE_FACILITY == 1 ) )
// #define snprintf(...) tfp_snprintf(__VA_ARGS__)
struct task_run_time_info
{
UBaseType_t task_id;
configRUN_TIME_COUNTER_TYPE run_time;
uint32_t age;
};
struct task_cpu_usage
{
uint16_t num;
uint16_t counter;
configRUN_TIME_COUNTER_TYPE totalTime;
struct task_run_time_info *tasks_detail;
};
struct task_cpu_usage rtos_tasks_time_stats;
void rtos_get_cpu_usage( char * pcWriteBuffer, int32_t uxBufferLength )
{
int32_t first_round = 0;
int32_t xOutputBufferFull = 0;
struct task_run_time_info *tmp;
int32_t x, i, current, iSnprintfReturnValue, uxConsumedBufferLength = 0;
UBaseType_t uxArraySize;
TaskStatus_t * pxTaskStatusArray;
configRUN_TIME_COUNTER_TYPE lastTotalTime, ulTotalTime = 0;
configRUN_TIME_COUNTER_TYPE ulStatsAsPercentage;
*pcWriteBuffer = ( char ) 0x00;
uxArraySize = uxTaskGetNumberOfTasks();
pxTaskStatusArray = rtos_malloc( uxArraySize * sizeof( TaskStatus_t ) );
if( pxTaskStatusArray != NULL )
{
uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalTime );
if (rtos_tasks_time_stats.tasks_detail == NULL)
{
rtos_tasks_time_stats.tasks_detail = rtos_malloc( uxArraySize * sizeof(struct task_run_time_info) );
if (rtos_tasks_time_stats.tasks_detail == NULL)
goto END;
memset(rtos_tasks_time_stats.tasks_detail, 0, uxArraySize * sizeof(struct task_run_time_info));
first_round = 1;
rtos_tasks_time_stats.counter = 1;
rtos_tasks_time_stats.num = uxArraySize;
rtos_tasks_time_stats.totalTime = 0;
}
else if (rtos_tasks_time_stats.num < uxArraySize)
{
tmp = (struct task_run_time_info*)rtos_malloc( uxArraySize * sizeof(struct task_run_time_info) );
if (tmp != NULL)
{
memcpy(tmp, rtos_tasks_time_stats.tasks_detail, rtos_tasks_time_stats.num * sizeof(struct task_run_time_info));
rtos_free(rtos_tasks_time_stats.tasks_detail);
rtos_tasks_time_stats.tasks_detail = tmp;
rtos_tasks_time_stats.num = uxArraySize;
}
else
{
goto END;
}
}
else
{
;
}
if (ulTotalTime > 0)
{
if (first_round == 0)
{
for( x = 0; x < uxArraySize; x++ )
{
for (i = 0; i < rtos_tasks_time_stats.num; i++)
{
if (rtos_tasks_time_stats.tasks_detail[i].task_id == pxTaskStatusArray[x].xTaskNumber)
{
rtos_tasks_time_stats.tasks_detail[i].age = rtos_tasks_time_stats.counter;
break;
}
}
}
}
lastTotalTime = ulTotalTime;
if (ulTotalTime >= rtos_tasks_time_stats.totalTime)
ulTotalTime = (ulTotalTime - rtos_tasks_time_stats.totalTime) / 100;
else
ulTotalTime = (((configRUN_TIME_COUNTER_TYPE)-1) - rtos_tasks_time_stats.totalTime + ulTotalTime) / 100;
for( x = 0; x < uxArraySize; x++ )
{
current = -1;
for (i = 0; i < rtos_tasks_time_stats.num; i++)
{
if (rtos_tasks_time_stats.tasks_detail[i].task_id == pxTaskStatusArray[x].xTaskNumber)
{
current = i;
break;
}
else if ((current < 0) && (rtos_tasks_time_stats.tasks_detail[i].age != rtos_tasks_time_stats.counter))
{
current = i;
}
}
if (current >= 0)
{
rtos_tasks_time_stats.tasks_detail[current].task_id = pxTaskStatusArray[x].xTaskNumber;
rtos_tasks_time_stats.tasks_detail[current].age = rtos_tasks_time_stats.counter;
if (pxTaskStatusArray[ x ].ulRunTimeCounter >= rtos_tasks_time_stats.tasks_detail[current].run_time)
ulStatsAsPercentage = (pxTaskStatusArray[ x ].ulRunTimeCounter - rtos_tasks_time_stats.tasks_detail[current].run_time) / ulTotalTime;
else
ulStatsAsPercentage = (((configRUN_TIME_COUNTER_TYPE)-1) - rtos_tasks_time_stats.tasks_detail[current].run_time + pxTaskStatusArray[ x ].ulRunTimeCounter) / ulTotalTime;
if( ( uxConsumedBufferLength + configMAX_TASK_NAME_LEN ) <= uxBufferLength )
{
pcWriteBuffer += snprintf(pcWriteBuffer, configMAX_TASK_NAME_LEN, "%-15s", pxTaskStatusArray[ x ].pcTaskName);
uxConsumedBufferLength = uxConsumedBufferLength + ( configMAX_TASK_NAME_LEN - 1U );
if( uxConsumedBufferLength < ( uxBufferLength - 1U ) )
{
if( ulStatsAsPercentage > 0U )
{
iSnprintfReturnValue = snprintf( pcWriteBuffer,
uxBufferLength - uxConsumedBufferLength,
"\t%u\t\t%u\r\n",
( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter,
( unsigned int ) ulStatsAsPercentage );
}
else
{
iSnprintfReturnValue = snprintf( pcWriteBuffer,
uxBufferLength - uxConsumedBufferLength,
"\t%u\t\t<1\r\n",
( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter );
}
uxConsumedBufferLength += iSnprintfReturnValue;
pcWriteBuffer += iSnprintfReturnValue;
}
else
{
xOutputBufferFull = 1;
}
}
else
{
xOutputBufferFull = 1;
}
rtos_tasks_time_stats.tasks_detail[current].run_time = pxTaskStatusArray[x].ulRunTimeCounter;
}
if( xOutputBufferFull == 1 )
break;
}
if (rtos_tasks_time_stats.num > (uxArraySize << 1))
{
tmp = rtos_malloc( uxArraySize * sizeof(struct task_run_time_info) );
if (tmp != NULL)
{
for( i = 0, x = 0; i < rtos_tasks_time_stats.num; i++ )
{
if (rtos_tasks_time_stats.tasks_detail[i].age == rtos_tasks_time_stats.counter)
{
tmp[x++] = rtos_tasks_time_stats.tasks_detail[i];
}
}
rtos_free(rtos_tasks_time_stats.tasks_detail);
rtos_tasks_time_stats.tasks_detail = tmp;
rtos_tasks_time_stats.num = uxArraySize;
}
else
{
goto END;
}
}
rtos_tasks_time_stats.counter++;
rtos_tasks_time_stats.totalTime = lastTotalTime;
}
END:
rtos_free( pxTaskStatusArray );
}
}
void rtos_get_cpu_usage1( char * pcWriteBuffer, int32_t uxBufferLength )
{
vTaskGetRunTimeStats(pcWriteBuffer);
}
#else
void rtos_get_cpu_usage( char * pcWriteBuffer, int32_t uxBufferLength )
{
}
void rtos_get_cpu_usage1( char * pcWriteBuffer, int32_t uxBufferLength )
{
}
#endif