開發(fā)人員喜歡相信運(yùn)行他們軟件的微處理器會(huì)忠實(shí)地遵循他們創(chuàng)建的程序流程,并按照預(yù)期無限期地運(yùn)行。事實(shí)是,有時(shí)事情會(huì)出錯(cuò),程序會(huì)被忽略。出現(xiàn)這種情況有許多可能的原因,例如覆蓋了數(shù)組的邊界,在初始化之前使用了指針,或者許多其他可能的原因。當(dāng)發(fā)生這種情況時(shí),嵌入式開發(fā)人員恢復(fù)系統(tǒng)的最有用的技術(shù)之一是用可以捕獲故障的東西來填充未使用的內(nèi)存。
有多種可能性可以填充未使用的內(nèi)存。第一個(gè)是重置向量位置。如果事情出了差錯(cuò),CPU將加載重置向量,程序?qū)念^開始。這將更像是應(yīng)用程序的一種軟的、不受控制的終止,幾乎沒有關(guān)于原因的調(diào)試信息。硬件將處于不確定狀態(tài),無法保證系統(tǒng)能從復(fù)位狀態(tài)中正?;謴?fù)。
第二種可能更合適的行為是將一個(gè)已知的中斷向量放在空內(nèi)存中。在這種情況下,當(dāng)事情變得非常糟糕時(shí),應(yīng)用程序有機(jī)會(huì)捕獲事件并提供一些線索,如CPU寄存器狀態(tài),以了解發(fā)生了什么。這使得開發(fā)人員可以重現(xiàn)和調(diào)試原因,而不是盲目猜測(cè)。
如果對(duì)調(diào)試信息不感興趣,可以使用的第三種選擇是用暫?;蜣D(zhuǎn)移到自身指令來填充存儲(chǔ)器。這將具有停止微控制器運(yùn)行的效果。這種技術(shù)的優(yōu)點(diǎn)是防止微控制器失控并繼續(xù)錯(cuò)誤地執(zhí)行代碼。相反,一切都停止了,值得信賴的看門狗定時(shí)器(每個(gè)嵌入式開發(fā)人員都會(huì)啟用,我希望如此)通過超時(shí)和執(zhí)行系統(tǒng)硬復(fù)位來拯救我們。
最后一個(gè)不推薦的選擇是用胡言亂語填充內(nèi)存。選擇一個(gè)位模式,如0x55、0xAA、0xAA55,并期待最好的結(jié)果。在這種情況下,填充存儲(chǔ)器實(shí)際上并不是為了提高應(yīng)用程序的健壯性,而是為了提供除0xFF之外的已知值,以便執(zhí)行ROM校驗(yàn)和。在網(wǎng)上簡單搜索一下就發(fā)現(xiàn)了一些巧妙的位模式比如0xDEADC0DE,0xDEADBEEF等等。
現(xiàn)在有許多不同的方法來用特定的位模式填充內(nèi)存。它們主要屬于兩個(gè)不同的類別;基于IDE或鏈接器。在IDE實(shí)現(xiàn)中,隱藏在屬性菜單深處的是一個(gè)“填充內(nèi)存”的選項(xiàng)。根據(jù)IDE和工具鏈的不同,可能會(huì)有額外的選項(xiàng)來設(shè)置特定的模式,或者工具可以自行決定。當(dāng)選擇“填充內(nèi)存”選項(xiàng)時(shí),大多數(shù)IDE工具要求開發(fā)人員選擇將要填充的內(nèi)存范圍。這反過來又迫使嵌入式開發(fā)人員不斷地監(jiān)視應(yīng)用程序在。鏈接器的文本部分。
基于鏈接器的方法為開發(fā)人員提供了更加靈活地定制填充解決方案的能力。例如,使用GNU工具鏈,可以創(chuàng)建一個(gè)包含F(xiàn)ILL()鏈接器命令的新部分輸出。向該命令傳遞應(yīng)該用于填充存儲(chǔ)器的位模式。從這個(gè)內(nèi)存段中,可以使用原點(diǎn)和長度函數(shù)來獲得將要被填充的內(nèi)存段的大小。允許用位模式自動(dòng)填充存儲(chǔ)空間,而不需要開發(fā)者管理。以下是可以找到一個(gè)帶有名為m_text的. text部分的GNU鏈接器的填充部分的例子。
.fillsection :
{
FILL(0xAA55AA55);
. = ORIGIN(m_text) + LENGTH(m_text) – 1;
BYTE(0xAA)
} > m_text
空內(nèi)存的結(jié)果是,在查看編譯期間生成的內(nèi)存文件時(shí),請(qǐng)求的位模式會(huì)填滿內(nèi)存:
S記錄中的位模式
使用鏈接器文件的一個(gè)優(yōu)點(diǎn)是,項(xiàng)目可以配置為在填充內(nèi)存和不填充內(nèi)存的鏈接器之間切換。使用內(nèi)存填充的缺點(diǎn)之一是每個(gè)內(nèi)存位置都被寫入。這意味著,如果你試圖調(diào)試應(yīng)用程序,每次更改代碼時(shí),你都必須等待所有閃存寫入,即使應(yīng)用程序不會(huì)影響它。這可能會(huì)給實(shí)施階段增加大量時(shí)間。因此,內(nèi)存填充應(yīng)該在開始時(shí)設(shè)置,并作為任何代碼提交的一部分,但仍然提供為調(diào)試啟用和禁用它的能力。請(qǐng)記住,開發(fā)人員希望盡可能多地使用這種內(nèi)存填充來捕捉任何意外的行為。
用中斷向量或停止命令正確地實(shí)現(xiàn)填充命令可以增加軟件系統(tǒng)的完整性。如果出現(xiàn)錯(cuò)誤指針、單事件擾亂或其他問題,導(dǎo)致應(yīng)用程序從意外的存儲(chǔ)位置開始執(zhí)行代碼,則填充位模式可以將程序執(zhí)行引導(dǎo)回已知位置,在該位置,嵌入式開發(fā)人員進(jìn)行適當(dāng)?shù)腻e(cuò)誤處理過程可以恢復(fù)系統(tǒng)。每個(gè)IDE和MCU實(shí)現(xiàn)該功能的方式略有不同,但通常不會(huì)比查看如何使用FILL命令的鏈接器數(shù)據(jù)表復(fù)雜多少。