搞嵌入式的知道,NOR FLASH,可以掉電儲存資料,但是反覆擦寫比較容易壞,在開發階段必然會不停的燒寫和驗證,這個過程必不可少,這必然會引入損壞nor flash的風險。其實這也不是不可以規避的風險,比如開發階段把程式下載到RAM中並執行,就可以規避這個。缺點就是掉電沒法儲存資料,不過RAM通常會比Nor FLASH 空間小,等程式的驗證完了,稍作修改就可以下載到nor flash中了,這樣最小次數的燒寫到flash 中。
1,在系統reset時會去找異常向量表中前4個位元組指向的地址作為棧頂
2,第4-8個位元組是reset handler函式的地址,然後PC會load這個地址,並執行。這個reset 向量指向的函式是我們能寫程式碼控制的最開始的位置。 cortext-m4 從向量表中把reset異常的函式地址載入到PC暫存器並執行是純硬體行為,而且是無法更改的,那麼如何做到從RAM運行了,就需要解決:
1,預設的向量表是在Nor Flash最開始的位置,現在就需要修改向量表到RAM中。
2,如何讓PC暫存器從RAM中向量表開始載入reset_handler 函式地址。---顯然我們是沒法用軟體控制的,我們的軟體的第一行程式碼都跑不到。
一個個的搞。
如圖片把向量表,和指令text 段都放在了 RAM地址空間中,所以解決第一個問題主要是修改連線指令碼。把原先從FLASH載入改到RAM載入,這時在coretx-m4 眼裡已經沒有了nor_flash。
另外就是data段把LMA和VMA都放在RAM中了。(原來在FLASH中執行時,是需要把data段資料從flash 中複製到RAM中,就是兩份data段的資料了,現在就不需要這個複製過程了)
連線指令碼改了後:
arm-none-eabi-nm 工具看一下
RAM中地址是0x20000000開始的,對比flash地址0x08000000。 cortext-m4 眼中的VMA已經全部是在RAM中,還有一個問題就是 cortext-m4 怎麼知道 向量表在RAM中了。
直接看圖片抓重點,有個VTOR暫存器可以更改向量表的位置。
直接指定VTOR為RAM開始的地方
2,第二個問題,更改PC到新的reset_handler函數出怎麼解決了。首先這個你是沒法透過改自己的編寫的程式碼去做到的, 因為跑不到你的第一行程式碼那兒去。我的除錯環境一直都是openocd +gdb。
先是下載到ram中。
看一下RAM 和 編譯的程式,沒問題。
dump來看reset 是呼叫函式地址是0x2000006b
這個CPU 目前最初始的狀態
其實到這裡就可以讓CPU直接跳到0x2000006b處就行。
程式也是正常的跑起來了,但是我們寫程式碼是肯定不知道reset異常對應handler 函式在哪位置了。
現在是0x2000006b,如果這個檔案前面加個一些函式就可能0x2000008b了反正不能確定編譯器把它放在哪裡?
都到這地方了,就是函式地址不固定了,那就固定他就好了,最好的是把它固定在向量表緊接著的位置。
向量表最後一個位置是0x000001A8.緊接著它的位置就是0x200001AC改一下程式碼及指令碼。
把這個reset_handler 放到.reset_fun 段中。
然後連線指令碼加上這段,並且把VMA放到0x200001AC位置。
好了地址固定了,最後VScode也好,還是命令列除錯,最後就一句話寫到腳本里
openocd.exe -f F:\OpenOCD-20200729-0.10.0\share\openocd\scripts\interface\stlink-v2-1.cfg -f F:\OpenOCD-20200729-0.10.0\share\openocd\scripts\target\stm32l4x.cfg -c init -c "reset halt" -c "load_image hello.bin 0x20000000" -c "resume 0x200001AC"
下載及執行都成功。
程式碼路徑 https://gitee.com/android_life/stm32_freertos_opensource/tree/master/assembly/run_code_on_ram
前面說了這個
原來在FLASH中執行時,是需要把data段資料從flash 中複製到RAM中,就是兩份data段的資料了,現在就不需要這個複製過程了