姓名:童琪凱? ? 學號:19020100176? ? 學院:電子工程學院
轉(zhuǎn)自:https://blog.csdn.net/qq_35028262/article/details/105449130?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_utm_term~default-0.base&spm=1001.2101.3001.4242
【嵌牛導讀】在學習嵌入式過程中,需要一定的程序技巧加以支持
【嵌牛鼻子】嵌入式有關(guān)的編程知識
【嵌牛提問】如何編寫標準宏荞驴?
【嵌牛正文】
宏定義
@ 預處理指令#define 聲明一個常數(shù)不皆,用以表明1年中有多少秒(忽略閏年問題)
#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
#define 語法的基本知識(例如:不能以分號結(jié)束,括號的使用熊楼,等等)
預處理器將為你計算常數(shù)表達式的值霹娄,因此直接寫出你如何計算一年中有多少秒而不是計算出實際的值,是更清晰而沒有代價的鲫骗。
意識到這個表達式將使一個16位機的整型數(shù)溢出-因此要用到長整型符號L,告訴編譯器這個常數(shù)是的長整型數(shù)犬耻。
如果你在你的表達式中用到UL(表示無符號長整型),那么你有了一個好的起點执泰。記住枕磁,第一印象很重要。
@ 寫一個"標準"宏MIN 术吝,這個宏輸入兩個參數(shù)并返回較小的一個计济。
#define MIN(A,B) ((A) <= (B) ? (A) : (B))
標識 #define 在宏中應用的基本知識。這是很重要的排苍。因為在 嵌入(inline)操作符 變?yōu)闃藴蔆的一部分之前沦寂,宏是方便產(chǎn)生嵌入代碼的唯一方法,對于嵌入式系統(tǒng)來說淘衙,為了能達到要求的性能传藏,嵌入代碼經(jīng)常是必須的方法。
三重條件操作符的知識彤守。這個操作符存在C語言中的原因是它使得編譯器能產(chǎn)生比if-then-else更優(yōu)的代碼漩氨,了解這個用法是很重要的。
懂得在宏中小心地把參數(shù)用括號括起來
用這個問題開始討論宏的副作用遗增,例如:當你寫下面的代碼時會發(fā)生什么事叫惊?
least = MIN(*p++, b);
@ 關(guān)鍵字volatile有什么含意?并給出三個不同的例子。
這是區(qū)分C程序員和嵌入式系統(tǒng)程序員的最基本的問題做修。搞嵌入式的家伙們經(jīng)常同硬件霍狰、中斷抡草、RTOS等等打交道,所有這些都要求用到volatile變量蔗坯。不懂得volatile的內(nèi)容將會帶來災難康震。
一個定義為volatile的變量是說這變量可能會被意想不到地改變,這樣宾濒,編譯器就不會去假設這個變量的值了腿短。精確地說就是,優(yōu)化器在用到這個變量時必須每次都小心地重新讀取這個變量的值绘梦,而不是使用保存在寄存器里的備份橘忱。下面是volatile變量的幾個例子:
并行設備的硬件寄存器(如:狀態(tài)寄存器)
一個中斷服務子程序中會訪問到的非自動變量(Non-automatic variables)
多線程應用中被幾個任務共享的變量
使用經(jīng)驗
調(diào)試的時候會發(fā)現(xiàn)有時變量值看不到,就需要用?volatile?定義變量卸奉,告訴編譯器不要優(yōu)化掉钝诚。
@ 內(nèi)存管理MMU的作用
內(nèi)存分配和回收
內(nèi)存保護
內(nèi)存擴充
地址映射
ROM是只讀存儲器,掉電不丟失
RAM是讀寫存儲器榄棵,掉電丟失
SRAM:CPU的緩存就是SRAM凝颇,靜態(tài)的隨機存取存儲器,
加電情況下疹鳄,不需要刷新拧略,數(shù)據(jù)不會丟失
DRAM,動態(tài)隨機存取存儲器最為常見的系統(tǒng)內(nèi)存瘪弓,需要不斷刷新辑鲤,才能保存數(shù)據(jù)
SDRAM:同步動態(tài)隨機存儲器,即數(shù)據(jù)的讀取需要時鐘來同步杠茬。
-128~127.
編譯生成的是目標文件(object *.o);
編譯過程中對于外部符號不做任何解釋和處理弛随。外部符號對應的就是“符號”
鏈接生成的是可執(zhí)行程序
鏈接將會解釋和處理外部符號瓢喉。外部符號對應的是地址
@?Linux驅(qū)動程序流程及功能。
設備驅(qū)動程序的功能:
對設備初始化和釋放
把數(shù)據(jù)從內(nèi)核傳送到硬件和從硬件讀取數(shù)據(jù)
讀取應用程序傳送給設備文件的數(shù)據(jù)和回送應用程序請求的數(shù)據(jù)
檢測和處理設備出現(xiàn)的錯誤
冒泡排序 — 時間換空間
快速排序,堆排序 — 空間換時間
ISO2110走贪,IEEE802,IEEE802.2
值傳遞
指針傳遞
嚴格來看坠狡,只有一種傳遞,值傳遞遂跟,指針傳遞也是按值傳遞的逃沿,復制的是地址婴渡。
@ 進程間通信方式:管道、命名管道凯亮、消息隊列边臼、共享內(nèi)存、信號假消、信號量柠并、套接字。
管道( pipe ):管道是一種半雙工的通信方式富拗,數(shù)據(jù)只能單向流動臼予,而且只能在具有親緣關(guān)系的進程間使用。進程的親緣關(guān)系通常是指父子進程關(guān)系媒峡。
有名管道 (named pipe) :有名管道也是半雙工的通信方式瘟栖,但是它允許無親緣關(guān)系進程間的通信。
信號量( semophore ) :信號量是一個計數(shù)器谅阿,可以用來控制多個進程對共享資源的訪問半哟。它常作為一種鎖機制,防止某進程正在訪問共享資源時签餐,其他進程也訪問該資源寓涨。因此,主要作為進程間以及同一進程內(nèi)不同線程之間的同步手段氯檐。
消息隊列( message queue ) : 消息隊列是由消息的鏈表戒良,存放在內(nèi)核中并由消息隊列標識符標識。消息隊列克服了信號傳遞信息少冠摄、管道只能承載無格式字節(jié)流以及緩沖區(qū)大小受限等缺點糯崎。
信號 ( sinal ) : 信號是一種比較復雜的通信方式,用于通知接收進程某個事件已經(jīng)發(fā)生河泳。
共享內(nèi)存( shared memory ) :共享內(nèi)存就是映射一段能被其他進程所訪問的內(nèi)存沃呢,這段共享內(nèi)存由一個進程創(chuàng)建,但多個進程都可以訪問拆挥。共享內(nèi)存是最快的 IPC 方式薄霜,它是針對其他進程間通信方式運行效率低而專門設計的。它往往與其他通信機制纸兔,如信號兩惰瓜,配合使用,來實現(xiàn)進程間的同步和通信汉矿。
套接字( socket ) : 套接字也是一種進程間通信機制崎坊,與其他通信機制不同的是,它可用于不同及其間的進程通信洲拇。
(1)痹届、函數(shù)調(diào)用時,先求出實參表達式的值打月,然后帶入形參队腐。而使用帶參數(shù)的宏只是進行簡單的字符替換。
(2)奏篙、函數(shù)調(diào)用是在程序運行時處理的柴淘,分配臨時的內(nèi)存單元;而宏展開則是在編譯時進行的秘通,在展開時并不分配內(nèi)存單元为严,不進行值的傳遞處理,也沒有“返回值”的概念肺稀。
(3)第股、對函數(shù)中的實參和形參都要定義類型,二者的類型要求一致话原,應進行類型轉(zhuǎn)換夕吻;而宏不存在類型問題,宏名無類型繁仁,它的參數(shù)也是無類型涉馅,只是一個符號代表,展開時帶入指定的字符即可黄虱。宏定義時稚矿,字符串可以是任何類型的數(shù)據(jù)。
(4)捻浦、調(diào)用函數(shù)只可得到一個返回值晤揣,而宏定義可以設法得到幾個結(jié)果。
(5)朱灿、使用宏次數(shù)多時昧识,宏展開后源程序長,因為每次展開一次都使程序增長母剥,而函數(shù)調(diào)用不使源程序變長。
(6)形导、宏替換不占運行時間环疼,只占編譯時間;而函數(shù)調(diào)用則占運行時間(分配單元朵耕、保留現(xiàn)場炫隶、值傳遞、返回)