文章總列表

Embedded System Studying note 12/19

埋 log 是很好用的方法, 為了提供高效率的 log 函數
我在 UART driver 上下了很多功夫, 除了用 interrupt driven 以外
還寫了一個 RING buffer, 讓資料寫進去, 可以之後慢慢送
配上 C standard library, 可以用 printf() 的感覺真的很好

不過在 BSS section 沒有填 0 的狀況下... 問題就不是用 log 那麼單純


----


我在 code 裡寫...

int (*a)(void);
int main() { ...}

這個 a 是 global variable, C 語言會假設 a 的初始值為 0
在 Win32/ Linux 底下, loader 會幫你做這些事, 把初始值填 0
但是 Embedded system 這些雜事得自己做...

如果不做會怎樣 ?

a 是一個 function pointer, 我很喜歡這樣寫...

if(a == 0)
/* do some initialization to a */
else
a();

在 a 沒有清成 0 的情況下, DRAM 的初始值根本就不知道 !!
本來該做的初始化就沒了, 於是 a() 會跳到哪裡?

1. 搞不好會跳到 data section, 裡面根本不是合法的指令
這時候 ARM 送我一個 undefied instruction 中斷...

2. 跳到 CPU 沒有定址的區段, 比如我的 SDRAM 只有 64MB, 他卻跳到 100MB
這時候 ARM 賞我一個 Abort 中斷...

3. 跳到 Address = 0, 跳到這裡系統會重新啟動, 於是我看到無限重新開機...


----


這種 bug 我也不知道怎麼抓... 在很長一段時間不堪其擾後, 我才開始研究...
我發現, 我用自己寫的 flash writer 把 code 寫進 Flash 以後
只要不斷電, 就可以正常開機

後來我知道原因, 因為我的 flash writer 會把記憶體的數值填 0
所以誤打誤撞完成某些部分的初始化...

要正確的 debug, 要拋開某些成見, 比如我認為某段 code 應該是正確無誤的...
假設某個地方是錯/對的, 然後設計個實驗去驗證他, 逐步找出原因

但是要做到這件事, 很難...
因為, 大部分的時候, 我只能沒有頭緒的找
起碼像這個 BSS section 沒有初始化的 bug, 我沒有太多選擇

最後我是回頭檢視一些我認為對的code, 才發現這件事


----


Debug 是一門藝術
我也還在學習, 怎麼有系統的做這件事

留言

這個網誌中的熱門文章

STM32 UART + DMA,使用HAL實作TX/RX,以及不定長度接收

幼犬書桌椅選擇心得 升降桌 兒童桌椅

CANON G3000 廢墨瓶改裝