跟濤哥一起學嵌入式 第05集:一道程序改錯題,測出你的嵌入式功底

大家好,歡迎閱讀《跟濤哥一起學嵌入式》第05集,我們今天討論一下中斷的基本概念。

中斷,是嵌入式開發中經常使用的一個功能,也是嵌入式工程師必須要掌握的一個概念:CPU和外設通信時,一般都採用中斷的形式異步通信,可以大大提高CPU資源的利用率。而你對中斷的理解,到底有多少呢?不要急,一道程序改錯題,就可以測出你的嵌入式系統功底。

比如,我們在嵌入式ARM裸機平臺上,要實現一個MP3播放器,要求實現如下功能:當按鍵按下時,可以播放、暫停、播放下一首、上一首。爲此,我們設計一個按鍵中斷服務程序,當有按鍵發生時,我們去讀取按鍵的值,然後再根據按鍵值去執行不同的操作,設計的按鍵中斷函數如下:

int keyboard_isr(int irq_num)
{
    char *buf =(char *)malloc(512);
    int key_value = 0,

    key_value = keyboard_scan();
    if(key_value == 1)
    {
        mp3_decode(buf,"xx.mp3");
        sleep(10);
        mp3_play(buf);//play    
    }
    else if(key_value == 2)
        mp3_pause(buf);//pause
    else if(key_value == 3)
        mp3_next(buf);//next song
    else if(key_value == 4)
        mp3_prev(buf);//prev song
    else
    {
        printf("UND key !");
        return -1;
    }
    return 0;   
} 

這個中斷函數差不多有8處錯誤或設計不合理的地方,先不用急着往下翻,你可以自己先思考下,看自己能找出來幾處。

(此處應有掌聲,暫停2分鐘)...

好,我們接下來繼續分析,看看這個中斷函數到底有哪些錯誤。

錯誤1:中斷關鍵字irq

中斷函數沒有使用關鍵字標記。C標準中沒有定義中斷函數,對於普通的函數調用,編譯器會幫我們自動實現函數的調用棧及出棧入棧管理,而對於中斷函數,我們知道,中斷是可以隨時發生的,編譯器無法確定你中斷函數在哪裏發生,所以就無法幫你實現調用棧。那怎麼辦?難道我們程序員自己實現?沒關係,各大編譯器廠商一般會通過增加一些關鍵字,來幫助程序員實現中斷的現場保護代碼。因此,我們可以使用interrupt或irq關鍵字聲明即可

__irq int keyboard_isr(int irq_num);

錯誤2:malloc/free

對於MP3解碼的數據,我們使用malloc函數申請了一個動態堆內存來存放,但是函數退出後沒有及時釋放,造成了內存泄露。關於函數的調用棧、調用傳參過程、程序的內存分配,如果不是很明白,可以參考《C語言嵌入式Linux高級編程》第4期:堆棧管理。

錯誤3:C標準庫

嵌入式裸機開發中,一般很少使用C標準庫的。很多嵌入式編譯廠商、IDE開發商並沒有完全實現C標準庫,或者只是實現了一部分。所以在一般在嵌入式系統中,我們可以使用一個全局數組來代替malloc申請的動態內存。

錯誤4:中斷返回值

中斷函數由於沒有獨立的函數棧,是不能有返回值的。想一想:中斷函數在哪裏被調用、何時被調用,我們全都不知道,中斷函數的返回值應該傳給誰?它會破壞當前被中斷函數的函數棧。

錯誤5:中斷傳參

同上,中斷函數也是不能傳參的,傳給誰?誰調用了它?都是未知的。如果你給中斷函數傳參,也會破壞當前被中斷函數的函數棧。所以中斷函數正確的聲明形式應該爲:

__irq void keyboard_isr(void);

錯誤6:延時

避免耗時、延時、可重入函數,比如sleep、printf等。

錯誤7:短小精悍、快速反應

中斷函數要求快速響應,短小精悍。要速戰速決,快速撤離中斷現場,然後等待下一次中斷。如果你在中斷程序中,要做大量工作:播放、解碼、延時,十分不合理。這些耗時的工作應該放到中斷外去做。如Linux中的中斷處理,就放到了中斷下半部去做。

好了,以上都是我們在編寫中斷函數時必須要掌握的一些基礎知識和技能,接下來就賣個關子:想一想,上面這個函數的設計,還有什麼不合理之處?思考的越多,你就得到的越多。老司機要下車了,先帶你到這裏,剩下的就靠你了~

本文根據《C語言嵌入式Linux高級編程》視頻教程改編。《跟濤哥一起學嵌入式》,會持續跟大家分享嵌入式相關技術、學習方法、學習路線、求職面試等,有興趣可加入嵌入式技術交流羣:475504428,或微信公衆號:宅學部落(armlinuxfun)。如果想系統學習嵌入式C語言進階,可關注51CTO學院,我的個人主頁:http://edu.51cto.com/lecturer/10824150.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章