2012-02-16 71 views
5

首先一些背景。當出於任何原因的固件崩潰(例如堆棧溢出,損壞的函數指針...)時,它可能發生,它跳到某處並開始執行一些代碼。這遲早會導致看門狗復位。 MCU將重置,我們回到正軌。除非......避免意外的固件覆蓋

什麼,當我們有一個寫入閃存(例如引導程序)代碼?現在可能會發生我們不小心直接跳入閃存編寫代碼 - 跳過所有檢查。在監督人員咆哮之前,最終會損壞固件。這正是我發生的事情。

現在,有些人可能會說 - 解決導致我們甚至跳進寫代碼的根本錯誤。那麼,當你正在開發時,你會不斷地改變代碼。即使目前在那裏沒有這樣的錯誤,明天可能會有。此外,沒有代碼是無bug的 - 或者至少不是我的。

所以現在我正在做一些交叉檢查。我有一個名爲'wen'的變量,我在通常的檢查之前將其設置爲0xa5(例如,檢查以確保目標有效)。然後在做實際的擦除或寫之前,我檢查'wen'是否真的被設置爲0xa5。否則這意味着我們不小心跳進了寫作代碼。成功寫入'文'後清除。我已經在C中完成了它,並且它運行良好。但是,仍然存在輕微的理論上的機會腐敗將會發生,因爲從'wen'這個最終檢查的指示很少,直到寫入SPMCR寄存器。

現在我想通過把這個檢查到組裝,在寫SPMCR和SPM指令之間,以改善這一點。

__asm__ __volatile__ 
( 
    "lds __zero_reg__, %0\n\t" 
    "out %1, %2\n\t" 
    "ldi r25, %3\n\t" 
    "add __zero_reg__, r25\n\t" 
    "brne spm_fail\n\t" 
    "spm\n\t" 
    "rjmp spm_done\n\t" 
    "spm_fail: clr __zero_reg__\n\t" 
    "call __assert\n\t" 
    "spm_done:" 
    : 
    : "i" ((uint16_t)(&wen)), 
     "I" (_SFR_IO_ADDR(__SPM_REG)), 
     "r" ((uint8_t)(__BOOT_PAGE_ERASE)), 
     "M" ((uint8_t)(-ACK)), 
     "z" ((uint16_t)(adr)) 
    : "r25" 
); 

還沒有試過的代碼呢,明天就會那樣做。你有沒有看到任何問題?你如何解決這個問題?

回答

3

一種技術我所看到的是,以確保立即字節之前你的閃存寫入程序會引發某種看門狗超時,或者復位處理器。這樣,就不可能執行導致閃存寫入功能的隨機數據,而只是「陷入」該功能。

您可能需要重置,以確保指令正確解釋前,有一些NOP指令。

您的驗證功能已經從開始運行的技術,看起來像一個很好的,假設你清除wen變量一旦你做到了寫。

+0

是的,成功寫入後會清除wen。 這個對__assert的調用實際上觸發了看門狗復位(加上它記錄了關於觸發它的一些信息)。 很高興聽到人們實際上使用這種方法:) – Stefan 2012-02-17 07:01:47

2

我不確定爲什麼你需要有能力在你的引導程序中寫入閃存。我們的引導加載程序可以,因爲它可以通過串口更新應用程序。因此,我們通過確保加載程序不包含任何寫入閃存的代碼,消除了無意寫入的可能性。下載的代碼是包含要寫入的圖像的相同包中的頭文件。板載圖像具有存儲的編程算法的校驗和,並在運行之前對其進行驗證。

如果你正在寫內部生成的東西,那麼我會看看硬件相關的聯鎖。如果先前已將特定離散輸出引腳設置爲ON,則只允許寫入。要回答「IP跳過檢查怎麼辦」的問題?你可以分兩部分來完成。首先爲算法設置一些關鍵變量。 (要寫入的地址 - 將初始化的內容保存到無效的內存中,並且只在寫入之前的獨立調用中正確設置,然後讓寫入功能檢查您的硬件互鎖。在中斷中執行其中一個啓用步驟,或者對計時器作出響應,如果你有惡意IP,那麼這些東西不可能以正確的順序被擊中。

如果您的IP真的可以跳到任何地方,可能無法防止無意的寫入。你所希望的最好的就是你確保到達那裏的唯一途徑也設置了成功寫作所需的一切。

+0

我正在做同樣的事情(通過UART更新)。在應用程序和引導程序中都有寫入代碼。所以他們可以交叉更新對方,並且我還在閃存中存儲了一些配置。 我不知道你有什麼樣的uC,但是我擁有的不能從RAM執行代碼,所以上傳寫入代碼不是一種選擇。 其實我正在使用類似的程序,你說的與HW聯鎖。這是我在設置問題時試圖解釋的問題......看起來我做得不好:) – Stefan 2012-02-17 18:09:43

+0

@Stefan:小心從應用程序更新引導加載程序。擦除和寫入之間的功率損耗會發生什麼?糟糕,您的引導程序已經消失,並且您已經堵塞了您的設備。作爲飛思卡爾HCS08項目,引導加載程序實際上設置了CPU寄存器以防止其被覆蓋,並且應用程序無法寫入閃存中的這些頁面。注意安全。 – tomlogic 2012-02-17 18:49:54

+0

@tomlogic:我有2個編寫代碼 - 在應用程序和引導程序中 - 他們可以交叉更新對方。 uC默認爲應用程序代碼。如果我無法更新bootloader,我仍然會喚醒應用程序並可以重試。 引導程序使用一個技巧。它將應用程序代碼從最高頁面寫入最低頁面。在寫入第一個頁面(實際上是最高頁面)之前,它會將'跳轉到引導加載程序'寫入頁面0.現在唯一的問題是它不應該寫入最後一頁(頁面0)。所以機會非常小,最終導致不可恢復的閃光。 – Stefan 2012-02-18 00:21:15