隨著單片機硬件的發展,其中的RAM和flash越做越大。MCU在實際的使用中,通常程序都是運行在flash上的,RAM的高速空間并沒有得到充分的利用,如果我們的程序需要運行的更快,系統有更好的實時性,我們可以考慮將這部分代碼放到RAM中運行,下邊我們將以STMF103RCT6作為舉例,向大家介紹在keil環境中如何使程序在RAM中運行。
在STMF103RCT6單片機上有兩個存儲空間,一個是片上的FLASH(相當于硬盤),有256K,另一個就是SRAM(相當于內存),有64K。
下邊是使用keil生成項目時的項目大小信息:
Code:程序代碼不分大小
RO-data:程序定義的常量
PW-data:已經初始化的的全局變量
ZI-data:未初始化的全局變量,以及初始化為0的變量
下面給出三個值:
RO Size= Code + RO Data (程序占用FLASH空間的大小).
RW Size-RW Data +ZI Data (運行時程序占用RAM空間的大小).
ROM Size=Code + RO Data + RW Data (燒寫時程序占用FLASH空間的大小).
我們都知道,在燒寫程序的時候,需要燒寫bin文件或者hex文件到STM32的flash當中,三部分:cole, RO-data和RW-data,為什么不包含ZI數據呢,是因為ZI數據都是0,沒必要包含,只要程序運行之前將ZI數據所在的區域(這一區域在RAM中)一律清零即可。包含進去反而浪費flash存儲空間。
STM32上電啟動以后, cpu根據boot0和boot1的硬件引腳決定從flash還是ram中啟動,默認是從flash中啟動;啟動之后會搬運rw-data到ram,但是不會搬運code;也就是說 cpu執行的代碼是在flash中讀取的,而不是在ram中。
快速新建一個項目,使一個LED燈閃爍。
實現函數如下:
在main函數中:
通過查看xx.msp文件,可以看到LEDToggle函數編譯后的地址是放在flash中的
那么如何將LEDToggle函數放在STM32的SRAM中:
1.打開編譯后生成的xx.sct文件,修改該文件
同時可以看到
Flash起始地址:0x08000000
RAM起始地址:0x20000000
2.在xx.sct文件中,定義一個RAMCODE的section,放在RW_IRAM1執行區域(0x20000000-0x00002000)。
3.修改代碼
方法一:用#pragma arm section code = "RAMCODE" 和 #pragma arm section將需要放到SRAM中的程序包括起來;
然后編譯,重新打開xx.msp文件,可以看到LEDToggle函數編譯后的地址已經在SRAM中
方法二:在需要放到RAM中的函數前,用__attribute__((section("RAMCODE")))聲明該函數放在RAMCODE section中。
然后編譯,重新打開xx.msp文件,可以看到LEDToggle函數編譯后的地址同樣在SRAM中
注意事項:
注意使用方法一時,該函數中調用到的所有函數也要放到RAMCODE section中,#pragma arm section code=“RAMCODE ”和#pragma arm section中可以包含多段代碼。