?個人名片:
??作者簡介:學(xué)生
??個人主頁:妄北y??個人QQ:2061314755
??個人郵箱:2061314755@qq.com
??個人WeChat:Vir2021GKBS
??本文由妄北y原創(chuàng),首發(fā)CSDN??????
??座右銘:大多數(shù)人想要改造這個世界,但卻罕有人想改造自己。
專欄導(dǎo)航:
妄北y系列專欄導(dǎo)航:
C/C++的基礎(chǔ)算法:C/C++是一種常用的編程語言,可以用于實現(xiàn)各種算法,這里我們對一些基礎(chǔ)算法進行了詳細的介紹與分享。??????
QT基礎(chǔ)入門學(xué)習(xí):對QT的基礎(chǔ)圖形化頁面設(shè)計進行了一個簡單的學(xué)習(xí)與認識,利用QT的基礎(chǔ)知識進行了翻金幣小游戲的制作??????
Linux基礎(chǔ)編程:初步認識什么是Linux,為什么學(xué)Linux,安裝環(huán)境,進行基礎(chǔ)命令的學(xué)習(xí),入門級的shell編程。??????
Linux應(yīng)用開發(fā)基礎(chǔ)開發(fā):分享Linux的基本概念、命令行操作、文件系統(tǒng)、用戶和權(quán)限管理等,網(wǎng)絡(luò)編程相關(guān)知識,TCP/IP 協(xié)議、套接字(Socket)編程等,可以實現(xiàn)網(wǎng)絡(luò)通信功能。??????
Linux項目開發(fā):Linux基礎(chǔ)知識的實踐,做項目是最鍛煉能力的一個學(xué)習(xí)方法,這里我們會學(xué)習(xí)到一些簡單基礎(chǔ)的項目開發(fā)與應(yīng)用,而且都是畢業(yè)設(shè)計級別的哦。??????
非常期待和您一起在這個小小的互聯(lián)網(wǎng)世界里共同探索、學(xué)習(xí)和成長。?????? ?? 歡迎訂閱本專欄 ???
文章介紹:
??本篇文章對Linux驅(qū)動基礎(chǔ)學(xué)習(xí)的相關(guān)知識進行分享!??????
???在做單片機開發(fā)時,要讀取 GPIO 按鍵,我們通常是執(zhí)行一個循環(huán),不斷地檢測 GPIO 引腳電平有沒有發(fā)生變化。但是在 Linux 系統(tǒng)中,讀取 GPIO 按鍵要考慮到效率,引入了很多種方法:查詢方式(非阻塞)、休眠-喚醒(阻塞方式)、 poll 方式、異步通知方式。
如果您覺得文章不錯,期待你的一鍵三連哦,你的鼓勵是我創(chuàng)作動力的源泉,讓我們一起加油,一起奔跑,讓我們頂峰相見!??!??????
??感謝大家點贊??收藏?評論??
目錄:
目錄
一、APP 怎么讀取按鍵值
1.1?驅(qū)動的基本技能:
1.2 APP 開發(fā)的基本技能:
二、媽媽怎么知道孩子醒了
2.1 時不時進房間看一下:查詢方式
2.2 進去房間陪小孩一起睡覺,小孩醒了會吵醒她:休眠-喚醒
2.3 媽媽要干很多活,但是可以陪小孩睡一會,定個鬧鐘:poll 方式
2.4 媽媽在客廳干活,小孩醒了他會自己走出房門告訴媽媽:異步通知
三、APP 讀取按鍵的 4 種方法
3.1?查詢方式
3.2?休眠-喚醒方式
3.3??poll 方式
3.4 異步通知方式?
3.4.1 異步通知的原理:發(fā)信號
3.4.2?應(yīng)用程序之間發(fā)信號示例代碼
?四、驅(qū)動程序提供能力,不提供策略
一、APP 怎么讀取按鍵值
????????在做單片機開發(fā)時,要讀取 GPIO 按鍵,我們通常是執(zhí)行一個循環(huán),不斷地檢測 GPIO 引腳電平有沒有發(fā)生變化。但是在 Linux 系統(tǒng)中,讀取 GPIO 按鍵要考慮到效率,引入了很多種方法:查詢方式(非阻塞)、休眠-喚醒(阻塞方式)、 poll 方式、異步通知方式。這 4 種方法并不僅僅用于 GPIO 按鍵,在所有的 APP 調(diào)用驅(qū)動程序過程中,都是使用這些方法。通過這 4 種方式的學(xué)習(xí),我們可以掌握如下知識:
1.1?驅(qū)動的基本技能:
????????中斷、休眠、喚醒、poll 等機制。
????????這些基本技能是驅(qū)動開發(fā)的基礎(chǔ),其他大型驅(qū)動復(fù)雜的地方是它的框架及設(shè)計思想,但是基本技術(shù)就這些。
1.2 APP 開發(fā)的基本技能:
????????阻塞 、非阻塞、休眠、poll、異步通知。
二、媽媽怎么知道孩子醒了
?媽媽怎么知道臥室里小孩醒了?
2.1 時不時進房間看一下:查詢方式
????????簡單,但是累
2.2 進去房間陪小孩一起睡覺,小孩醒了會吵醒她:休眠-喚醒
????????不累,但是媽媽干不了活了
2.3 媽媽要干很多活,但是可以陪小孩睡一會,定個鬧鐘:poll 方式
?????????要浪費點時間,但是可以繼續(xù)干活。
?????????媽媽要么是被小孩吵醒,要么是被鬧鐘吵醒。
2.4 媽媽在客廳干活,小孩醒了他會自己走出房門告訴媽媽:異步通知
????????媽媽、小孩互不耽誤
這 4 種方法沒有優(yōu)劣之分,在不同的場合使用不同的方法。
三、APP 讀取按鍵的 4 種方法
APP 去讀取按鍵和舉例的場景很相似,也有 4 種方法:
查詢方式 ????????????????休眠-喚醒方式 ????????????????poll 方式 ????????????????異步通知方式
第 2、3、4 種方法,都涉及中斷服務(wù)程序。中斷,就像小孩醒了會哭鬧一樣, 中斷不經(jīng)意間到來,它會做某些事情:喚醒 APP、向 APP 發(fā)信號。
所以,在按鍵驅(qū)動程序中,中斷是核心。
????????實際上,中斷無論是在單片機還是在 Linux 中都很重要。在 Linux 中,中斷的知識還涉及進程、線程等。?
寫一個驅(qū)動程序的套路? ? ?
?
寫一個驅(qū)動程序的套路? ?
3.1?查詢方式
這種方法最簡單:和之前的LED驅(qū)動程序類似,之前是寫引腳來改變高低電平,現(xiàn)在我們是不斷讀取引腳來查詢是否發(fā)生電平的變化
????????驅(qū)動程序中構(gòu)造、注冊一個 file_operations 結(jié)構(gòu)體,里面提供有對應(yīng)的 open,read 函數(shù)。????????
????????APP 調(diào)用 open 時,導(dǎo)致驅(qū)動中對應(yīng)的 open 函數(shù)被調(diào)用,在里面配置 GPIO 為輸入引腳。
????????APP 調(diào)用 read 時,導(dǎo)致驅(qū)動中對應(yīng)的 read 函數(shù)被調(diào)用,它讀取寄存器,把引腳狀態(tài)直接返回給 APP。
3.2?休眠-喚醒方式
?驅(qū)動程序中構(gòu)造、注冊一個 file_operations 結(jié)構(gòu)體,里面提供有對應(yīng)的 open,read 函數(shù)。
????????APP 調(diào)用 open 時,導(dǎo)致驅(qū)動中對應(yīng)的 open 函數(shù)被調(diào)用,在里面配置 GPIO 為輸入引腳;并且注冊 GPIO 的中斷處理函數(shù)。
????????APP 調(diào)用 read 時,導(dǎo)致驅(qū)動中對應(yīng)的 read 函數(shù)被調(diào)用,如果有按鍵數(shù)據(jù)則直接返回給 APP;否則 APP 在內(nèi)核態(tài)休眠。
????????當用戶按下按鍵時,GPIO 中斷被觸發(fā),導(dǎo)致驅(qū)動程序之前注冊的中斷服務(wù)程序被執(zhí)行。它會記錄按鍵數(shù)據(jù),并喚醒休眠中的 APP。
????????APP 被喚醒后繼續(xù)在內(nèi)核態(tài)運行,即繼續(xù)執(zhí)行驅(qū)動代碼,把按鍵數(shù)據(jù)返回給 APP(的用戶空間)。
3.3??poll 方式
????????上面的休眠-喚醒方式有個缺點:如果用戶一直沒操作按鍵,那么 APP 就會永遠休眠。 我們可以給 APP 定個鬧鐘,這就是 poll 方式。
?驅(qū)動程序中構(gòu)造、注冊一個 file_operations 結(jié)構(gòu)體,里面提供有對應(yīng)的 open,read,poll 函數(shù)。
????????APP 調(diào)用 open 時,導(dǎo)致驅(qū)動中對應(yīng)的 open 函數(shù)被調(diào)用,在里面配置 GPIO 為輸入引腳;并且注冊 GPIO 的中斷處理函數(shù)。
????????APP 調(diào)用 poll 或 select 函數(shù),意圖是“查詢”是否有數(shù)據(jù),這 2 個 函數(shù)都可以指定一個超時時間,即在這段時間內(nèi)沒有數(shù)據(jù)的話就返回錯誤。這會導(dǎo)致驅(qū)動中對應(yīng)的 poll 函數(shù)被調(diào)用,如果有按鍵數(shù)據(jù)則直接返回給 APP;否則 APP 在內(nèi)核態(tài)休眠一段時間。
????????當用戶按下按鍵時,GPIO 中斷被觸發(fā),導(dǎo)致驅(qū)動程序之前注冊的中斷服務(wù)程序被執(zhí)行。它會記錄按鍵數(shù)據(jù),并喚醒休眠中的 APP。
????????如果用戶沒按下按鍵,但是超時時間到了,內(nèi)核也會喚醒 APP。
????????所以 APP 被喚醒有 2 種原因:用戶操作了按鍵,超時。被喚醒的 APP 在內(nèi)核態(tài)繼續(xù)運行,即繼續(xù)執(zhí)行驅(qū)動代碼,把“狀態(tài)”返回給 APP(的用戶空間)。
????????APP 得到 poll/select 函數(shù)的返回結(jié)果后,如果確認是有數(shù)據(jù)的,則再調(diào)用 read 函數(shù),這會導(dǎo)致驅(qū)動中的 read 函數(shù)被調(diào)用,這時驅(qū)動程序中含有數(shù)據(jù),會直接返回數(shù)據(jù)。
3.4 異步通知方式?
3.4.1 異步通知的原理:發(fā)信號
異步通知的實現(xiàn)原理是:內(nèi)核給 APP 發(fā)信號。信號有很多種,這里發(fā)的是 SIGIO。?
驅(qū)動程序給應(yīng)用程序發(fā)信號,應(yīng)用程序收到信號后執(zhí)行它的信號處理函數(shù)
驅(qū)動程序中構(gòu)造、注冊一個file_operations 結(jié)構(gòu)體,里面提供有對應(yīng)的 open,read,fasync函數(shù)。
? APP 調(diào)用 open 時,導(dǎo)致驅(qū)動中對應(yīng)的 open 函數(shù)被調(diào)用,在里面配置 GPIO 為輸入引腳;并且注冊 GPIO 的中斷處理函數(shù)。
? APP 給信號 SIGIO 注冊自己的處理函數(shù):my_signal_fun。
? APP 調(diào)用 fcntl 函數(shù),把驅(qū)動程序的 flag 改為 FASYNC,這會導(dǎo)致驅(qū)動程序的 fasync 函數(shù)被調(diào)用,它只是簡單記錄進程 PID。
? 當用戶按下按鍵時,GPIO 中斷被觸發(fā),導(dǎo)致驅(qū)動程序之前注冊的中斷服務(wù)程序被執(zhí)行。它會記錄按鍵數(shù)據(jù),然后給進程 PID 發(fā)送 SIGIO 信號。
? APP 收到信號后會被打斷,先執(zhí)行信號處理函數(shù):在信號處理函數(shù)中可以去調(diào)用 read 函數(shù)讀取按鍵值。
? 信號處理函數(shù)返回后,APP 會繼續(xù)執(zhí)行原先被打斷的代碼。
3.4.2?應(yīng)用程序之間發(fā)信號示例代碼
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void my_sig_func(int signo)
{
printf("get a signal : %d\n", signo);
}
int main(int argc, char **argv)
{
int i = 0;
signal(SIGIO, my_sig_func); //事件處理函數(shù),如果這里沒有事件處理函數(shù),則收到應(yīng)用程序的信號就會停下退出,如果有事件處理函數(shù),則收到應(yīng)用程序后先執(zhí)行事件處理函數(shù)再繼續(xù)執(zhí)行不會停止進程
while (1)
{
printf("Hello, world %d!\n", i++);
sleep(2);
}
return 0;
}
第 13 行注冊信號處理函數(shù)
第 15 行就是一個無限循環(huán)。在它運行期間,你可以 用另一個 APP 發(fā)信號給它。?
$ gcc -o signal signal.c // 編譯程序 $ ./signal & // 后臺運行 $ ps -A | grep signal // 查看進程 ID,假設(shè)是 9527 $ kill -SIGIO 9527 // 給這個進程發(fā)信號
book@100ask:~/05_嵌入式Linux驅(qū)動開發(fā)基礎(chǔ)知識/source/03_signal_example$ gcc -o signal signal.c
book@100ask:~/05_嵌入式Linux驅(qū)動開發(fā)基礎(chǔ)知識/source/03_signal_example$ ./signal
?
重新開一個進程查詢ID
book@100ask:~$ ps -A
book@100ask:~$ kill -SIGIO 4491
這樣另一邊的進程就收到信息了
?
?四、驅(qū)動程序提供能力,不提供策略
????????我們的驅(qū)動程序可以實現(xiàn)上述 4 種提供按鍵的方法,但是驅(qū)動程序不應(yīng)該限制 APP 使用哪種方法。
????????這就是驅(qū)動設(shè)計的一個原理:提供能力,不提供策略。就是說,你想用哪種方法都行,驅(qū)動程序都可以提供;但是驅(qū)動程序不能限制你使用哪種方法? 。? ? ?
大佬覺得有用的話點個贊 ???? 唄。
??????本人水平有限,如有紕漏,歡迎各位大佬評論批評指正!????????????如果覺得這篇文對你有幫助的話,也請給個點贊、收藏下吧,非常感謝!?? ?? ??
??????任務(wù)在無形中完成,價值在無形中升華,讓我們一起加油吧!??????文章來源:http://www.zghlxwxcb.cn/news/detail-833037.html
![]()
文章來源地址http://www.zghlxwxcb.cn/news/detail-833037.html
到了這里,關(guān)于Linux 驅(qū)動開發(fā)基礎(chǔ)知識——APP 怎么讀取按鍵值(十二)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!