大多數現代嵌入式軟件應用程序都是從閃存存儲和執行的。閃存為基于微控制器的應用程序提供了一種廉價且快速的存儲介質。但這些應用程序通常是實時應用程序,其中執行時間和確定性行為至關重要。雖然閃存速度很快,但不如從RAM執行代碼快。為了加快基于flash的應用程序的執行時間,嵌入式開發人員可以有選擇地選擇關鍵功能并從RAM中執行它們,以獲得額外的速度提升。
為了從RAM執行功能,開發人員通常需要遵循三個步驟。這些措施包括:1.在鏈接器中為函數創建RAM區域;2.指定哪些函數應存儲在RAM中;3.啟動時將功能復制到RAM中。
讓我們詳細檢查這個過程。
步驟1–在鏈接器中為函數創建RAM區域
每個編譯器都有不同的語法來定義微控制器中的內存區域。對于今天的示例,我將使用基于GCC的Code Composer Studio和Texas儀器C2000系列使用的語法,因為我認為它提供了一個很好的示例。
當我們修改鏈接器文件以包含將從RAM執行的函數時,我們需要創建一個內存部分,該部分將指定函數從何處加載到RAM中,以及該函數從何處加載到RAM中。鏈接器文件將包含指定重要程序分配的區域,例如:
cinit
text
codestart
stack
constants
···
嵌入式開發人員需要為其RAM功能創建一個區域。這可以通過以下方法實現:
ramfuncs : LOAD = FLASHA,
RUN = RAML0,
LOAD_START (_RamfuncsLoadStart),
LOAD_END (_RamfuncsLoadEnd),
RUN_START (_RamfuncsRunStart),
LOAD_SIZE (_RamfuncsLoadSize),
PAGE = 0
如你所見,這是在RAM中創建一個名為ramfuncs的區域。RAM區域是從存儲在閃存A扇區中的函數加載的。它被指定在RAM區域RAML0中運行。然后有一些定義用于指定RAM函數的開始和結束位置以及它們的大小。這些值在步驟#3中很重要。
步驟2–指定哪些函數應存儲在RAM中
一旦我們在鏈接器中創建了一個RAM部分來存儲我們的函數,我們就需要向鏈接器指定哪些函數應該駐留在那里。最常用的方法是使用#pragma。一般來說,我們應該盡量避免在代碼中使用#pragma,因為這些功能依賴于編譯器。這意味著,如果編譯器發生更改,嵌入式開發人員很可能不得不修改#pragma行。就我們今天的目的而言,這沒有問題,因為我們無論如何都必須修改一個新的鏈接器文件,并且我們需要找出正確的語法來指定如何在內存區域中放置函數。
通常從RAM執行的一組常見功能是與訪問和控制閃存有關的功能。原因是當我們想要寫入或擦除閃存時,大多數微控制器不允許你同時從閃存執行代碼!所以,我們無論如何都需要把這些函數放到RAM中。我們可以使用類似于以下代碼的代碼將諸如Flash_Init之類的函數放入RAM區域:
#pragma CODE_SECTION(Flash_Init, “ramfuncs”);
從該語句中可以看出,我們正在使用自定義編譯器指定代碼_部分來指定函數Flash_Init應放置在鏈接器的ramfuncs區域中。此語句通常直接放在函數定義的上方,以提醒任何處理函數的開發人員它將被放入RAM中。(這也使得我們更容易找到是否應該決定函數不需要放在RAM中)。
步驟3–啟動時將功能復制到RAM中
該過程的最后一步是確保在微控制器啟動期間,我們想要在RAM中執行的功能實際上被復制到RAM中。最簡單的方法是使用memcpy。我通常在配置系統時鐘和中斷向量表后不久,但在初始化板載外圍設備和應用程序代碼之前,執行此復制。我在步驟1中提到,我們定義了幾個變量,這些變量稍后會派上用場。這些是RamfuncsRunStart、RamfuncsLoadStart和RamfuncsLoadSize。我們將使用以下語句將這些函數與memcpy一起復制到RAM中:
/* Copy time critical code and Flash setup code to RAM
* The RamfuncsLoadStart, RamfuncsLoadSize, and RamfuncsRunStart
* symbols are created by the linker. Refer to the project.cmd file.
*/
memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (Uint32)&RamfuncsLoadSize);
就這么簡單。一旦這樣做了,開發人員只需像平常一樣調用函數,函數在RAM中執行。
結論
當嵌入式開發人員從flash執行應用程序代碼時,他們可以通過將這些函數復制到RAM中來加速代碼的關鍵部分。從RAM執行功能將通過移除可能與從閃存訪問和加載指令相關的任何等待狀態來提高執行速度。這種額外的提升可以確保關鍵功能能夠以盡可能快的速度執行。正如我們所看到的,將函數加載到RAM中并執行它們是簡單而直接的(只要你做了一兩次)。