2015-08-09 37 views
0

我正在使用包含cortex-M4處理器的EK-LM4F120XL開發板。我也使用GCC-ARM-none-eabi作爲工具鏈。強制函數在進行函數調用之前恢復所有寄存器

我正在建立一個小型的愛好項目,它慢慢變成了一個操作系統。其中一個重要部分是我需要切換寄存器來切換進程。這發生在一箇中斷內部,這個特定的處理器確保所有的臨時寄存器(r0-r3,r12,lr)被推送到進程堆棧。因此,爲了繼續,我需要將r4-r11和SP的內容寫入內存中,我需要加載新進程的r4-r11,加載它的堆棧指針並返回。另外,lr值包含有關被中斷的進程的一些信息,所以我也需要來自該寄存器的信息。

所有這些工作,因爲我在彙編寫它。我將彙編函數直接鏈接到中斷,所以我完全可以控制寄存器發生了什麼。 C和內聯彙編的組合不起作用,因爲編譯器通常會將一些寄存器推送到堆棧,這是致命的。但操作系統正在不斷增長,環境變化也在不斷增長:現在還有一些需要改變的全局變量等等。所有這些在彙編中都是可行的,但是它成爲一個痛苦:程序集很難讀取和調試。所以我想要一個C/Assemlby組合。基本上我正在尋找類似這樣的東西:

void contextSwitch(void){ 
    //Figure out what the next process will be 
    //Change every variable that needs changing 

    // Restore register state to the moment of interrupt. The following function will not return in the sense that it will end the interrupt. 
    swapRegisters(oldProc, newProc); 
} 

然後在彙編中只寫入swapRegisters。有沒有辦法做到這一點?我的解決方案是最好的解決方案嗎?

+0

您正在編寫一個操作系統內核。這真的很難,尤其是中斷驅動程序。我不確定任何人都可以通過博客做什麼,甚至不知道你確切的問題是什麼。 –

+0

你的意思是我的問題不清楚? – Cheiron

+1

您的內核條目可以將所有寄存器保存到內存中,所以C端只需操作內存。出口然後恢復它。入口/出口處於組裝狀態。 – Jester

回答

0

沒有可移植的方法直接訪問C中的CPU寄存器;您將需要彙編程序,內聯彙編程序,編譯器內在函數或內核庫(使用匯編程序代碼)。

有關Cortex-M如何完成的詳細信息在其他地方已有很好的介紹,可能過於複雜,無法在此重複:在ARM信息中心網站here中描述了在Cortex-M4(F)中執行此操作的具體細節。除了FPU考慮之外,該方法對於Cortex-M3非常相似,提供了關於上下文切換的M3特定描述in this Embedded.com article。因爲不同的作者使得某些事情比其他人更清楚,或者給出更好或更直接適用的例子,所以你也永遠不會有足夠的解釋,here's another - 也是基於M3的,但是如果不使用FPU或者M4不使用FPU。和yet another example

+0

當我開始研究上下文切換器時,我閱讀了這些源代碼。它們的一個主要缺點是它們都沒有保證在內聯彙編發揮作用之前,哪些寄存器被推入堆棧並被C函數編輯。 GCC編譯器在內聯彙編命中之前幾乎總是將重要寄存器推入堆棧,因此我決定在彙編中完成整個事情。這些資源對我的問題沒有幫助。 – Cheiron

+0

@Cheiron:恢復上下文的函數不返回;堆棧指針的切換,寄存器的彈出以及最終的「bx lr」導致直接返回到目標上下文(因爲鏈接寄存器「LR」被彈出窗口修改,而「bx lr」修改PC) ,所以寄存器不會被交換函數exit epilogue修改,因爲它不會退出 - 它仍然是無法訪問的代碼。 – Clifford

相關問題