免責聲明:本文提供的所有內容僅供學習、分享與交流,不保證內容的正確性,亦不對內容可能帶來的風險擔責。如若轉載,請署名以及註明原始出處。本文僅代表個人的立場和觀點,並不代表任何公司或組織。
下面的全部操作僅適用Window 10 64bits 環境。
前幾篇中的示例程序都存儲在Flash memory內,屬於EEPROM(Electrically Erasable Programmable read only memory,是指帶電可擦可編程只讀存儲器,是一種掉電後數據不丟失的存儲晶片),類似硬碟。變量不方便存儲在Flash內,需要存儲在RAM內,以便進行變量的修改。
Connex開發板擁有64MB的RAM,內存起始地址為0xA0000000,變量可以存儲這個內存區域。該開發板的內存映射如下圖:
Memory Map
0x01 LMA -> VMA
上電時,RAM中沒有數據可以直接可用。所有的代碼和數據在上電前存儲在Flash內存內。上電時,啟動代碼複製Flash中的數據到RAM,然後運行程序處理數據。程序.data區段有2個地址,一個是Flash中的load address(也稱為LMA,Load Memory Address),一個是RAM中的runtime address(也稱為VMA ,Virtual Memory Address)。
連結腳本裡需要指定.data區段的加載地址和運行時地址,彙編代碼需要複製.data從Flash到RAM。
0x02 指定加載地址LMA
VMA運行時地址就是標籤的地址。在之前的示例中,為.data區段指定了VMA。LMA加載地址沒有顯式指定,默認等同於運行時地址。程序直接從flash上執行時,這樣是沒有問題的。如果數據放到RAM上執行,LMA對應Flash、VMA對應RAM。看連結腳本:
SECTIONS { . = 0x00000000; .text : { * (.text); } flash_sdata = .; ❶ . = 0xA0000000; ram_sdata = .; ❷ .data : AT (flash_sdata) { * (.data); }; ram_edata = .; ❸ data_size = ram_edata - ram_sdata; ❹}
❶
在Flash內存裡,僅挨著代碼段,放數據data段,flash_sdata表示數據段的開始地址。
❷
數據段在RAM中的開始地址就是RAM的基地址。AT關鍵字指定Flash中數據段的地址。
❸ ❹
數據段的大小的計算,即RAM中數據段的結束地址、開始地址的差值。
0x04 賦值.data到RAM
從Flash中複製數據到RAM,需要下述信息:
Flash中的數據起始地址flash_sdata、RAM中的數據起始地址ram_sdata、.data區段的大小data_size。彙編代碼如下,注意copy操作的實現:
.dataval1: .4byte 10 @ First number 用於求和的第一個數val2: .4byte 30 @ Second number 用於求和的第二個數result: .space 4 @ 1 byte space for result 存放結果的空間 .global _start .text @;; Copy data to RAM. 複製Flash中的數據到RAM_start: ldr r0, =flash_sdata ldr r1, =ram_sdata ldr r2, =data_sizecopy: ldrb r4, [r0], #1 strb r4, [r1], #1 subs r2, r2, #1 bne copy @;; Add and store result. 計算加和 並存放結果 ldr r0, =val1 @ r0 = &val1 ldr r1, =val2 @ r1 = &val2 ldr r2, [r0] @ r2 = *r0 ldr r3, [r1] @ r3 = *r1 add r4, r2, r3 @ r4 = r2 + r3 ldr r0, =result @ r0 = &result str r4, [r0] @ *r0 = r4stop: b stop
GDB 單步調試:
從https://gitee.com/huawei_liteos_studio/arm_assembly/tree/master/DataInRAM檢出示例代碼工程,使用LiteOS Studio打開工程。編譯、開始調測,我們打開build目錄下面的asm文件,並且分欄展示,F10單步調試,單步調試如之前操作。
點擊查看內存,輸入起始內存地址0xA000000,長度輸入100,可以打開查看內存窗口。
可以看到0xA0000000處的值為0x0A=10 0xA0000004處的值為0x1E=30. 從Flash處複製了數據。
查看內存
界面如下:
0x05 參考資料
http://www.bravegnu.org/gnu-eprog/data-in-ram.html