Linux驅(qū)動(dòng)開發(fā)_ 內(nèi)核中斷處理、定時(shí)器、阻塞與非阻塞IO

      網(wǎng)友投稿 1119 2025-04-01

      任務(wù)1: 復(fù)習(xí): 內(nèi)核中斷處理(按鍵為例)


      裸機(jī)的中斷(STM32為例):

      1. ?中斷線

      2. ?中斷號(hào)(設(shè)置優(yōu)先級(jí)、使能)

      3. ?中斷服務(wù)函數(shù)

      4. ?建立中斷向量表(是中斷入口函數(shù)地址)

      linux操作系統(tǒng)下中斷:

      1. ?編寫中斷服務(wù)函數(shù)

      2. ?注冊(cè)中斷 request_irq

      3. ?注銷中斷 free_irq

      4. ?獲取中斷號(hào)(通過GPIO口編號(hào)進(jìn)行獲取)

      5. ?產(chǎn)生中斷的屬性: 邊沿觸發(fā)。

      6. ?中斷向量表(在linux內(nèi)核不需要寫,它是在UBOOT階段建立的)

      Linux系統(tǒng)下中斷處理

      1. ?內(nèi)核中斷服務(wù)函數(shù)里不能出現(xiàn)會(huì)導(dǎo)致系統(tǒng)休眠的函數(shù)。比如: mdelay

      2. ?內(nèi)核中斷處理分為上文和下文(真正做事情的地方)。

      3. ?內(nèi)核中斷下文一般使用工作隊(duì)列或者內(nèi)核的微線程實(shí)現(xiàn)。

      4. ?內(nèi)核中斷上文一般就調(diào)度工作隊(duì)列或者內(nèi)核微線程。

      注明:工作隊(duì)列和內(nèi)核微線程里可以使用休眠函數(shù)。

      查看內(nèi)核所有中斷的信息: [root@tiny4412 ]#cat /proc/interrupts

      任務(wù)2: 復(fù)習(xí): 工作隊(duì)列

      工作隊(duì)列是將任務(wù)推后執(zhí)行的一種機(jī)制,什么時(shí)候執(zhí)行? CPU空閑的時(shí)候執(zhí)行。

      工作: 就是一個(gè)結(jié)構(gòu)體,結(jié)構(gòu)體里保存了工作對(duì)應(yīng)的函數(shù)(函數(shù)指針)。

      隊(duì)列: 是一個(gè)鏈表形式,每一個(gè)鏈表的節(jié)點(diǎn)就是一個(gè)工作結(jié)構(gòu)體。

      這個(gè)隊(duì)列由內(nèi)核的一個(gè)線程輪詢執(zhí)行,當(dāng)內(nèi)核執(zhí)行了工作之后,該工作結(jié)構(gòu)體就會(huì)從鏈表節(jié)點(diǎn)里刪除掉。

      注意事項(xiàng): 如果之前加入的工作已經(jīng)在工作隊(duì)列里,還沒有被執(zhí)行,這個(gè)時(shí)候不能再重復(fù)添加。

      在Linux內(nèi)核里有默認(rèn)的工作隊(duì)列: 共享工作隊(duì)列。 也可以自己去創(chuàng)建自己的隊(duì)列。

      練習(xí):

      1. ?將上課代碼全部寫一遍: 作業(yè)、中斷、工作隊(duì)列

      2. ?試著使用內(nèi)核定時(shí)器給按鍵進(jìn)行消抖。

      任務(wù)3: 內(nèi)核定時(shí)器

      內(nèi)核定時(shí)器特性:

      1. ?基于軟件層的定時(shí)器,定時(shí)器的定時(shí)器不是特別精準(zhǔn)。

      2. ?內(nèi)核定時(shí)器的使用: 注冊(cè)和注銷。

      3. ?內(nèi)核定時(shí)器是可以無限注冊(cè),內(nèi)部是通過鏈表實(shí)現(xiàn)---->隊(duì)列。

      鏈表的每一個(gè)節(jié)點(diǎn)就是一個(gè)定時(shí)任務(wù),這個(gè)節(jié)點(diǎn)本身就是一個(gè)定時(shí)任務(wù)結(jié)構(gòu)體,在結(jié)構(gòu)體里就有一個(gè)函數(shù)指針。

      4. ?定時(shí)器是基于 jiffies(節(jié)拍總數(shù)) 來實(shí)現(xiàn)定時(shí)。

      計(jì)算一個(gè)節(jié)拍是多少時(shí)間? jiffies 1秒鐘(1000ms)增加HZ(200)次 , jiffies+1的時(shí)間:5m

      int cnt=0;

      void timer(void) //硬件中斷

      {

      cnt++; //5ms一次 1000000

      }

      void main(void)

      {

      int time=cnt+200;

      while(cnt==time){}

      printf("1234");

      }

      s64 ktime_to_us(const ktime_t kt); //轉(zhuǎn)換為 us 單位

      s64 ktime_to_ms(const ktime_t kt); //轉(zhuǎn)換為 ms 單位

      my_time=ktime_get(); //獲取當(dāng)前時(shí)間

      紅外線編碼驅(qū)動(dòng)、超聲波測(cè)距之類的模塊。

      任務(wù)4: 等待隊(duì)列

      等待隊(duì)列: 在驅(qū)動(dòng)里阻塞進(jìn)程的一種方式,可以將進(jìn)程加入到等待隊(duì)列里休眠。

      使用等待隊(duì)列:

      1. ?定義一個(gè)等待隊(duì)列頭(靜態(tài))。

      2. ?在指定位置將進(jìn)程休眠(掛起)。

      3. ?在指定位置將進(jìn)程喚醒。

      等待隊(duì)列休眠的原理:

      任務(wù)5: 阻塞與非阻塞IO

      在應(yīng)用可以通過哪些方法(系統(tǒng)調(diào)用)得知驅(qū)動(dòng)層資源已經(jīng)獲取成功?

      有這3個(gè)函數(shù)接口: epoll、poll、select -----多路復(fù)用IO解決方法。

      案例: 網(wǎng)絡(luò)編程里可以通過以上函數(shù)得知是否收到數(shù)據(jù)。

      5.1 Poll函數(shù)學(xué)習(xí)

      應(yīng)用層的函數(shù)接口:

      #include

      int poll(struct pollfd *fds, nfds_t nfds, int timeout);

      struct pollfd {

      int fd; /*文件描述符 */

      short events; /*監(jiān)控的事件 */

      short revents; /*驅(qū)動(dòng)層返回的事件 */

      };

      函數(shù)參數(shù):

      struct pollfd *fds :保存我們將要監(jiān)控的文件描述符所有信息。

      nfds_t nfds :監(jiān)控的數(shù)量(有多少個(gè)文件描述符)。

      int timeout : >0表示休眠的正常時(shí)間單位。=0表示不休眠。<0表示永久休眠。

      說明: 時(shí)間單位是ms

      返回值: 表示產(chǎn)生事件文件描述符數(shù)量。

      說明: epoll、poll、select 這3個(gè)函數(shù)共用一個(gè)poll驅(qū)動(dòng)。

      static unsigned int tiny4412_poll(struct file *file, struct poll_table_struct *poll_table)

      {

      unsigned int mask = 0; /*返回值: 掩碼*/

      poll_wait(file,&key_wait,poll_table);

      if(tiny4412_key_val)mask=POLLIN;

      return mask;

      }

      5.2 異步通知

      如何通知? 發(fā)送信號(hào),發(fā)送信號(hào)需要進(jìn)程PID號(hào)。

      應(yīng)用層如何接收或者發(fā)送信號(hào)?

      1. ?C語言代碼里可以通過signal函數(shù)來捕獲信號(hào):

      #include

      typedef void (*sighandler_t)(int);

      sighandler_t signal(int signum, sighandler_t handler);

      參數(shù):

      int signum: 將要捕獲信號(hào)。

      sighandler_t handler: 處理信號(hào)的方法(函數(shù)指針)。

      2. ?如何發(fā)送信號(hào)?

      #include

      #include

      Linux驅(qū)動(dòng)開發(fā)_ 內(nèi)核中斷處理、定時(shí)器、阻塞與非阻塞IO

      int kill(pid_t pid, int sig);

      也可以通過命令:kill [-s signal|-p] [--] pid...

      用法1: kill -s <信號(hào)名稱>

      用法2: kill -<信號(hào)名稱>

      3. ?有哪些信號(hào)發(fā)送呢?

      [root@wbyq key_interrupt_drv]# kill -l

      1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP

      6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1

      11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM

      16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP

      21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ

      26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR

      31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3

      38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8

      43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13

      48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12

      53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7

      58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2

      63) SIGRTMAX-1 64) SIGRTMAX

      讓驅(qū)動(dòng)層代碼給進(jìn)程發(fā)送信號(hào)需要哪些條件?

      1. ?驅(qū)動(dòng)層必須得支持異步通知的功能。

      2. ?驅(qū)動(dòng)層得知道進(jìn)程的PID號(hào)。

      驅(qū)動(dòng)層怎么給進(jìn)程發(fā)送信號(hào)?

      設(shè)置文件的狀態(tài)信息:

      #include

      #include

      int fcntl(int fd, int cmd, ... /* arg */ );

      練習(xí):

      1. ?將等待隊(duì)列、poll函數(shù)驅(qū)動(dòng)、異步IO驅(qū)動(dòng)寫一次。

      2. ?poll函數(shù)支持多路復(fù)用: 將按鍵驅(qū)動(dòng)拆分成4個(gè)驅(qū)動(dòng),在應(yīng)用層使用一個(gè)poll函數(shù)同時(shí)監(jiān)控4個(gè)按鍵驅(qū)動(dòng),并讀出按鍵值。

      Linux 任務(wù)調(diào)度

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:如何在表格中快速找到重復(fù)(如何在表格中快速找到重復(fù)的名字)
      下一篇:Google Python挑戰(zhàn)賽:不服,就來!
      相關(guān)文章
      亚洲精品NV久久久久久久久久| 亚洲综合国产成人丁香五月激情| 亚洲av午夜国产精品无码中文字 | 区三区激情福利综合中文字幕在线一区亚洲视频1 | 亚洲精品无码久久久影院相关影片| 亚洲人成国产精品无码| 亚洲 小说区 图片区 都市| 精品亚洲福利一区二区| 韩国亚洲伊人久久综合影院| 爱情岛亚洲论坛在线观看| 日韩欧美亚洲中文乱码| 亚洲国产成人精品无码区二本 | 亚洲日韩中文无码久久| 国外亚洲成AV人片在线观看| 亚洲色自偷自拍另类小说| 亚洲熟妇丰满多毛XXXX| 亚洲国产另类久久久精品黑人| 亚洲国产第一站精品蜜芽| 亚洲av永久无码精品漫画 | 亚洲精品V欧洲精品V日韩精品| 久久亚洲精品视频| 久久久久久a亚洲欧洲AV| 亚洲日本一区二区三区| 亚洲码在线中文在线观看| 91亚洲一区二区在线观看不卡| 亚洲毛片免费观看| 亚洲看片无码在线视频| 亚洲字幕AV一区二区三区四区| 亚洲精华国产精华精华液好用 | 亚洲综合伊人久久大杳蕉| 亚洲情a成黄在线观看| 国产亚洲情侣一区二区无| 亚洲AV无码一区二区三区DV | 亚洲视频精品在线观看| 亚洲a∨无码男人的天堂| 亚洲乱妇老熟女爽到高潮的片| 国产精品亚洲综合一区在线观看| 亚洲精品国产电影| 久久精品国产精品亚洲精品 | 亚洲精品在线播放| 亚洲综合一区无码精品|