PMP導致異常問題分析
現(xiàn)象和確認異常原因
觸發(fā)了異常中斷
查看異常原因為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字節(jié)區(qū)域,即pmpaddrxx對應的4字節(jié)區(qū)域
L=1
A=10=2 NA4
R=1
X=0
W=0
對應pmp13cfg的pmpaddr13=0xa0e0ab4 是34位地址右移2位的值,所以左移兩位恢復實際值是0x2C38 2AD0
表示的范圍是[0x2C38 2AD0,0x2C38 2AD3] 4字節(jié)
我們的地址空間是0x28000000-0x2bffffff
寫0x2C38 2AD0實際映射到了寫0x2838 2AD0 64M繞回。
所以寫0x2838 2AD0這個不具備寫屬性的地址觸發(fā)了store access-fault
exception.異常
所以以上確認了原因是PMP設置了該地址不具備寫屬性,而代碼中去寫所以導致了異常。
代碼
我們的空間最多只有128M,最多到0x2bff ffff,為什么寫了個0x2C38 2AD0的地址進去,
先找到對應的代碼
由于是用的所以13的配置,所以先找這個索引對應
#define PMP_FIXED_INDEX_TASK_STACK 13
然后再搜索這個索引
找到如下函數(shù)
這個函數(shù)在vTaskSwitchContext調用
if (prev != pxCurrentTCB) {
pmp_task_stack_set((uint32_t)pxCurrentTCB- >pxStack);
}
即任務有切換時,設置棧底4字節(jié)不可寫,用于棧溢出檢測。
加個死循環(huán)用于在設置該值時停住
所以要確認什么時候寫了0x2838 2AD0這個地址,由于使能了PMP,所以watchpoint抓不到,先觸發(fā)了pmp的異常。
所以先關閉pmp設置
if (prev != pxCurrentTCB) {
///pmp_task_stack_set((uint32_t)pxCurrentTCB- >pxStack);
}
然后設置數(shù)據斷點
watch (unsigned int )0x28382ad0
運行
第一次停在棧初始化,第二次停在如下處
可以看到
任務棧的地址是 0x28382ad0開始但是 臨時變量mem的地址是0x28382a60在棧前面去了,所以棧溢出了。
把棧改大即可
審核編輯:湯梓紅
-
嵌入式
+關注
關注
5059文章
18973瀏覽量
302042 -
調試
+關注
關注
7文章
571瀏覽量
33872 -
PMP
+關注
關注
0文章
45瀏覽量
18131 -
RISC-V
+關注
關注
44文章
2204瀏覽量
45958
發(fā)布評論請先 登錄
相關推薦
評論