[RISC-V MCU 应用开发] RISC-V内核中的mtvec寄存器

[复制链接]
2441|5
CloudKiss 发表于 2025-8-30 14:51 | 显示全部楼层 |阅读模式
内核, 寄存器, , , ,

RISC-V内核中的mtvec寄存器

今天下午研究了一下沁恒CH32V317,要玩CH32V317也要使用WCH-Link。WCH-Link支持RISC-V模式和ARM模式。还是蛮高级的一件事。再来研究了一下RISC-V和ARM的一个显著区别——中断向量表的配置mtvec寄存器,其支持ARM的vector table模式。好吧!再多看看mtvec寄存器。

mtvec 寄存器是用来设置机器模式的异常向量基地址寄存器(Machine Mode Exception Vector Base Address Register)。这个寄存器决定了如何处理中断和异常。

寄存器概述

在 RISC-V 中,mtvec 寄存器是一个 CSR(Control and Status Register),其地址为 0x305。它有两个主要的配置模式:直接模式和向量模式。

直接模式

在直接模式下,mtvec 的最低位(bit 0)被设置为 0。在这种模式下,异常向量基地址的低两位被忽略,因此实际的基地址是对齐到4字节边界的。例如,如果 mtvec 被设置为 0x80000000,实际的异常处理代码起始地址会是 0x80000000。

向量模式

在向量模式下,mtvec 的最低位被设置为 1。在这种模式下,异常向量基地址的低两位用来决定是使用 4 字节对齐的异常处理代码还是使用 16 字节对齐的异常处理代码。例如,如果 mtvec 被设置为 0x80000001,则实际的异常处理代码起始地址会是 0x80000000(4字节对齐),如果是 0x80000003,则可能是 0x80000010(16字节对齐)。

如何设置 mtvec

在汇编语言中,你可以使用 csrrw, csrrs, csrrc, 或 csrrwi, csrrsi, csrrci 指令来操作 mtvec 寄存器。例如,要将 mtvec 设置为向量模式下的 0x80000010(16字节对齐),你可以使用以下指令:

li t0, 0x80000013  # Load the value into a register
csrw mtvec, t0     # Write the value to mtvec

或者,如果你只想设置基地址而不改变模式位(比如设置为直接模式下的 0x80000024):

li t1, 0x80000024  # Load the base address into a register
csrw mtvec, t1     # Write the base address to mtvec (direct mode, mode bit is 0)

注意事项

确保异常处理代码在指定的内存地址处正确对齐。

在多核处理器中,通常每个核心的 mtvec 可以独立设置,以便每个核心可以有不同的异常处理代码。

在启动代码或操作系统初始化时设置 mtvec 是非常重要的,以确保系统能够正确响应异常和中断。

通过正确配置和使用 mtvec,你可以有效地管理和响应 RISC-V 系统中的异常和中断。

总结

学习之后,可以看到沁恒在mtvec寄存器上面应该融入了自己想法。将其扩展之后,更加适合现场应用。

快乐制造机 发表于 2025-9-1 22:54 | 显示全部楼层
通过修改 mtvec 寄存器的值,可动态切换中断向量表
魔法森林精灵 发表于 2025-9-3 20:40 | 显示全部楼层
在向量模式下,除标准 4 字节和 16 字节对齐支持外,沁恒可能针对嵌入式场景优化了对齐粒度适配,允许根据异常处理代码长度动态调整(如 8 字节对齐)
逆鳞风暴 发表于 2025-9-3 22:38 | 显示全部楼层
向量表必须4字节对齐,编译器加.align 2
 楼主| CloudKiss 发表于 2025-9-6 10:49 | 显示全部楼层
逆鳞风暴 发表于 2025-9-3 22:38
向量表必须4字节对齐,编译器加.align 2

现在的编译器是不是都会4字节对齐?!
感觉只要不特殊声明,其一定会4字节地址对齐。
OceanDepths 发表于 2025-9-7 13:51 | 显示全部楼层
向量模式应该是risv的独有特色了吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

31

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部