嵌入式學(xué)習(xí)(八)——嵌入式Linux設(shè)備應(yīng)用層開發(fā)

姓名:李萌怡? 學(xué)號:19020100103? 學(xué)院:電子工程學(xué)院

轉(zhuǎn)自:https://blog.csdn.net/weixin_44839882/article/details/108468131

【嵌牛導(dǎo)讀】:嵌入式系統(tǒng)分為硬件層氧急、驅(qū)動層、操作系統(tǒng)層和應(yīng)用層。要深入學(xué)習(xí)嵌入式系統(tǒng)班巩,應(yīng)用層開發(fā)是非常重要的部分亮钦。

【嵌牛鼻子】:應(yīng)用層? 文件結(jié)構(gòu)

【嵌牛提問】:Linux的文件結(jié)構(gòu)分為哪幾部分赫蛇?

【嵌牛正文】

1 應(yīng)用層與驅(qū)動層

要想學(xué)習(xí)嵌入式Linux應(yīng)用層的開發(fā)酷麦,首先要區(qū)分好應(yīng)用層和驅(qū)動層之間的關(guān)系甚负。我們在本科階段學(xué)習(xí)51等較簡單的單片機(jī)時霎挟,都是把應(yīng)用層和驅(qū)動層混在一個文件里寫的窝剖。比如拿下面的I2C程序為例:

#include<reg51.h>

#include<intrins.h>

#define uchar unsigned char

#define nop _nop_()

sbit sda = P2^1;//sda接在P2.1 ?

sbit scl = P2^0;//sda接在P2.0

void delay1()//用于每個語句間的延時

{

;//空語句

;

;

}

void delay(unsigned int i )//用于LED亮燈延時

{

while(i--);

}

/*scl在高電平期間,sda由高電平變成低電平時酥夭,I2C啟動*/

void start_24c02() ? //用于24C02的啟動

{

scl = 1;

delay1(); ?

sda = 1;

delay1();

sda = 0;

delay1();

}

/*scl在高電平期間赐纱,sda由低電平變成高電平時,I2C停止*/

void stop_24c02() //用于24c02啟動

{

sda = 0;

delay1();

scl = 1;

delay1();

sda = 1;

delay1();

}

/*scl在高電平期間熬北,sda變成低電平表示應(yīng)答*/

void ack_24c02() //24C02的應(yīng)答

{

uchar i = 0;

scl = 1;

delay1();

while((sda ==1)&&(i<200)) //(i<200)表示:如果期間不給應(yīng)答信號疙描,則程序會一直停在這里,為了避免長時間的等待應(yīng)答讶隐,在此處增加了一個延時

{

i++;

}

scl = 0;

delay1();

}

/*I2C總線初始化起胰,將I2C總線全部設(shè)置為高電平,來釋放總線*/

void init_24c02()//I2C總線的初始化

{

sda = 1;

delay1();? ?

scl = 0;

delay1();

}

/*讀取一個字節(jié)*/

uchar read_onebyte_24c02()

{

uchar i,date;

scl=0;

delay1();

sda=1;

delay1();

for(i = 0;i<8;i++) ? ? ? ? ? ?

{

scl = 1; ?

delay1();

date=(date<<1)|sda; ? ?

scl = 0;

delay1();

}

delay1();

return date;

}

/*寫一個字節(jié)*/

void write_onebyte_24c02(uchar date)

{

uchar i,temp;

temp = date;

for(i=0;i<8;i++)

{

temp = temp<<1;

scl = 0;

delay1();

sda =CY;? //temp 左移一位巫延,將移出的最高位字節(jié)放到PSW的CY中

delay1();

scl = 1;

delay1();

}

scl = 0;

delay1();

sda = 1;

delay1();

}

/*對從機(jī)的某一地址的某一位置寫入一個字節(jié)

1效五、找到要操作地址的從機(jī),同時進(jìn)行寫操作0xA0

2烈评、要寫入的位置add

3火俄、要寫入的數(shù)據(jù)dat

*/

void write_add_dat_24c02(uchar add,uchar dat)

{

start_24c02();

write_onebyte_24c02(0xA0); //進(jìn)行寫操作0XA0,24C02 的高四位地址為1010;后三位地址A2讲冠、A1瓜客、A0全部接地,所以為000,竿开;由于為寫操作谱仪,所以最后一位也為0

ack_24c02();

write_onebyte_24c02(add);

ack_24c02();

write_onebyte_24c02(dat);

ack_24c02();

stop_24c02();

}

/*讀取某地址的一個字節(jié)

1、找到要操作地址的從機(jī)否彩,同時進(jìn)行寫操作0xA0

2疯攒、要寫入的地址add

3、對選中地址的從機(jī)進(jìn)行讀操作 0xA1

4列荔、調(diào)用讀取一個字節(jié)函數(shù)read_onebyte_24c02()敬尺,進(jìn)行數(shù)據(jù)讀取

*/

uchar read_add_dat_24c02(uchar add)

{

uchar dat;

start_24c02();

write_onebyte_24c02(0xa0);

ack_24c02();

write_onebyte_24c02(add);

ack_24c02();

start_24c02();

write_onebyte_24c02(0xa1); //進(jìn)行讀操作0XA0,24C02 的高四位地址為1010枚尼;后三位地址A2、A1砂吞、A0全部接地署恍,所以為000,;由于為讀操作蜻直,所以最后一位為1

ack_24c02();

dat = read_onebyte_24c02();

ack_24c02();

stop_24c02();

return (dat);

}

void main()

{

init_24c02(); //初始化I2C

while(1)

{

write_add_dat_24c02(3,0x0f); //對地址3進(jìn)行寫入數(shù)據(jù)

delay(200);

write_add_dat_24c02(4,0xf0); //對地址4進(jìn)行寫入數(shù)據(jù)

delay(200);

P3 = read_add_dat_24c02(3); //讀取地址3的數(shù)據(jù)

delay(55000); //保持燈亮

P3 = read_add_dat_24c02(4); //讀取地址4的數(shù)據(jù)

delay(55000); //保持燈亮

}

}

該程序所要實現(xiàn)的功能是將數(shù)據(jù)0x0f和0xf0分別寫入地址3和地址4盯质。這個目標(biāo)可以分為兩部分執(zhí)行:第一部分是計算出要存儲的數(shù)據(jù)(由于該程序要存儲的數(shù)據(jù)已經(jīng)給出來了,就不用算了概而,但在實際工程中呼巷,這些數(shù)據(jù)一般是要自己獲取的),第二部分是按照I2C協(xié)議的時序?qū)⑦@些數(shù)據(jù)發(fā)送給硬件赎瑰。于是王悍,上面提到的第一部分被稱為應(yīng)用層開發(fā),第二部分被稱為驅(qū)動層開發(fā)乡范。

我們觀察以上示例代碼配名,發(fā)現(xiàn)作者還是很規(guī)矩地把驅(qū)動層程序編程了函數(shù)的形式(例如write_add_dat_24c02()),但應(yīng)用層和驅(qū)動層的程序終究還是存儲在同一個c文件中晋辆。而在Linux系統(tǒng)中渠脉,驅(qū)動層和應(yīng)用層分的很清楚,它們分別保存在兩個不同的文件中瓶佳。并且應(yīng)用層的程序運行在用戶空間中芋膘,驅(qū)動層的程序則是被編進(jìn)了Linux內(nèi)核里。在實際調(diào)用程序的過程中霸饲,由應(yīng)用層程序執(zhí)行數(shù)據(jù)計算等任務(wù)为朋,任務(wù)執(zhí)行完后通過一個接口將算好的數(shù)據(jù)發(fā)送給驅(qū)動層程序,最后由驅(qū)動層程序進(jìn)行硬件實現(xiàn)厚脉。這樣的分層有一個好處习寸,就是對于調(diào)用同一個硬件的應(yīng)用程序,他的驅(qū)動層可以不用修改傻工,只修改應(yīng)用層程序就可以了霞溪。

由于Linux操作系統(tǒng)現(xiàn)在發(fā)展的已經(jīng)比較完善了,很多硬件設(shè)備都能在網(wǎng)上找到寫好的驅(qū)動中捆,因此在進(jìn)行嵌入式Linux開發(fā)的過程中鸯匹,一般更多地進(jìn)行應(yīng)用層的開發(fā),只是當(dāng)找不到合適的驅(qū)動時泄伪,才會在現(xiàn)有驅(qū)動程序的基礎(chǔ)上進(jìn)行適當(dāng)改寫殴蓬,以使其適應(yīng)我們的硬件。

2 Linux的文件結(jié)構(gòu)

Linux下一切皆文件蟋滴。在Linux系統(tǒng)中染厅,不僅像文本文檔等傳統(tǒng)文件是文件痘绎,各種設(shè)備也可以被映射成一個文件。通過對設(shè)備文件進(jìn)行操作就可以實現(xiàn)對設(shè)備的操作肖粮。因此简逮,了解Linux的文件結(jié)構(gòu)非常重要。

2.1 目錄

目錄是用來保存其他文件節(jié)點(inode)號和名字的文件尿赚,目錄文件中的每項數(shù)據(jù)都指向一個文件的節(jié)點,刪除一個文件就相當(dāng)于刪除了目錄文件中對應(yīng)的節(jié)點項蕉堰。

那么問題來了凌净,什么是文件的節(jié)點(inode)呢?文件節(jié)點其實就是保存了文件的屬性的一個東西屋讶,這些屬性包括文件的創(chuàng)建/修改日期冰寻、訪問權(quán)限、文件位置皿渗、文件長度等等斩芭。Linux在尋找某文件或?qū)Γ硞€文件進(jìn)行操作時乐疆,不是去尋找文件的名字划乖,而是去尋找文件對應(yīng)的節(jié)點。

Linux系統(tǒng)中最常用的目錄之一就是家目錄挤土。Linux系統(tǒng)會為每個用戶創(chuàng)建一個家目錄琴庵。比如你的用戶名叫neil,那你的家目錄就是/home/neil/仰美。很多Linux系統(tǒng)迷殿,比如Ubuntu,都允許用~ 符號代替用戶的家目錄咖杂。然而庆寺,標(biāo)準(zhǔn)庫函數(shù)不能識別文件參數(shù)中的~ 符號,因此在程序中不要使用波浪線符號代替家目錄诉字。

所有目錄的最頂層是根目錄懦尝。在它下面包含了存放系統(tǒng)程序的/bin目錄、存放系統(tǒng)配置文件的/etc目錄奏窑、存放系統(tǒng)函數(shù)庫的/lib目錄和存放代表物理設(shè)備的設(shè)備文件的/dev目錄等等导披。

2.2 文件和設(shè)備

在Linux中,設(shè)備可以被映射成一個文件埃唯。例如撩匕,我們可以使用以下命令將CD-ROM驅(qū)動掛載為一個文件:

mount -t iso9660 /dev/hdc /mnt/cdrom

cd /mnt/cdrom

這時我們進(jìn)入到/mnt/cdrom下就可以查看CD-ROM中包含的目錄,只不過其中的目錄都是只讀的墨叛。

Linux中有3個比較重要的設(shè)備文件:/dev/console止毕、/dev/tty和/dev/null模蜡。

/dev/console

這個設(shè)備代表系統(tǒng)控制臺。錯誤信息和診斷信息通常會被發(fā)到這個設(shè)備扁凛。

/dev/tty

如果一個進(jìn)程有控制終端的話忍疾,文件/dev/tty就會作為控制終端的別名。但對于系統(tǒng)自動運行的進(jìn)程和腳本谨朝,它們就沒有控制終端卤妒,不需要訪問設(shè)備/dev/tty。

/dev/null

這個設(shè)備是“空”設(shè)備字币,所有寫向這個設(shè)備的輸出都會被丟棄则披,而讀這個設(shè)備會返回一個文件尾標(biāo)志。通常用于作復(fù)制空文件的源文件洗出,或?qū)⒉恍枰妮敵鲋囟ㄏ虻酱宋募?/p>

設(shè)備可以分為字符設(shè)備和塊設(shè)備士复,兩者的區(qū)別在于訪問設(shè)備時是否需要一次讀寫一整塊。字符設(shè)備通常是普通的設(shè)備翩活,塊設(shè)備通常是硬盤阱洪、SD卡等存儲設(shè)備。

————————————————

版權(quán)聲明:本文為CSDN博主「畢浩然」的原創(chuàng)文章菠镇,遵循CC 4.0 BY-SA版權(quán)協(xié)議冗荸,轉(zhuǎn)載請附上原文出處鏈接及本聲明。

原文鏈接:https://blog.csdn.net/weixin_44839882/article/details/108468131

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末利耍,一起剝皮案震驚了整個濱河市俏竞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌堂竟,老刑警劉巖魂毁,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異出嘹,居然都是意外死亡席楚,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進(jìn)店門税稼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來烦秩,“玉大人,你說我怎么就攤上這事郎仆≈混簦” “怎么了?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵扰肌,是天一觀的道長抛寝。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么盗舰? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任晶府,我火速辦了婚禮,結(jié)果婚禮上钻趋,老公的妹妹穿的比我還像新娘川陆。我一直安慰自己,他們只是感情好蛮位,可當(dāng)我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布较沪。 她就那樣靜靜地躺著,像睡著了一般失仁。 火紅的嫁衣襯著肌膚如雪购对。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天陶因,我揣著相機(jī)與錄音,去河邊找鬼垂蜗。 笑死楷扬,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的贴见。 我是一名探鬼主播烘苹,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼片部!你這毒婦竟也來了镣衡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤档悠,失蹤者是張志新(化名)和其女友劉穎廊鸥,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體辖所,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡惰说,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了缘回。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吆视。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖酥宴,靈堂內(nèi)的尸體忽然破棺而出啦吧,到底是詐尸還是另有隱情,我是刑警寧澤拙寡,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布授滓,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏褒墨。R本人自食惡果不足惜炫刷,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望郁妈。 院中可真熱鬧浑玛,春花似錦、人聲如沸噩咪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽胃碾。三九已至涨享,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間仆百,已是汗流浹背厕隧。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留俄周,地道東北人吁讨。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像峦朗,于是被迫代替她去往敵國和親建丧。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內(nèi)容