小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

【STM32F303開發(fā)】 關于連接寄存器LR的值

 刀首木 2019-02-10
昨天有位同學看了我之前的這個帖子:【STM32F303開發(fā)】+如何找到導致程序出現(xiàn)HardFault的代碼   后在社區(qū)群里說他也遇到了這個問題,但是他不太清楚那個帖子最后的那個圖片的中的有2個LR的值哪個才是有用的,該使用哪個LR的值去找跑飛的代碼。我告訴他是debug viewer中輸出的那個,他好像還是不太明白,下面我們就簡單的看下LR的變化過程。他說的那個圖片如下,其中包含了2個LR,左邊一個寄存器R14的值,右邊debug viewer輸出一個。
lr.jpg
我們通常說的LR寄存器就是寄存器R14,它常用于在調用子程序分支時存儲返回地址,調用完成后用于返回到調用之前的地方繼續(xù)執(zhí)行下面的代碼,
《Cortex-M3 權威指南》對LR的描述如下,其中提到了LR的地址等于當前子程序分支的下一條指令的地址。
lr.jpg
我們知道當程序發(fā)生異?;蛘咧袛鄷r會自動保存現(xiàn)場將xPSR,PC,LR,以及R0-R3由硬件自動壓入堆棧以及一些其他的處理,然后程序進入異?;蛘咧袛嗪瘮?shù),此時LR的值將會被自動被更新為特殊的EXC_RETURN.《Cortex-M3 權威指南》里的詳細的介紹如下:
lr.jpg

下面我們根據(jù)上面的敘述結合實際的代碼看下LR的值的變化過程:
1)我們在異常函數(shù)void HardFault_Handler(void)里面設置一個斷點后debug下全速運行,這個函數(shù)是重載的系統(tǒng)的函數(shù),當出現(xiàn)HardFault時會自動進入這個函數(shù),可以看到此時的LR=0XFFFFFFF9,且此時處于Handler模式,和上面的描述相符。在這個函數(shù)里面首先判斷是使用的MSP還是SPS,然后將這個SP的值保存到r0寄存器,然后調用函數(shù)void Hard_Fault_Handler(uint32_t stack[]),此時的r0,作為函數(shù)Hard_Fault_Handler的參數(shù)。
lr.jpg
下面我們進入到void Hard_Fault_Handler(uint32_t stack[]),具體如下,主要是打印一些信息出來,我們在下面的函數(shù)里設置一個斷點,然后進入到下面的函數(shù)中去
  1. void Hard_Fault_Handler(uint32_t stack[])

  2. {

  3. static char msg[80];

  4. printf('In Hard Fault Handler\n');

  5. sprintf(msg, 'SCB->HFSR = 0x%08x\n', SCB->HFSR);

  6. printf(msg);

  7. if ((SCB->HFSR & (1 << 30)) != 0)

  8. {

  9. printf('Forced Hard Fault\n');

  10. sprintf(msg, 'SCB->CFSR = 0x%08x\n', SCB->CFSR );

  11. printf(msg);

  12. if((SCB->CFSR & 0xFFFF0000) != 0) {

  13. printUsageErrorMsg(SCB->CFSR);

  14. }

  15. if((SCB->CFSR & 0xFF00) != 0) {

  16. printBusFaultErrorMsg(SCB->CFSR);

  17. }

  18. if((SCB->CFSR & 0xFF) != 0) {

  19. printMemoryManagementErrorMsg(SCB->CFSR);

  20. }      

  21. }  

  22. stackDump(stack);

  23. __ASM volatile('BKPT #01');

  24. while(1);

  25. }

在斷點暫停后我們發(fā)現(xiàn)LR的值還沒有發(fā)生變化,還是剛進入中斷函數(shù)的0xFFFFFFF9,
lr.jpg
程序在進入函數(shù)時把r0的值傳給了r4,用于保存參數(shù)的值,因為下面要用到r0.
lr.jpg

繼續(xù)看下面的匯編。將要輸出的字符的地址傳到r0保存,我們可以在內存中看到地址0x08000818中保存的就是要輸出的字符串'In Hard Fault Handler\n',同時也可以在我們上次得到的反匯編文件中看到這個FLASH地址保存的輸出字符。
lr.jpg
反匯編中得到保存的輸出字符的位置,具體參考:【STM32F303開發(fā)】+使用fromelf反匯編keil生成的AXF文件
lr.jpg
保存好參數(shù)r0后程序會跳轉到輸出函數(shù)的地址0x08002080繼續(xù)執(zhí)行,注意輸出字符串函數(shù)下面的一條語句的地址為0x080006c6,這個地址將會在程序跳轉到輸出函數(shù)時被保存在LR中,此時的LR的值將會發(fā)生變化。在0x08002080設置個斷點,然后全速運行程序,程序會暫停在輸出函數(shù)。
從下圖中可以看到LR的值從進入中斷函數(shù)時的0xFFFFFFF9變成了0x080006c7(指令最低bit0必須為1),這個值正好是我們跳轉前的下一句代碼的地址0x080006c6.
lr.jpg

綜上,進入中斷函數(shù)時的LR為特殊的EXC_RETURN,但是如果在中斷函數(shù)中有發(fā)生子程序分支調用時,LR的值就會被壓棧,然后發(fā)生變化用于存儲子程序的返回地址。而我們用于保存跑飛代碼的LR的值一直在保存著并沒有發(fā)生變化,最后在debug viewer輸出的正是我們要找的LR的值。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多