單片(pian)機MCU如何實現讓部(bu)分代碼運(yun)行在RAM中
時(shi)間:2019-06-06 來源:華清(qing)遠(yuan)見
隨(sui)著單片機硬件(jian)的發展,其中(zhong)(zhong)的RAM和(he)flash越做越大。MCU在實(shi)際的使用(yong)中(zhong)(zhong),通常(chang)程序都(dou)是運行(xing)在flash上(shang)的,RAM的高速(su)空間并沒有(you)得到(dao)充分的利用(yong),如(ru)果我們(men)(men)的程序需要運行(xing)的更快(kuai),系統(tong)有(you)更好的實(shi)時性,我們(men)(men)可以考慮將這部分代碼放到(dao)RAM中(zhong)(zhong)運行(xing),下邊我們(men)(men)將以STMF103RCT6作為舉例,向大家介紹在keil環境(jing)中(zhong)(zhong)如(ru)何使程序在RAM中(zhong)(zhong)運行(xing)。
在(zai)STMF103RCT6單(dan)片機上(shang)有兩(liang)個(ge)存(cun)儲(chu)空間(jian),一(yi)個(ge)是片上(shang)的(de)FLASH(相當(dang)于(yu)(yu)硬(ying)盤),有256K,另一(yi)個(ge)就是SRAM(相當(dang)于(yu)(yu)內存(cun)),有64K。
下邊是使用keil生成項目時的項目大小信息:

Code:程序代碼不分(fen)大(da)小
RO-data:程序定義(yi)的常(chang)量
PW-data:已經初始(shi)化的(de)(de)的(de)(de)全局(ju)變量
ZI-data:未初始化(hua)的(de)全局變量(liang),以及初始化(hua)為0的(de)變量(liang)
下面給出三個值:
RO Size= Code + RO Data (程序占用(yong)FLASH空間的(de)大小).
RW Size-RW Data +ZI Data (運(yun)行(xing)時程序(xu)占用RAM空間的(de)大小).
ROM Size=Code + RO Data + RW Data (燒寫時程序占用FLASH空間(jian)的大小).
我(wo)們都(dou)知道,在(zai)燒(shao)寫程序的時候,需(xu)要燒(shao)寫bin文件或者hex文件到STM32的flash當中,三部分:cole, RO-data和RW-data,為(wei)(wei)什(shen)么不包(bao)含ZI數據(ju)呢,是因為(wei)(wei)ZI數據(ju)都(dou)是0,沒必要包(bao)含,只要程序運行之前將ZI數據(ju)所在(zai)的區(qu)域(這一區(qu)域在(zai)RAM中)一律清零即可。包(bao)含進去反而浪費flash存儲空間。
STM32上電啟(qi)動(dong)以(yi)后(hou), cpu根據boot0和boot1的硬件引(yin)腳決(jue)定從flash還是(shi)(shi)ram中(zhong)啟(qi)動(dong),默認是(shi)(shi)從flash中(zhong)啟(qi)動(dong);啟(qi)動(dong)之后(hou)會(hui)搬(ban)運(yun)rw-data到ram,但是(shi)(shi)不會(hui)搬(ban)運(yun)code;也就是(shi)(shi)說 cpu執行的代碼是(shi)(shi)在flash中(zhong)讀取(qu)的,而不是(shi)(shi)在ram中(zhong)。
快(kuai)速新建一個(ge)項目(mu),使一個(ge)LED燈閃爍。
實現函(han)數(shu)如下:

在main函數中:

通過查(cha)看(kan)xx.msp文(wen)件,可以看(kan)到(dao)LEDToggle函數編譯后的地址(zhi)是放在flash中(zhong)的

那么如何將LEDToggle函(han)數放在STM32的SRAM中:
1.打開編譯后生成的xx.sct文件(jian)(jian),修改該文件(jian)(jian)

同時可以看到
Flash起始(shi)地址:0x08000000
RAM起始地址:0x20000000
2.在(zai)xx.sct文件中,定義一個RAMCODE的section,放在(zai)RW_IRAM1執(zhi)行區域(0x20000000-0x00002000)。

3.修改代碼
方法一:用#pragma arm section code = "RAMCODE" 和 #pragma arm section將需要(yao)放(fang)到SRAM中的程序包(bao)括起來(lai);

然(ran)后編譯,重新打開xx.msp文件,可以看到LEDToggle函數編譯后的地址已(yi)經在SRAM中

方法二:在需(xu)要放到RAM中(zhong)的(de)函數(shu)前,用__attribute__((section("RAMCODE")))聲(sheng)明(ming)該函數(shu)放在RAMCODE section中(zhong)。

然后編譯,重(zhong)新打開(kai)xx.msp文(wen)件,可以(yi)看(kan)到LEDToggle函數(shu)編譯后的地址同樣在SRAM中(zhong)

注意事項:
注意使用(yong)方法(fa)一時,該函數中調用(yong)到(dao)(dao)的所(suo)有函數也要(yao)放到(dao)(dao)RAMCODE section中,#pragma arm section code=“RAMCODE ”和#pragma arm section中可以包含(han)多段代碼。

