MMU,cache,裸機(jī)嵌入式C編程還有帶操作系統(tǒng)的編程
通過CMSIS-utrealos項(xiàng)目中的CTBUG調(diào)試,使我對(duì)裸機(jī)C編程加深了認(rèn)識(shí)。那個(gè)BUG調(diào)試,現(xiàn)象是出現(xiàn)hard fault,但是fault出現(xiàn)地的匯編指令看著貌似沒啥問題,解決一處的fault后,其他處又出現(xiàn)fault了。最后我看到原來是fault出現(xiàn)地的指令中源地址錯(cuò)誤了,源地址應(yīng)該在數(shù)據(jù)段中,卻意外地落到了代碼段中。這個(gè)現(xiàn)象我忙活了半天才找到。
然后通過看那奇怪的源地址,對(duì)照它四周的現(xiàn)象代碼,最終才發(fā)現(xiàn)是我的demo C文件中的頭文件包含錯(cuò)誤了(這個(gè)錯(cuò)誤顯然易見,但是在review代碼時(shí)卻沒發(fā)現(xiàn))。導(dǎo)致該問題指令的那個(gè)源地址計(jì)算錯(cuò)誤,落到了代碼段中。
調(diào)試時(shí)間花了不少,最后這段調(diào)試經(jīng)歷使我對(duì)裸機(jī)C編程發(fā)生了興趣,從而認(rèn)真讀了armcm3編程權(quán)威指南一書。
還有王SAN那個(gè)棧溢出調(diào)試,王SAN本來還想研究是否是內(nèi)存分配方面的錯(cuò)誤,但是和我最后討論后,結(jié)果用arm權(quán)威指南及我們組項(xiàng)目筆記文章中的那個(gè)棧溢出調(diào)試方法,很快就找出BUG原因了。
我的那個(gè)BUG調(diào)試告訴我ARMCM3上沒有MMU那種保護(hù)功能,也沒有操作系統(tǒng)(linux操作系統(tǒng)中的那種開啟MMU保護(hù)以及虛存訪問權(quán)限檢查的功能這里沒有)。雖然有MPU,但是這個(gè)是可選器件。
linux下的MMU及虛存保護(hù),使得我們PC機(jī)編程中,可以不用C指針時(shí),及時(shí)將其置為空從而起到保護(hù)程序的作用,但是回到裸機(jī)下,尤其沒MMU部件時(shí),空指針的作用意義在這里都消失了。這也就是嵌入式編程的復(fù)雜性。
但是通過嵌入式編程,尤其王san那個(gè)BUG調(diào)試,畢竟能加深對(duì)C編程底層調(diào)試的認(rèn)識(shí)。比如現(xiàn)在嵌入式調(diào)試,可以直接通過觀看內(nèi)存地址處的數(shù)據(jù)信息是否異常,各個(gè)匯編指令和cpu寄存器值變化是否異常,嵌入式調(diào)試使人真正回到了二進(jìn)制時(shí)代。
不可否認(rèn),MMU和虛擬存儲(chǔ)的設(shè)計(jì),真正簡化了上層程序的設(shè)計(jì),提供給用戶一個(gè)好的開發(fā)應(yīng)用程序的界面。詳情見uclinux與linux的不同一文。
但是由于MMU的存在必要,這延緩了CPU訪問內(nèi)存的速度。為了解決這一問題,又帶來cache,還有TLB(之前作linux性能檢證搞過TLB的性能分析一文可以參考)。而ARM CM3中沒有這一切,畢竟cortex-m3和A5的應(yīng)用范圍是不同的。