一、系統(tǒng)相關(guān)
波特率
1)定義:
波特率表示每秒鐘傳送的碼元符號(hào)的個(gè)數(shù),是衡量數(shù)據(jù)傳送速率的指標(biāo),它用單位時(shí)間內(nèi)載波調(diào)制狀態(tài)改變的次數(shù)來(lái)表示。
在信息傳輸通道中,攜帶數(shù)據(jù)信息的信號(hào)單元叫碼元,每秒鐘通過(guò)信道傳輸?shù)拇a元數(shù)稱(chēng)為碼元傳輸速率,簡(jiǎn)稱(chēng)波特率。波特率是傳輸通道頻寬的指標(biāo)。
2)計(jì)算:
波特率115200 = 115200 (位/秒)
以最普通的串口(起始位+8位數(shù)據(jù)+停止位)為例:
除以10,得到的是每秒字節(jié)數(shù):
波特率115200 = 115200 (位/秒) = 11520 (字節(jié)/秒)
再除以 1024,就是每秒 KB 數(shù):
波特率115200 = 115200 (位/秒) = 11.25 (KB/秒)
如果有一位奇偶校驗(yàn)位,就應(yīng)該除以 11,得到的是每秒字節(jié)數(shù)。
最后:
波特率115200 = 115200 (位/秒) = 10.27 (KB/秒)
備注:
二進(jìn)制環(huán)境下,波特率 = 比特率。
哈佛結(jié)構(gòu)
哈佛結(jié)構(gòu)是一種將程序指令存儲(chǔ)和數(shù)據(jù)存儲(chǔ)分開(kāi)的存儲(chǔ)器結(jié)構(gòu),它的主要特點(diǎn)是將程序和數(shù)據(jù)存儲(chǔ)在不同的存儲(chǔ)空間中,即程序存儲(chǔ)器和數(shù)據(jù)存儲(chǔ)器是兩個(gè)獨(dú)立的存儲(chǔ)器,每個(gè)存儲(chǔ)器獨(dú)立編址、獨(dú)立訪問(wèn),目的是為了減輕程序運(yùn)行時(shí)的訪存瓶頸。
程序指令儲(chǔ)存和數(shù)據(jù)儲(chǔ)存分開(kāi),數(shù)據(jù)和指令的儲(chǔ)存可以同時(shí)進(jìn)行,可以使指令和數(shù)據(jù)有不同的數(shù)據(jù)寬度,如Microchip公司的PIC16芯片的程序指令是14位寬度,而數(shù)據(jù)是8位寬度。
其中,51單片機(jī)和stm32都為哈佛結(jié)構(gòu)。
馮諾依曼結(jié)構(gòu)
馮·諾依曼結(jié)構(gòu),又稱(chēng)為普林斯頓體系結(jié)構(gòu),是一種將程序指令存儲(chǔ)器和數(shù)據(jù)存儲(chǔ)器合并在一起的存儲(chǔ)器結(jié)構(gòu)。取指令和取操作數(shù)都在同一總線上,通過(guò)分時(shí)復(fù)用的方式進(jìn)行;缺點(diǎn)是在高速運(yùn)行時(shí),不能達(dá)到同時(shí)取指令和取操作數(shù),從而形成了傳輸過(guò)程的瓶頸。由于程序指令存儲(chǔ)地址和數(shù)據(jù)存儲(chǔ)地址指向同一個(gè)存儲(chǔ)器的不同物理位置,因此程序指令和數(shù)據(jù)的寬度相同。
其中,msp430、ARM7、freescale等單片機(jī)為馮諾依曼結(jié)構(gòu)。
改進(jìn)型哈佛結(jié)構(gòu)
改進(jìn)型哈佛結(jié)構(gòu)雖然也使用兩個(gè)不同的存儲(chǔ)器:程序存儲(chǔ)器和數(shù)據(jù)存儲(chǔ)器,但它把兩個(gè)存儲(chǔ)器的地址總線合并了,數(shù)據(jù)總線也進(jìn)行了合并,即原來(lái)的哈佛結(jié)構(gòu)需要4條不同的總線,改進(jìn)后需要兩條總線。
ARM處理器的工作模式
一個(gè)程序運(yùn)行在不同的模式下面的時(shí)候,能夠運(yùn)行的ARM處理器的指令是不一樣的,能夠訪問(wèn)的ARM處理器的寄存器都是不一樣的。這些模式為:
特權(quán)模式
除用戶(hù)模式外,其它模式均為特權(quán)模式(Privileged ModesARM內(nèi)部寄存器和一些片內(nèi)外設(shè)在硬件設(shè)計(jì)上只允許(或者可選為只允許)特權(quán)模式下訪問(wèn)。此外,特權(quán)模式可以自由的切換處理器模式,而用戶(hù)模式不能直接切換到別的模式。
異常模式
特權(quán)模式中除系統(tǒng)(system)模式之外的其他5種模式又統(tǒng)稱(chēng)為異常模式。它們除了可以通過(guò)在特權(quán)下的程序切換進(jìn)入外,也可以由特定的異常進(jìn)入。比如硬件產(chǎn)生中斷信號(hào)進(jìn)入中斷異常模式,讀取沒(méi)有權(quán)限數(shù)據(jù)進(jìn)入中止異常模式,執(zhí)行未定義指令時(shí)進(jìn)入未定義指令中止異常模式。其中管理模式也稱(chēng)為超級(jí)用戶(hù)模式,是為操作系統(tǒng)提供軟中斷的特有模式,正是由于有了軟中斷,用戶(hù)程序才可以通過(guò)系統(tǒng)調(diào)用切換到管理模式。
硬件權(quán)限級(jí)別:系統(tǒng)模式 > 異常模式 > 用戶(hù)模式
對(duì)于Linux而言,一般的應(yīng)用程序運(yùn)行在User模式,而Linux內(nèi)核運(yùn)行在SVC模式,即Supervisor模式
(1)用戶(hù)模式:
用戶(hù)模式是用戶(hù)程序的工作模式,它運(yùn)行在操作系統(tǒng)的用戶(hù)態(tài),它沒(méi)有權(quán)限去操作其它硬件資源,只能執(zhí)行處理自己的數(shù)據(jù),也不能切換到其它模式下,要想訪問(wèn)硬件資源或切換到其它模式只能通過(guò)軟中斷或產(chǎn)生異常。
(2)系統(tǒng)模式:
系統(tǒng)模式是特權(quán)模式,不受用戶(hù)模式的限制。用戶(hù)模式和系統(tǒng)模式共用一套寄存器,操作系統(tǒng)在該模式下可以方便的訪問(wèn)用戶(hù)模式的寄存器,而且操作系統(tǒng)的一些特權(quán)任務(wù)可以使用這個(gè)模式訪問(wèn)一些受控的資源。
說(shuō)明:用戶(hù)模式與系統(tǒng)模式兩者使用相同的寄存器,都沒(méi)有SPSR(Saved Program Statement Register,已保存程序狀態(tài)寄存器),但系統(tǒng)模式比用戶(hù)模式有更高的權(quán)限,可以訪問(wèn)所有系統(tǒng)資源。
(3)一般中斷模式:
一般中斷模式也叫普通中斷模式,用于處理一般的中斷請(qǐng)求,通常在硬件產(chǎn)生中斷信號(hào)之后自動(dòng)進(jìn)入該模式,該模式為特權(quán)模式,可以自由訪問(wèn)系統(tǒng)硬件資源。
(4)快速中斷模式:
快速中斷模式是相對(duì)一般中斷模式而言的,它是用來(lái)處理對(duì)時(shí)間要求比較緊急的中斷請(qǐng)求,主要用于高速數(shù)據(jù)傳輸及通道處理中。
(5)管理模式(Supervisor,SVC):
管理模式是CPU上電后默認(rèn)模式,因此在該模式下主要用來(lái)做系統(tǒng)的初始化,軟中斷處理也在該模式下。當(dāng)用戶(hù)模式下的用戶(hù)程序請(qǐng)求使用硬件資源時(shí),通過(guò)軟件中斷進(jìn)入該模式。
說(shuō)明:系統(tǒng)復(fù)位或開(kāi)機(jī)、軟中斷時(shí)進(jìn)入到SVC模式下。
(6)終止模式:
中止模式用于支持虛擬內(nèi)存或存儲(chǔ)器保護(hù),當(dāng)用戶(hù)程序訪問(wèn)非法地址,沒(méi)有權(quán)限讀取的內(nèi)存地址時(shí),會(huì)進(jìn)入該模式,linux下編程時(shí)經(jīng)常出現(xiàn)的segment fault通常都是在該模式下拋出返回的。
(7)未定義模式:
未定義模式用于支持硬件協(xié)處理器的軟件仿真,CPU在指令的譯碼階段不能識(shí)別該指令操作時(shí),會(huì)進(jìn)入未定義模式。
流水線機(jī)制
傳統(tǒng)的單片機(jī)(如8051)中,處理器只有完成一條指令的讀取和執(zhí)行后,才會(huì)開(kāi)始下一條指令的處理,所以PC(程序計(jì)數(shù)器)總是指向正在執(zhí)行的指令。而ARM體系架構(gòu)中則引入了流水線的概念。
到ARM7為止的ARM處理器使用了簡(jiǎn)單的三級(jí)流水線。三級(jí)流水線使用三個(gè)工位,將指令的處理分為三個(gè)階段,分別為取指、譯碼和執(zhí)行。取指:從存儲(chǔ)器中裝載;譯碼:識(shí)別將要被執(zhí)行的指令;執(zhí)行:處理指令并將結(jié)果寫(xiě)回寄存器。
Cortex-A9架構(gòu)基于先進(jìn)的推測(cè)型八級(jí)流水線
同步通信和異步通信
(1)同步通信要求接收端時(shí)鐘頻率和發(fā)送端時(shí)鐘頻率一致,發(fā)送端發(fā)送連續(xù)的比特流;異步通信時(shí)不要求接收端時(shí)鐘和發(fā)送端時(shí)鐘同步,發(fā)送端發(fā)送完一個(gè)字節(jié)后,可經(jīng)過(guò)任意長(zhǎng)的時(shí)間間隔再發(fā)送下一個(gè)字節(jié)。
(2)同步通信效率高;異步通信效率較低。
(3)同步通信較復(fù)雜,雙方時(shí)鐘的允許誤差較小;異步通信簡(jiǎn)單,雙方時(shí)鐘可允許一定誤差。
(4)同步通信可用于點(diǎn)對(duì)多點(diǎn);異步通信只適用于點(diǎn)對(duì)點(diǎn)。同步是阻塞模式,異步是非阻塞模式。
異步通信:異步通信中的接收方并不知道數(shù)據(jù)什么時(shí)候會(huì)到達(dá),收發(fā)雙方可以有各自自己的時(shí)鐘。發(fā)送方發(fā)送的時(shí)間間隔可以不均,接收方是在數(shù)據(jù)的起始位和停止位的幫助下實(shí)現(xiàn)信息同步的。這種傳輸通常是很小的分組,比如一個(gè)字符為一組,為這個(gè)組配備起始位和結(jié)束位。所以這種傳輸方式的效率是比較低的,畢竟額外加入了很多的輔助位作為負(fù)載,常用在低速的傳輸中。典型通信為串口通信。
同步通信:同步通信中雙方使用頻率一致的時(shí)鐘,它的分組相比異步則大得多,稱(chēng)為一個(gè)數(shù)據(jù)幀,通過(guò)獨(dú)特的bit串作為啟停標(biāo)識(shí)。發(fā)送方要以固定的節(jié)奏去發(fā)送數(shù)據(jù),而接收方要時(shí)刻做好接收數(shù)據(jù)的準(zhǔn)備,識(shí)別到前導(dǎo)碼后馬上要開(kāi)始接收數(shù)據(jù)了。同步這種方式中因?yàn)榉纸M很大,很長(zhǎng)一段數(shù)據(jù)才會(huì)有額外的輔助位負(fù)載,所以效率更高,更加適合對(duì)速度要求高的傳輸,當(dāng)然這種通信對(duì)時(shí)序的要求也更高。典型通信為:SPI和IIC。
軟實(shí)時(shí)和硬實(shí)時(shí)
硬實(shí)時(shí)與軟實(shí)時(shí)之間最關(guān)鍵的差別在于,軟實(shí)時(shí)只能提供統(tǒng)計(jì)意義上的實(shí)時(shí)。例如,有的應(yīng)用要求系統(tǒng)在95%的情況下都會(huì)確保在規(guī)定的時(shí)間內(nèi)完成某個(gè)動(dòng)作,而不一定要求100%。在許多情況下,這樣的“軟性”正確率已經(jīng)可以達(dá)到用戶(hù)期望的水平。比如,用戶(hù)在操作DVD播放機(jī)時(shí),只要98%的情況都能正常播放,用戶(hù)可能就滿(mǎn)意了;而發(fā)射衛(wèi)星、控制核反應(yīng)堆的應(yīng)用系統(tǒng),這些系統(tǒng)的實(shí)時(shí)性必須達(dá)到100%,是絕對(duì)不允許出現(xiàn)意外。
ARM體系的CPU兩種工作狀態(tài)
ARM狀態(tài):arm處理器工作于32位指令的狀態(tài),所有指令均為32位。
THumb狀態(tài):arm執(zhí)行16位指令的狀態(tài),即16位狀態(tài)。
THumb指令集是arm指令集的一個(gè)子集,是針對(duì)代碼密度問(wèn)題而提出的,它具有16位的代碼寬度。與等價(jià)的32位代碼相比較,THumb指令集在保留32位代碼優(yōu)勢(shì)的同時(shí),大大的節(jié)省了系統(tǒng)的存儲(chǔ)空間。
另外:ARM的M系列主要用Thumb指令,ARM9和A系列主要用ARM指令。
Linux文件權(quán)限
權(quán)限數(shù)字對(duì)應(yīng)權(quán)限組說(shuō)明:
總共分為4部分
【文件或文件夾】【owner權(quán)限】【group權(quán)限】【others權(quán)限】
【文件是-,文件夾是d】【r/w/x相加】【r/w/x相加】【r/w/x相加】
如 chmod 777 xxx.xxx 就是說(shuō)xxx文件的權(quán)限為可讀可寫(xiě)可執(zhí)行且對(duì)所有用戶(hù)有效。
ls -l a 查看a文件的權(quán)限
二、軟件相關(guān)
各種變量類(lèi)型所占內(nèi)存
大端小端問(wèn)題
所謂的大端模式,就是高位字節(jié)排放在內(nèi)存的低地址端,低位字節(jié)排放在內(nèi)存的高地址端。(ARM)
所謂的小端模式,就是低位字節(jié)排放在內(nèi)存的低地址端,高位字節(jié)排放在內(nèi)存的高地址端。(x86平臺(tái)、c51)
小端模式 :強(qiáng)制轉(zhuǎn)換數(shù)據(jù)不需要調(diào)整字節(jié)內(nèi)容,1、2、4字節(jié)的存儲(chǔ)方式一樣。
大端模式 :符號(hào)位的判定固定為第一個(gè)字節(jié),容易判斷正負(fù)。
判斷大小端:
#include #include typedef union{ short a; //定義一個(gè)short變量,因?yàn)樗甲止?jié)數(shù)為2,便于與長(zhǎng)度為2的char數(shù)組內(nèi)存對(duì)齊 char b[2];//定義一個(gè)char數(shù)組,因?yàn)閏har變量所占字節(jié)數(shù)為1,char[2]就是長(zhǎng)度為2了 }test; int main(int argc, char *argv[]) { test ut; ut.a = 0x1234; printf("ut.b[0]:%02x/r/n",ut.b[0]);//若打印0x12即為小端,打印出0x34則為大端 printf("ut.b[1]:%02x/r/n",ut.b[1]); printf("ut:%d/r/n",sizeof(ut)); return 0; }
大小端轉(zhuǎn)換實(shí)例:
//16位 #define BSWAP_16(x) / (uint_16)((((uint_16)(x) & 0x00ff) <<8) | / (((uint_16)(x) & 0xff00) >> 8) / )
volatile關(guān)鍵詞
volatile是一個(gè)類(lèi)型修飾符(type specifier),就像我們熟悉的const一樣,它是被設(shè)計(jì)用來(lái)修飾被不同線程訪問(wèn)和修改的變量;volatile的作用是作為指令關(guān)鍵字,確保本條指令不會(huì)因編譯器的優(yōu)化而省略,且要求每次直接讀值。
簡(jiǎn)單地說(shuō)就是防止編譯器對(duì)代碼進(jìn)行優(yōu)化。
例如,在多線程,或者是存在中斷的場(chǎng)景下:
buff[0]=0x01; buff[0]=0x02; buff[0]=0x03; buff[0]=0x04;
編譯器可能會(huì)將上面4行代碼優(yōu)化為1行 buff[0]=0x04;
但是,可能我們想要的結(jié)果就是需要連續(xù)運(yùn)行著四段代碼,因?yàn)橛锌赡茉诹硗獾木€程或中斷訪問(wèn)buff[0]時(shí),我們需要得到一個(gè)實(shí)時(shí)的結(jié)果,可能是0x01,也可能是0x03,但如果不加volatile關(guān)鍵詞,可能得到的值永遠(yuǎn)都是0x04。
do{}while(0)的技巧用法
(1)在后面要加分號(hào),使調(diào)用如同函數(shù)
在定義宏后,使用do{}while(0)如果不加分號(hào)會(huì)直接報(bào)錯(cuò)
(2)避免括號(hào)等使用因素對(duì)實(shí)際運(yùn)行造成影響
例如,定義一個(gè)宏:
#define foo(x) bar(x); baz(x)
然后你可能這樣調(diào)用:
foo(wolf);
這將被宏擴(kuò)展為:
bar(wolf); baz(wolf);
這的確是我們期望的正確輸出。下面看看如果我們這樣調(diào)用:
if (!feral) foo(wolf);
那么擴(kuò)展后可能就不是你所期望的結(jié)果。上面語(yǔ)句將擴(kuò)展為:
if (!feral) bar(wolf); baz(wolf);
顯而易見(jiàn),這是錯(cuò)誤的。如果使用do while寫(xiě)法即可避免這個(gè)問(wèn)題:
if (!feral) do { bar(wolf); baz(wolf); } while (0);
等價(jià)于:
if (!feral) { bar(wolf); baz(wolf); }
(3)避免空宏引起的warning
內(nèi)核中由于不同架構(gòu)的限制,很多時(shí)候會(huì)用到空宏,在編譯的時(shí)候,空宏會(huì)給出warning,為了避免這樣的warning,就可以使用do{}while(0)來(lái)定義空宏:
#define EMPTYMICRO do{}while(0)
(4)避免使用goto對(duì)程序流進(jìn)行統(tǒng)一的控制
有些函數(shù)中,在函數(shù)return之前我們經(jīng)常會(huì)進(jìn)行一些收尾的工作,比如free掉一塊函數(shù)開(kāi)始malloc的內(nèi)存,goto一直都是一個(gè)比較簡(jiǎn)便的方法:
int foo() { somestruct* ptr = malloc(...); dosomething...; if(error) { goto END; } dosomething...; if(error) { goto END; } dosomething...; END: free(ptr); return 0; }
由于goto不符合軟件工程的結(jié)構(gòu)化,而且有可能使得代碼難懂,所以很多人都不倡導(dǎo)使用,那這個(gè)時(shí)候就可以用do{}while(0)來(lái)進(jìn)行統(tǒng)一的管理:
int foo() { somestruct* ptr = malloc(...); do{ dosomething...; if(error) { break; } dosomething...; if(error) { break; } dosomething...; }while(0); free(ptr); return 0; }
這里將函數(shù)主體使用do()while(0)包含起來(lái),使用break來(lái)代替goto,后續(xù)的處理工作在while之后,就能夠達(dá)到同樣的效果。
(5)定義一個(gè)單獨(dú)的函數(shù)塊來(lái)實(shí)現(xiàn)復(fù)雜的操作:
當(dāng)你的功能很復(fù)雜,變量很多你又不愿意增加一個(gè)函數(shù)的時(shí)候,使用do{}while(0);,將你的代碼寫(xiě)在里面,里面可以定義變量而不用考慮變量名會(huì)同函數(shù)之前或者之后的重復(fù)。
版權(quán)聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接和本聲明。
本文鏈接:https://blog.csdn.net/sinat_30146065/article/details/105428988
-
嵌入式
+關(guān)注
關(guān)注
5154文章
19708瀏覽量
318164
發(fā)布評(píng)論請(qǐng)先 登錄
【硬件方向】名企面試筆試真題:大疆創(chuàng)新校園招聘筆試題
嵌入式應(yīng)用中常見(jiàn)的安全威脅

嵌入式機(jī)器學(xué)習(xí)的應(yīng)用特性與軟件開(kāi)發(fā)環(huán)境

嵌入式主板的概述與發(fā)展

C語(yǔ)言筆試題
LDO在嵌入式系統(tǒng)中的應(yīng)用 常見(jiàn)LDO故障及解決方法
什么是嵌入式人工智能

嵌入式系統(tǒng)開(kāi)發(fā)與硬件的關(guān)系 嵌入式系統(tǒng)開(kāi)發(fā)常見(jiàn)問(wèn)題解決
利用能量收集技術(shù)實(shí)現(xiàn)永久運(yùn)行的嵌入式系統(tǒng)

什么是嵌入式?一文讀懂嵌入式主板
嵌入式主板是什么意思?嵌入式主板全面解析
嵌入式開(kāi)發(fā)常見(jiàn)問(wèn)題排查

評(píng)論