RISCV处理器的中断过程及移植FreeRTOS系统的相关知识总结

RISCV内部与中断相关的信号

  • mcause_interrupt指示当前触发的是中断还是异常:1——中断、0——异常。
  • mcause_exceptionCode[3:0] 标识中断异常编码,如下表所示。
异常编码异常种类
0指令地址未对齐
1取指失败
2非法指令
3断点
4内存数据读取地址未对齐
5内存数据读取失败
6内存数据写入地址未对齐
7内存数据写入失败
11环境调用
中段编码中断种类
3软件中断
7定时器中断
11外部中断
  • mepc[31:0]存放异常情况发生时的PC值,作为中断处理程序结束后的返回地址。
  • mtvec_mode[1:0]和mtvec_base[29:0]确定异常情况处理程序的地址,如下表所示。
  • mstatus[3]为全局中断使能,当该位为0时,所有中断被禁止。
中断模式异常情况处理程序的地址
0PC = mtvec_base << 2
1PC = mtvec_base << 2 + 4 *异常/中断编码
2、3未定义

中断及异常发生的具体流程

中断及异常发生的具体流程如下图所示。中断异常触发后,保存当前PC值至mepc寄存器,同时判断是何类型中断异常并保存至mcause寄存器。之后从mtvec寄存器获取系统初始化时预存的异常处理程序的地址,跳转至异常处理程序进行处理,处理完毕跳转到异常发生地址的下一条指令继续执行程序。图中的箭头即为程序的执行顺序。
中断/异常触发的具体流程

RISC-V架构中断触发的条件

RISC-V架构中断触发的条件为:全局中断使能为1、相应类型的中断使能为1、相应类型的中断状态位为1。与此相关的信号包括:

  • mstatus_MIE:全局中断使能位。该信号为零时,外部中断、定时器中断、软件中断都被禁止。
  • mstatus_MPIE:全局中断使能保持/恢复位。中断发生时,该信号会记录MIE值,mret指令从中断返回时,将自身值重新赋值给MIE。
  • mie_MEIE:外部中断使能位。
  • mie_MTIE:定时器中断使能位。
  • mie_MSIE:软件中断使能位。
  • mip_MEIP:外部中断状态位。
  • mip_MTIP:定时器中断状态位。
  • mip_MSIP:软件中断状态位。

MIE、MPIE深层含义

RISC-V在处理中断/异常过程中,进入中断/异常处理程序之前,会先将MIE拉低,并将MIE旧值保存进MPIE中。退出中断/异常处理程序之后,将MPIE保存的旧值恢复至MIE中。 该操作其实是由于RISC-V架构定义的硬件机制无法支持中断嵌套行为,一旦响应中断进入异常模式后,全局中断使能被关闭,从而无法响应新的中断。

M()IE深层含义

RISC-V系统在最开始配置时,会确定不同类型的使能位。MTIE、MEIE、MSIE配置为固定值,并在处理器运行过程中始终不变。

M()IP信号深层含义

MTIP信号的深层含义为定时器模块传输给RISC-V处理器的定时器中断请求。RISC-V定义了两个64位寄存器:

  • mtime:时钟定时器,以固定的频率做计数。
  • mtimecmp:计数阈值,当mtime的值大于或等于该值,触发产生时钟中断请求。
    其中mtimecmp由系统下发给RISC-V处理器,FreeRTOS以RISC-V的定时器中断为基准,通过配置mtimecmp寄存器,保证系统心跳的频率。具体配置过程如下图,首先不同应用任务被创建,创建完成后启动任务调度器,在启动任务调度器过程中,系统会初始化定时器中断,即配置mtimecmp寄存器。然后系统选取没有阻塞且优先级最高的一个任务执行。任务执行到mtime计数大于等于mtimecmp时,触发定时器中断。跳转到定时器中断处理程序继续执行。在处理程序中,系统会确定是否需要切换任务——是否有任务解除阻塞且优先级更高。这个过程中再次配置mtimecmp寄存器,开始下一轮的心跳。该过程的循环成就了FreeRTOS可以按照节拍多任务并行。
     RISC-V配置定时相关寄存器过程
    MEIP就是各种外部中断源经过PLIC(中断控制器)输入到RISCV的外部中断信号。

FreeRTOS内的中断服务处理程序

中断服务处理程序freertos_risc_v_trap_handler的具体流程如下图。
首先对触发中断之前的任务现场进行保存,并读取MIE旧值压进栈内。接下来判断是中断触发还是异常触发,异常分为环境调用和普通异常两类,中断分为定时器中断和外部中断两类。针对不同的中断/异常触发进行不同的程序处理,在处理环境调用和定时器中断时,会跳转到任务切换处理函数,系统会确定是否需要切换任务——是否有任务解除阻塞且优先级更高。最后将之前压进栈内的MIE旧值弹出赋值给MIE寄存器,恢复现场。
FreeRTOS利用定时器中断和环境调用两种异常实现其任务调度机制。
①定时器中断更新计数器的值,查看是否有等待延时的任务解除阻塞,如果有,则完成任务切换。
②任务调用ecall(环境调用指令)实现主动的任务切换,通知调度器立即进行任务切换,而不必等到当前任务的时间片耗尽。某个任务调用ecall等效于其自愿放弃运行态,如调用vTaskDelay()
中断服务处理程序的具体流程

FreeRTOS内的堆栈指针

FreeRTOS系统编译好的程序可能的内存空间分配如下图,两个指针MSP(主堆栈指针)和PSP(进程堆栈指针)在其中发挥着重要的作用。MSP指针用于操作系统内核及处理异常;PSP指针用于不同任务,每个任务有自己的任务堆栈,在任务创建时会创建指定大小的任务堆栈。
FreeRTOS内存空间分配
FreeRTOS系统在创建任务时,不仅会创建指定大小的任务堆栈,还会定义一个任务控制块结构体——TCB(Tack Control Block),用于存储任务的状态信息。TCB内重要信息包括:栈顶指针、状态列表项(处于就绪列表还是等待列表)、任务优先级等等。FreeRTOS的核心是确保处于优先级最高的就绪任务获得CPU运行权,任务切换函数会找出就绪列表中最高优先级任务的TCB,将其中的栈顶指针赋给当前栈指针。

关键

FreeRTOS的任务创建函数xTaskCreate中,将初始化任务堆栈保护起来放入临界区,临界区是指那些必须完整运行、不能被打断的代码段。进入临界区会拉低MIE的值关闭中断,退出临界区会置高MIE的值打开中断。这样可以保证任务堆栈内的MIE值初始化为0,防止第一次切换任务时有可能触发的异常中断紊乱。

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值