diff options
Diffstat (limited to 'libiot/freertos/adds.c')
| -rw-r--r-- | libiot/freertos/adds.c | 317 |
1 files changed, 317 insertions, 0 deletions
diff --git a/libiot/freertos/adds.c b/libiot/freertos/adds.c new file mode 100644 index 0000000..3eede33 --- /dev/null +++ b/libiot/freertos/adds.c @@ -0,0 +1,317 @@ +/* + * Copyright (C) 2015 - 2018, IBEROXARXA SERVICIOS INTEGRALES, S.L. + * Copyright (C) 2015 - 2018, Jaume Olivé Petrus (jolive@whitecatboard.org) + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the <organization> nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * * The WHITECAT logotype cannot be changed, you can remove it, but you + * cannot change it in any way. The WHITECAT logotype is: + * + * /\ /\ + * / \_____/ \ + * /_____________\ + * W H I T E C A T + * + * * Redistributions in binary form must retain all copyright notices printed + * to any local or remote output device. This include any reference to + * Lua RTOS, whitecatboard.org, Lua, and other copyright notices that may + * appear in the future. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Lua RTOS, FreeRTOS additions + * + */ + +//#include "luartos.h" + +//#include "esp_attr.h" + +//#include "lua.h" +#include <FreeRTOS.h> +#include <task.h> +#include "adds.h" + +#include <stdint.h> +#include <string.h> + +#include <stdlib.h> + +#include <malloc.h> + +#define THREAD_LOCAL_STORAGE_POINTER_ID 0 + +// Reference to lua_thread, which is created in app_main +extern pthread_t lua_thread; + +// Global state +static lua_State *gL = NULL; + +static int compare(const void *a, const void *b) { + if (((task_info_t *)a)->task_type < ((task_info_t *)b)->task_type) { + return 1; + } else if (((task_info_t*)a)->task_type > ((task_info_t *)b)->task_type) { + return -1; + } else { + if (((task_info_t *)a)->core < ((task_info_t *)b)->core) { + return -1; + } else if (((task_info_t *)a)->core > ((task_info_t *)b)->core) { + return 1; + } else { + return strcmp(((task_info_t *)a)->name, ((task_info_t *)b)->name); + } + } +} + +void uxSetThreadId(UBaseType_t id) { + lua_rtos_tcb_t *lua_rtos_tcb; + + // Get Lua RTOS specific TCB parts for current task + if ((lua_rtos_tcb = pvTaskGetThreadLocalStoragePointer(xTaskGetCurrentTaskHandle(), THREAD_LOCAL_STORAGE_POINTER_ID))) { + // Store thread id into Lua RTOS specific TCB parts + lua_rtos_tcb->threadid = id; + } +} + +UBaseType_t uxGetThreadId() { + lua_rtos_tcb_t *lua_rtos_tcb; + int threadid = 0; + + // Get Lua RTOS specific TCB parts for current task + if ((lua_rtos_tcb = pvTaskGetThreadLocalStoragePointer(xTaskGetCurrentTaskHandle(), THREAD_LOCAL_STORAGE_POINTER_ID))) { + // Get current thread od from Lua RTOS specific TCB parts + threadid = lua_rtos_tcb->threadid; + } + + return threadid; +} + +void uxSetThreadStatus(TaskHandle_t h, pthread_status_t status) { + lua_rtos_tcb_t *lua_rtos_tcb; + + // Get Lua RTOS specific TCB parts for current task + if ((lua_rtos_tcb = pvTaskGetThreadLocalStoragePointer(xTaskGetCurrentTaskHandle(), THREAD_LOCAL_STORAGE_POINTER_ID))) { + // Store thread id into Lua RTOS specific TCB parts + lua_rtos_tcb->status = status; + } +} + +void uxSetLThread(lthread_t *lthread) { + lua_rtos_tcb_t *lua_rtos_tcb; + + // Get Lua RTOS specific TCB parts for current task + if ((lua_rtos_tcb = pvTaskGetThreadLocalStoragePointer(xTaskGetCurrentTaskHandle(), THREAD_LOCAL_STORAGE_POINTER_ID))) { + lua_rtos_tcb->lthread = lthread; + } +} + +void uxSetLuaState(lua_State* L) { + lua_rtos_tcb_t *lua_rtos_tcb; + + // Get Lua RTOS specific TCB parts for current task + if ((lua_rtos_tcb = pvTaskGetThreadLocalStoragePointer(xTaskGetCurrentTaskHandle(), THREAD_LOCAL_STORAGE_POINTER_ID))) { + // Store current lua state into Lua RTOS specific TCB parts + if (!lua_rtos_tcb->lthread) { + lua_rtos_tcb->lthread = calloc(1, sizeof(lthread_t)); + if (lua_rtos_tcb->lthread == NULL) { + panic(); + } + //assert(lua_rtos_tcb->lthread); + } + lua_rtos_tcb->lthread->L = L; + } + + // If this is the lua thread, store state in global state + if ((uxGetThreadId() == lua_thread) && (gL == NULL)) { + gL = L; + } +} + +lua_State* pvGetLuaState() { + lua_rtos_tcb_t *lua_rtos_tcb; + lua_State *L = NULL; + + // Get Lua RTOS specific TCB parts for current task + if ((lua_rtos_tcb = pvTaskGetThreadLocalStoragePointer(NULL, THREAD_LOCAL_STORAGE_POINTER_ID))) { + + // Get current lua state from Lua RTOS specific TCB parts + if (lua_rtos_tcb->lthread) { + L = lua_rtos_tcb->lthread->L; + } + } + + if (L == NULL) { + L = gL; + } + + return L; +} + +lthread_t *pvGetLThread() { + lua_rtos_tcb_t *lua_rtos_tcb; + lthread_t *lthread = NULL; + + // Get Lua RTOS specific TCB parts for current task + if ((lua_rtos_tcb = pvTaskGetThreadLocalStoragePointer(NULL, THREAD_LOCAL_STORAGE_POINTER_ID))) { + lthread = lua_rtos_tcb->lthread; + } + + return lthread; +} + +uint32_t uxGetSignaled(TaskHandle_t h) { + lua_rtos_tcb_t *lua_rtos_tcb; + int signaled = 0; + + // Get Lua RTOS specific TCB parts for current task + if ((lua_rtos_tcb = pvTaskGetThreadLocalStoragePointer(h, THREAD_LOCAL_STORAGE_POINTER_ID))) { + // Get current signeled mask from Lua RTOS specific TCB parts + signaled = lua_rtos_tcb->signaled; + } + + return signaled; +} + +void uxSetSignaled(TaskHandle_t h, int s) { + lua_rtos_tcb_t *lua_rtos_tcb; + + // Get Lua RTOS specific TCB parts for current task + if ((lua_rtos_tcb = pvTaskGetThreadLocalStoragePointer(h, THREAD_LOCAL_STORAGE_POINTER_ID))) { + // Store current signaled mask into Lua RTOS specific TCB parts + lua_rtos_tcb->signaled = s; + } +} + +uint8_t ucGetCoreID(TaskHandle_t h) { + tskTCB_t *task = (tskTCB_t *)h; + + return task->xCoreID; +} + +int uxGetStack(TaskHandle_t h) { + tskTCB_t *task = (tskTCB_t *)h; + + return task->pxEndOfStack - task->pxStack + 4; +} + +task_info_t *GetTaskInfo() { + tskTCB_t *ctask; + task_info_t *info; + uint8_t task_type; + lua_rtos_tcb_t *lua_rtos_tcb; + TaskStatus_t *status_array; + UBaseType_t task_num = 0; + UBaseType_t start_task_num = 0; + uint32_t total_runtime = 0; + + //Allocate status_array + start_task_num = uxTaskGetNumberOfTasks(); + + status_array = (TaskStatus_t *)calloc(start_task_num, sizeof(TaskStatus_t)); + if (!status_array) { + return NULL; + } + +//#ifndef CONFIG_FREERTOS_USE_TRACE_FACILITY +//#warning Please enable CONFIG_FREERTOS_USE_TRACE_FACILITY to support thread.list +// free(status_array); +// return NULL; +#ifndef configUSE_TRACE_FACILITY +#warning Please enable configUSE_TRACE_FACILITY to support thread.list + free(status_array); + return NULL; +#else + task_num = uxTaskGetSystemState(status_array, (start_task_num), &total_runtime); + // For percentage calculations. + total_runtime /= 100UL; + + info = (task_info_t *)calloc(task_num + 1, sizeof(task_info_t)); + if (!info) { + free(status_array); + return NULL; + } +#endif + + for(int i = 0; i <task_num; i++){ + if (status_array[i].eCurrentState == eDeleted) { + continue; + } + + // Get the task TCB + ctask = (tskTCB_t *)status_array[i].xHandle; + + // Get the task type + // 0: freertos task + // 1: pthread task + // 2: lua thread task + task_type = 0; + + info[i].thid = 0; + info[i].status = 0; + + // Get Lua RTOS specific TCB parts for current task + if ((lua_rtos_tcb = pvTaskGetThreadLocalStoragePointer(status_array[i].xHandle, THREAD_LOCAL_STORAGE_POINTER_ID))) { + // Task has Lua RTOS specific TCB parts + if (lua_rtos_tcb->lthread) { + // Lua thread + task_type = 2; + } else { + // pthread + task_type = 1; + } + + info[i].thid = lua_rtos_tcb->threadid; + info[i].lthread = lua_rtos_tcb->lthread; + info[i].status = lua_rtos_tcb->status; + } + + // Populate info item + info[i].prio = status_array[i].uxCurrentPriority; + info[i].task_type = task_type; + info[i].core = ctask->xCoreID; + + // Some system tasks shows 255!! + if (info[i].core > 1) { + info[i].core = 0; + } + + info[i].free_stack = uxTaskGetStackHighWaterMark(status_array[i].xHandle); + info[i].stack_size = ctask->pxEndOfStack - ctask->pxStack + 4; + memcpy(info[i].name, status_array[i].pcTaskName, configMAX_TASK_NAME_LEN); + + info[i].cpu_usage = 0; +#ifdef CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS + if( total_runtime > 0 ) { + // only gives valid values if CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is defined + info[i].cpu_usage = status_array[i].ulRunTimeCounter / total_runtime; + } +#endif + + } + + free(status_array); + + qsort (info, task_num, sizeof (task_info_t), compare); + + return info; +} |
