printf 沒有-MCU照樣能除錯debug

寫程式的人對於 printf( )應該不陌生,用它印變數真是再方便不過了,除了印文字還可以印數字,還包含了各種格式,整數、浮點、十六進位等等一應俱全。但若遇到沒辦法使用 printf( )的情況時,該怎麼辦呢?

阿信助教就碰到了,因為微處理器(MCU, Micro Controller Unit)的flash memory很小只有幾K而已,而我的程式碼已經寫到瀕臨memory的邊界,只要再多寫幾行code記憶體就會爆掉,尤其是 printf( )只要一加進去,記憶體馬上就爆了,這真的很傷腦筋。

printf 很佔空間

平常寫PC的程式,記憶體動輒以Giga Byte來計算,大家也許不會感覺到memory空間的限制;而MCU的程式,由於記憶體空間只有4K~16KByte等級,因此程式大小錙銖必計能省則省。每呼叫一次函式,就會產生一堆的push/pop指令,如果參數很多數量就很可觀,而printf還用了動態參數,吃掉更多空間,在記憶體捉襟見肘的情況下,如何來做debug呢?

//printf可使用不定個數的參數, 舉例如下
printf("%d",a);  //1個參數可以使用
printf("%d, %x",a,b);  //2個參數, 也可以

Simulator力有未逮

一定有人會想,若printf不能用那就改用模擬器的step run單步執行就好了,只是如果一切都如此美好就好了。因為開發環境內的模擬器Simulator它再厲害也只能模擬正常情況。

而我要處理的是偶發性的異常事件,避免MCU當機。例如故意將USB或I2C短路,造成程式異常,這可是模擬器沒辦法模擬的。

那為何我要故意將他們短路,因為實際在run的情況之下,這些周邊通訊電路就是有可能因為EMI而有機會發生異常,由於不是每次EMI都會發生干擾,我沒那麼多時間在那守株待兔,所以直接將I2C短路讓它異常,效果直接而且狀況跟被EMI干擾的結果相同。

善用GPIO

我們現在需要某種output來做為debug的工具,若不能用printf那還有甚麼方法可以做輸出呢? 還好微處理器的IO(Input/Output)很多,我們可以利用GPIO(General Purpose Input Output)來輸出電壓當作debug訊號,之後再接上示波器就能看到電壓的變化,所以你可以預先自行定義GPIO的high與low各是甚麼意義,這就可以當作debug的輸出。

但是High與Low只有兩種狀態,若想要在超過兩個不同地方安插debug訊號,可以使用下面的寫法,用來觀察程式是否有跑到預期的地方。這裡是以CY7C68013A為例,我利用GPIO PortC的PC.0的腳位來輸出電壓變化。

如下範例,三種脈衝分別擺在程式的不同位置,萬一有function當掉,看示波器的波形就馬上能知道是哪個函式出問題。

void test(void)
{

    func1();
    //產生一個脈衝
    IOC=(IOC&0xFE)| 0;
    IOC=(IOC&0xFE)| 1; //只有這裡是1, 其他都是0
    IOC=(IOC&0xFE)| 0;

    func2();
    //產生2個脈衝
    IOC=(IOC&0xFE)| 0;
    IOC=(IOC&0xFE)| 1; //這裡是1
    IOC=(IOC&0xFE)| 0;
    IOC=(IOC&0xFE)| 1; //這裡是1
    IOC=(IOC&0xFE)| 0;

    func3();
    //產生3個脈衝
    IOC=(IOC&0xFE)| 0;
    IOC=(IOC&0xFE)| 1; //這裡是1
    IOC=(IOC&0xFE)| 0;
    IOC=(IOC&0xFE)| 1; //這裡是1
    IOC=(IOC&0xFE)| 0;
    IOC=(IOC&0xFE)| 1; //這裡是1
    IOC=(IOC&0xFE)| 0;
}

光看程式可能很難想像結果,實際在示波器上看到的GPIO波形會是甚麼樣子呢?

就是如下圖這個樣子,框起來的地方分別是三種脈衝訊號的波形。當然如果你擔心脈衝訊號彼此太靠近,會容易搞不清楚到底誰跟誰是一組的話,就在脈衝前後多加幾個0(也就是low),就能把距離拉開了。

沒有 printf 就改用GPIO做為Debug訊號
沒有 printf 就改用GPIO做為Debug訊號

想當年

依稀記得多年前正在研究一個MCU的時候,由於它體積很小pin腳也少,少到連UART都不見了,這下可好,我變成瞎子了。所以當時我只能先用一根GPIO接上LED確認程式會動之後,再慢慢接出其他的GPIO來輔助debug,於是就變成了用一顆LED來除錯的工程師,現在想起來都覺得很瘋狂。但是面對時程的壓力,身為工程師當然是要想盡辦法達標,才能擦亮自己的招牌啊。

 

Be the first to comment

Leave a Reply

Your email address will not be published.


*