Initial FreeRTOS support.

Signed-off-by: Yilin Sun <imi415@imi.moe>
This commit is contained in:
Yilin Sun 2024-03-10 12:36:38 +08:00
parent 11173b0dba
commit f8fcd25e5f
Signed by: imi415
GPG Key ID: 17F01E106F9F5E0A
15 changed files with 352 additions and 62 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "lib/freertos"]
path = lib/freertos
url = https://github.com/imi415/FreeRTOS-Kernel.git

View File

@ -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})

View File

@ -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;
}

95
include/FreeRTOSConfig.h Normal file
View File

@ -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 */

45
include/t113i.h Normal file
View File

@ -0,0 +1,45 @@
#ifndef T113I_H
#define T113I_H
#include <stdint.h>
#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

1
lib/freertos Submodule

@ -0,0 +1 @@
Subproject commit 62d75c88279c1f98f8eaef761a20c28b583e37f6

View File

@ -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

40
src/freertos/port.c Normal file
View File

@ -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();
}

View File

@ -1,9 +1,16 @@
#include <stdint.h>
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 (;;) {
/**/
}
}

View File

@ -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));
}
}

8
src/tasks/app_tasks.c Normal file
View File

@ -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);
}

16
startup/c906_it.c Normal file
View File

@ -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");
}

View File

@ -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

83
startup/startup_c906.S Normal file
View File

@ -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

View File

@ -1,3 +1,3 @@
void SystemInit(void) {
/* -- Nothing to do here for now. -- */
}
}