From f8fcd25e5faf7c667f48198cd45558dd93f7156e Mon Sep 17 00:00:00 2001 From: Yilin Sun Date: Sun, 10 Mar 2024 12:36:38 +0800 Subject: [PATCH] Initial FreeRTOS support. Signed-off-by: Yilin Sun --- .gitmodules | 3 ++ CMakeLists.txt | 16 ++++++- GCC/T113i_RAM.ld | 36 +++++++-------- include/FreeRTOSConfig.h | 95 ++++++++++++++++++++++++++++++++++++++ include/t113i.h | 45 ++++++++++++++++++ lib/freertos | 1 + riscv64-elf.cmake | 4 +- src/freertos/port.c | 40 ++++++++++++++++ src/main.c | 13 ++++-- src/tasks/app_task_hello.c | 16 +++++++ src/tasks/app_tasks.c | 8 ++++ startup/c906_it.c | 16 +++++++ startup/start_c906.S | 36 --------------- startup/startup_c906.S | 83 +++++++++++++++++++++++++++++++++ startup/system_c906.c | 2 +- 15 files changed, 352 insertions(+), 62 deletions(-) create mode 100644 .gitmodules create mode 100644 include/FreeRTOSConfig.h create mode 100644 include/t113i.h create mode 160000 lib/freertos create mode 100644 src/freertos/port.c create mode 100644 src/tasks/app_task_hello.c create mode 100644 src/tasks/app_tasks.c create mode 100644 startup/c906_it.c delete mode 100644 startup/start_c906.S create mode 100644 startup/startup_c906.S diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..6ffe2dc --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/freertos"] + path = lib/freertos + url = https://github.com/imi415/FreeRTOS-Kernel.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a174af..f87db9e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.10) -project(t113i_c906_template) +project(t113i_c906_freertos) enable_language(CXX) enable_language(ASM) @@ -9,10 +9,14 @@ enable_language(ASM) set(TARGET_LDSCRIPT_FLASH "${CMAKE_SOURCE_DIR}/GCC/T113i_RAM.ld") set(TARGET_SOURCES + "startup/c906_it.c" "startup/resource_table.c" - "startup/start_c906.S" + "startup/startup_c906.S" "startup/system_c906.c" + "src/freertos/port.c" "src/main.c" + "src/tasks/app_task_hello.c" + "src/tasks/app_tasks.c" ) set(TARGET_C_DEFINES @@ -24,6 +28,7 @@ set(TARGET_C_INCLUDES # Shared libraries linked with application set(TARGET_LIBS + "freertos_kernel" "c" "m" "nosys" @@ -51,6 +56,13 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-common -fno-builtin -f set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -x assembler-with-cpp") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") +add_library(freertos_config INTERFACE) +target_include_directories(freertos_config SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include) +set(FREERTOS_PORT GCC_RISC_V_GENERIC CACHE STRING "") +set(FREERTOS_RISCV_EXTENSION RV64GCV_XuanTie_C906 CACHE STRING "") +set(FREERTOS_HEAP "4" CACHE STRING "") +add_subdirectory(lib/freertos) + # Shared sources, includes and definitions add_compile_definitions(${TARGET_C_DEFINES}) include_directories(${TARGET_C_INCLUDES}) diff --git a/GCC/T113i_RAM.ld b/GCC/T113i_RAM.ld index 0787197..b69a173 100644 --- a/GCC/T113i_RAM.ld +++ b/GCC/T113i_RAM.ld @@ -5,8 +5,8 @@ ENTRY( _start ) * too high may cause SDRAM overflow. * Collision may occur with heap when stack gets too deep. */ -__stack_size = 2048; -__heap_size = 2048; +__stack_size = 32768; +__heap_size = 32768; MEMORY { @@ -18,28 +18,28 @@ SECTIONS { .resource_table : { - . = ALIGN(4); + . = ALIGN(8); KEEP(*(SORT_NONE(.resource_table))) - . = ALIGN(4); + . = ALIGN(8); } >SDRAM .init : { - . = ALIGN(4); + . = ALIGN(8); KEEP(*(SORT_NONE(.init))) - . = ALIGN(4); + . = ALIGN(8); } >SDRAM .vectors : { - . = ALIGN(4); + . = ALIGN(8); KEEP(*(SORT_NONE(.vectors))) - . = ALIGN(4); + . = ALIGN(8); } >SDRAM .text : { - . = ALIGN(4); + . = ALIGN(8); _stext = .; *(.text) @@ -49,7 +49,7 @@ SECTIONS *(.rodata*) *(.gnu.linkonce.r.*) - . = ALIGN(4); + . = ALIGN(8); _etext = .; } >SDRAM @@ -96,7 +96,7 @@ SECTIONS .data : { - . = ALIGN(4); + . = ALIGN(8); _sdata = .; *(.data .data.*) @@ -105,7 +105,7 @@ SECTIONS *(.srodata .srodata.*) *(.gnu.linkonce.s.*) - . = ALIGN(4); + . = ALIGN(8); _edata = .; } >SDRAM @@ -114,7 +114,7 @@ SECTIONS .bss : { - . = ALIGN(4); + . = ALIGN(8); _sbss = .; *(.sbss) @@ -125,25 +125,25 @@ SECTIONS *(.gnu.linkonce.b.*) *(COMMON) - . = ALIGN(4); + . = ALIGN(8); _ebss = .; } >SDRAM .heap_stack : { - . = ALIGN(8); + . = ALIGN(16); _end = .; PROVIDE(end = . ); . = . + __heap_size; - . = ALIGN(8); + . = ALIGN(16); PROVIDE(_heap_end = .); . = . + __stack_size; - . = ALIGN(8); + . = ALIGN(16); } >SDRAM /* Place initial SP to the end of SDRAM */ __stack_top = ORIGIN(SDRAM) + LENGTH(SDRAM); - PROVIDE(_eusrstack = __stack_top); + __freertos_irq_stack_top = __stack_top; } diff --git a/include/FreeRTOSConfig.h b/include/FreeRTOSConfig.h new file mode 100644 index 0000000..cbd6a6e --- /dev/null +++ b/include/FreeRTOSConfig.h @@ -0,0 +1,95 @@ +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configUSE_TICKLESS_IDLE 0 +#define configCPU_CLOCK_HZ 24000000 +#define configSYSTICK_CLOCK_HZ 24000000 +#define configTICK_RATE_HZ 1000 +#define configMAX_PRIORITIES 16 +#define configMINIMAL_STACK_SIZE 512 +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_TASK_NOTIFICATIONS 1 +#define configTASK_NOTIFICATION_ARRAY_ENTRIES 3 +#define configUSE_MUTEXES 0 +#define configUSE_RECURSIVE_MUTEXES 0 +#define configUSE_COUNTING_SEMAPHORES 0 +#define configUSE_ALTERNATIVE_API 0 /* Deprecated! */ +#define configQUEUE_REGISTRY_SIZE 10 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 0 +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 +#define configUSE_MINI_LIST_ITEM 1 +#define configSTACK_DEPTH_TYPE uint64_t +#define configMESSAGE_BUFFER_LENGTH_TYPE size_t +#define configHEAP_CLEAR_MEMORY_ON_FREE 1 +#define configUSE_APPLICATION_TASK_TAG 0 +#define configSTATS_BUFFER_MAX_LENGTH 0xFFFF + +/* Memory allocation related definitions. */ +#define configSUPPORT_STATIC_ALLOCATION 0 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configKERNEL_PROVIDED_STATIC_MEMORY 1 +#define configTOTAL_HEAP_SIZE (64 * 1024) +#define configAPPLICATION_ALLOCATED_HEAP 0 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 +#define configENABLE_HEAP_PROTECTOR 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configCHECK_FOR_STACK_OVERFLOW 0 +#define configUSE_MALLOC_FAILED_HOOK 0 +#define configUSE_DAEMON_TASK_STARTUP_HOOK 0 +#define configUSE_SB_COMPLETED_CALLBACK 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configUSE_TRACE_FACILITY 0 +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine related definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 1 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY 15 +#define configTIMER_QUEUE_LENGTH 10 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Define to trap errors during development. */ +#define configASSERT(x) if((x) == 0) {for(;;) {}} + +/* RISC-V related settings */ +#define configMTIME_BASE_ADDRESS 0 +#define configMTIMECMP_BASE_ADDRESS 0 + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_xResumeFromISR 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_uxTaskGetStackHighWaterMark2 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 1 +#define INCLUDE_xTimerPendFunctionCall 0 +#define INCLUDE_xTaskAbortDelay 0 +#define INCLUDE_xTaskGetHandle 0 +#define INCLUDE_xTaskResumeFromISR 1 + +/* A header file that defines trace macro can be included here. */ + +#endif /* FREERTOS_CONFIG_H */ \ No newline at end of file diff --git a/include/t113i.h b/include/t113i.h new file mode 100644 index 0000000..a9beca0 --- /dev/null +++ b/include/t113i.h @@ -0,0 +1,45 @@ +#ifndef T113I_H +#define T113I_H + +#include + +#define __PACKED __attribute__((packed)) + +#define __IM volatile +#define __OM const volatile +#define __IOM volatile + +typedef struct { + __IOM uint32_t CFG[4]; /* 0x00 - 0x0C */ + __IOM uint32_t DAT; /* 0x10 */ + __IOM uint32_t DRV[4]; /* 0x14 - 0x20 */ + __IOM uint32_t PULL[2]; /* 0x24 - 0x28 */ +} GPIO_Type; + +typedef struct { + __IOM uint32_t RBR_THR_DLL; + __IOM uint32_t DLH_IER; + __IOM uint32_t IIR_FCR; + __IOM uint32_t LCR; + __IOM uint32_t MCR; + __IOM uint32_t LSR; + __IOM uint32_t MSR; + __IOM uint32_t SCH; + +} UART_Type; + +#define GPIOB_BASE (0x02000030) +#define GPIOC_BASE (0x02000060) +#define GPIOD_BASE (0x02000090) +#define GPIOE_BASE (0x020000C0) +#define GPIOF_BASE (0x020000F0) +#define GPIOG_BASE (0x02000120) + +#define GPIOB ((GPIO_Type *)GPIOB_BASE) +#define GPIOC ((GPIO_Type *)GPIOC_BASE) +#define GPIOD ((GPIO_Type *)GPIOD_BASE) +#define GPIOE ((GPIO_Type *)GPIOE_BASE) +#define GPIOF ((GPIO_Type *)GPIOF_BASE) +#define GPIOG ((GPIO_Type *)GPIOG_BASE) + +#endif // T113I_H diff --git a/lib/freertos b/lib/freertos new file mode 160000 index 0000000..62d75c8 --- /dev/null +++ b/lib/freertos @@ -0,0 +1 @@ +Subproject commit 62d75c88279c1f98f8eaef761a20c28b583e37f6 diff --git a/riscv64-elf.cmake b/riscv64-elf.cmake index 68dcd82..867eb82 100644 --- a/riscv64-elf.cmake +++ b/riscv64-elf.cmake @@ -9,8 +9,8 @@ set(CMAKE_CXX_COMPILER riscv64-elf-g++) # Optionally set size binary name, for elf section size reporting. set(TARGET_TOOLCHAIN_SIZE riscv64-elf-size) -set(CMAKE_C_FLAGS_INIT "-march=rv64imafdc_zicsr -mabi=lp64d") -set(CMAKE_CXX_FLAGS_INIT "-march=rv64imafdc_zicsr -mabi=lp64d") +set(CMAKE_C_FLAGS_INIT "-march=rv64gc -mabi=lp64d") +set(CMAKE_CXX_FLAGS_INIT "-march=rv64gc -mabi=lp64d") set(CMAKE_EXE_LINKER_FLAGS_INIT "-specs=nano.specs -specs=nosys.specs -nostartfiles -Wl,--print-memory-usage -Wl,--no-warn-rwx-segments") # Make CMake happy about those compilers diff --git a/src/freertos/port.c b/src/freertos/port.c new file mode 100644 index 0000000..c91e634 --- /dev/null +++ b/src/freertos/port.c @@ -0,0 +1,40 @@ +#include "FreeRTOS.h" +#include "task.h" + +#define CLINT_BASE 0x14000000 + +extern uint64_t ullNextTime; +extern volatile uint64_t *pullMachineTimerCompareRegister; + +static inline uint64_t timer_get_current(void) { + uint64_t ret; + + asm volatile("csrr %0, time" : "=r"(ret)); + + return ret; +} + +static inline void timer_set_match(uint64_t match) { + *(uint32_t *)(CLINT_BASE + 0x4004) = match >> 32; + *(uint32_t *)(CLINT_BASE + 0x4000) = match; +} + +static inline void enable_timer_interrupt(void) { + uint64_t mie; + + asm volatile("csrr %0, mie" : "=r"(mie)); + + mie |= (1U << 7); /* Machine timer interrupt */ + + asm volatile("csrw mie, %0" : : "r"(mie)); +} + +void vPortSetupTimerInterrupt(void) { + uint64_t cur_time = timer_get_current(); + uint64_t match_inc = configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ; + ullNextTime = cur_time + match_inc; + pullMachineTimerCompareRegister = (volatile uint64_t *)(CLINT_BASE + 0x4000); + + timer_set_match(ullNextTime); + enable_timer_interrupt(); +} \ No newline at end of file diff --git a/src/main.c b/src/main.c index aa956c8..ed3951c 100644 --- a/src/main.c +++ b/src/main.c @@ -1,9 +1,16 @@ #include -static volatile uint64_t s_count = 0U; +#include "FreeRTOS.h" +#include "task.h" + +void app_tasks_init(void); int main(void) { - for(;;) { - s_count++; + app_tasks_init(); + + vTaskStartScheduler(); + + for (;;) { + /**/ } } \ No newline at end of file diff --git a/src/tasks/app_task_hello.c b/src/tasks/app_task_hello.c new file mode 100644 index 0000000..f83716a --- /dev/null +++ b/src/tasks/app_task_hello.c @@ -0,0 +1,16 @@ +#include "FreeRTOS.h" +#include "task.h" + +#include "t113i.h" + +#define LED_PIN (11) /* PG11 */ + +void app_task_hello(void *arguments) { + for(;;) { + GPIOG->DAT &= ~(1U << LED_PIN); + vTaskDelay(pdMS_TO_TICKS(1000)); + + GPIOG->DAT |= (1U << LED_PIN); + vTaskDelay(pdMS_TO_TICKS(1000)); + } +} \ No newline at end of file diff --git a/src/tasks/app_tasks.c b/src/tasks/app_tasks.c new file mode 100644 index 0000000..6140f6d --- /dev/null +++ b/src/tasks/app_tasks.c @@ -0,0 +1,8 @@ +#include "FreeRTOS.h" +#include "task.h" + +void app_task_hello(void *arguments); + +void app_tasks_init(void) { + xTaskCreate(app_task_hello, "HELLO", 1024, NULL, 2, NULL); +} diff --git a/startup/c906_it.c b/startup/c906_it.c new file mode 100644 index 0000000..7c0e2f6 --- /dev/null +++ b/startup/c906_it.c @@ -0,0 +1,16 @@ +#define __IRQ __attribute__((interrupt)) +#define __IRQ_NAKED __attribute__((naked)) + +__IRQ void Default_Handler(void) { + for (;;) { + /* -- */ + } +} + +__IRQ_NAKED void Exception_Handler(void) { + asm volatile("j freertos_risc_v_exception_handler"); +} + +__IRQ_NAKED void M_Timer_IRQHandler(void) { + asm volatile("j freertos_risc_v_mtimer_interrupt_handler"); +} \ No newline at end of file diff --git a/startup/start_c906.S b/startup/start_c906.S deleted file mode 100644 index 678242a..0000000 --- a/startup/start_c906.S +++ /dev/null @@ -1,36 +0,0 @@ -/* Custom CSR definitions */ - -#define CSR_MCOR 0x7C2 -#define CSR_MSMPR 0x7f3 - -/* Reset vector */ - - .section .init,"ax",@progbits - .global _start -_start: - /* Initialize GP */ -.option push -.option norelax - la gp, __global_pointer$ -.option pop - - - /* Initialize SP */ - la sp, __stack_top - - /* Data section has been copied by framework. */ - -clear_bss: - /* Clear bss section */ - la a0, _sbss - la a1, _ebss - bgeu a0, a1, post_crt0 - -loop_clear_bss: - sd zero, (a0) - addi a0, a0, 8 - bltu a0, a1, loop_clear_bss - -post_crt0: - jal SystemInit - jal main diff --git a/startup/startup_c906.S b/startup/startup_c906.S new file mode 100644 index 0000000..8bdd8e5 --- /dev/null +++ b/startup/startup_c906.S @@ -0,0 +1,83 @@ +/* Custom CSR definitions */ + +/* Reset vector */ + +.section .init,"ax",@progbits +.global _start +.align 8 +_start: + + /* Initialize GP */ +.option push +.option norelax + la gp, __global_pointer$ +.option pop + + csrw mie, x0 + csrw mip, x0 + + li t0, 0x70013 + csrw 0x7c2, t0 /* MCOR */ + + li t0, 0 + csrw 0x7c1, t0 /* MHCR */ + + /* Enable FP */ + li t0, 0xa00007900 + csrw mstatus, t0 + + /* Initialize SP */ + la sp, __stack_top + + /* Data section has been copied by framework. */ + +clear_bss: + /* Clear bss section */ + la a0, _sbss + la a1, _ebss + bgeu a0, a1, main_entry + +loop_clear_bss: + sd zero, (a0) + addi a0, a0, 8 + bltu a0, a1, loop_clear_bss + + /* Exception system */ + la t0, vec_base + addi t0, t0, 1 + csrw mtvec, t0 + +main_entry: + jal SystemInit + jal main + +dead_loop: + j dead_loop + +.option push +.option norvc + .align 8 +vec_base: + j Exception_Handler /* 00 Exception */ + j S_Software_IRQHandler /* 01 Supervisor software interrupt */ + j Default_Handler /* 02 Reserved */ + j M_Software_IRQHandler /* 03 Machine software interrupt */ + j Default_Handler /* 04 Reserved */ + j S_Timer_IRQHandler /* 05 Supervisor timer interrupt */ + j Default_Handler /* 06 Reserved */ + j M_Timer_IRQHandler /* 07 Machine timer interrupt */ +.option pop + +.weak Exception_Handler +.weak S_Software_IRQHandler +.weak M_Software_IRQHandler +.weak S_Timer_IRQHandler +.weak M_Timer_IRQHandler + +.align 8 +Exception_Handler: +S_Software_IRQHandler: +M_Software_IRQHandler: +S_Timer_IRQHandler: +M_Timer_IRQHandler: + j Default_Handler \ No newline at end of file diff --git a/startup/system_c906.c b/startup/system_c906.c index 4378041..d41e731 100644 --- a/startup/system_c906.c +++ b/startup/system_c906.c @@ -1,3 +1,3 @@ void SystemInit(void) { /* -- Nothing to do here for now. -- */ -} \ No newline at end of file +}