嵌入式開發中的一些細節(dlmu2001

2021-04-02 07:55:38 字數 2372 閱讀 9667

從事開發一年多,發現到一些小細節,會影響到自己開發的效率,特總結如下,以免犯錯

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

嵌入式開發中的一些細節續(dlmu2001

7.關於區域性變數 區域性變數是在棧上分配的空間,只在函式內部有效,退出函式,空間就釋放了,看一下一下幾個例子 1 void dlmu malloc char buf 100 return void buf 2 void dlmu malloc char p char buf 100 p buf r...

嵌入式開發中的一些細節

從事開發一年多,發現到一些小細節,會影響到自己開發的效率,特總結如下,以免犯錯 1.標準c中str系列的函式中,0 有特殊的含義 字串結束 所以如果要操作具有0x00 有實際意義 的字串,不應該用該系列的函式。例 有字串 0nocookie 0nocache 0 本義是想用 0 來表示分隔符,分隔出...

Linux嵌入式開發的一些總結

宋立新email zjujoe yahoo.com 做了幾年 linux 底層嵌入式開發,有一些心得,這裡記錄下來,作為進一步學習 linux 之前的乙個總結。daily build nokia microsoft 等,都採用了該機制。是終端產品開發中乙個 best practise.其好處有 構建...