新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 關于stm32中R15寄存器的理解

        關于stm32中R15寄存器的理解

        作者: 時間:2016-11-09 來源:網絡 收藏
        今天上午看《stm32權威指南》中關于R15寄存器中有些內容不理解,查了查資料,原來是這樣。


        本文引用地址:http://www.104case.com/article/201611/317761.htm

        這里有一個別人的問題。

        我把Nor Flash里的一個函數代碼數據(函數首地址是:0x6400EC10)拷貝到RAM的 0x2000FC00,
        然后把0x2000FC00加載給PC指針(為了讓代碼在RAM里運行),接著就出現了Hard Fault
        Exception,而用 IAR 單步執行的時候能正常運行。同時我將一個函數地址值賦給一個unsigned int
        變量之后發現自動加了1。對于這些問題先看權威指南里是怎么說的吧。
        一,PC指針(程序計數器R15)(權威指南)
        R15是程序計數器,在匯編代碼中稱為“PC指針”。因為CM3內部使用了指令流水線,讀PC時返回的值
        是當前指令的地址+4。比如說:
        0x1000: MOV R0, PC ; R0 = 0x1004
        如果向PC中寫數據,就會引起一次程序的分支(但是不更新LR寄存器)。CM3中的指令至少是半字
        對齊的,所以PC的LSB總是讀回0。然而,在分支時,無論是直接寫PC的值還是使用分支指令,都必
        須保證加載到PC的數值是奇數(即LSB=1),用以表明這是在Thumb狀態下執行。倘若寫了0,則視
        為企圖轉入ARM模式,CM3將產生一個fault異常。這些可以總結為讀PC指針時,返回LSB總是為0;
        寫PC指針時,一定要保證LSB為奇數。
        二,函數地址(自己總結的)
        正如上面所說,寫PC指針的時候必須保證LSB為奇數,如果執行跳轉指令的時候,將一個函數指針
        加載給PC,這時候就必須保證這個函數地址的LSB為奇數,而且還必須是(4*n+1)(n=0,1,2,3)
        這樣的奇數,只有這樣運行程序才不會跑飛。在以后的編程中,如果執行函數跳轉的時候,一定要
        保證這個函數地址的低四位的值為(4*n+1)(n=0,1,2,3)。
        基于上面兩點,就可以很好的解釋所出現的問題了,如果將0x2000FC00加載給PC指針,肯定會出現
        Hard Fault Exception,因為 0x2000FC00 的 LSB = 0;但是如果將 0x2000FC01加載給PC指針,程
        序就能正常運行了,這就應證了權威指南里所說的寫PC指針的時候必須保證加載給PC的值的LSB為1

        而之前的為什么用IAR單步執行能成功,原因是IAR的調試器做了處理,使得每一次調試的時候對PC
        指針的LSB做了一個奇偶變換;當全速運行的時候,調試器不管用了,直接由CPU接管,這個時候將
        函數地址加載給PC的值的LSB為偶數,當然導致程序跑飛了。
        還有為什么將一個函數地址值賦給一個unsigned int 變量之后會自動加一呢,這個是Cortex-M3的一
        個特性,也就是說讀取一個函數地址值返回的LSB為0,當賦值給一個變量的時候會加1,這是為了將
        這個變量值加載給PC指針之后保證PC指針的LSB為1。
        問題解決了,希望對碰到同樣問題的朋友能有所幫助。同時如果總結的不好,大家可以一起交流交流。

        但是,這個部分又是怎么理解的呢?



        關鍵詞: stm32R15寄存

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 金阳县| 剑川县| 广安市| 德州市| 衡山县| 类乌齐县| 巴彦淖尔市| 武强县| 杭锦旗| 海城市| 通辽市| 襄樊市| 光山县| 固始县| 辽宁省| 儋州市| 肇东市| 武清区| 屯昌县| 岐山县| 当涂县| 开江县| 裕民县| 肇州县| 景洪市| 新源县| 阿拉善右旗| 高邑县| 彭阳县| 镇赉县| 大安市| 博野县| 铜鼓县| 淮南市| 平泉县| 柯坪县| 大理市| 宜丰县| 屏边| 高要市| 天门市|