[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
This commit is contained in:
Paul Pan 2023-02-01 20:57:30 +08:00
parent 8aa6d19cea
commit 0a8b4a7ec5
15 changed files with 304 additions and 7 deletions

2
.gitignore vendored
View File

@ -1,3 +1,4 @@
.idea
.vscode
**/__pycache__
**/build
@ -12,3 +13,4 @@
*.svd
*.pack
**/_build
cmake-build-*

3
.gitmodules vendored
View File

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

View File

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

View File

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

View File

@ -1 +1,2 @@
sdk_add_subdirectory_ifdef(CONFIG_FREERTOS freertos)
sdk_add_subdirectory_ifdef(CONFIG_FREERTOS freertos)
sdk_add_subdirectory_ifdef(CONFIG_FREERTOS2 freertos2)

View File

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

@ -1 +1 @@
Subproject commit c9bf3486c6ea83a3499047b35d95edef5321bdfe
Subproject commit 98c7fbbf8dc7ba9c44504b160590d87e43882beb

@ -0,0 +1 @@
Subproject commit 06b4e233ec768d3d460571915dd0eb492c91585b

View File

@ -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 <FreeRTOS.h>
#include <semphr.h>
__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;
}

View File

@ -0,0 +1,6 @@
#ifndef FREERTOS_BL_PORT_H
#define FREERTOS_BL_PORT_H
void SetupFreeRTOS(void);
#endif //FREERTOS_BL_PORT_H

View File

@ -0,0 +1,71 @@
#include <FreeRTOS.h>
#include <task.h>
#include <stdio.h>
#include <rv_hart.h>
#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();
}

View File

@ -0,0 +1,60 @@
#include "freertos_bl_port.h"
#include <FreeRTOS.h>
#include <stdio.h>
#include <rv_hart.h>
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
}

View File

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

View File

@ -1,5 +1,7 @@
#include <FreeRTOS.h>
#include "semphr.h"
#include <malloc.h>
#include <semphr.h>
#include <freertos_bl_port.h>
#include "board.h"
#define DBG_TAG "MAIN"
@ -63,6 +65,8 @@ int main(void)
{
board_init();
SetupFreeRTOS();
configASSERT((configMAX_PRIORITIES > 4));
/* Create semaphore */

View File

@ -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)
set(CONFIG_FREERTOS2 1)