PMP導致異常問題分析
現象和確認異常原因
觸發了異常中斷
查看異常原因為7 store access-fault exception.
并查看異常訪問的地址為0x28382ad0
gdb也確認這個地址確實只能讀不能寫
查看PMP寄存器確認根本原因
Pmpcfg0 對應地址pmp0cfg~pmp3cfg
Pmpcfg1 對應地址pmp4cfg~pmp7cfg
Pmpcfg2 對應地址pmp8cfg~pmp11cfg
Pmpcfg3 對應地址pmp12cfg~pmp15cfg
pmpcfg3為0x5100即對應pmp13cfg為0x51
8位的配置屬性0x51如下 只讀
A=10 即NA4表示4字節區域,即pmpaddrxx對應的4字節區域
L=1
A=10=2 NA4
R=1
X=0
W=0
對應pmp13cfg的pmpaddr13=0xa0e0ab4 是34位地址右移2位的值,所以左移兩位恢復實際值是0x2C38 2AD0
表示的范圍是[0x2C38 2AD0,0x2C38 2AD3] 4字節
我們的地址空間是0x28000000-0x2bffffff
寫0x2C38 2AD0實際映射到了寫0x2838 2AD0 64M繞回。
所以寫0x2838 2AD0這個不具備寫屬性的地址觸發了store access-fault
exception.異常
所以以上確認了原因是PMP設置了該地址不具備寫屬性,而代碼中去寫所以導致了異常。
代碼
我們的空間最多只有128M,最多到0x2bff ffff,為什么寫了個0x2C38 2AD0的地址進去,
先找到對應的代碼
由于是用的所以13的配置,所以先找這個索引對應
#define PMP_FIXED_INDEX_TASK_STACK 13
然后再搜索這個索引
找到如下函數
這個函數在vTaskSwitchContext調用
if (prev != pxCurrentTCB) {
pmp_task_stack_set((uint32_t)pxCurrentTCB- >pxStack);
}
即任務有切換時,設置棧底4字節不可寫,用于棧溢出檢測。
加個死循環用于在設置該值時停住
所以要確認什么時候寫了0x2838 2AD0這個地址,由于使能了PMP,所以watchpoint抓不到,先觸發了pmp的異常。
所以先關閉pmp設置
if (prev != pxCurrentTCB) {
///pmp_task_stack_set((uint32_t)pxCurrentTCB- >pxStack);
}
然后設置數據斷點
watch (unsigned int )0x28382ad0
運行
第一次停在棧初始化,第二次停在如下處
可以看到
任務棧的地址是 0x28382ad0開始但是 臨時變量mem的地址是0x28382a60在棧前面去了,所以棧溢出了。
把棧改大即可
審核編輯:湯梓紅
-
嵌入式
+關注
關注
5146文章
19597瀏覽量
316187 -
調試
+關注
關注
7文章
611瀏覽量
34615 -
PMP
+關注
關注
0文章
45瀏覽量
18403 -
RISC-V
+關注
關注
46文章
2525瀏覽量
48498
發布評論請先 登錄
RISC-V Summit China 2024 | 青稞RISC-V+接口PHY,賦能RISC-V高效落地
玄鐵VirtualZone:基于RISC-V架構的安全擴展
RISC-V規范的演進 RISC-V何時爆發?
使用Eclipse和MCUXpresso IDE調試RV32M1-VEGA RISC-V開發板

RISC-V學習筆記【1】RISC-V概述
Imagination CPU 系列研討會 | RISC-V 平臺的性能分析和調試

RISC-V Summit China 2024 青稞RISC-V+接口PHY,賦能RISC-V高效落地

加入全球 RISC-V Advocate 行列,共筑 RISC-V 的未來 !

評論