diff --git a/.github/workflows/github_ci.yml b/.github/workflows/github_ci.yml index 09784824..832cbfc2 100644 --- a/.github/workflows/github_ci.yml +++ b/.github/workflows/github_ci.yml @@ -2,10 +2,10 @@ name: GitHub CI on: push: - branches: [ stable, development, cc_os_stage] + branches: [ stable, development, helios_stage] pull_request: - branches: [ stable, development, cc_os_stage] + branches: [ stable, development, helios_stage] jobs: build: @@ -49,8 +49,8 @@ jobs: make demo_avr make demo_avr_cpp make demo_riscv - make demo_cc_os_avr - make demo_cc_os_riscv + make demo_helios_avr + make demo_helios_riscv - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v1 diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index d32bf159..a5066287 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -5,12 +5,12 @@ on: branches: - stable - development - - cc_os_stage + - helios_stage pull_request: branches: - stable - development - - cc_os_stage + - helios_stage jobs: build: diff --git a/.vscode/launch.json b/.vscode/launch.json index 9adbd8ac..4fef0018 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -35,8 +35,50 @@ "text": "b plug" }, ], - - + }, + { + "name": "FE310 Debug (JLink)", + "type": "cppdbg", + "request": "launch", + "miDebuggerServerAddress": ":2331", + "program": "${workspaceFolder}/out/${input:project}/${input:project}.elf", + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "MIMode": "gdb", + "svdPath": "", + "externalConsole": false, + "showDisplayString": true, + "variables": { + "elfPath": "${workspaceFolder}/out/${input:project}/${input:project}.elf" + }, + "miDebuggerPath": "${workspaceFolder}/tools/risc-v-toolchain/bin/riscv64-unknown-elf-gdb", + "miDebuggerArgs": "${elfPath}", + "setupCommands": + [ + { + "text": "b init" + }, + { + "text": "b plug" + }, + ], + "postRemoteConnectCommands": [ + { + "text": "file ${elfPath}" + }, + { + "text": "monitor halt" + }, + { + "text": "load" + }, + { + "text": "monitor reset" + }, + { + "text": "monitor go" + } + ] } ], "inputs": [ @@ -48,6 +90,7 @@ "demo_avr", "demo_avr_cpp", "demo_riscv", + "demo_helios_riscv" ], "default": "demo_avr" }, diff --git a/.vscode/settings.json b/.vscode/settings.json index afd7a788..5a104cc8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -40,8 +40,6 @@ "*.{c,c.dev.c.temp,c.tmp,c.old,h,h.dev,h.old,h.temp,h.tmp)": "C", "*.{cpp,cpp.dev,cpp.temp,cpp.tmp,cpp.old}": "C++", "*.{S,S.old,S.dev.S.temp,S.tmp,s.old,s.temp,s.tmp,s.dev,asm,asm.old,asm.dev.asm.temp,asm.tmp,inc,inc.old,inc.temp,inc.tmp,ld,ld.old,ld.temp,ld.tmp,ld.sx,ld.sx.old,ld.sx.temp,ld.sx.tmp,lst}": "coffeescript", - "cc_os_sched.h": "c", - "cc_os.h": "c" }, "files.autoSave": "afterDelay", "files.autoSaveDelay": 100, diff --git a/projects/demo_cc_os_avr/cc_os_config.mk b/projects/demo_cc_os_avr/cc_os_config.mk deleted file mode 100644 index 178c1a57..00000000 --- a/projects/demo_cc_os_avr/cc_os_config.mk +++ /dev/null @@ -1,16 +0,0 @@ -# -# CYANCORE LICENSE -# Copyrights (C) 2019-2023, Cyancore Team -# -# File Name : cc_os_config.mk -# Description : This file consists of CC_OS kernal configuration -# Primary Author : Pranjal Chanda [pranjalchanda08@gmail.com] -# Organisation : Cyancore Core-Team -# - -CC_OS_USE_DYNAMIC := 1 -CC_OS_HEAP_SIZE := 1024 -CC_OS_MAX_THREAD := 4 -CC_OS_IDLE_TASK_STACK_LEN := 255 -CC_OS_POWER_SAVE_EN := 0 -CC_OS_ANTI_DEADLOCK := 0 diff --git a/projects/demo_cc_os_riscv/cc_os_config.mk b/projects/demo_cc_os_riscv/cc_os_config.mk deleted file mode 100644 index 05fa1d78..00000000 --- a/projects/demo_cc_os_riscv/cc_os_config.mk +++ /dev/null @@ -1,16 +0,0 @@ -# -# CYANCORE LICENSE -# Copyrights (C) 2019-2023, Cyancore Team -# -# File Name : kern_config.mk -# Description : This file consists of CC_OS kernal configuration -# Primary Author : Pranjal Chanda [pranjalchanda08@gmail.com] -# Organisation : Cyancore Core-Team -# - -CC_OS_USE_DYNAMIC := 1 -CC_OS_HEAP_SIZE := 1024 -CC_OS_MAX_THREAD := 4 -CC_OS_IDLE_TASK_STACK_LEN := 255 -CC_OS_POWER_SAVE_EN := 0 -CC_OS_ANTI_DEADLOCK := 0 diff --git a/projects/demo_cc_os.src/build.mk b/projects/demo_helios.src/build.mk similarity index 100% rename from projects/demo_cc_os.src/build.mk rename to projects/demo_helios.src/build.mk diff --git a/projects/demo_cc_os.src/project.c b/projects/demo_helios.src/project.c similarity index 52% rename from projects/demo_cc_os.src/project.c rename to projects/demo_helios.src/project.c index 345a4928..26677c04 100644 --- a/projects/demo_cc_os.src/project.c +++ b/projects/demo_helios.src/project.c @@ -11,15 +11,15 @@ #include #include #include -#include +#include #define TASK_WAIT_TICKS 10 -void task_handler(cc_os_args args); +void task_handler(helios_args args); -static cc_os_task_t * Task_A; -static cc_os_task_t * Task_B; -static cc_os_task_t * Task_C; +static helios_task_t Task_A; +static helios_task_t Task_B; +static helios_task_t Task_C; /* Define Plug */ void plug() @@ -28,10 +28,10 @@ void plug() driver_setup_all(); printf("Demo CC OS Program!\n"); - cc_os_add_task(Task_A, "Task A", &task_handler, NULL, 10, 255, (uintptr_t) NULL); - cc_os_add_task(Task_B, "Task B", &task_handler, NULL, 10, 255, (uintptr_t) NULL); - cc_os_add_task(Task_C, "Task C", &task_handler, NULL, 10, 255, (uintptr_t) NULL); - cc_os_run(); + helios_add_task(&Task_A, "Task A", &task_handler, NULL, 5, 255, (uintptr_t) NULL); + helios_add_task(&Task_B, "Task B", &task_handler, NULL, 10, 255, (uintptr_t) NULL); + helios_add_task(&Task_C, "Task C", &task_handler, NULL, 4, 255, (uintptr_t) NULL); + helios_run(); } /* Define Play */ @@ -42,11 +42,11 @@ void play() } /* Define the Task Handler */ -void task_handler(cc_os_args args _UNUSED) +void task_handler(helios_args args _UNUSED) { while(true) { - printf("In Task: %s\n", cc_os_get_curr_task_name()); - cc_os_task_wait(TASK_WAIT_TICKS); + printf("In Task: %s\n", helios_get_curr_task_name()); + helios_task_wait(TASK_WAIT_TICKS); } } diff --git a/projects/demo_cc_os_avr/build.mk b/projects/demo_helios_avr/build.mk similarity index 80% rename from projects/demo_cc_os_avr/build.mk rename to projects/demo_helios_avr/build.mk index b5ea41ab..dd292c5d 100644 --- a/projects/demo_cc_os_avr/build.mk +++ b/projects/demo_helios_avr/build.mk @@ -11,9 +11,9 @@ PROJECT_DIR := $(GET_PATH) -include $(PROJECT_DIR)/../demo_cc_os.src/build.mk +include $(PROJECT_DIR)/../demo_helios.src/build.mk include $(PROJECT_DIR)/config.mk -include $(PROJECT_DIR)/cc_os_config.mk +include $(PROJECT_DIR)/helios_config.mk DIR := $(PROJECT_DIR) include mk/obj.mk diff --git a/projects/demo_cc_os_avr/config.mk b/projects/demo_helios_avr/config.mk similarity index 100% rename from projects/demo_cc_os_avr/config.mk rename to projects/demo_helios_avr/config.mk diff --git a/projects/demo_helios_avr/helios_config.mk b/projects/demo_helios_avr/helios_config.mk new file mode 100644 index 00000000..ba80daae --- /dev/null +++ b/projects/demo_helios_avr/helios_config.mk @@ -0,0 +1,16 @@ +# +# CYANCORE LICENSE +# Copyrights (C) 2019-2023, Cyancore Team +# +# File Name : helios_config.mk +# Description : This file consists of HELIOS kernal configuration +# Primary Author : Pranjal Chanda [pranjalchanda08@gmail.com] +# Organisation : Cyancore Core-Team +# + +HELIOS_USE_DYNAMIC := 1 +HELIOS_HEAP_SIZE := 1024 +HELIOS_MAX_THREAD := 4 +HELIOS_IDLE_TASK_STACK_LEN := 255 +HELIOS_POWER_SAVE_EN := 0 +HELIOS_ANTI_DEADLOCK := 0 diff --git a/projects/demo_cc_os_riscv/build.mk b/projects/demo_helios_riscv/build.mk similarity index 80% rename from projects/demo_cc_os_riscv/build.mk rename to projects/demo_helios_riscv/build.mk index b5ea41ab..dd292c5d 100644 --- a/projects/demo_cc_os_riscv/build.mk +++ b/projects/demo_helios_riscv/build.mk @@ -11,9 +11,9 @@ PROJECT_DIR := $(GET_PATH) -include $(PROJECT_DIR)/../demo_cc_os.src/build.mk +include $(PROJECT_DIR)/../demo_helios.src/build.mk include $(PROJECT_DIR)/config.mk -include $(PROJECT_DIR)/cc_os_config.mk +include $(PROJECT_DIR)/helios_config.mk DIR := $(PROJECT_DIR) include mk/obj.mk diff --git a/projects/demo_cc_os_riscv/config.mk b/projects/demo_helios_riscv/config.mk similarity index 76% rename from projects/demo_cc_os_riscv/config.mk rename to projects/demo_helios_riscv/config.mk index f36fd2de..1a0b11de 100644 --- a/projects/demo_cc_os_riscv/config.mk +++ b/projects/demo_helios_riscv/config.mk @@ -12,11 +12,11 @@ COMPILER := gcc TC_VER := 10.2.0 FAMILY := sifive PLATFORM := fe310g002 -HEAP_SIZE := 256 -STACK_SIZE := 256 -STDLOG_MEMBUF := 0 -BOOTMSGS := 0 -EARLYCON_SERIAL := 1 -CONSOLE_SERIAL := 1 +HEAP_SIZE := 3K +STACK_SIZE := 1K +STDLOG_MEMBUF := 1 +BOOTMSGS := 1 +EARLYCON_SERIAL := 0 +CONSOLE_SERIAL := 0 OBRDLED_ENABLE := 1 TERRAKERN := 1 diff --git a/projects/demo_helios_riscv/helios_config.mk b/projects/demo_helios_riscv/helios_config.mk new file mode 100644 index 00000000..ba80daae --- /dev/null +++ b/projects/demo_helios_riscv/helios_config.mk @@ -0,0 +1,16 @@ +# +# CYANCORE LICENSE +# Copyrights (C) 2019-2023, Cyancore Team +# +# File Name : helios_config.mk +# Description : This file consists of HELIOS kernal configuration +# Primary Author : Pranjal Chanda [pranjalchanda08@gmail.com] +# Organisation : Cyancore Core-Team +# + +HELIOS_USE_DYNAMIC := 1 +HELIOS_HEAP_SIZE := 1024 +HELIOS_MAX_THREAD := 4 +HELIOS_IDLE_TASK_STACK_LEN := 255 +HELIOS_POWER_SAVE_EN := 0 +HELIOS_ANTI_DEADLOCK := 0 diff --git a/src/include/visor/terravisor/cc_os/utils/cc_os_sched.h b/src/include/visor/terravisor/cc_os/utils/cc_os_sched.h deleted file mode 100644 index 30fe6289..00000000 --- a/src/include/visor/terravisor/cc_os/utils/cc_os_sched.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * CYANCORE LICENSE - * Copyrights (C) 2022, Cyancore Team - * - * File Name : cc_os_sched.h - * Description : CC OS Kernel scheduler declaration - * Primary Author : Pranjal Chanda [pranjalchanda08@gmail.com] - * Organisation : Cyancore Core-Team - */ - -#pragma once - -/***************************************************** - * INCLUDES - *****************************************************/ -#include -#include -#include - -/***************************************************** - * DEFINES - *****************************************************/ -#define CC_OS_NULL_PTR NULL -#define CC_OS_DELAY_MAX SIZE_MAX - -#define CC_OS_DYNAMIC CC_OS_USE_DYNAMIC - -#define CC_OS_ASSERT_IF_FALSE(con) RET_ON_FAIL(con, error_func_inval_arg) - -/***************************************************** - * TYPEDEFS - *****************************************************/ -typedef struct cc_sched_tcb cc_sched_tcb_t; -typedef struct cc_sched cc_sched_t; -typedef const char c_char; -typedef void * cc_os_args; -typedef void (*task_fn_t)(cc_os_args args); -typedef void (*cc_cb_hook_t)(cc_os_args args); -typedef enum -{ - cc_sched_task_status_exit = 0x00, ///> Initial State - cc_sched_task_status_running = 0x01, ///> Task currently running - cc_sched_task_status_ready = 0x02, ///> Task Ready to despatch - cc_sched_task_status_wait = 0x03, ///> Task in wait state - cc_sched_task_status_pause = 0x04, ///> Task in pause state - cc_sched_task_status_max = 0xff, ///> Do Nt Use -} cc_sched_task_status_t; - -/* - * @note All negative callbacks are internally used by the scheduler - */ -typedef enum -{ - cc_sched_cb_power_pre_sleep = 0x00, - cc_sched_cb_power_post_sleep = 0x01, - cc_sched_cb_power_sleep = 0x02, - cc_sched_cb_deadlock_notify = 0x03, - cc_sched_cb_max = 0xff -}cc_sched_cb_t; - -typedef enum -{ - cc_task_flag_set_anti_deadlock = (1 << 0) ///> Enable Antideadlock for the task -}cc_task_flag_t; -typedef struct link -{ - cc_sched_tcb_t * prev; - cc_sched_tcb_t * next; -}link_t; - -typedef struct wres -{ - uintptr_t wait_on_resource; ///> Resource on hich the task is waiting on - size_t task_delay_ticks; ///> Time delay in ticks -}wres_t; - -struct cc_sched_tcb -{ - - c_char * name; ///> Name of the Current Task - uint8_t priority; ///> Priority of the task - uint8_t task_flags; ///> Task Flags - uint16_t task_id; ///> Task ID assigned - uintptr_t stack_ptr; ///> Stack Pointer - task_fn_t task_func; ///> Task Call Function - uintptr_t args_ptr; ///> Task Call argument ptr - wres_t wait_res; ///> Wait Task resource - link_t ready_link; ///> Ready Linked List Pointers - link_t wait_link; ///> Wait Linked List Pointers -#if CC_OS_ANTI_DEADLOCK - size_t task_wd_ticks; ///> Tick down counter for Anti Deadlock system -#endif /* CC_OS_ANTI_DEADLOCK */ - cc_sched_task_status_t task_status; ///> Current state of the task -}; - -typedef struct cc_sched_func_cb -{ - cc_cb_hook_t pre_sched; -#if CC_OS_POWER_SAVE_EN - cc_cb_hook_t pre_sleep_cb; - cc_cb_hook_t post_sleep_cb; - cc_cb_hook_t sleep_cb; -#endif /* CC_OS_POWER_SAVE_EN */ -#if CC_OS_ANTI_DEADLOCK - cc_cb_hook_t deadlock_notify; -#endif /* CC_OS_ANTI_DEADLOCK */ -}cc_sched_func_cb_t; - -typedef struct cc_sched_ctrl -{ - cc_sched_tcb_t * ready_list_head; - cc_sched_tcb_t * curr_task; - cc_sched_tcb_t * wait_list_head; - cc_sched_tcb_t * task_max_prio; - cc_sched_t * selected_sched; - cc_sched_func_cb_t cb_hooks_reg; -}cc_sched_ctrl_t; - -/** - * @brief Prototype of scheduler algorithm function - */ -typedef void (* algo_fn)(cc_sched_ctrl_t * sched_ctrl); - -typedef enum -{ - cc_sched_algo_round_robin = 0x00, ///> Round Robin scheduling algorithm - cc_sched_algo_priority_driven = 0x01, ///> Priority driven Scheduling - cc_sched_algo_max = 0xff -}cc_sched_algo_t; - -typedef struct cc_sched -{ - cc_sched_algo_t cc_selected_algo; ///> Selected Algorithm ID - algo_fn algo_function; ///> Pointer to algorithm function -}cc_sched_t; - -typedef struct cc_sched_anti_deadlock -{ - c_char * name; - task_fn_t task_func; -}cc_sched_anti_deadlock_t; diff --git a/src/include/visor/terravisor/cc_os/cc_os.h b/src/include/visor/terravisor/helios/helios.h similarity index 59% rename from src/include/visor/terravisor/cc_os/cc_os.h rename to src/include/visor/terravisor/helios/helios.h index aaac3656..008e28c6 100644 --- a/src/include/visor/terravisor/cc_os/cc_os.h +++ b/src/include/visor/terravisor/helios/helios.h @@ -2,20 +2,20 @@ * CYANCORE LICENSE * Copyrights (C) 2022, Cyancore Team * - * File Name : cc_os.h + * File Name : helios.h * Description : CC OS Kernel * Primary Author : Pranjal Chanda [pranjalchanda08@gmail.com] * Organisation : Cyancore Core-Team */ -#ifndef __CC_OS__ -#define __CC_OS__ +#ifndef __HELIOS__ +#define __HELIOS__ /***************************************************** * INCLUDES *****************************************************/ -#include -#include -#include +#include +#include +#include -#endif /* __CC_OS__ */ +#endif /* __HELIOS__ */ diff --git a/src/include/visor/terravisor/cc_os/cc_os_sem.h b/src/include/visor/terravisor/helios/helios_sem.h similarity index 80% rename from src/include/visor/terravisor/cc_os/cc_os_sem.h rename to src/include/visor/terravisor/helios/helios_sem.h index 0f6acf29..8887462c 100644 --- a/src/include/visor/terravisor/cc_os/cc_os_sem.h +++ b/src/include/visor/terravisor/helios/helios_sem.h @@ -2,7 +2,7 @@ * CYANCORE LICENSE * Copyrights (C) 2022, Cyancore Team * - * File Name : cc_os_sem.h + * File Name : helios_sem.h * Description : CC OS semaphore declaration * Primary Author : Pranjal Chanda [pranjalchanda08@gmail.com] * Organisation : Cyancore Core-Team @@ -12,7 +12,7 @@ /***************************************************** * DEFINES *****************************************************/ -#include +#include /***************************************************** * TYPEDEFS *****************************************************/ @@ -26,7 +26,7 @@ typedef struct sem *****************************************************/ #define CC_SEM_INST(_Name) _Name##_sem_inst -#if CC_OS_DYNAMIC == false +#if HELIOS_DYNAMIC == false #define CC_SEM_DEF(_Name) \ static sem_t _Name##_sem = { \ .sem_init = 0, \ @@ -35,7 +35,7 @@ static sem_t _Name##_sem = { \ sem_t * _Name##_sem_inst = &_Name##_sem #else #define CC_SEM_DEF(_Name) \ -sem_t * _Name##_sem_inst = CC_OS_NULL_PTR +sem_t * _Name##_sem_inst = HELIOS_NULL_PTR #endif /***************************************************** * USER FUNCTION DECLARATIONS @@ -49,7 +49,7 @@ sem_t * _Name##_sem_inst = CC_OS_NULL_PTR * * @return status_t */ -status_t cc_os_sem_create (sem_t ** sem_ptr, size_t init_val); +status_t helios_sem_create (sem_t ** sem_ptr, size_t init_val); /** * @brief Delete a semaphore and de-initialise it @@ -58,7 +58,7 @@ status_t cc_os_sem_create (sem_t ** sem_ptr, size_t init_val); * * @return status_t */ -status_t cc_os_sem_delete (sem_t ** sem_ptr); +status_t helios_sem_delete (sem_t ** sem_ptr); /** * @brief Decrement a semaphore value @@ -67,7 +67,7 @@ status_t cc_os_sem_delete (sem_t ** sem_ptr); * * @return status_t */ -status_t cc_os_sem_give (sem_t * sem_ptr); +status_t helios_sem_give (sem_t * sem_ptr); /** * @brief Increment a semaphore value @@ -77,7 +77,7 @@ status_t cc_os_sem_give (sem_t * sem_ptr); * * @return status_t */ -status_t cc_os_sem_take (sem_t * sem_ptr, size_t wait_ticks); +status_t helios_sem_take (sem_t * sem_ptr, size_t wait_ticks); /** * @brief Get current semaphore value @@ -88,4 +88,4 @@ status_t cc_os_sem_take (sem_t * sem_ptr, size_t wait_ticks); * @return status_t */ -status_t cc_os_sem_get_val (const sem_t * sem_ptr, size_t * val); +status_t helios_sem_get_val (const sem_t * sem_ptr, size_t * val); diff --git a/src/include/visor/terravisor/cc_os/cc_os_tasks.h b/src/include/visor/terravisor/helios/helios_tasks.h similarity index 69% rename from src/include/visor/terravisor/cc_os/cc_os_tasks.h rename to src/include/visor/terravisor/helios/helios_tasks.h index 9e007a8b..b94e96ee 100644 --- a/src/include/visor/terravisor/cc_os/cc_os_tasks.h +++ b/src/include/visor/terravisor/helios/helios_tasks.h @@ -2,7 +2,7 @@ * CYANCORE LICENSE * Copyrights (C) 2022, Cyancore Team * - * File Name : cc_os_task.h + * File Name : helios_task.h * Description : CC OS Kernel Tasks declaration * Primary Author : Pranjal Chanda [pranjalchanda08@gmail.com] * Organisation : Cyancore Core-Team @@ -16,7 +16,7 @@ #include "status.h" #include "stdlib.h" #include "stdint.h" -#include +#include /***************************************************** * TYPEDEFS @@ -25,7 +25,7 @@ * @brief TASK infrastructure * */ -typedef uintptr_t cc_os_task_t; +typedef uint16_t helios_task_t; /***************************************************** * MACROS @@ -38,7 +38,7 @@ typedef uintptr_t cc_os_task_t; * @brief A Function to add a task to the scheduler * * - * @param cc_os_task[out] Pointer to the TASK_instance + * @param helios_task[out] Pointer to the TASK_instance * @param name[in] Conatant Name string provided by the user * @param task_func[in] Pointer to the task function * @param args[in] Pointer to the argument variable provided to the task @@ -48,55 +48,55 @@ typedef uintptr_t cc_os_task_t; * * @return status_t */ -status_t cc_os_add_task ( - cc_os_task_t * cc_os_task, const char* name, - task_fn_t task_func, cc_os_args args, +status_t helios_add_task ( + helios_task_t * helios_task, const char* name, + task_fn_t task_func, helios_args args, uint8_t priority,size_t stack_len, uintptr_t stack_ptr); /** * @brief A function to delete a task from the scheduler by instance * - * @param cc_os_task[in] pointer to the TASK_instance; + * @param helios_task[in] pointer to the TASK_instance; * Pass NULL to point to current task * @return status_t */ -status_t cc_os_del_task(cc_os_task_t cc_os_task); +status_t helios_del_task(helios_task_t helios_task); /** * @brief A Function to pause the task until call resume explicitly using its instance * - * @param cc_os_task[in] pointer to the TASK_instance; + * @param helios_task[in] pointer to the TASK_instance; * Pass NULL to point to current task * @return status_t */ -status_t cc_os_pause_task(cc_os_task_t cc_os_task); +status_t helios_pause_task(helios_task_t helios_task); /** * * @brief A Function to resume paused task using its instance * @note Calling this function for already non-waiting task has no effect. * - * @param cc_os_task[in] pointer to the TASK_instance; + * @param helios_task[in] pointer to the TASK_instance; * Pass NULL to point to current task * @return status_t */ -status_t cc_os_resume_task(cc_os_task_t cc_os_task); +status_t helios_resume_task(helios_task_t helios_task); /** * @brief A Function to pause all the tasks except the current and the IDLE Task - * @note To resume all please use cc_os_resume_all_task() call + * @note To resume all please use helios_resume_all_task() call * * @return status_t */ -status_t cc_os_pause_all_task(void); +status_t helios_pause_all_task(void); /** * @brief A Function to resume all the tasks * * @return status_t */ -status_t cc_os_resume_all_task(void); +status_t helios_resume_all_task(void); /** * @brief A function to set CC OS scheduler algorithm @@ -104,7 +104,7 @@ status_t cc_os_resume_all_task(void); * @param sched_algo[in] The algorithm that needs to be selected to * @return status_t */ -status_t cc_os_set_sched_algo(cc_sched_algo_t sched_algo); +status_t helios_set_sched_algo(helios_sched_algo_t sched_algo); /** * @brief A function to set the functional callback hooks @@ -113,7 +113,7 @@ status_t cc_os_set_sched_algo(cc_sched_algo_t sched_algo); * @param cb_func[in] Callback hook function associated to the cb_type * @return status_t */ -status_t cc_os_set_callback(const cc_sched_cb_t cb_type, const cc_cb_hook_t cb_func); +status_t helios_set_callback(const helios_sched_cb_t cb_type, const helios_cb_hook_t cb_func); /** * @brief Get name of current running task @@ -121,45 +121,45 @@ status_t cc_os_set_callback(const cc_sched_cb_t cb_type, const cc_cb_hook_t cb_f * @param None * @return Pointer to the current task name */ -const char * cc_os_get_curr_task_name(void); +const char * helios_get_curr_task_name(void); /** * @brief Get name of any task using task handler * - * @param cc_os_task[in] Task handler + * @param helios_task[in] Task handler * @return Pointer to the task name */ -const char *cc_os_get_task_name(cc_os_task_t cc_os_task); +const char *helios_get_task_name(helios_task_t helios_task); /** * @brief A Function to put the current task to a waiting state and yield * @note To just Yeild set ticks to 0 * - * @param ticks[in] Number of CC_OS Ticks + * @param ticks[in] Number of HELIOS Ticks * @return None */ -void cc_os_task_wait(const size_t ticks); +void helios_task_wait(const size_t ticks); /** * @brief A Function to switch to next available task * * @return None */ -void cc_os_task_yield(void); +void helios_task_yield(void); /** * @brief A Function to invoke the kernel * * @return status_t */ -void cc_os_run(void); +void helios_run(void); /** * @brief A function to enable anti-deadlock for the task and feed timer value to scheduler. The same shall be used to reset the task watchdog to keep the task alive. - * @note 1. For this feature user needs to enable CC_OS_ANTI_DEADLOCK flag. - * @note 2. CC_OS does NOT keep the reference of previously set watchdog tick value. + * @note 1. For this feature user needs to enable HELIOS_ANTI_DEADLOCK flag. + * @note 2. HELIOS does NOT keep the reference of previously set watchdog tick value. * It is the responsibility of the user to feed the required number of ticks for the tasks to be considered alive. - * @note 3. User needs to set an user callback of type cc_sched_cb_deadlock_notify using cc_os_set_callback(). + * @note 3. User needs to set an user callback of type helios_sched_cb_deadlock_notify using helios_set_callback(). * @note 4. This fucntion shall be called from the Task atleast once for the timer to get started. * @note 5. This function is only allowed to be called from within the task. * @@ -167,7 +167,7 @@ void cc_os_run(void); * * @return status_t */ -status_t cc_os_task_anti_deadlock_enable_and_feed(size_t task_wd_ticks); +status_t helios_task_anti_deadlock_enable_and_feed(size_t task_wd_ticks); /** * @brief A function to disable anti deadlock for the task. @@ -175,4 +175,4 @@ status_t cc_os_task_anti_deadlock_enable_and_feed(size_t task_wd_ticks); * * @return status_t */ -status_t cc_os_task_anti_deadlock_disable(void); +status_t helios_task_anti_deadlock_disable(void); diff --git a/src/include/visor/terravisor/cc_os/utils/cc_os_heap.h b/src/include/visor/terravisor/helios/utils/helios_heap.h similarity index 68% rename from src/include/visor/terravisor/cc_os/utils/cc_os_heap.h rename to src/include/visor/terravisor/helios/utils/helios_heap.h index 44ad205a..14dc7506 100644 --- a/src/include/visor/terravisor/cc_os/utils/cc_os_heap.h +++ b/src/include/visor/terravisor/helios/utils/helios_heap.h @@ -2,7 +2,7 @@ * CYANCORE LICENSE * Copyrights (C) 2022, Cyancore Team * - * File Name : cc_os_heap.h + * File Name : helios_heap.h * Description : CC OS Heap declaration (Placeholder) * Primary Author : Pranjal Chanda [pranjalchanda08@gmail.com] * Organisation : Cyancore Core-Team @@ -11,7 +11,7 @@ #include #include #include -#include +#include -void * cc_os_malloc(size_t size); -void cc_os_free(void *addr); +void * helios_malloc(size_t size); +void helios_free(void *addr); diff --git a/src/include/visor/terravisor/helios/utils/helios_sched.h b/src/include/visor/terravisor/helios/utils/helios_sched.h new file mode 100644 index 00000000..83c1d4c1 --- /dev/null +++ b/src/include/visor/terravisor/helios/utils/helios_sched.h @@ -0,0 +1,140 @@ +/* + * CYANCORE LICENSE + * Copyrights (C) 2022, Cyancore Team + * + * File Name : helios_sched.h + * Description : CC OS Kernel scheduler declaration + * Primary Author : Pranjal Chanda [pranjalchanda08@gmail.com] + * Organisation : Cyancore Core-Team + */ + +#pragma once + +/***************************************************** + * INCLUDES + *****************************************************/ +#include +#include +#include + +/***************************************************** + * DEFINES + *****************************************************/ +#define HELIOS_NULL_PTR NULL +#define HELIOS_DELAY_MAX SIZE_MAX + +#define HELIOS_DYNAMIC HELIOS_USE_DYNAMIC + +#define HELIOS_ASSERT_IF_FALSE(con) RET_ON_FAIL(con, error_func_inval_arg) + +/***************************************************** + * TYPEDEFS + *****************************************************/ +typedef struct helios_sched_tcb helios_sched_tcb_t; +typedef struct helios_sched helios_sched_t; +typedef const char c_char; +typedef void * helios_args; +typedef void (*task_fn_t)(helios_args args); +typedef void (*helios_cb_hook_t)(helios_args args); +typedef enum +{ + helios_sched_task_status_exit = 0x00, ///> Initial State + helios_sched_task_status_running = 0x01, ///> Task currently running + helios_sched_task_status_ready = 0x02, ///> Task Ready to despatch + helios_sched_task_status_wait = 0x03, ///> Task in wait state + helios_sched_task_status_pause = 0x04, ///> Task in pause state + helios_sched_task_status_max = 0xff, ///> Do Nt Use +} helios_sched_task_status_t; + +/* + * @note All negative callbacks are internally used by the scheduler + */ +typedef enum +{ + helios_sched_cb_power_pre_sleep = 0x00, + helios_sched_cb_power_post_sleep = 0x01, + helios_sched_cb_power_sleep = 0x02, + helios_sched_cb_deadlock_notify = 0x03, + helios_sched_cb_max = 0xff +}helios_sched_cb_t; + +typedef enum +{ + helios_task_flag_set_anti_deadlock = (1 << 0) ///> Enable Antideadlock for the task +}helios_task_flag_t; +typedef struct link +{ + helios_sched_tcb_t * prev; + helios_sched_tcb_t * next; +}link_t; + +typedef struct wres +{ + uintptr_t wait_on_resource; ///> Resource on hich the task is waiting on + size_t task_delay_ticks; ///> Time delay in ticks +}wres_t; + +struct helios_sched_tcb +{ + + c_char * name; ///> Name of the Current Task + uint8_t priority; ///> Priority of the task + uint8_t task_flags; ///> Task Flags + uintptr_t stack_ptr; ///> Stack Pointer + task_fn_t task_func; ///> Task Call Function + uintptr_t args_ptr; ///> Task Call argument ptr + wres_t wait_res; ///> Wait Task resource + link_t ready_link; ///> Ready Linked List Pointers + link_t wait_link; ///> Wait Linked List Pointers + uint16_t task_id; ///> Task ID assigned +#if HELIOS_ANTI_DEADLOCK + size_t task_wd_ticks; ///> Tick down counter for Anti Deadlock system +#endif /* HELIOS_ANTI_DEADLOCK */ + helios_sched_task_status_t task_status; ///> Current state of the task +}; + +typedef struct helios_sched_func_cb +{ + helios_cb_hook_t pre_sched; +#if HELIOS_POWER_SAVE_EN + helios_cb_hook_t pre_sleep_cb; + helios_cb_hook_t post_sleep_cb; + helios_cb_hook_t sleep_cb; +#endif /* HELIOS_POWER_SAVE_EN */ +#if HELIOS_ANTI_DEADLOCK + helios_cb_hook_t deadlock_notify; +#endif /* HELIOS_ANTI_DEADLOCK */ +}helios_sched_func_cb_t; + +typedef struct helios_sched_ctrl +{ + helios_sched_tcb_t * ready_list_head; + helios_sched_tcb_t * curr_task; + helios_sched_tcb_t * wait_list_head; + helios_sched_t * selected_sched; + helios_sched_func_cb_t cb_hooks_reg; +}helios_sched_ctrl_t; + +/** + * @brief Prototype of scheduler algorithm function + */ +typedef void (* algo_fn)(helios_sched_ctrl_t * sched_ctrl); + +typedef enum +{ + helios_sched_algo_round_robin = 0x00, ///> Round Robin scheduling algorithm + helios_sched_algo_priority_driven = 0x01, ///> Priority driven Scheduling + helios_sched_algo_max = 0xff +}helios_sched_algo_t; + +typedef struct helios_sched +{ + helios_sched_algo_t helios_selected_algo; ///> Selected Algorithm ID + algo_fn algo_function; ///> Pointer to algorithm function +}helios_sched_t; + +typedef struct helios_sched_anti_deadlock +{ + c_char * name; + task_fn_t task_func; +}helios_sched_anti_deadlock_t; diff --git a/src/visor/terravisor/services/kernel/cc_os_config.mk b/src/visor/terravisor/services/kernel/cc_os_config.mk index b753b386..96aa435e 100644 --- a/src/visor/terravisor/services/kernel/cc_os_config.mk +++ b/src/visor/terravisor/services/kernel/cc_os_config.mk @@ -3,25 +3,25 @@ # Copyrights (C) 2019, Cyancore Team # # File Name : cc_os_config.mk -# Description : This file consists of CC_OS kernal configuration +# Description : This file consists of HELIOS kernal configuration # Primary Author : Pranjal Chanda[pranjalchanda08@gmail.com] # Organisation : Cyancore Core-Team # -CC_OS_IDLE_TASK_PRIORITY := 1 -CC_OS_USE_DYNAMIC ?= 1 -CC_OS_HEAP_SIZE ?= 1024 -CC_OS_MAX_THREAD ?= 2 -CC_OS_IDLE_TASK_NAME ?= \"CC_OS_IDLE\" -CC_OS_IDLE_TASK_STACK_LEN ?= 255 -CC_OS_POWER_SAVE_EN ?= 0 -CC_OS_ANTI_DEADLOCK ?= 1 +HELIOS_IDLE_TASK_PRIORITY := 1 +HELIOS_USE_DYNAMIC ?= 1 +HELIOS_HEAP_SIZE ?= 1024 +HELIOS_MAX_THREAD ?= 2 +HELIOS_IDLE_TASK_NAME ?= \"HELIOS_IDLE\" +HELIOS_IDLE_TASK_STACK_LEN ?= 255 +HELIOS_POWER_SAVE_EN ?= 0 +HELIOS_ANTI_DEADLOCK ?= 1 -$(eval $(call add_define,CC_OS_USE_DYNAMIC)) -$(eval $(call add_define,CC_OS_HEAP_SIZE)) -$(eval $(call add_define,CC_OS_MAX_THREAD)) -$(eval $(call add_define,CC_OS_IDLE_TASK_NAME)) -$(eval $(call add_define,CC_OS_IDLE_TASK_PRIORITY)) -$(eval $(call add_define,CC_OS_IDLE_TASK_STACK_LEN)) -$(eval $(call add_define,CC_OS_POWER_SAVE_EN)) -$(eval $(call add_define,CC_OS_ANTI_DEADLOCK)) +$(eval $(call add_define,HELIOS_USE_DYNAMIC)) +$(eval $(call add_define,HELIOS_HEAP_SIZE)) +$(eval $(call add_define,HELIOS_MAX_THREAD)) +$(eval $(call add_define,HELIOS_IDLE_TASK_NAME)) +$(eval $(call add_define,HELIOS_IDLE_TASK_PRIORITY)) +$(eval $(call add_define,HELIOS_IDLE_TASK_STACK_LEN)) +$(eval $(call add_define,HELIOS_POWER_SAVE_EN)) +$(eval $(call add_define,HELIOS_ANTI_DEADLOCK)) diff --git a/src/visor/terravisor/services/kernel/cc_os_sched.c b/src/visor/terravisor/services/kernel/cc_os_sched.c deleted file mode 100644 index f2ed2842..00000000 --- a/src/visor/terravisor/services/kernel/cc_os_sched.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * CYANCORE LICENSE - * Copyrights (C) 2022, Cyancore Team - * - * File Name : cc_os_sched.c - * Description : CC OS Kernel scheduler definations - * Primary Author : Pranjal Chanda [pranjalchanda08@gmail.com] - * Organisation : Cyancore Core-Team - */ - -/***************************************************** - * INCLUDES - *****************************************************/ -#include -#include - -/***************************************************** - * DEFINES - *****************************************************/ -#define CC_SCHED_ALGO(_id, _fn) { \ - .cc_selected_algo = _id, \ - .algo_function = _fn} - -/***************************************************** - * STATIC FUNCTION DECLARATION - *****************************************************/ -static void __cc_sched_deadlock_adjustment_and_detection(const cc_sched_ctrl_t * sched_ctrl); -static void __cc_sched_wait_list_adjustment(cc_sched_ctrl_t * sched_ctrl); -static void __cc_sched_algo_round_robin_fn(cc_sched_ctrl_t * sched_ctrl); -static void __cc_sched_algo_priority_driven_fn(cc_sched_ctrl_t * sched_ctrl); - -/***************************************************** - * GLOBAL DECLARATIONS - *****************************************************/ -#if !CC_OS_USE_DYNAMIC -cc_sched_tcb_t g_cc_os_tcb_list [CC_OS_MAX_THREAD]; -#else -cc_sched_tcb_t * g_cc_os_tcb_list = CC_OS_NULL_PTR; -#endif - -cc_sched_t g_cc_sched_list [] = -{ - CC_SCHED_ALGO(cc_sched_algo_round_robin, __cc_sched_algo_round_robin_fn), - CC_SCHED_ALGO(cc_sched_algo_priority_driven, __cc_sched_algo_priority_driven_fn), -}; - -cc_sched_ctrl_t g_sched_ctrl = -{ -#if !CC_OS_USE_DYNAMIC - .ready_list_head = &(g_cc_os_tcb_list[false]), - .curr_task = &(g_cc_os_tcb_list[false]), -#else - .ready_list_head = CC_OS_NULL_PTR, - .curr_task = CC_OS_NULL_PTR, -#endif - .wait_list_head = CC_OS_NULL_PTR, - .task_max_prio = CC_OS_NULL_PTR, - .selected_sched = &(g_cc_sched_list[cc_sched_algo_round_robin]) -}; - -/***************************************************** - * INTERNAL USED FUNCTIONS (NON-STATIC) - *****************************************************/ -status_t _insert_after(cc_sched_tcb_t ** ptr, cc_sched_tcb_t * new_node, uint8_t link_type) -{ - CC_OS_ASSERT_IF_FALSE(new_node != CC_OS_NULL_PTR); - if (link_type == true) - { - /* Wait Link */ - if (*ptr == CC_OS_NULL_PTR) - { - *ptr = new_node; - new_node->wait_link.next = new_node; - new_node->wait_link.prev = new_node; - } - else - { - new_node->wait_link.next = (*ptr)->wait_link.next; - new_node->wait_link.prev = *ptr; - new_node->wait_link.next->wait_link.prev = new_node; - (*ptr)->wait_link.next = new_node; - } - } - else - { - /* Ready Link */ - if (*ptr == CC_OS_NULL_PTR) - { - *ptr = new_node; - new_node->ready_link.next = new_node; - new_node->ready_link.prev = new_node; - } - else - { - new_node->ready_link.next = (*ptr)->ready_link.next; - new_node->ready_link.prev = *ptr; - new_node->ready_link.next->ready_link.prev = new_node; - (*ptr)->ready_link.next = new_node; - } - } - return success; -} -status_t _insert_before(cc_sched_tcb_t ** ptr, cc_sched_tcb_t * new_node, uint8_t link_type) -{ - CC_OS_ASSERT_IF_FALSE(new_node != CC_OS_NULL_PTR); - if (link_type == true) - { - /* Wait Link */ - if (*ptr == CC_OS_NULL_PTR) - { - *ptr = new_node; - new_node->wait_link.next = new_node; - new_node->wait_link.prev = new_node; - } - else - { - new_node->wait_link.next = *ptr; - new_node->wait_link.prev = (*ptr)->wait_link.prev; - (*ptr)->wait_link.prev = new_node; - new_node->wait_link.prev->wait_link.next = new_node; - } - } - else - { - /* Ready Link */ - if (*ptr == CC_OS_NULL_PTR) - { - *ptr = new_node; - new_node->ready_link.next = new_node; - new_node->ready_link.prev = new_node; - } - else - { - new_node->ready_link.next = *ptr; - new_node->ready_link.prev = (*ptr)->ready_link.prev; - (*ptr)->ready_link.prev = new_node; - new_node->ready_link.prev->ready_link.next = new_node; - } - } - return success; -} - -void _cc_sched_send_to_wait(cc_sched_ctrl_t * sched_ctrl, cc_sched_tcb_t * ptr, const size_t ticks) -{ - if (ptr->task_status == cc_sched_task_status_wait) - { - return; - } - if(_insert_before(&(sched_ctrl->wait_list_head), ptr, true) == success) - { - ptr->wait_res.task_delay_ticks = ticks; - ptr->task_status = cc_sched_task_status_wait; - } -} - -void _cc_sched_send_to_pause(cc_sched_ctrl_t * sched_ctrl, cc_sched_tcb_t * ptr) -{ - if (ptr->task_status == cc_sched_task_status_pause) - { - return; - } - if(_insert_before(&(sched_ctrl->wait_list_head), ptr, true) == success) - { - ptr->wait_res.task_delay_ticks = CC_OS_DELAY_MAX; - ptr->task_status = cc_sched_task_status_pause; - } -} - -void _cc_sched_send_to_resume(cc_sched_ctrl_t * sched_ctrl, cc_sched_tcb_t * ptr) -{ - if (ptr->task_status < cc_sched_task_status_wait) - { - return; - } - - if (ptr == sched_ctrl->wait_list_head) - { - /* First in the list */ - sched_ctrl->wait_list_head = ptr->wait_link.next; - if (ptr->wait_link.next == ptr && ptr->wait_link.prev == ptr) - { - /* Last Wait task left */ - sched_ctrl->wait_list_head = CC_OS_NULL_PTR; - } - } - ptr->wait_link.prev->wait_link.next = ptr->wait_link.next; - ptr->wait_link.next->wait_link.prev = ptr->wait_link.prev; - ptr->wait_link.prev = CC_OS_NULL_PTR; - ptr->wait_link.next = CC_OS_NULL_PTR; - ptr->wait_res.task_delay_ticks = false; - ptr->task_status = cc_sched_task_status_ready; -} - -void _cc_os_pre_sched(cc_os_args args) -{ - cc_sched_ctrl_t * sched_ctrl = (cc_sched_ctrl_t *) args; - - __cc_sched_wait_list_adjustment(sched_ctrl); - __cc_sched_deadlock_adjustment_and_detection(sched_ctrl); -} - -void _cc_os_scheduler_despatch(void) -{ - if (g_sched_ctrl.cb_hooks_reg.pre_sched != NULL) - { - /* Call Pre_sched Function */ - g_sched_ctrl.cb_hooks_reg.pre_sched((cc_os_args) &g_sched_ctrl); - } - else - { - /* A System Error case */ - arch_panic_handler(); - } - - if (g_sched_ctrl.selected_sched != NULL) - { - /* Call the scheduler */ - g_sched_ctrl.selected_sched->algo_function(&g_sched_ctrl); - } - else - { - /* A System Error case */ - arch_panic_handler(); - } - -} -/***************************************************** - * STATIC FUNCTION DEFINATIONS - *****************************************************/ -static void __cc_sched_context_switch(cc_sched_tcb_t * next_task) -{ - next_task->task_status = cc_sched_task_status_running; -} - -static void __cc_sched_deadlock_adjustment_and_detection(const cc_sched_ctrl_t * sched_ctrl _UNUSED) -{ -#if CC_OS_ANTI_DEADLOCK - cc_sched_tcb_t * ptr = sched_ctrl->ready_list_head; - static cc_sched_anti_deadlock_t anti_deadlock_notify; - while (ptr != CC_OS_NULL_PTR) - { - if (ptr->task_status != cc_sched_task_status_pause) - { - ptr->task_wd_ticks--; - } - if ((ptr->task_wd_ticks == false) && (sched_ctrl->cb_hooks_reg.deadlock_notify != CC_OS_NULL_PTR)) - { - /* Create notification params */ - anti_deadlock_notify.name = ptr->name; - anti_deadlock_notify.task_func = ptr->task_func; - - if (ptr->task_status != cc_sched_task_status_exit) - { - ptr->task_status = cc_sched_task_status_exit; - } - /* Notify the user that the task pointed by ptr is dead and has been terminated */ - sched_ctrl->cb_hooks_reg.deadlock_notify((cc_os_args) &anti_deadlock_notify); - } - if (ptr->ready_link.next == sched_ctrl->ready_list_head) - { - break; - } - } -#else - return; -#endif /* CC_OS_ANTI_DEADLOCK */ -} -static void __cc_sched_wait_list_adjustment(cc_sched_ctrl_t * sched_ctrl) -{ - cc_sched_tcb_t * ptr = sched_ctrl->wait_list_head; - const int * wait_res = (int *)ptr->wait_res.wait_on_resource; - while(ptr != CC_OS_NULL_PTR) - { - if (ptr->task_status == cc_sched_task_status_wait) - { - ptr->wait_res.task_delay_ticks--; /* Tick caliberations required */ - - if ((wait_res != CC_OS_NULL_PTR) && *wait_res > false) - { - /* The resource is available can can go to ready state */ - ptr->wait_res.task_delay_ticks = false; - ptr->wait_res.wait_on_resource = false; - } - if(ptr->wait_res.task_delay_ticks == false) - { - _cc_sched_send_to_resume(sched_ctrl, ptr); - } - if (ptr->wait_link.next == sched_ctrl->wait_list_head) - { - break; - } - else - { - ptr = ptr->wait_link.next; - } - } - } -} - -/***************************************************** - * SCHEDULER ALGORITHMS - *****************************************************/ -static void __cc_sched_algo_round_robin_fn(cc_sched_ctrl_t * sched_ctrl) -{ - /* do waitlist adjustment */ - cc_sched_tcb_t * ptr = sched_ctrl->curr_task->ready_link.next; - - __cc_sched_wait_list_adjustment(sched_ctrl); - - if (ptr == sched_ctrl->ready_list_head) - { - /* IDLE Task */ - _cc_sched_send_to_resume(&g_sched_ctrl, ptr); - } - /* Context switch to next task */ - if (ptr->task_status == cc_sched_task_status_ready) - { - __cc_sched_context_switch(ptr->ready_link.next); - } -} - -static void __cc_sched_algo_priority_driven_fn(cc_sched_ctrl_t * sched_ctrl) -{ - /* do waitlist adjustment */ - __cc_sched_wait_list_adjustment(sched_ctrl); - - cc_sched_tcb_t * ptr = sched_ctrl->ready_list_head->ready_link.prev; - if(ptr != CC_OS_NULL_PTR) - { - while (ptr->task_status != cc_sched_task_status_ready) - { - ptr = ptr->wait_link.prev; - if (ptr == sched_ctrl->ready_list_head) - { - /* IDLE Task */ - _cc_sched_send_to_resume(&g_sched_ctrl, ptr); - break; - } - } - __cc_sched_context_switch(ptr); - } -} diff --git a/src/visor/terravisor/services/kernel/cc_os_task_idle.c b/src/visor/terravisor/services/kernel/cc_os_task_idle.c deleted file mode 100644 index af1925fb..00000000 --- a/src/visor/terravisor/services/kernel/cc_os_task_idle.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * CYANCORE LICENSE - * Copyrights (C) 2022, Cyancore Team - * - * File Name : cc_os_task_idle.c - * Description : CC OS IDLE Task definitions - * Primary Author : Pranjal Chanda [pranjalchanda08@gmail.com] - * Organisation : Cyancore Core-Team - */ - -/***************************************************** - * INCLUDES - *****************************************************/ -#include -#include - -/***************************************************** - * STATIC FUNCTION DECLARATION - *****************************************************/ -/** - * @brief This function cleans up the terminated task form the TCB list - * - * @param ptr[in] Pointer to the TCB being cleaned - * @return cc_sched_tcb_t * Pointer to the next TCB - */ -static cc_sched_tcb_t * __free_terminated_task(cc_sched_tcb_t * ptr) -{ - cc_sched_tcb_t * next_ptr = ptr->ready_link.next; - if (ptr->ready_link.next->task_status == cc_sched_task_status_exit) - { - ptr->ready_link.prev->ready_link.next = ptr->ready_link.next; - ptr->ready_link.next->ready_link.prev = ptr->ready_link.prev; - -#if CC_OS_DYNAMIC == false - ptr->ready_link.next = CC_OS_NULL_PTR; - ptr->ready_link.prev = CC_OS_NULL_PTR; -#else - cc_os_free((void *)ptr->stack_ptr); - cc_os_free(ptr); -#endif - } - - return next_ptr; -} - -#if CC_OS_POWER_SAVE_EN -static void __cc_power_save_callback(void) -{ - arch_wfi(); -} -#endif -/***************************************************** - * USER FUNCTION DEFINATION - *****************************************************/ -void _cc_os_idle_task_fn(cc_os_args args) -{ - static cc_sched_tcb_t * ptr = CC_OS_NULL_PTR; - cc_sched_ctrl_t * sched_ctrl = (cc_sched_ctrl_t *) args; - ptr = sched_ctrl->ready_list_head; -#if CC_OS_POWER_SAVE_EN - if (sched_ctrl->cb_hooks_reg.sleep_cb == CC_OS_NULL_PTR) - { - sched_ctrl->cb_hooks_reg.sleep_cb = __cc_power_save_callback; - } -#endif - while (true) - { - /* Clean up task if terminated */ - ptr = __free_terminated_task(ptr); - -#if CC_OS_POWER_SAVE_EN - /* Power Save code */ - if (sched_ctrl->cb_hooks_reg.pre_sleep_cb != CC_OS_NULL_PTR) - { - sched_ctrl->cb_hooks_reg.pre_sleep_cb(); - } - if (sched_ctrl->cb_hooks_reg.sleep_cb != CC_OS_NULL_PTR) - { - sched_ctrl->cb_hooks_reg.sleep_cb(); - } - if (sched_ctrl->cb_hooks_reg.post_sleep_cb != CC_OS_NULL_PTR) - { - sched_ctrl->cb_hooks_reg.post_sleep_cb(); - } -#endif - /* Yield for next available task */ - cc_os_task_yield(); - } -} diff --git a/src/visor/terravisor/services/kernel/cc_os_tasks.c b/src/visor/terravisor/services/kernel/cc_os_tasks.c deleted file mode 100644 index 5304ad4f..00000000 --- a/src/visor/terravisor/services/kernel/cc_os_tasks.c +++ /dev/null @@ -1,478 +0,0 @@ -/* - * CYANCORE LICENSE - * Copyrights (C) 2022, Cyancore Team - * - * File Name : cc_os_tasks.c - * Description : CC OS Kernel tasks related definations definations - * Primary Author : Pranjal Chanda [pranjalchanda08@gmail.com] - * Organisation : Cyancore Core-Team - */ - -/***************************************************** - * INCLUDES - *****************************************************/ -#include -#include -#include -#include -#include - -/***************************************************** - * DEFINES - *****************************************************/ -#define CC_OS_PRIORITY_MAX 255 - -/***************************************************** - * INTERNAL EXTERNS FUNCTIONS - *****************************************************/ -extern status_t _insert_after(cc_sched_tcb_t **ptr, cc_sched_tcb_t *new_node, uint8_t link_type); -extern status_t _insert_before(cc_sched_tcb_t **ptr, cc_sched_tcb_t *new_node, uint8_t link_type); -extern void _cc_sched_send_to_wait(cc_sched_ctrl_t *sched_ctrl, cc_sched_tcb_t *ptr, const size_t ticks); -extern void _cc_sched_send_to_pause(cc_sched_ctrl_t * sched_ctrl, cc_sched_tcb_t * ptr); -extern void _cc_sched_send_to_resume(cc_sched_ctrl_t *sched_ctrl, cc_sched_tcb_t *ptr); -extern void _cc_os_pre_sched(cc_os_args args); -/***************************************************** - * GLOBAL EXTERNS VARIABLES - *****************************************************/ -extern void _cc_os_idle_task_fn(cc_os_args args); -extern cc_sched_t g_cc_sched_list[]; -extern cc_sched_ctrl_t g_sched_ctrl; - -/***************************************************** - * GLOBAL DECLARATIONS - *****************************************************/ -#if CC_OS_DYNAMIC == false -extern cc_sched_tcb_t g_cc_os_tcb_list[]; -#else -extern cc_sched_tcb_t *g_cc_os_tcb_list; -#endif - -#if CC_OS_DYNAMIC == false -uint8_t _cc_os_stack[CC_OS_IDLE_STACK_LEN]; -#else -uint8_t *_cc_os_stack = CC_OS_NULL_PTR; -#endif -cc_os_task_t *cc_os_idle_task; -/***************************************************** - * STATIC VARIABLES - *****************************************************/ -static size_t __cc_os_task_id_gen = false; -/***************************************************** - * STATIC FUNCTION DEFINATIONS - *****************************************************/ -static void __cc_init_scheduler(void) -{ - g_sched_ctrl.cb_hooks_reg.pre_sched = &_cc_os_pre_sched; - return; -} - -static size_t __cc_os_task_id_generate() -{ - __cc_os_task_id_gen++; - return __cc_os_task_id_gen; -} - -static cc_sched_tcb_t * __cc_os_get_tcb_using_task_id(const uintptr_t task_id) -{ - cc_sched_tcb_t * ptr = g_sched_ctrl.ready_list_head; - bool _is_id_found = false; - while (ptr->ready_link.next != g_sched_ctrl.ready_list_head) - { - if (ptr->task_id == task_id) - { - _is_id_found = true; - break; - } - ptr = ptr->ready_link.next; - } - if (_is_id_found == false) - { - ptr = CC_OS_NULL_PTR; - } - return ptr; -} - -static status_t __cc_os_set_task_flag(cc_sched_tcb_t* cc_os_task, cc_task_flag_t task_flag, bool en) -{ - CC_OS_ASSERT_IF_FALSE( cc_os_task != CC_OS_NULL_PTR); - - if (en) - { - cc_os_task->task_flags |= (uint8_t)task_flag; - } - else - { - cc_os_task->task_flags &= (uint8_t)~task_flag; - } - return success; -} - -static bool __cc_os_is_task_flag(const cc_sched_tcb_t *cc_os_task, cc_task_flag_t task_flag) -{ - if (cc_os_task != CC_OS_NULL_PTR) - { - return (cc_os_task->task_flags & task_flag) == false; - } - - return false; -} -/***************************************************** - * USER FUNCTION DEFINATIONS - *****************************************************/ -status_t cc_os_add_task( - cc_os_task_t *cc_os_task, - const char *name, - task_fn_t task_func, - cc_os_args args, - uint8_t priority, - size_t stack_len, -#if CC_OS_DYNAMIC - uintptr_t stack_ptr _UNUSED -#else - uintptr_t stack_ptr -#endif /* CC_OS_DYNAMIC */ -) -{ - CC_OS_ASSERT_IF_FALSE(cc_os_task == CC_OS_NULL_PTR); - CC_OS_ASSERT_IF_FALSE(name != CC_OS_NULL_PTR); -#if CC_OS_DYNAMIC == false - CC_OS_ASSERT_IF_FALSE(stack_ptr != (uintptr_t)CC_OS_NULL_PTR); -#endif - CC_OS_ASSERT_IF_FALSE(task_func != CC_OS_NULL_PTR); - CC_OS_ASSERT_IF_FALSE(stack_len != false); - CC_OS_ASSERT_IF_FALSE(priority >= CC_OS_IDLE_TASK_PRIORITY); - CC_OS_ASSERT_IF_FALSE(priority < CC_OS_PRIORITY_MAX); - - cc_os_pause_all_task(); - - cc_sched_tcb_t *ptr = g_sched_ctrl.ready_list_head; - -#if CC_OS_DYNAMIC == true - if (ptr == CC_OS_NULL_PTR) - { - /* First Dynamic task */ - ptr = (cc_sched_tcb_t *)cc_os_malloc(sizeof(cc_sched_tcb_t)); - if (ptr == CC_OS_NULL_PTR) - { - cc_os_resume_all_task(); - return error_memory_low; - } - } -#endif /* CC_OS_DYNAMIC */ - if ((ptr->ready_link.next == CC_OS_NULL_PTR) && (ptr->ready_link.prev == CC_OS_NULL_PTR)) - { - ptr->ready_link.next = ptr->ready_link.prev = g_sched_ctrl.ready_list_head; - } - - else - { -#if CC_OS_DYNAMIC == false - /* Static Task Allocation */ - for (size_t i = false; i < CC_OS_MAX_THREAD; i++) - { - /* Get an available node from global tcb list */ - if (g_cc_os_tcb_list[i].task_status == cc_sched_task_status_exit) - { - ptr = &(g_cc_os_tcb_list[i]); - break; - } - } - if (ptr != g_sched_ctrl.ready_list_head) - { - ptr->stack_ptr = stack_ptr; -#else - /* Dynamic Task Declaration */ - ptr = (cc_sched_tcb_t *)cc_os_malloc(sizeof(cc_sched_tcb_t)); - if (ptr != CC_OS_NULL_PTR) - { - ptr->stack_ptr = (uintptr_t)malloc(stack_len); - if (ptr->stack_ptr == (uintptr_t)CC_OS_NULL_PTR) - { - cc_os_resume_all_task(); - return error_memory_low; - } -#endif /* CC_OS_DYNAMIC */ - /* Fill tcb details */ - ptr->name = name; - ptr->priority = priority; - ptr->task_func = task_func; - ptr->args_ptr = (uintptr_t)args; -#if CC_OS_ANTI_DEADLOCK - ptr->task_wd_ticks = SIZE_MAX; -#endif /* CC_OS_ANTI_DEADLOCK */ - } - else - { - cc_os_resume_all_task(); - return error_memory_low; - } - } - /* Insert Tasks in assending order of its priority */ - if (g_sched_ctrl.task_max_prio == CC_OS_NULL_PTR) - { - g_sched_ctrl.task_max_prio = ptr; - } - else if (g_sched_ctrl.task_max_prio->priority <= ptr->priority) - { - if (_insert_after(&(g_sched_ctrl.task_max_prio), ptr, false) == success) - { - g_sched_ctrl.task_max_prio = ptr; - } - else - { - cc_os_resume_all_task(); - return error_os_task_overfow; - } - } - else - { - cc_sched_tcb_t *comp_ptr = g_sched_ctrl.task_max_prio->ready_link.next; - while (true) - { - if (comp_ptr->priority <= ptr->priority && (_insert_after(&comp_ptr, ptr, false) == success)) - { - break; - } - else - { - comp_ptr = comp_ptr->ready_link.next; - } - } - } - - ptr->task_status = cc_sched_task_status_ready; - ptr->task_id = __cc_os_task_id_generate(); - *cc_os_task = ptr->task_id; - cc_os_resume_all_task(); - return success; -} - -status_t cc_os_del_task(cc_os_task_t cc_os_task) -{ - cc_sched_tcb_t * ptr = __cc_os_get_tcb_using_task_id(cc_os_task); - CC_OS_ASSERT_IF_FALSE(ptr->task_func != &_cc_os_idle_task_fn); - - if (ptr == CC_OS_NULL_PTR) - { - ptr = g_sched_ctrl.curr_task; - } - /* Code to handle first node */ - if (ptr == g_sched_ctrl.ready_list_head) - { - /* IDLE Task can not be deleted */ - return error_os_invalid_op; - } - ptr->task_status = cc_sched_task_status_exit; - - if (ptr == g_sched_ctrl.curr_task) - { - cc_os_task_yield(); /* Yeild */ - } - - return success; -} - -status_t cc_os_pause_task(cc_os_task_t cc_os_task) -{ - cc_sched_tcb_t *ptr = __cc_os_get_tcb_using_task_id(cc_os_task); - if (ptr == CC_OS_NULL_PTR) - { - ptr = g_sched_ctrl.curr_task; - } - - _cc_sched_send_to_pause(&g_sched_ctrl, ptr); - - return success; -} - -status_t cc_os_pause_all_task(void) -{ - cc_sched_tcb_t *ptr = g_sched_ctrl.ready_list_head->ready_link.next; - - while (ptr != g_sched_ctrl.ready_list_head) - { - if (ptr == g_sched_ctrl.curr_task) - { - /* Do not pause the current task */ - continue; - } - - _cc_sched_send_to_pause(&g_sched_ctrl, ptr); - ptr = ptr->ready_link.next; - } - - return success; -} - -status_t cc_os_resume_all_task(void) -{ - cc_sched_tcb_t *ptr = g_sched_ctrl.ready_list_head->ready_link.next; - if (ptr != CC_OS_NULL_PTR) - { - while (ptr != g_sched_ctrl.ready_list_head) - { - if ((ptr == g_sched_ctrl.curr_task) || (ptr->task_status != cc_sched_task_status_pause)) - { - continue; - } - _cc_sched_send_to_resume(&g_sched_ctrl, ptr); - ptr = ptr->ready_link.next; - } - } - else - { - return error_os_invalid_op; - } - - return success; -} - -status_t cc_os_resume_task(cc_os_task_t cc_os_task) -{ - cc_sched_tcb_t *ptr = __cc_os_get_tcb_using_task_id(cc_os_task); - CC_OS_ASSERT_IF_FALSE(ptr != CC_OS_NULL_PTR); - - if (ptr->task_status != cc_sched_task_status_pause) - { - _cc_sched_send_to_resume(&g_sched_ctrl, ptr); - } - else - { - return error_os_invalid_op; - } - return success; -} - -status_t cc_os_set_sched_algo(cc_sched_algo_t sched_algo) -{ - CC_OS_ASSERT_IF_FALSE(sched_algo != cc_sched_algo_max); - - g_sched_ctrl.selected_sched = &(g_cc_sched_list[sched_algo]); - - return success; -} - -status_t cc_os_task_anti_deadlock_enable_and_feed(size_t task_wd_ticks _UNUSED) -{ -#if CC_OS_ANTI_DEADLOCK - CC_OS_ASSERT_IF_FALSE((task_wd_ticks > false) && (task_wd_ticks < SIZE_MAX)); - - cc_sched_tcb_t *ptr = g_sched_ctrl.curr_task; - if (__cc_os_is_task_flag(ptr, cc_task_flag_set_anti_deadlock)) - { - __cc_os_set_task_flag(ptr, cc_task_flag_set_anti_deadlock, true); - } - - ptr->task_wd_ticks = task_wd_ticks; - return success; -#else - cc_sched_tcb_t *ptr = g_sched_ctrl.curr_task; - if (__cc_os_is_task_flag(ptr, cc_task_flag_set_anti_deadlock)) - { - __cc_os_set_task_flag(ptr, cc_task_flag_set_anti_deadlock, false); - } - return error_func_inval; -#endif /* CC_OS_ANTI_DEADLOCK */ -} - -status_t cc_os_task_anti_deadlock_disable(void) -{ - cc_sched_tcb_t *ptr = g_sched_ctrl.curr_task; - - if (__cc_os_is_task_flag(ptr, cc_task_flag_set_anti_deadlock)) - { - __cc_os_set_task_flag(ptr, cc_task_flag_set_anti_deadlock, false); - } - -#if CC_OS_ANTI_DEADLOCK - ptr->task_wd_ticks = SIZE_MAX; - return success; -#else - return error_func_inval; -#endif /* CC_OS_ANTI_DEADLOCK */ -} -status_t cc_os_set_callback(const cc_sched_cb_t cb_type, const cc_cb_hook_t cb_func _UNUSED) -{ - status_t ret = success; - switch (cb_type) - { - case cc_sched_cb_power_post_sleep: -#if CC_OS_POWER_SAVE_EN - g_sched_ctrl.cb_hooks_reg.post_sleep_cb = cb_func; - break; -#endif - case cc_sched_cb_power_pre_sleep: -#if CC_OS_POWER_SAVE_EN - g_sched_ctrl.cb_hooks_reg.pre_sleep_cb = cb_func; - break; -#endif - case cc_sched_cb_power_sleep: -#if CC_OS_POWER_SAVE_EN - g_sched_ctrl.cb_hooks_reg.power_sleep = cb_func; - break; -#endif - case cc_sched_cb_deadlock_notify: -#if CC_OS_ANTI_DEADLOCK - g_sched_ctrl.cb_hooks_reg.deadlock_notify = cb_func; - break; -#endif - case cc_sched_cb_max: - ret = error_func_inval; - break; - } - return ret; -} - -const char *cc_os_get_curr_task_name(void) -{ - return g_sched_ctrl.curr_task->name; -} - -const char *cc_os_get_task_name(cc_os_task_t cc_os_task) -{ - const cc_sched_tcb_t *ptr = __cc_os_get_tcb_using_task_id(cc_os_task); - if(ptr != CC_OS_NULL_PTR) - { - return ptr->name; - } - return CC_OS_NULL_PTR; -} - -void cc_os_task_wait(const size_t ticks) -{ - cc_sched_tcb_t *ptr = g_sched_ctrl.curr_task; - - if (ticks > false) - { - _cc_sched_send_to_wait(&g_sched_ctrl, ptr, ticks); - } - - cc_os_task_yield(); -} - -void cc_os_task_yield() -{ - return; -} - -void cc_os_run(void) -{ - /* OS Init code */ - /* Initialise IDLE Task */ - cc_os_add_task(cc_os_idle_task, - CC_OS_IDLE_TASK_NAME, - &_cc_os_idle_task_fn, - &g_sched_ctrl, - CC_OS_IDLE_TASK_PRIORITY, - CC_OS_IDLE_TASK_STACK_LEN, - (uintptr_t)_cc_os_stack); - - /* Initialise scheduler */ - __cc_init_scheduler(); - cc_os_task_yield(); /* Yeild */ - while (true) - { - /* Code shall not reach here */ - arch_wfi(); - } -} diff --git a/src/visor/terravisor/services/kernel/cc_os_heap.c b/src/visor/terravisor/services/kernel/helios_heap.c similarity index 86% rename from src/visor/terravisor/services/kernel/cc_os_heap.c rename to src/visor/terravisor/services/kernel/helios_heap.c index e307f9bb..6942085e 100644 --- a/src/visor/terravisor/services/kernel/cc_os_heap.c +++ b/src/visor/terravisor/services/kernel/helios_heap.c @@ -2,7 +2,7 @@ * CYANCORE LICENSE * Copyrights (C) 2022, Cyancore Team * - * File Name : cc_os_heap.c + * File Name : helios_heap.c * Description : CC OS Kernel definations * Primary Author : Pranjal Chanda [pranjalchanda08@gmail.com] * Organisation : Cyancore Core-Team @@ -11,7 +11,7 @@ /***************************************************** * INCLUDES *****************************************************/ -#include +#include /***************************************************** * GLOBAL/STATIC VARIABLE DECLARATIONS @@ -28,11 +28,11 @@ /***************************************************** * USER FUNCTION DEFINATIONS *****************************************************/ -void * cc_os_malloc(size_t size) +void * helios_malloc(size_t size) { return malloc(size); } -void cc_os_free(void *addr ) +void helios_free(void *addr ) { free(addr); } diff --git a/src/visor/terravisor/services/kernel/helios_sched.c b/src/visor/terravisor/services/kernel/helios_sched.c new file mode 100644 index 00000000..763bafff --- /dev/null +++ b/src/visor/terravisor/services/kernel/helios_sched.c @@ -0,0 +1,489 @@ +/* + * CYANCORE LICENSE + * Copyrights (C) 2022, Cyancore Team + * + * File Name : helios_sched.c + * Description : CC OS Kernel scheduler definations + * Primary Author : Pranjal Chanda [pranjalchanda08@gmail.com] + * Organisation : Cyancore Core-Team + */ + +/***************************************************** + * INCLUDES + *****************************************************/ +#include +#include + +/***************************************************** + * DEFINES + *****************************************************/ +#define CC_SCHED_ALGO(_id, _fn) { \ + .helios_selected_algo = _id, \ + .algo_function = _fn} + +/***************************************************** + * STATIC FUNCTION DECLARATION + *****************************************************/ +static void __helios_sched_deadlock_adjustment_and_detection(const helios_sched_ctrl_t * sched_ctrl); +static void __helios_sched_wait_list_adjustment(helios_sched_ctrl_t * sched_ctrl); +static void __helios_sched_algo_round_robin_fn(helios_sched_ctrl_t * sched_ctrl); +static void __helios_sched_algo_priority_driven_fn(helios_sched_ctrl_t * sched_ctrl); + +/***************************************************** + * GLOBAL DECLARATIONS + *****************************************************/ +#if !HELIOS_USE_DYNAMIC +helios_sched_tcb_t g_helios_tcb_list [HELIOS_MAX_THREAD]; +#else +helios_sched_tcb_t * g_helios_tcb_list = HELIOS_NULL_PTR; +#endif + +helios_sched_t g_helios_sched_list [] = +{ + CC_SCHED_ALGO(helios_sched_algo_round_robin, __helios_sched_algo_round_robin_fn), + CC_SCHED_ALGO(helios_sched_algo_priority_driven, __helios_sched_algo_priority_driven_fn), +}; + +helios_sched_ctrl_t g_sched_ctrl = +{ +#if !HELIOS_USE_DYNAMIC + .ready_list_head = &(g_helios_tcb_list[false]), + .curr_task = &(g_helios_tcb_list[false]), +#else + .ready_list_head = HELIOS_NULL_PTR, + .curr_task = HELIOS_NULL_PTR, +#endif + .wait_list_head = HELIOS_NULL_PTR, + .selected_sched = &(g_helios_sched_list[helios_sched_algo_round_robin]) +}; + +/***************************************************** + * INTERNAL USED FUNCTIONS (NON-STATIC) + *****************************************************/ + +/** + * @brief Insert a node after a reference pointer + * + * @param ptr[in_out] Reference pointer address + * @param new_node[in] Node to be inserted + * @param link_type[in] true -> Wait Link, false -> Ready link + * + * @return None +*/ +status_t _helios_sched_insert_after(helios_sched_tcb_t ** ptr, helios_sched_tcb_t * new_node, uint8_t link_type) +{ + HELIOS_ASSERT_IF_FALSE(new_node != HELIOS_NULL_PTR); + if (link_type == true) + { + /* Wait Link */ + if (*ptr == HELIOS_NULL_PTR) + { + *ptr = new_node; + new_node->wait_link.next = new_node; + new_node->wait_link.prev = new_node; + } + else + { + new_node->wait_link.next = (*ptr)->wait_link.next; + new_node->wait_link.prev = *ptr; + new_node->wait_link.next->wait_link.prev = new_node; + (*ptr)->wait_link.next = new_node; + } + } + else + { + /* Ready Link */ + if (*ptr == HELIOS_NULL_PTR) + { + *ptr = new_node; + new_node->ready_link.next = new_node; + new_node->ready_link.prev = new_node; + } + else + { + new_node->ready_link.next = (*ptr)->ready_link.next; + new_node->ready_link.prev = *ptr; + new_node->ready_link.next->ready_link.prev = new_node; + (*ptr)->ready_link.next = new_node; + } + } + return success; +} + +/** + * @brief Insert a node before a reference pointer + * + * @param ptr[in_out] Reference pointer address + * @param new_node[in] Node to be inserted + * @param link_type[in] true -> Wait Link, false -> Ready link + * + * @return None +*/ +status_t _helios_sched_insert_before(helios_sched_tcb_t ** ptr, helios_sched_tcb_t * new_node, uint8_t link_type) +{ + HELIOS_ASSERT_IF_FALSE(new_node != HELIOS_NULL_PTR); + if (link_type == true) + { + /* Wait Link */ + if (*ptr == HELIOS_NULL_PTR) + { + *ptr = new_node; + new_node->wait_link.next = new_node; + new_node->wait_link.prev = new_node; + } + else + { + new_node->wait_link.next = *ptr; + new_node->wait_link.prev = (*ptr)->wait_link.prev; + (*ptr)->wait_link.prev = new_node; + new_node->wait_link.prev->wait_link.next = new_node; + } + } + else + { + /* Ready Link */ + if (*ptr == HELIOS_NULL_PTR) + { + *ptr = new_node; + new_node->ready_link.next = new_node; + new_node->ready_link.prev = new_node; + } + else + { + new_node->ready_link.next = *ptr; + new_node->ready_link.prev = (*ptr)->ready_link.prev; + (*ptr)->ready_link.prev = new_node; + new_node->ready_link.prev->ready_link.next = new_node; + } + } + return success; +} +/** + * @brief Send a task to wait state + * + * @param sched_ctrl[in_out] Current scheduler control + * @param ptr[in_out] Pointer to task TCB + * @param ticks[in] Ticks to wait + * + * @return None + */ +void _helios_sched_send_to_wait(helios_sched_ctrl_t * sched_ctrl, helios_sched_tcb_t * ptr, const size_t ticks) +{ + if (ptr->task_status == helios_sched_task_status_wait) + { + return; + } + if(_helios_sched_insert_before(&(sched_ctrl->wait_list_head), ptr, true) == success) + { + ptr->wait_res.task_delay_ticks = ticks; + ptr->task_status = helios_sched_task_status_wait; + } +} + +/** + * @brief Send a task to pause state + * + * @param sched_ctrl[in_out] Current scheduler control + * @param ptr[in_out] Pointer to task TCB + * + * @return None + */ +void _helios_sched_send_to_pause(helios_sched_ctrl_t * sched_ctrl, helios_sched_tcb_t * ptr) +{ + if (ptr->task_status == helios_sched_task_status_pause) + { + return; + } + if(_helios_sched_insert_before(&(sched_ctrl->wait_list_head), ptr, true) == success) + { + ptr->wait_res.task_delay_ticks = HELIOS_DELAY_MAX; + ptr->task_status = helios_sched_task_status_pause; + } +} + +/** + * @brief Send a task to ready state + * + * @param sched_ctrl[in_out] Current scheduler control + * @param ptr[in_out] Pointer to task TCB + * + * @return None + */ +void _helios_sched_send_to_resume(helios_sched_ctrl_t * sched_ctrl, helios_sched_tcb_t * ptr) +{ + if (ptr->task_status < helios_sched_task_status_wait) + { + return; + } + + if (ptr == sched_ctrl->wait_list_head) + { + /* First in the list */ + sched_ctrl->wait_list_head = ptr->wait_link.next; + if (ptr->wait_link.next == ptr && ptr->wait_link.prev == ptr) + { + /* Last Wait task left */ + sched_ctrl->wait_list_head = HELIOS_NULL_PTR; + } + } + ptr->wait_link.prev->wait_link.next = ptr->wait_link.next; + ptr->wait_link.next->wait_link.prev = ptr->wait_link.prev; + ptr->wait_link.prev = HELIOS_NULL_PTR; + ptr->wait_link.next = HELIOS_NULL_PTR; + ptr->wait_res.task_delay_ticks = false; + ptr->task_status = helios_sched_task_status_ready; +} + +/** + * @brief A function to detach an existing node from a link + * + * @param node_ptr[in_out] Address of the node to be detached + * @param link_type[in] true -> Wait Link, false -> Ready link + * + * @return None +*/ +status_t _helios_sched_node_detach(helios_sched_tcb_t *node_ptr, uint8_t link_type) +{ + HELIOS_ASSERT_IF_FALSE(node_ptr == HELIOS_NULL_PTR); + + if (link_type == true) + { + /* Wait Link */ + node_ptr->wait_link.prev->wait_link.next = node_ptr->wait_link.next; + node_ptr->wait_link.next->wait_link.prev = node_ptr->wait_link.prev; + node_ptr->wait_link.prev = node_ptr->wait_link.next = HELIOS_NULL_PTR; + if (node_ptr == g_sched_ctrl.wait_list_head) + { + g_sched_ctrl.wait_list_head = node_ptr->ready_link.next; + } + } + else + { + /* Ready Link */ + node_ptr->ready_link.prev->ready_link.next = node_ptr->ready_link.next; + node_ptr->ready_link.next->ready_link.prev = node_ptr->ready_link.prev; + node_ptr->ready_link.prev = node_ptr->ready_link.next = HELIOS_NULL_PTR; + + if (node_ptr == g_sched_ctrl.ready_list_head) + { + g_sched_ctrl.ready_list_head = node_ptr->ready_link.next; + } + } + return success; +} + +/** + * @brief Send a task to the back of its own priority list + * + * @param node_ptr[in_out] Pointer to task TCB + * + * @return None + */ +void _helios_sched_send_back_of_task_prio(helios_sched_tcb_t *node_ptr) +{ + helios_sched_tcb_t * ref_ptr = g_sched_ctrl.ready_list_head; + if(ref_ptr != HELIOS_NULL_PTR) + { + if (node_ptr == ref_ptr) + { + /* Very first node */ + return; + } + + bool least_prio = true; + /* Find an optimal space */ + while(node_ptr->priority >= ref_ptr->priority) + { + least_prio = false; + ref_ptr = ref_ptr->ready_link.next; + if (ref_ptr == g_sched_ctrl.ready_list_head) + { + /* traversal complete */ + break; + } + } + if (least_prio) + { + /* Set ready list head if least prio detected */ + g_sched_ctrl.ready_list_head = node_ptr; + } + if(node_ptr->ready_link.next == node_ptr->ready_link.prev) + { + /** + * New Node + * Insert it behind the same priority + */ + _helios_sched_insert_before(&ref_ptr, node_ptr, false); + } + else + { + /** + * Detach the current node from link and insert it at the end + * of priority + * This would help to round robin over the same priority when + * scheduling + */ + _helios_sched_node_detach(node_ptr, false); + _helios_sched_insert_before(&node_ptr, ref_ptr, false); + } + } +} + +/** + * @brief HELIOS pre scheduler callback being called before any task scheduling is done + * + * @param args[in] helios_args (provides scheduler ctrl) + * + * @return None + */ +void _helios_pre_sched(helios_args args) +{ + helios_sched_ctrl_t * sched_ctrl = (helios_sched_ctrl_t *) args; + sched_ctrl->curr_task->task_status = helios_sched_task_status_ready; + __helios_sched_wait_list_adjustment(sched_ctrl); + __helios_sched_deadlock_adjustment_and_detection(sched_ctrl); + _helios_sched_send_back_of_task_prio(sched_ctrl->curr_task); +} + +/** + * @brief Despatch a scheduling as per selected algorithm + * + * @return None + */ +void _helios_scheduler_despatch(void) +{ + if (g_sched_ctrl.cb_hooks_reg.pre_sched != NULL) + { + /* Call Pre_sched Function */ + g_sched_ctrl.cb_hooks_reg.pre_sched((helios_args) &g_sched_ctrl); + } + else + { + /* A System Error case */ + arch_panic_handler(); + } + + if (g_sched_ctrl.selected_sched != NULL) + { + /* Call the scheduler */ + g_sched_ctrl.selected_sched->algo_function(&g_sched_ctrl); + } + else + { + /* A System Error case */ + arch_panic_handler(); + } + +} +/***************************************************** + * STATIC FUNCTION DEFINATIONS + *****************************************************/ +static void __helios_sched_context_switch(helios_sched_tcb_t * next_task) +{ + next_task->task_status = helios_sched_task_status_running; +} + +static void __helios_sched_deadlock_adjustment_and_detection(const helios_sched_ctrl_t * sched_ctrl _UNUSED) +{ +#if HELIOS_ANTI_DEADLOCK + helios_sched_tcb_t * ptr = sched_ctrl->ready_list_head; + static helios_sched_anti_deadlock_t anti_deadlock_notify; + while (ptr != HELIOS_NULL_PTR) + { + if (ptr->task_status != helios_sched_task_status_pause) + { + ptr->task_wd_ticks--; + } + if ((ptr->task_wd_ticks == false) && (sched_ctrl->cb_hooks_reg.deadlock_notify != HELIOS_NULL_PTR)) + { + /* Create notification params */ + anti_deadlock_notify.name = ptr->name; + anti_deadlock_notify.task_func = ptr->task_func; + + if (ptr->task_status != helios_sched_task_status_exit) + { + ptr->task_status = helios_sched_task_status_exit; + } + /* Notify the user that the task pointed by ptr is dead and has been terminated */ + sched_ctrl->cb_hooks_reg.deadlock_notify((helios_args) &anti_deadlock_notify); + } + if (ptr->ready_link.next == sched_ctrl->ready_list_head) + { + break; + } + } +#else + return; +#endif /* HELIOS_ANTI_DEADLOCK */ +} +static void __helios_sched_wait_list_adjustment(helios_sched_ctrl_t * sched_ctrl) +{ + helios_sched_tcb_t * ptr = sched_ctrl->wait_list_head; + const int * wait_res = (int *)ptr->wait_res.wait_on_resource; + while(ptr != HELIOS_NULL_PTR) + { + if (ptr->task_status == helios_sched_task_status_wait) + { + ptr->wait_res.task_delay_ticks--; /* Tick caliberations required */ + + if ((wait_res != HELIOS_NULL_PTR) && *wait_res > false) + { + /* The resource is available can can go to ready state */ + ptr->wait_res.task_delay_ticks = false; + ptr->wait_res.wait_on_resource = false; + } + if(ptr->wait_res.task_delay_ticks == false) + { + _helios_sched_send_to_resume(sched_ctrl, ptr); + } + if (ptr->wait_link.next == sched_ctrl->wait_list_head) + { + break; + } + else + { + ptr = ptr->wait_link.next; + } + } + } +} + +/***************************************************** + * SCHEDULER ALGORITHMS + *****************************************************/ +static void __helios_sched_algo_round_robin_fn(helios_sched_ctrl_t * sched_ctrl) +{ + /* do waitlist adjustment */ + helios_sched_tcb_t * ptr = sched_ctrl->curr_task->ready_link.next; + + if (ptr == sched_ctrl->ready_list_head) + { + /* IDLE Task */ + _helios_sched_send_to_resume(&g_sched_ctrl, ptr); + } + /* Context switch to next task */ + if (ptr->task_status == helios_sched_task_status_ready) + { + __helios_sched_context_switch(ptr->ready_link.next); + } +} + +static void __helios_sched_algo_priority_driven_fn(helios_sched_ctrl_t * sched_ctrl) +{ + /* do waitlist adjustment */ + helios_sched_tcb_t * ptr = sched_ctrl->ready_list_head->ready_link.prev; + if(ptr != HELIOS_NULL_PTR) + { + while (ptr->task_status != helios_sched_task_status_ready) + { + ptr = ptr->wait_link.prev; + if (ptr == sched_ctrl->ready_list_head) + { + /* IDLE Task */ + _helios_sched_send_to_resume(&g_sched_ctrl, ptr); + break; + } + } + __helios_sched_context_switch(ptr); + } +} diff --git a/src/visor/terravisor/services/kernel/cc_os_sem.c b/src/visor/terravisor/services/kernel/helios_sem.c similarity index 54% rename from src/visor/terravisor/services/kernel/cc_os_sem.c rename to src/visor/terravisor/services/kernel/helios_sem.c index 3703b5db..f45e4558 100644 --- a/src/visor/terravisor/services/kernel/cc_os_sem.c +++ b/src/visor/terravisor/services/kernel/helios_sem.c @@ -2,16 +2,16 @@ * CYANCORE LICENSE * Copyrights (C) 2022, Cyancore Team * - * File Name : cc_os_sem.c + * File Name : helios_sem.c * Description : CC OS Semaphore function definations - * Primary Author : Pranjal Chanda [pranjalchandaCC_OS_FALSE8@gmail.com] + * Primary Author : Pranjal Chanda [pranjalchandaHELIOS_FALSE8@gmail.com] * Organisation : Cyancore Core-Team */ /***************************************************** * INCLUDES *****************************************************/ -#include +#include /***************************************************** * GLOBAL/STATIC VARIABLE DECLARATIONS @@ -20,7 +20,7 @@ /***************************************************** * GLOBAL EXTERNS *****************************************************/ -extern cc_sched_ctrl_t g_sched_ctrl; +extern helios_sched_ctrl_t g_sched_ctrl; /***************************************************** * STATIC FUNCTION DEFINATIONS *****************************************************/ @@ -29,14 +29,14 @@ extern cc_sched_ctrl_t g_sched_ctrl; * USER FUNCTION DEFINATIONS *****************************************************/ -status_t cc_os_sem_create (sem_t ** sem_ptr, size_t init_val) +status_t helios_sem_create (sem_t ** sem_ptr, size_t init_val) { -#if CC_OS_DYNAMIC == false - CC_OS_ASSERT_IF_FALSE((*sem_ptr != CC_OS_NULL_PTR && (*sem_ptr)->sem_init == false)); +#if HELIOS_DYNAMIC == false + HELIOS_ASSERT_IF_FALSE((*sem_ptr != HELIOS_NULL_PTR && (*sem_ptr)->sem_init == false)); #else - CC_OS_ASSERT_IF_FALSE(*sem_ptr == CC_OS_NULL_PTR); - *sem_ptr = cc_os_malloc(sizeof(sem_t)); - if (*sem_ptr == CC_OS_NULL_PTR) + HELIOS_ASSERT_IF_FALSE(*sem_ptr == HELIOS_NULL_PTR); + *sem_ptr = helios_malloc(sizeof(sem_t)); + if (*sem_ptr == HELIOS_NULL_PTR) { return error_memory_low; } @@ -46,9 +46,9 @@ status_t cc_os_sem_create (sem_t ** sem_ptr, size_t init_val) return success; } -status_t cc_os_sem_take (sem_t * sem_ptr, size_t wait_ticks) +status_t helios_sem_take (sem_t * sem_ptr, size_t wait_ticks) { - CC_OS_ASSERT_IF_FALSE((sem_ptr != CC_OS_NULL_PTR && sem_ptr->sem_init != false)); + HELIOS_ASSERT_IF_FALSE((sem_ptr != HELIOS_NULL_PTR && sem_ptr->sem_init != false)); if (sem_ptr->sem_val == false) { @@ -58,7 +58,7 @@ status_t cc_os_sem_take (sem_t * sem_ptr, size_t wait_ticks) } else { g_sched_ctrl.curr_task->wait_res.wait_on_resource = (uintptr_t) sem_ptr; - cc_os_task_wait(wait_ticks); + helios_task_wait(wait_ticks); } } else @@ -67,30 +67,30 @@ status_t cc_os_sem_take (sem_t * sem_ptr, size_t wait_ticks) } return success; } -status_t cc_os_sem_give (sem_t * sem_ptr) +status_t helios_sem_give (sem_t * sem_ptr) { - CC_OS_ASSERT_IF_FALSE((sem_ptr != CC_OS_NULL_PTR && sem_ptr->sem_init != false)); + HELIOS_ASSERT_IF_FALSE((sem_ptr != HELIOS_NULL_PTR && sem_ptr->sem_init != false)); sem_ptr->sem_val++; return success; } -status_t cc_os_sem_delete (sem_t ** sem_ptr) +status_t helios_sem_delete (sem_t ** sem_ptr) { - CC_OS_ASSERT_IF_FALSE((*sem_ptr != CC_OS_NULL_PTR && (*sem_ptr)->sem_init != false)); + HELIOS_ASSERT_IF_FALSE((*sem_ptr != HELIOS_NULL_PTR && (*sem_ptr)->sem_init != false)); (*sem_ptr)->sem_init = false; -#if CC_OS_DYNAMIC == true - cc_os_free(*sem_ptr); +#if HELIOS_DYNAMIC == true + helios_free(*sem_ptr); #endif return success; } -status_t cc_os_sem_get_val (const sem_t * sem_ptr, size_t * val) +status_t helios_sem_get_val (const sem_t * sem_ptr, size_t * val) { - CC_OS_ASSERT_IF_FALSE((sem_ptr != CC_OS_NULL_PTR && sem_ptr->sem_init != false)); - CC_OS_ASSERT_IF_FALSE(val != CC_OS_NULL_PTR); + HELIOS_ASSERT_IF_FALSE((sem_ptr != HELIOS_NULL_PTR && sem_ptr->sem_init != false)); + HELIOS_ASSERT_IF_FALSE(val != HELIOS_NULL_PTR); *val = sem_ptr->sem_val; diff --git a/src/visor/terravisor/services/kernel/helios_task_idle.c b/src/visor/terravisor/services/kernel/helios_task_idle.c new file mode 100644 index 00000000..ed74ca67 --- /dev/null +++ b/src/visor/terravisor/services/kernel/helios_task_idle.c @@ -0,0 +1,90 @@ +/* + * CYANCORE LICENSE + * Copyrights (C) 2022, Cyancore Team + * + * File Name : helios_task_idle.c + * Description : CC OS IDLE Task definitions + * Primary Author : Pranjal Chanda [pranjalchanda08@gmail.com] + * Organisation : Cyancore Core-Team + */ + +/***************************************************** + * INCLUDES + *****************************************************/ +#include +#include + +/***************************************************** + * EXTERN FUNCTION DECLARATION + *****************************************************/ +extern status_t _helios_sched_node_detach(helios_sched_tcb_t *node_ptr, uint8_t link_type); + +/***************************************************** + * STATIC FUNCTION DECLARATION + *****************************************************/ +/** + * @brief This function cleans up the terminated task form the TCB list + * + * @param ptr[in] Pointer to the TCB being cleaned + * @return helios_sched_tcb_t * Pointer to the next TCB + */ +static helios_sched_tcb_t * __free_terminated_task(helios_sched_tcb_t * ptr) +{ + helios_sched_tcb_t * next_ptr = ptr->ready_link.next; + if (ptr->ready_link.next->task_status == helios_sched_task_status_exit) + { + _helios_sched_node_detach(ptr, false); + +#if HELIOS_DYNAMIC == true + helios_free((void *)ptr->stack_ptr); + helios_free(ptr); +#endif + } + + return next_ptr; +} + +#if HELIOS_POWER_SAVE_EN +static void __helios_power_save_callback(void) +{ + arch_wfi(); +} +#endif +/***************************************************** + * USER FUNCTION DEFINATION + *****************************************************/ +void _helios_idle_task_fn(helios_args args) +{ + static helios_sched_tcb_t * ptr = HELIOS_NULL_PTR; + helios_sched_ctrl_t * sched_ctrl = (helios_sched_ctrl_t *) args; + ptr = sched_ctrl->ready_list_head; +#if HELIOS_POWER_SAVE_EN + if (sched_ctrl->cb_hooks_reg.sleep_cb == HELIOS_NULL_PTR) + { + sched_ctrl->cb_hooks_reg.sleep_cb = __helios_power_save_callback; + } +#endif + while (true) + { + /* Clean up task if terminated */ + ptr = __free_terminated_task(ptr); + +#if HELIOS_POWER_SAVE_EN + /* Power Save code */ + if (sched_ctrl->cb_hooks_reg.pre_sleep_cb != HELIOS_NULL_PTR) + { + sched_ctrl->cb_hooks_reg.pre_sleep_cb(); + } + if (sched_ctrl->cb_hooks_reg.sleep_cb != HELIOS_NULL_PTR) + { + sched_ctrl->cb_hooks_reg.sleep_cb(); + } + if (sched_ctrl->cb_hooks_reg.post_sleep_cb != HELIOS_NULL_PTR) + { + sched_ctrl->cb_hooks_reg.post_sleep_cb(); + } +#endif + /* Yield for next available task */ + helios_task_yield(); + } +} diff --git a/src/visor/terravisor/services/kernel/helios_tasks.c b/src/visor/terravisor/services/kernel/helios_tasks.c new file mode 100644 index 00000000..cc5adbe2 --- /dev/null +++ b/src/visor/terravisor/services/kernel/helios_tasks.c @@ -0,0 +1,442 @@ +/* + * CYANCORE LICENSE + * Copyrights (C) 2022, Cyancore Team + * + * File Name : helios_tasks.c + * Description : CC OS Kernel tasks related definations definations + * Primary Author : Pranjal Chanda [pranjalchanda08@gmail.com] + * Organisation : Cyancore Core-Team + */ + +/***************************************************** + * INCLUDES + *****************************************************/ +#include +#include +#include +#include +#include + +/***************************************************** + * DEFINES + *****************************************************/ +#define HELIOS_PRIORITY_MAX 255 + +/***************************************************** + * INTERNAL EXTERNS FUNCTIONS + *****************************************************/ +extern status_t _helios_sched_insert_after(helios_sched_tcb_t **ptr, helios_sched_tcb_t *new_node, uint8_t link_type); +extern status_t _helios_sched_insert_before(helios_sched_tcb_t **ptr, helios_sched_tcb_t *new_node, uint8_t link_type); +extern void _helios_sched_send_to_wait(helios_sched_ctrl_t *sched_ctrl, helios_sched_tcb_t *ptr, const size_t ticks); +extern void _helios_sched_send_to_pause(helios_sched_ctrl_t * sched_ctrl, helios_sched_tcb_t * ptr); +extern void _helios_sched_send_to_resume(helios_sched_ctrl_t *sched_ctrl, helios_sched_tcb_t *ptr); +extern void _helios_sched_send_back_of_task_prio(helios_sched_tcb_t *node_ptr); +extern void _helios_scheduler_despatch(void); +extern void _helios_pre_sched(helios_args args); +/***************************************************** + * GLOBAL EXTERNS VARIABLES + *****************************************************/ +extern void _helios_idle_task_fn(helios_args args); +extern helios_sched_t g_helios_sched_list[]; +extern helios_sched_ctrl_t g_sched_ctrl; + +/***************************************************** + * GLOBAL DECLARATIONS + *****************************************************/ +#if HELIOS_DYNAMIC == false +extern helios_sched_tcb_t g_helios_tcb_list[]; +#else +extern helios_sched_tcb_t *g_helios_tcb_list; +#endif + +#if HELIOS_DYNAMIC == false +uint8_t _helios_stack[HELIOS_IDLE_TASK_STACK_LEN]; +#else +uint8_t *_helios_stack = HELIOS_NULL_PTR; +#endif +helios_task_t helios_idle_task; +/***************************************************** + * STATIC VARIABLES + *****************************************************/ +static uint16_t __helios_task_id_gen = false; +/***************************************************** + * STATIC FUNCTION DEFINATIONS + *****************************************************/ +static void __helios_init_scheduler(void) +{ + g_sched_ctrl.cb_hooks_reg.pre_sched = &_helios_pre_sched; + return; +} + +static uint16_t __helios_task_id_generate() +{ + __helios_task_id_gen++; + return __helios_task_id_gen; +} + +static helios_sched_tcb_t * __helios_get_tcb_using_task_id(const uintptr_t task_id) +{ + helios_sched_tcb_t * ptr = g_sched_ctrl.ready_list_head; + bool _is_id_found = false; + while (ptr->ready_link.next != g_sched_ctrl.ready_list_head) + { + if (ptr->task_id == task_id) + { + _is_id_found = true; + break; + } + ptr = ptr->ready_link.next; + } + if (_is_id_found == false) + { + ptr = HELIOS_NULL_PTR; + } + return ptr; +} + +static status_t __helios_set_task_flag(helios_sched_tcb_t* helios_task, helios_task_flag_t task_flag, bool en) +{ + HELIOS_ASSERT_IF_FALSE( helios_task != HELIOS_NULL_PTR); + + if (en) + { + helios_task->task_flags |= (uint8_t)task_flag; + } + else + { + helios_task->task_flags &= (uint8_t)~task_flag; + } + return success; +} + +static bool __helios_is_task_flag(const helios_sched_tcb_t *helios_task, helios_task_flag_t task_flag) +{ + if (helios_task != HELIOS_NULL_PTR) + { + return (helios_task->task_flags & task_flag) == false; + } + + return false; +} + +/***************************************************** + * USER FUNCTION DEFINATIONS + *****************************************************/ +status_t helios_add_task( + helios_task_t *helios_task, + const char *name, + task_fn_t task_func, + helios_args args, + uint8_t priority, + size_t stack_len, +#if HELIOS_DYNAMIC + uintptr_t stack_ptr _UNUSED +#else + uintptr_t stack_ptr +#endif /* HELIOS_DYNAMIC */ +) +{ + HELIOS_ASSERT_IF_FALSE(*helios_task == (uintptr_t)HELIOS_NULL_PTR); + HELIOS_ASSERT_IF_FALSE(name != HELIOS_NULL_PTR); +#if HELIOS_DYNAMIC == false + HELIOS_ASSERT_IF_FALSE(stack_ptr != (uintptr_t)HELIOS_NULL_PTR); +#endif + HELIOS_ASSERT_IF_FALSE(task_func != HELIOS_NULL_PTR); + HELIOS_ASSERT_IF_FALSE(stack_len != false); + HELIOS_ASSERT_IF_FALSE(priority >= HELIOS_IDLE_TASK_PRIORITY); + HELIOS_ASSERT_IF_FALSE(priority < HELIOS_PRIORITY_MAX); + + helios_pause_all_task(); + + helios_sched_tcb_t *ptr = HELIOS_NULL_PTR; + +#if HELIOS_DYNAMIC == false + /* Static Task Allocation */ + for (size_t i = false; i < HELIOS_MAX_THREAD; i++) + { + /* Get an available node from global tcb list */ + if (g_helios_tcb_list[i].task_status == helios_sched_task_status_exit) + { + ptr = &(g_helios_tcb_list[i]); + break; + } + } + if (ptr != g_sched_ctrl.ready_list_head) + { + ptr->stack_ptr = stack_ptr; +#else + /* Dynamic Task Declaration */ + ptr = (helios_sched_tcb_t *)helios_malloc(sizeof(helios_sched_tcb_t)); + if (ptr != HELIOS_NULL_PTR) + { + ptr->stack_ptr = (uintptr_t)malloc(stack_len); + if (ptr->stack_ptr == (uintptr_t)HELIOS_NULL_PTR) + { + helios_resume_all_task(); + return error_memory_low; + } +#endif /* HELIOS_DYNAMIC */ + } + else + { + helios_resume_all_task(); + return error_memory_low; + } + /* Fill tcb details */ + ptr->name = name; + ptr->priority = priority; + ptr->task_func = task_func; + ptr->args_ptr = (uintptr_t)args; +#if HELIOS_ANTI_DEADLOCK + ptr->task_wd_ticks = SIZE_MAX; +#endif /* HELIOS_ANTI_DEADLOCK */ + if (g_sched_ctrl.ready_list_head == HELIOS_NULL_PTR) + { + ptr->ready_link.next = ptr->ready_link.prev = g_sched_ctrl.ready_list_head = ptr; + } + /* Insert Tasks in assending order of its priority */ + _helios_sched_send_back_of_task_prio(ptr); + ptr->task_status = helios_sched_task_status_ready; + ptr->task_id = __helios_task_id_generate(); + *helios_task = ptr->task_id; + helios_resume_all_task(); + return success; +} + +status_t helios_del_task(helios_task_t helios_task) +{ + helios_sched_tcb_t * ptr = __helios_get_tcb_using_task_id(helios_task); + + if (ptr == HELIOS_NULL_PTR) + { + ptr = g_sched_ctrl.curr_task; + } + HELIOS_ASSERT_IF_FALSE(ptr->task_func != &_helios_idle_task_fn); + /* Code to handle first node */ + if (ptr == g_sched_ctrl.ready_list_head) + { + /* IDLE Task can not be deleted */ + return error_os_invalid_op; + } + ptr->task_status = helios_sched_task_status_exit; + + if (ptr == g_sched_ctrl.curr_task) + { + helios_task_yield(); /* Yeild */ + } + + return success; +} + +status_t helios_pause_task(helios_task_t helios_task) +{ + helios_sched_tcb_t *ptr = __helios_get_tcb_using_task_id(helios_task); + if (ptr == HELIOS_NULL_PTR) + { + ptr = g_sched_ctrl.curr_task; + } + + _helios_sched_send_to_pause(&g_sched_ctrl, ptr); + + return success; +} + +status_t helios_pause_all_task(void) +{ + helios_sched_tcb_t *ptr = g_sched_ctrl.ready_list_head; + if(ptr != HELIOS_NULL_PTR) + { + while (true) + { + if (ptr == g_sched_ctrl.curr_task) + { + /* Do not pause the current task */ + continue; + } + + _helios_sched_send_to_pause(&g_sched_ctrl, ptr); + ptr = ptr->ready_link.next; + + if(ptr == g_sched_ctrl.ready_list_head) + { + break; + } + } + } + + return success; +} + +status_t helios_resume_all_task(void) +{ + helios_sched_tcb_t *ptr = g_sched_ctrl.ready_list_head; + if (ptr != HELIOS_NULL_PTR) + { + while (true) + { + ptr = ptr->ready_link.next; + _helios_sched_send_to_resume(&g_sched_ctrl, ptr); + if (ptr == g_sched_ctrl.ready_list_head) + { + break; + } + } + } + else + { + return error_os_invalid_op; + } + + return success; +} + +status_t helios_resume_task(helios_task_t helios_task) +{ + helios_sched_tcb_t *ptr = __helios_get_tcb_using_task_id(helios_task); + HELIOS_ASSERT_IF_FALSE(ptr != HELIOS_NULL_PTR); + + if (ptr->task_status != helios_sched_task_status_pause) + { + _helios_sched_send_to_resume(&g_sched_ctrl, ptr); + } + else + { + return error_os_invalid_op; + } + return success; +} + +status_t helios_set_sched_algo(helios_sched_algo_t sched_algo) +{ + HELIOS_ASSERT_IF_FALSE(sched_algo != helios_sched_algo_max); + + g_sched_ctrl.selected_sched = &(g_helios_sched_list[sched_algo]); + + return success; +} + +status_t helios_task_anti_deadlock_enable_and_feed(size_t task_wd_ticks _UNUSED) +{ +#if HELIOS_ANTI_DEADLOCK + HELIOS_ASSERT_IF_FALSE((task_wd_ticks > false) && (task_wd_ticks < SIZE_MAX)); + + helios_sched_tcb_t *ptr = g_sched_ctrl.curr_task; + if (__helios_is_task_flag(ptr, helios_task_flag_set_anti_deadlock)) + { + __helios_set_task_flag(ptr, helios_task_flag_set_anti_deadlock, true); + } + + ptr->task_wd_ticks = task_wd_ticks; + return success; +#else + helios_sched_tcb_t *ptr = g_sched_ctrl.curr_task; + if (__helios_is_task_flag(ptr, helios_task_flag_set_anti_deadlock)) + { + __helios_set_task_flag(ptr, helios_task_flag_set_anti_deadlock, false); + } + return error_func_inval; +#endif /* HELIOS_ANTI_DEADLOCK */ +} + +status_t helios_task_anti_deadlock_disable(void) +{ + helios_sched_tcb_t *ptr = g_sched_ctrl.curr_task; + + if (__helios_is_task_flag(ptr, helios_task_flag_set_anti_deadlock)) + { + __helios_set_task_flag(ptr, helios_task_flag_set_anti_deadlock, false); + } + +#if HELIOS_ANTI_DEADLOCK + ptr->task_wd_ticks = SIZE_MAX; + return success; +#else + return error_func_inval; +#endif /* HELIOS_ANTI_DEADLOCK */ +} +status_t helios_set_callback(const helios_sched_cb_t cb_type, const helios_cb_hook_t cb_func _UNUSED) +{ + status_t ret = success; + switch (cb_type) + { + case helios_sched_cb_power_post_sleep: +#if HELIOS_POWER_SAVE_EN + g_sched_ctrl.cb_hooks_reg.post_sleep_cb = cb_func; + break; +#endif + case helios_sched_cb_power_pre_sleep: +#if HELIOS_POWER_SAVE_EN + g_sched_ctrl.cb_hooks_reg.pre_sleep_cb = cb_func; + break; +#endif + case helios_sched_cb_power_sleep: +#if HELIOS_POWER_SAVE_EN + g_sched_ctrl.cb_hooks_reg.power_sleep = cb_func; + break; +#endif + case helios_sched_cb_deadlock_notify: +#if HELIOS_ANTI_DEADLOCK + g_sched_ctrl.cb_hooks_reg.deadlock_notify = cb_func; + break; +#endif + case helios_sched_cb_max: + ret = error_func_inval; + break; + } + return ret; +} + +const char *helios_get_curr_task_name(void) +{ + return g_sched_ctrl.curr_task->name; +} + +const char *helios_get_task_name(helios_task_t helios_task) +{ + const helios_sched_tcb_t *ptr = __helios_get_tcb_using_task_id(helios_task); + if(ptr != HELIOS_NULL_PTR) + { + return ptr->name; + } + return HELIOS_NULL_PTR; +} + +void helios_task_wait(const size_t ticks) +{ + helios_sched_tcb_t *ptr = g_sched_ctrl.curr_task; + + if (ticks > false) + { + _helios_sched_send_to_wait(&g_sched_ctrl, ptr, ticks); + } + + helios_task_yield(); +} + +void helios_task_yield() +{ + _helios_scheduler_despatch(); + return; +} + +void helios_run(void) +{ + /* OS Init code */ + /* Initialise IDLE Task */ + helios_add_task(&helios_idle_task, + HELIOS_IDLE_TASK_NAME, + &_helios_idle_task_fn, + &g_sched_ctrl, + HELIOS_IDLE_TASK_PRIORITY, + HELIOS_IDLE_TASK_STACK_LEN, + (uintptr_t)_helios_stack); + + /* Initialise scheduler */ + __helios_init_scheduler(); + helios_task_yield(); /* Yeild */ + while (true) + { + /* Code shall not reach here */ + arch_wfi(); + } +}