在 RISC-V 内核的 MCU 上用 C 语言做底层开发,经常要直接读写 CSR(控制状态寄存器),分享几个实用要点:
1. CSR 无法用标准 C 直接寻址,必须用内联汇编封装成宏,例如:
#define read_csr(reg) ({ unsigned long __v; asm volatile("csrr %0, " #reg : "=r"(__v)); __v; })
#define write_csr(reg, val) asm volatile("csrw " #reg ", %0" :: "r"(val))
2. 宏参数用字符串拼接 #reg,编译器会直接展开成 csrr mstatus 这类指令,没有运行时查表开销。
3. 读-改-写场景(例如单独使能某个中断位)应使用 csrrs/csrrc 的 set/clear 版本,不要用 csrw 整字覆盖,否则容易误清其他位。
4. 涉及中断全局开关(mstatus.MIE)时,建议用 csrsi/csrci 单条指令完成,保证原子性,比"先读再写"更安全。
5. 编译选项记得写清 -march(如 rv32imac),否则部分 CSR 或压缩指令会直接报错。
以上写法在 GD32V、CH32V 等 RISC-V 内核芯片上通用,欢迎各位补充踩坑经验。 |
|