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指令通知上下文切换;其余异常由用户自定义管理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

怦然心动如往昔

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

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

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

打赏作者

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

抵扣说明:

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

余额充值