RISC-V移植FreeRTOS

文章介绍了如何在RISC-V架构上配置和使用FreeRTOS操作系统,包括时基设置、内置模块类型定义、中断入口设置、异常处理函数以及中断和异常的解析流程。特别提到了MTIME模块在提供时基和中断方面的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

RTOS源码

下载FreeRTOS 202210-LTSportable文件夹保留/MemMang/GCC/RISC-V

+---freertos
|   |   FreeRTOSConfig.h						//RTOS 配置文件
|   \---kernel                          		//RTOS源文件
|       |   croutine.c
|       |   event_groups.c
|       |   list.c
|       |   manifest.yml
|       |   queue.c
|       |   Quick_Start_Guide.url
|       |   stream_buffer.c
|       |   tasks.c
|       |   timers.c
|       +---include								//所有 header 文件
|       \---portable							//移植接口文件
|           |   riscv_application_isr.c         //创建文件实现中断接口
|           +---MemMang
|           \---RISC-V
\---src
    |   linker.ld
    |   main.c
    \---bsp
        \---driver
            +---gpio
            +---riscv_mc
            +---smbus_mailbox
            \---uart

关键配置

时基

内置模块类型

#define portasmHAS_SIFIVE_CLINT         0
#define portasmHAS_MTIME                1
#define portasmADDITIONAL_CONTEXT_SIZE  0

Machine Timer地址

#define configMTIME_BASE_ADDRESS		( RISCV_UCPU_INST_BASE_ADDR + 0x400 )
#define configMTIMECMP_BASE_ADDRESS		( RISCV_UCPU_INST_BASE_ADDR + 0x410 )

时钟配置

#define configCPU_CLOCK_HZ				( ( unsigned long ) 90000000 )
#define configTICK_RATE_HZ				( ( TickType_t ) 1000 )

中断

设置中断入口

	la t0, freertos_risc_v_trap_handler
	csrw    mtvec, t0

重定义中断和异常接口函数,参数为mcause寄存器的值

void freertos_risc_v_application_interrupt_handler( uint32_t ulMcause )
{
	/* Not implemented yet! */
    printf( "interrupt: 0x%04x\r\n", ulMcause );
}

/*-----------------------------------------------------------*/
void freertos_risc_v_application_exception_handler( uint32_t ulMcause )
{
    /* Not implemented yet! */
	printf( "exception: 0x%04x\r\n", ulMcause );
}

中断和异常解析

.section .text.freertos_risc_v_trap_handler
.align 8
freertos_risc_v_trap_handler:
    portcontextSAVE_CONTEXT_INTERNAL
    csrr a0, mcause
    csrr a1, mepc
    bge a0, x0, synchronous_exception

asynchronous_interrupt:
    store_x a1, 0( sp )                 /* Save unmodified exception return address. */
    load_x sp, xISRStackTop             /* Switch to ISR stack. */
    j handle_interrupt

synchronous_exception:
    addi a1, a1, 4                      /* Update exception return address to the instruction after the instruction that generated the exeption. */
    store_x a1, 0( sp )                 /* Save updated exception return address. */
    load_x sp, xISRStackTop             /* Switch to ISR stack. */
    j handle_exception

handle_interrupt:
#if( portasmHAS_MTIME != 0 )
    test_if_mtimer:                     /* If there is a CLINT then the mtimer is used to generate the tick interrupt. */
        addi t0, x0, 1
        slli t0, t0, __riscv_xlen - 1   /* LSB is already set, shift into MSB.  Shift 31 on 32-bit or 63 on 64-bit cores. */
        addi t1, t0, 7                  /* 0x8000[]0007 == machine timer interrupt. */
        bne a0, t1, application_interrupt_handler /* mtimer更新定时器,其余中断进入重定义的中断接口 */

        portUPDATE_MTIMER_COMPARE_REGISTER
        call xTaskIncrementTick
        beqz a0, processed_source       /* Don't switch context if incrementing tick didn't unblock a task. */
        call vTaskSwitchContext
        j processed_source
#endif /* portasmHAS_MTIME */

application_interrupt_handler:
    call freertos_risc_v_application_interrupt_handler
    j processed_source

handle_exception:
    /* a0 contains mcause. */
    li t0, 11                                   /* 11 == environment call. */
    bne a0, t0, application_exception_handler   /* ecall执行切换,其余异常进入重定义的异常接口 */
    call vTaskSwitchContext
    j processed_source

application_exception_handler:
    call freertos_risc_v_application_exception_handler
    j processed_source                  /* No other exceptions handled yet. */

processed_source:
    portcontextRESTORE_CONTEXT
  • 中断状态下mepc保持不变,异常状态下mepc指向下一条指令mepc+4
  • MTimer提供OS时基,产生的中断更新定时器;其余中断由用户自定义管理
  • #define portYIELD() __asm volatile( "ecall" );ecall指令通知上下文切换;其余异常由用户自定义管理
RT-Thread是一个开源、灵活且适用于嵌入式系统的实时操作系统,而RISC-V则是一种基于开源指令集架构的处理器设计。要在RISC-V平台上进行RT-Thread的移植,需要进行以下几个步骤: 1. 硬件平台选择:首先,需要选择适合的RISC-V硬件平台来运行RT-Thread。可以选择一些流行的RISC-V开发板,如SiFive HiFive系列或者Loongson等。根据硬件平台选择适当的编译工具链和开发环境。 2. 编译工具链准备:为了在RISC-V平台上编译RT-Thread,需要准备适当的编译工具链。可以使用开源的RISC-V GNU工具链或LLVM工具链来编译和调试程序。 3. 移植RT-Thread内核:将RT-Thread的内核源代码移植RISC-V平台上。首先,需要根据目标平台的处理器架构,修改相关的的代码。然后,根据硬件平台的特性和需求,配置相关的外设驱动和系统组件。 4. 配置启动文件和链接脚本:在移植过程中,需要针对RISC-V平台编写适当的启动文件和链接脚本。启动文件负责初始化处理器、设置堆栈和启动操作系统,而链接脚本定义了程序的内存布局和链接规则。 5. 适配设备驱动:移植过程中,可能需要调整和适配一些硬件设备驱动,以便在RISC-V平台上正常工作。这包括串口通信、网络连接和外部设备驱动等。 6. 编译和调试:移植完成后,使用编译工具链将RT-Thread编译为可执行文件,然后将其烧录到RISC-V硬件平台上进行测试。使用调试工具进行调试和性能优化,确保RT-Thread在RISC-V上稳定运行。 总之,要在RISC-V平台上移植RT-Thread,需要根据硬件平台选择适当的工具链并进行适配和配置。通过适配内核、设备驱动和调试进行测试和优化,最终使RT-Thread能够在RISC-V平台上正常运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

怦然心动如往昔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值