寫程式的人對於 printf( )應該不陌生,用它印變數真是再方便不過了,除了印文字還可以印數字,其中包含了各種格式,整數、浮點、十六進位等一應俱全。但若遇到沒辦法使用 printf( )的情況時,該怎麼辦呢?
有種情況是在微處理器(MCU, Micro Controller Unit)的flash memory很小只有幾K下發生,當程式碼已經寫到瀕臨memory的邊界,只要再多寫幾行code記憶體就會爆掉,尤其是 printf( )只要一加進去,記憶體馬上就爆了,這真的很令人傷腦筋。
printf 很佔空間
平常寫PC的程式,記憶體動輒以Giga Byte來計算,大家也許不會感覺到memory空間的限制;而MCU的程式,由於記憶體空間只有4K~16KByte等級,因此程式大小錙銖必計能省則省。每呼叫一次函式,就會產生一堆的push/pop指令,如果參數很多則占用的記憶體數量就很可觀,不僅如此printf還用了動態參數,讓參數的數量可以任意變動(如下方範例),為了彈性便需要吃掉更多空間,在記憶體捉襟見肘的情況下,若沒有printf該如何來做debug呢?
參數數量(圖片來源:實作派提供)
Simulator用不上
一定有人會想若printf不能用,那就改用模擬器Simulator的step run單步執行就好了,但如果一切都如此美好就好了。因為開發環境內的模擬器,它再厲害也只能模擬正常情況,而我這裡是要處理偶發性的異常事件,必須要抓到問題才能避免MCU當機。例如故意將USB或I2C短路,造成程式異常,這可是模擬器沒辦法模擬的。
那為何要故意造成USB或I2C短路呢?是因為實際在run的情況下,這些周邊通訊電路,就是有可能因為EMI而有機會發生異常。由於,不是每次EMI都會發生干擾,但我們並沒有太多時間守株待兔,所以直接將I2C短路讓它異常,效果直接而且狀況跟被EMI干擾的結果相同。
GPIO要好好利用
既然我們需要某種output來做為debug的工具,若不能用printf那還有甚麼方法可以做輸出呢?還好微處理器的IO(Input/Output)很多,只要設定得當,就可以利用GPIO(General Purpose Input Output)來輸出電壓當作debug訊號,之後再接上示波器就能看到電壓的變化,所以可以預先自行定義GPIO的high與low各是甚麼意義,這就可以當作debug的輸出。
由於GPIO只有High與Low兩種狀態,若想要在超過兩個不同地方安插debug訊號,可以使用下面的寫法,用來觀察程式是否有跑到預期的地方。這裡我以CY7C68013A為例,利用GPIO PortC的PC.0的腳位來輸出電壓變化。
如下方範例,我寫了三種脈衝,分別會產生1根pulse、2根pulse以及3根pulse,將它們放在程式中的不同位置,來代表程式中的不同階段,萬一有function當掉,看示波器的波形就馬上能知道是哪個函式出問題。
只需不到短短一分鐘...
輸入您的信箱與ID註冊即可享有一切福利!
會員福利
免費電子報
會員搶先看
主題訂閱
好文收藏