當前位置:
首頁 > 最新 > 嵌入式er日常!從事嵌入式開發一年多,發現一些小細節總結

嵌入式er日常!從事嵌入式開發一年多,發現一些小細節總結

從事開發一年多,發現到一些小細節,會影響到自己開發的效率,今天來總結一下:

1.標準C中str系列的函數中,"/0"有特殊的含義(字元串結束),所以如果要操作具有0x00(有實際意義)的字元串,不應該用該系列的函數。

例:有字元串"/0nocookie/0nocache/0",本義是想用"/0"來表示分隔符,分隔出nocookie和nocache,拷貝的時候用strcpy(Buf,"/0nocookie/0nocache/0"),結果Buf裡面什麼也沒有,因為strcpy碰到0x00就自動結束了。要實現這一個功能,應該改用memcpy,memcpy(Buf,"/0nocookie/0nocache/0",strlen("0nocookie0nocache0"));注意到strlen裡面我沒有再使用"/0"

2.在開發中,對內存的操作經常採用基址+偏移的方式,這時候相當於一塊大的內存多用,每次用只記錄相對於基址的偏移以及使用到的內存塊的長度,比如開一塊Buf,200k,用Buf+Start來存放某一個變數,Len表示該變數佔用的內存塊長度,這種用法的時候,兩個相鄰的變數之間可能沒有間隔,所以盡量不要再用str系列的函數。當然,保險的方法是人為的加入一些間隔

3.宏和常量

在開發中,為了利於以後的維護,經常對一些字元串,常數,以宏或者常量的形式定義,這二者是有區別的,宏是在預編譯的時候替代的,而常量是在運行時賦值的。所以如果對宏賦值,編譯器大部分能報錯,但是對常量賦值,編譯器不一定會報錯,但是運行時肯定有問題,應該避免編碼的時候對常量賦值。

4.全局變數的問題

有的系統支持聲明時賦值,但是為了提高可移植性,最好不要對全局變數進行聲明時賦值的操作,否則在有些系統上會產生意想不到的破壞效果。比較保險的做法是有個初始化函數處理所有的全局變數的賦初值工作。

順便插一句,在函數裡頭,最好養成先在開頭聲明所有變數,然後初始化,然後再操作的習慣,有些系統是不支持在函數的中間聲明變數的

5.動態內存的申請和釋放

這是嵌入式系統中一個比較頭疼的問題,有幾個問題需要注意1)系統是否支持動態內存,可支持多大的動態內存。為了提高移植性,建議將內存操作的函數封裝一下,實現內核代碼的與平台無關2)對動態內存,一般在分配後要檢查是否成功,以避免對空地址操作。一般是採用聲明時賦初值null,分配後檢查是否為NULL。3)內存釋放後最好對指針賦0,由於有的系統內存空間釋放以後,指針的值並沒有變,這時候如果指針不小心再拿來使用,會有很大的問題,所以在free以後強烈建議一定對指針賦空4)內存泄漏,在內存分配以後,必須保證以任何出口(途徑)退出,都要釋放申請的內存,很多系統在查找內存的釋放上都比較費力,所以在編碼的時候一定要檢查仔細。

另外,如果可以用數組代替的地方,盡量用數組代替,而不使用動態內存。對內存泄漏的查找要有步驟的進行,首先是重現泄漏,然後總結規律,根據規律打斷點,看相應的代碼。如果沒有任何規律,只好一步步排查,就是運行到某個節點,然後退出,沒有泄漏,即可以判斷泄漏出現在該節點之後。

6.關於sizeof

在C語言中,sizeof是個單目操作符,它以位元組的形式給出了操作數的存儲大小,可以用於數據結構類型或者變數1)int,long,double,float這些類型的大小不同的編譯器是不一樣的2)對指針使用sizeof操作符,每個指針都是一樣大小的,視編譯器不同而定,比如micorsoft的C,C++編譯器,指針總是4個位元組的,例:

char TestBuf[100];

int Len1,Len2,Len3;

char *p;

memset(TestBuf,0,100);

Len1=Len2=Len3 = 0;

strcpy(TestBuf,"testbuf");

Len1 = sizeof(TestBuf);

Len2 = strlen(TestBuf);

p = TestBuf;

Len3 = sizeof(p);

則Len1 = 100,Len2 = 7,Len3 = 4(在Microsoft c編譯器中)

在這一點中還要注意一個問題,就是數組名作為函數參數傳遞的時候,其實傳遞的是數組首地址,就是相當於指針,因此在函數中對該數組名sizeof,得到總是指針的長度。比如上例中,有個函數

void Test(char *p)

{

int Len4 = sizeof(p);

}

如果實參是數組名TestBuf,Len4也總等於4

3)聯合類型操作數的sizeof是其最大位元組成員的位元組數。結構類型操作數的sizeof是這種類型對象的總位元組數,包括任何墊補在內。

讓我們看如下結構:

struct a;

在某些機器上sizeof(a)=12,而一般sizeof(char)+ sizeof(double)=9。

這是因為編譯器在考慮對齊問題時,在結構中插入空位以控制各成員對象的地址對齊。如double類型的結構成員x要放在被4整除的地址。

4)枚舉類型一般當作int型處理,如Microsoft上,對枚舉變數用sizeof得4


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 嵌入式ARM 的精彩文章:

從一個不起眼的小公司逐漸成為半導體行業巨頭,Microchip CEO史蒂夫桑吉不一般的「擴張」之路
嵌入式Linux驅動開發基礎總結

TAG:嵌入式ARM |