如何解决RARS中Digital Lab Sim运行冻结问题?
RARS使用Digital Lab Sim(DLS)十六进制键盘时频繁冻结的问题排查与优化
我正在学习RISC-V,使用RARS及其内置的Digital Lab Sim(DLS)模拟设备实现十六进制键盘按键读取功能,但RARS仅运行几次就会冻结,必须重启。试过增加延迟时长、降低程序运行速度,均无效果。以下是我的实现代码:
.eqv IN_ADDRESS_HEXA_KEYBOARD 0xFFFF0012 .eqv OUT_ADDRESS_HEXA_KEYBOARD 0xFFFF0014 .data message: .asciz "Key scan code: " # ----------------------------------------------------------------- # MAIN Procedure # ----------------------------------------------------------------- .macro checkKeyCode(%registor, %value, %ascii) li t0, %value bne t0, %registor, skip li s6, %ascii skip: .end_macro .text main: # Load the interrupt service routine address to the UTVEC register la t0, handler csrrs zero, utvec, t0 # Set the UEIE (User External Interrupt Enable) bit in UIE register li t1, 0x100 csrrs zero, uie, t1 # uie - ueie bit (bit 8) # Set the UIE (User Interrupt Enable) bit in USTATUS register csrrsi zero, ustatus, 0x1 # ustatus - enable uie (bit 0) # Enable the interrupt of keypad of Digital Lab Sim li t1, IN_ADDRESS_HEXA_KEYBOARD li t3, 0x80 # bit 7 = 1 to enable interrupt sb t3, 0(t1) # --------------------------------------------------------- # Loop to print a sequence of numbers # --------------------------------------------------------- xor s0, s0, s0 # count = s0 = 0 loop: addi s0, s0, 1 # count = count + 1 prn_seq: addi a7, zero, 1 add a0, s0, zero # Print auto sequence number ecall addi a7, zero, 11 li a0, '\n' # Print EOL ecall sleep: addi a7, zero, 32 li a0, 5000 # Sleep 300 ms ecall j loop end_main: # ----------------------------------------------------------------- # Interrupt service routine # ----------------------------------------------------------------- handler: # Saves the context addi sp, sp, -16 sw a0, 0(sp) sw a7, 4(sp) sw t1, 8(sp) sw t2, 12(sp) # Handles the interrupt prn_msg: addi a7, zero, 4 la a0, message ecall load_all_rows: li t1, IN_ADDRESS_HEXA_KEYBOARD li t2, OUT_ADDRESS_HEXA_KEYBOARD li t3, 0x1 # Start from Row 1 li t4, 0x8 # Row 4 (maximum row) scan_rows: addi t5, t3, 0x80 sb t5, 0(t1) # Write Row (Row n) to IN_ADDRESS lb a0, 0(t2) # Read key scan code from OUT_ADDRESS beqz a0, next_row # If no key pressed, move to the next row # Handle key press (print scan code) checkkeyCode: checkKeyCode(a0, 0x11, 0x30) checkKeyCode(a0, 0x21, 0x31) checkKeyCode(a0, 0x41, 0x32) checkKeyCode(a0, 0x81, 0x33) checkKeyCode(a0, 0x12, 0x34) checkKeyCode(a0, 0x22, 0x35) checkKeyCode(a0, 0x42, 0x36) checkKeyCode(a0, 0x82, 0x37) checkKeyCode(a0, 0x14, 0x38) checkKeyCode(a0, 0x24, 0x39) checkKeyCode(a0, 0x44, 0x61) checkKeyCode(a0, 0x84, 0x62) checkKeyCode(a0, 0x18, 0x63) checkKeyCode(a0, 0x28, 0x64) checkKeyCode(a0, 0x48, 0x65) checkKeyCode(a0, 0x88, 0x66) next_row: slli t3, t3, 1 # Shift left to move to the next row ble t3, t4, scan_rows # Repeat for Row 4 prn_key_code: mv a0, s6 li a7, 11 ecall # Restores the context lw t2, 12(sp) lw t1, 8(sp) lw a7, 4(sp) lw a0, 0(sp) addi sp, sp, 16 # Back to the main procedure uret
问题根源分析
1. 代码层面问题
- 上下文保存不完整:中断服务程序(ISR)中修改了
s6寄存器,但未将其保存到栈中,会破坏主程序的s6状态,导致程序逻辑混乱甚至崩溃。 - 中断标志未清除:DLS键盘触发中断后,未手动清除中断标志,会导致中断持续触发,CPU被中断完全占用,出现假死。
- 宏标签冲突:
checkKeyCode宏中的skip标签会在多次展开后重复,导致跳转逻辑错误,执行流程混乱。 - 无中断嵌套防护:ISR执行期间未关闭外部中断,可能触发嵌套中断,导致栈溢出。
2. 模拟层面问题
- RARS的DLS模拟存在已知的稳定性bug,频繁触发外部中断时容易出现死锁。
- 模拟设备的中断触发速率过高,事件队列堆积导致冻结。
解决建议与优化方案
代码修复
完善上下文保存:在ISR中保存并恢复所有被修改的寄存器,包括
s6:handler: # 扩展栈空间以保存s6 addi sp, sp, -20 sw a0, 0(sp) sw a7, 4(sp) sw t1, 8(sp) sw t2, 12(sp) sw s6, 16(sp) # 保存s6 # ... 原有处理逻辑 ... # 恢复s6 lw s6, 16(sp) lw t2, 12(sp) lw t1, 8(sp) lw a7, 4(sp) lw a0, 0(sp) addi sp, sp, 20清除中断标志:读取按键后,向键盘输入地址重新写入使能值以清除中断:
# 在处理完按键后添加 sb t5, 0(t1) # 重新写入行选择+使能位,清除中断标志修复宏标签冲突:给宏的跳转标签添加唯一后缀,避免重复:
.macro checkKeyCode(%reg, %val, %ascii, %skip_label) li t0, %val bne t0, %reg, %skip_label li s6, %ascii %skip_label: .end_macro # 调用示例 checkKeyCode(a0, 0x11, 0x30, skip_1) checkKeyCode(a0, 0x21, 0x31, skip_2)添加中断嵌套防护:ISR执行期间临时关闭外部中断,执行完成后恢复:
handler: # 临时关闭UEIE中断 csrrc t0, uie, 0x100 # ... 保存上下文与处理逻辑 ... # 恢复UEIE中断 csrrs zero, uie, t0
RARS模拟优化
- 只开启必要的模拟设备,关闭其他无关设备以降低负载。
- 更新RARS至最新版本,修复已知的DLS稳定性bug。
- 调整DLS键盘的防抖设置,减少误触发导致的频繁中断。
内容的提问来源于stack exchange,提问作者kiyoshi_akira
相关产品推荐
相关产品推荐

