From 0a8b4a7ec503fd19bec13e8fd8227f1a4f1a4b4e Mon Sep 17 00:00:00 2001 From: Paul Pan Date: Wed, 1 Feb 2023 20:57:30 +0800 Subject: [PATCH] [feat] Integrate FreeRTOS - Part1 1. add custom POSIX support as submodule 2. add FreeRTOS and POSIX CMake build support 3. add FreeRTOS port-related code 4. fix mm support in FreeRTOS 5. modify FreeRTOS example TODO: 1. D0 interrupt support 2. D0 privilege support --- .gitignore | 4 +- .gitmodules | 3 + components/mm/mmheap/bflb_mmheap.c | 8 ++- components/mm/tlsf/bflb_tlsf.c | 3 +- components/os/CMakeLists.txt | 3 +- components/os/freertos2/CMakeLists.txt | 68 ++++++++++++++++++ components/os/freertos2/FreeRTOS-Kernel | 2 +- .../os/freertos2/Lab-Project-FreeRTOS-POSIX | 1 + components/os/freertos2/port/demo.c | 72 +++++++++++++++++++ .../freertos2/port/include/freertos_bl_port.h | 6 ++ components/os/freertos2/port/port.c | 71 ++++++++++++++++++ components/os/freertos2/port/setup.c | 60 ++++++++++++++++ examples/freertos/FreeRTOSConfig.h | 2 + examples/freertos/main.c | 6 +- examples/freertos/proj.conf | 2 +- 15 files changed, 304 insertions(+), 7 deletions(-) create mode 100644 components/os/freertos2/CMakeLists.txt create mode 160000 components/os/freertos2/Lab-Project-FreeRTOS-POSIX create mode 100644 components/os/freertos2/port/demo.c create mode 100644 components/os/freertos2/port/include/freertos_bl_port.h create mode 100644 components/os/freertos2/port/port.c create mode 100644 components/os/freertos2/port/setup.c diff --git a/.gitignore b/.gitignore index 5717c713..45267fff 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.idea .vscode **/__pycache__ **/build @@ -11,4 +12,5 @@ *.pptx *.svd *.pack -**/_build \ No newline at end of file +**/_build +cmake-build-* \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 204acbf3..5f0fe91f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "components/os/freertos2/FreeRTOS-Kernel"] path = components/os/freertos2/FreeRTOS-Kernel url = https://git.0x7f.app/StreamEdge/FreeRTOS-Kernel.git +[submodule "components/os/freertos2/Lab-Project-FreeRTOS-POSIX"] + path = components/os/freertos2/Lab-Project-FreeRTOS-POSIX + url = https://git.0x7f.app/StreamEdge/Lab-Project-FreeRTOS-POSIX.git diff --git a/components/mm/mmheap/bflb_mmheap.c b/components/mm/mmheap/bflb_mmheap.c index 8d29bc79..1c6324ae 100644 --- a/components/mm/mmheap/bflb_mmheap.c +++ b/components/mm/mmheap/bflb_mmheap.c @@ -35,7 +35,13 @@ #ifdef CONFIG_FREERTOS -#define _IRQ_CONTEXT() xPortIsInsideInterrupt() +/* It should be ok to set to zero + * 1. bflb_mem_sem_take will enter critical sections -> disable interrupt (CHECK ME) + * there are no race conditions, thus no need to add free operations into delay list + * 2. Performance issue in IRQ ?? + */ +#define _IRQ_CONTEXT() (0) + #define _SCHED_LOCK() (taskSCHEDULER_RUNNING != xTaskGetSchedulerState()) #define _ENTER_CRITICAL() portENTER_CRITICAL() #define _EXIT_CRITICAL() portEXIT_CRITICAL() diff --git a/components/mm/tlsf/bflb_tlsf.c b/components/mm/tlsf/bflb_tlsf.c index f79f25dc..75ba4cd5 100644 --- a/components/mm/tlsf/bflb_tlsf.c +++ b/components/mm/tlsf/bflb_tlsf.c @@ -35,7 +35,8 @@ #ifdef CONFIG_FREERTOS -#define _IRQ_CONTEXT() xPortIsInsideInterrupt() +/* described in mmheap/bflb_mmheap.c */ +#define _IRQ_CONTEXT() (0) #define _SCHED_LOCK() (taskSCHEDULER_RUNNING != xTaskGetSchedulerState()) #define _ENTER_CRITICAL() portENTER_CRITICAL() #define _EXIT_CRITICAL() portEXIT_CRITICAL() diff --git a/components/os/CMakeLists.txt b/components/os/CMakeLists.txt index 78500fe9..00f98a2c 100644 --- a/components/os/CMakeLists.txt +++ b/components/os/CMakeLists.txt @@ -1 +1,2 @@ -sdk_add_subdirectory_ifdef(CONFIG_FREERTOS freertos) +sdk_add_subdirectory_ifdef(CONFIG_FREERTOS freertos) +sdk_add_subdirectory_ifdef(CONFIG_FREERTOS2 freertos2) diff --git a/components/os/freertos2/CMakeLists.txt b/components/os/freertos2/CMakeLists.txt new file mode 100644 index 00000000..19ece5a9 --- /dev/null +++ b/components/os/freertos2/CMakeLists.txt @@ -0,0 +1,68 @@ +if( NOT "${CHIP}" STREQUAL "bl808" ) + message( FATAL_ERROR "CONFIG_FREERTOS2 has only been tested on BL808" ) +endif() + +sdk_generate_library() + +# kernel sources +sdk_library_add_sources( + FreeRTOS-Kernel/croutine.c + FreeRTOS-Kernel/event_groups.c + FreeRTOS-Kernel/list.c + FreeRTOS-Kernel/queue.c + FreeRTOS-Kernel/stream_buffer.c + FreeRTOS-Kernel/tasks.c + FreeRTOS-Kernel/timers.c + FreeRTOS-Kernel/portable/MemMang/heap_4.c +) +sdk_add_include_directories( FreeRTOS-Kernel/include ) + +# portable sources +sdk_library_add_sources( + FreeRTOS-Kernel/portable/GCC/RISC-V/port.c + FreeRTOS-Kernel/portable/GCC/RISC-V/portASM.S +) +sdk_add_include_directories( + FreeRTOS-Kernel/portable/GCC/RISC-V + FreeRTOS-Kernel/portable/GCC/RISC-V/chip_specific_extensions/Thead_common +) + +# BL_MCU_SDK port source +sdk_library_add_sources( + port/demo.c + port/port.c + port/setup.c +) +sdk_add_include_directories( port/include ) +sdk_add_compile_definitions( -Ddefault_trap_handler=freertos_risc_v_exception_handler ) +sdk_add_compile_definitions( -Ddefault_interrupt_handler=freertos_risc_v_interrupt_handler ) + +# POSIX support +sdk_library_add_sources_ifdef( + CONFIG_POSIX + Lab-Project-FreeRTOS-POSIX/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_clock.c + Lab-Project-FreeRTOS-POSIX/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_mqueue.c + Lab-Project-FreeRTOS-POSIX/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_pthread.c + Lab-Project-FreeRTOS-POSIX/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_pthread_barrier.c + Lab-Project-FreeRTOS-POSIX/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_pthread_cond.c + Lab-Project-FreeRTOS-POSIX/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_pthread_mutex.c + Lab-Project-FreeRTOS-POSIX/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_sched.c + Lab-Project-FreeRTOS-POSIX/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_semaphore.c + Lab-Project-FreeRTOS-POSIX/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_timer.c + Lab-Project-FreeRTOS-POSIX/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_unistd.c + Lab-Project-FreeRTOS-POSIX/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_utils.c +) +sdk_add_include_directories_ifdef( + CONFIG_POSIX + Lab-Project-FreeRTOS-POSIX/include +) +sdk_add_private_include_directories_ifdef( + CONFIG_POSIX + Lab-Project-FreeRTOS-POSIX/FreeRTOS-Plus-POSIX/include + Lab-Project-FreeRTOS-POSIX/FreeRTOS-Plus-POSIX/include/portable + Lab-Project-FreeRTOS-POSIX/FreeRTOS-Plus-POSIX/include/portable/bl/bl808 + Lab-Project-FreeRTOS-POSIX/include/private +) + +# BL_MCU_SDK components +sdk_add_compile_definitions( -DCONFIG_FREERTOS ) diff --git a/components/os/freertos2/FreeRTOS-Kernel b/components/os/freertos2/FreeRTOS-Kernel index c9bf3486..98c7fbbf 160000 --- a/components/os/freertos2/FreeRTOS-Kernel +++ b/components/os/freertos2/FreeRTOS-Kernel @@ -1 +1 @@ -Subproject commit c9bf3486c6ea83a3499047b35d95edef5321bdfe +Subproject commit 98c7fbbf8dc7ba9c44504b160590d87e43882beb diff --git a/components/os/freertos2/Lab-Project-FreeRTOS-POSIX b/components/os/freertos2/Lab-Project-FreeRTOS-POSIX new file mode 160000 index 00000000..06b4e233 --- /dev/null +++ b/components/os/freertos2/Lab-Project-FreeRTOS-POSIX @@ -0,0 +1 @@ +Subproject commit 06b4e233ec768d3d460571915dd0eb492c91585b diff --git a/components/os/freertos2/port/demo.c b/components/os/freertos2/port/demo.c new file mode 100644 index 00000000..3c9637f2 --- /dev/null +++ b/components/os/freertos2/port/demo.c @@ -0,0 +1,72 @@ +/* Following code snippets are copied from FreeRTOS Demo */ + +/* +* FreeRTOS V202212.00 +* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of +* this software and associated documentation files (the "Software"), to deal in +* the Software without restriction, including without limitation the rights to +* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +* the Software, and to permit persons to whom the Software is furnished to do so, +* subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +* https://www.FreeRTOS.org +* https://github.com/FreeRTOS +* +*/ + +#include +#include + +__attribute__((weak)) void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) +{ + /* If the buffers to be provided to the Idle task are declared inside this + function then they must be declared static - otherwise they will be allocated on + the stack and so not exists after this function exits. */ + static StaticTask_t xIdleTaskTCB; + static StackType_t uxIdleTaskStack[configMINIMAL_STACK_SIZE]; + + /* Pass out a pointer to the StaticTask_t structure in which the Idle task's + state will be stored. */ + *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; + + /* Pass out the array that will be used as the Idle task's stack. */ + *ppxIdleTaskStackBuffer = uxIdleTaskStack; + + /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; +} + +__attribute__((weak)) void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize) +{ + /* If the buffers to be provided to the Timer task are declared inside this + function then they must be declared static - otherwise they will be allocated on + the stack and so not exists after this function exits. */ + static StaticTask_t xTimerTaskTCB; + static StackType_t uxTimerTaskStack[configTIMER_TASK_STACK_DEPTH]; + + /* Pass out a pointer to the StaticTask_t structure in which the Timer + task's state will be stored. */ + *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; + + /* Pass out the array that will be used as the Timer task's stack. */ + *ppxTimerTaskStackBuffer = uxTimerTaskStack; + + /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer. + Note that, as the array is necessarily of type StackType_t, + configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; +} diff --git a/components/os/freertos2/port/include/freertos_bl_port.h b/components/os/freertos2/port/include/freertos_bl_port.h new file mode 100644 index 00000000..c32b5b09 --- /dev/null +++ b/components/os/freertos2/port/include/freertos_bl_port.h @@ -0,0 +1,6 @@ +#ifndef FREERTOS_BL_PORT_H +#define FREERTOS_BL_PORT_H + +void SetupFreeRTOS(void); + +#endif //FREERTOS_BL_PORT_H diff --git a/components/os/freertos2/port/port.c b/components/os/freertos2/port/port.c new file mode 100644 index 00000000..4953add0 --- /dev/null +++ b/components/os/freertos2/port/port.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include + +#if defined(CPU_M0) + +void freertos_risc_v_application_exception_handler(uint32_t mcause) +{ + // Notice: in exception_entry: cause 8, 11 will modify mepc + // CONFIG_TRAP_DUMP_ALL_REGS is not supported: not using bl_mcu_sdk stack + // TODO: reuse bl_mcu_sdk stack +#ifdef CONFIG_TRAP_DUMP_ALL_REGS +#error "CONFIG_TRAP_DUMP_ALL_REGS is not supported" +#endif + extern void exception_entry(uintptr_t * regs); + exception_entry((uintptr_t *)0); +} + +void freertos_risc_v_application_interrupt_handler() +{ + extern void interrupt_entry(void); + interrupt_entry(); +} + +#elif defined(CPU_D0) +// TODO + +void freertos_risc_v_application_exception_handler(uint32_t mcause) +{ + // Notice: in exception_entry: 8, 11 will modify mepc + // CONFIG_TRAP_DUMP_ALL_REGS is not supported: not using bl_mcu_sdk stack + // TODO: reuse bl_mcu_sdk stack +#ifdef CONFIG_TRAP_DUMP_ALL_REGS +#error "CONFIG_TRAP_DUMP_ALL_REGS is not supported" +#endif + extern void exception_entry(uintptr_t * regs); + exception_entry((uintptr_t *)0); +} + +void freertos_risc_v_application_interrupt_handler() +{ + // TODO: plic interaction + extern void interrupt_entry(uint64_t irq_num); +} + +#endif + +__attribute__((weak)) void vAssertCalled(void) +{ + printf("vAssertCalled: Halt CPU\r\n"); + portDISABLE_INTERRUPTS(); + rv_hart_hang(); +} + +__attribute__((weak)) void vApplicationMallocFailedHook(void) +{ + printf("vApplicationMallocFailedHook: Halt CPU\r\n"); + portDISABLE_INTERRUPTS(); + rv_hart_hang(); +} + +void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName) +{ + (void)pcTaskName; + (void)pxTask; + + printf("vApplicationStackOverflowHook: pcTaskName=%s Halt CPU\r\n", pcTaskName); + portDISABLE_INTERRUPTS(); + rv_hart_hang(); +} \ No newline at end of file diff --git a/components/os/freertos2/port/setup.c b/components/os/freertos2/port/setup.c new file mode 100644 index 00000000..5aa95770 --- /dev/null +++ b/components/os/freertos2/port/setup.c @@ -0,0 +1,60 @@ +#include "freertos_bl_port.h" +#include +#include +#include + +void implement_me(void) +{ + printf("TODO: unimplement\r\n"); + portDISABLE_INTERRUPTS(); + rv_hart_hang(); + + __builtin_unreachable(); +} + +#if defined(CPU_M0) + +typedef void (*pFunc)(void); +extern pFunc __Vectors[]; + +extern pFunc freertos_risc_v_exception_handler; +extern pFunc freertos_risc_v_mtimer_interrupt_handler; + +void reconfigure_m0_vector(void) +{ + // default_interrupt_handler is replaced by freertos_risc_v_interrupt_handler in compile commands + // default_trap_handler is replaced by freertos_risc_v_exception_handler in compile commands + + // useless since MTVEC.MODE is hard-wired to 2'b11 + __Vectors[0] = freertos_risc_v_exception_handler; + + // replace mtimer interrupt handler + __Vectors[7] = freertos_risc_v_mtimer_interrupt_handler; +} + +#elif defined(CPU_D0) + +void reconfigure_d0_vector(void) +{ +#warning "Currently, FreeRTOS Only Support Machine Mode" + + // disable S-mode interrupt + asm("csrci mstatus, 0x2"); + + implement_me(); +} + +#endif + +void SetupFreeRTOS() +{ +#if defined(CPU_M0) + printf("SetupFreeRTOS: CPU_M0\r\n"); + reconfigure_m0_vector(); +#elif defined(CPU_D0) + printf("SetupFreeRTOS: CPU_D0\r\n"); + reconfigure_d0_vector(); +#else +#error "Unsupported CPU" +#endif +} diff --git a/examples/freertos/FreeRTOSConfig.h b/examples/freertos/FreeRTOSConfig.h index 5ef568e9..10cf1937 100644 --- a/examples/freertos/FreeRTOSConfig.h +++ b/examples/freertos/FreeRTOSConfig.h @@ -44,9 +44,11 @@ #if __riscv_xlen == 64 #define configMTIME_BASE_ADDRESS (0) #define configMTIMECMP_BASE_ADDRESS ((0xE4000000UL) + 0x4000UL) +#define configCPU_THEAD_C906 1 #else #define configMTIME_BASE_ADDRESS ((0xE0000000UL) + 0xBFF8UL) #define configMTIMECMP_BASE_ADDRESS ((0xE0000000UL) + 0x4000UL) +#define configCPU_THEAD_C906 0 #endif #endif #define configSUPPORT_STATIC_ALLOCATION 1 diff --git a/examples/freertos/main.c b/examples/freertos/main.c index 0f8aeab7..1b6c7586 100644 --- a/examples/freertos/main.c +++ b/examples/freertos/main.c @@ -1,5 +1,7 @@ #include -#include "semphr.h" +#include +#include +#include #include "board.h" #define DBG_TAG "MAIN" @@ -63,6 +65,8 @@ int main(void) { board_init(); + SetupFreeRTOS(); + configASSERT((configMAX_PRIORITIES > 4)); /* Create semaphore */ diff --git a/examples/freertos/proj.conf b/examples/freertos/proj.conf index 1c72fe2b..3ac00386 100644 --- a/examples/freertos/proj.conf +++ b/examples/freertos/proj.conf @@ -4,4 +4,4 @@ set(CONFIG_VSNPRINTF_FLOAT 1) set(CONFIG_VSNPRINTF_FLOAT_EX 1) set(CONFIG_VSNPRINTF_LONG_LONG 1) -set(CONFIG_FREERTOS 1) \ No newline at end of file +set(CONFIG_FREERTOS2 1) \ No newline at end of file