国产成人精品三级麻豆,色综合天天综合高清网,亚洲精品夜夜夜,国产成人综合在线女婷五月99播放,色婷婷色综合激情国产日韩

當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > SylixOS熱插拔概述

SylixOS熱插拔概述 時(shí)間:2018-09-28      來源:未知

SylixOS熱插拔概述

1. 熱插拔系統(tǒng)簡介

1.1 熱插拔系統(tǒng)

    熱插拔設(shè)備指支持帶電操作的一類設(shè)備,允許用戶不關(guān)閉系統(tǒng)、不切斷電源情況下取出或更換設(shè)備。熱插拔系統(tǒng)用于管理系統(tǒng)中所有熱插拔設(shè)備的插入、拔出狀態(tài),從而能夠讓系統(tǒng)內(nèi)部自動(dòng)完成此類設(shè)備的創(chuàng)建、刪除工作而無需用戶手動(dòng)處理。同時(shí),熱插拔系統(tǒng)還會(huì)收集熱插拔相關(guān)信息,供應(yīng)用程序使用。SylixOS 中有一個(gè)名稱為"t_hotplug"的內(nèi)核線程,設(shè)備的熱插拔狀態(tài)通過事件的方式報(bào)告給該線程。系統(tǒng)中還有一個(gè)名為"/dev/hotplug"的虛擬設(shè)備,它負(fù)責(zé)收集相關(guān)熱插拔消息,應(yīng)用程序可通過讀取"/dev/hotplug"設(shè)備,獲得自己關(guān)心的熱插拔消息。

1.2 實(shí)現(xiàn)原理

    在 SylixOS 中,可以使用如下兩種方法獲得熱插拔事件:

    1.中斷產(chǎn)生,例如"mini2440"開發(fā)板上SD卡熱插拔操作,當(dāng)SD卡插入或者拔出時(shí)會(huì)觸發(fā)引腳中斷,中斷服務(wù)程序中會(huì)根據(jù)讀取的引腳狀態(tài),產(chǎn)生相應(yīng)的熱插拔事件,將需要處理的事件加入到熱插拔工作處理隊(duì)列,等待內(nèi)核線程處理。

    2. 輪詢檢測,當(dāng)有些熱插拔設(shè)備不產(chǎn)生中斷(沒有插拔中斷功能的設(shè)備),則需要輪詢檢測某些事件標(biāo)志。設(shè)備驅(qū)動(dòng)程序需要將檢測函數(shù)和參數(shù)注冊(cè)到"hotplug"循環(huán)檢測鏈表中,"t_hotplug"內(nèi)核線程會(huì)定時(shí)調(diào)用檢測函數(shù),輪詢檢測函數(shù)會(huì)產(chǎn)生相應(yīng)事件,等待內(nèi)核線程處理。

    當(dāng)設(shè)備熱插拔操作結(jié)束時(shí),會(huì)產(chǎn)生一條熱插拔消息存入緩存區(qū),應(yīng)用層程序可以通過讀取虛擬設(shè)備"/dev/hotplug"(熱插拔設(shè)備驅(qū)動(dòng)創(chuàng)建),從緩存區(qū)中獲取熱插拔消息。

2 讀取熱插拔消息

    前文提到,熱插拔事件產(chǎn)生后會(huì)產(chǎn)生熱插拔消息,存放在"/dev/hotplug"設(shè)備的緩存區(qū)中,則應(yīng)用層可以對(duì)"/dev/hotplug"設(shè)備進(jìn)行讀取,獲得應(yīng)用層需要的熱插拔消息。由于"/dev/hotplug"設(shè)備是字符設(shè)備,所以應(yīng)用層可以對(duì)設(shè)備進(jìn)行open、read、write、ioctl、close等操作,獲得應(yīng)用層所需的熱插拔消息。

2.1 獲取熱插拔消息實(shí)例

    SylixOS 中定義了當(dāng)前常見的熱插拔設(shè)備消息,如 USB、SD卡、PCI等,用戶也可以自定義添加。此外,還有網(wǎng)卡的連接與斷開等與熱插拔行為相似的消息。

    下面舉例說明如何獲取網(wǎng)卡熱插拔消息(本例程序是在mini2440開發(fā)板上測試運(yùn)行),測試代碼代碼清單2-1所示。 

代碼清單 2-1

[cpp] view plain copy print?

1. #include <stdio.h>  

2. #include <string.h>  

3.

4. #define      MSG_LEN_MAX                (534)  

5.

6. int main (int  argc, char  *argv[])  

7. {  

8.     UINT8   pucMsgBuff[MSG_LEN_MAX];  

9.     INT     iFd;  

10.     INT32   iMsgType;  

11.     BOOL    bInsert;  

12.     ssize_t sstReadLen;  

13.

14.     CHAR   *pcDevName = NULL;  

15.     UINT8  *pucArg    = NULL;  

16.     UINT8  *pucTemp   = NULL;  

17.

18.

19.     iFd = open("/dev/hotplug", O_RDONLY);                             /*  打開hotplug虛擬設(shè)備         */  

20.     if (iFd < 0) {  

21.         fprintf(stderr, "open /dev/hotplug failed.\n");  

22.         return (-1);  

23.     }  

24.

25.     ioctl(iFd, LW_HOTPLUG_FIOSETMSG, LW_HOTPLUG_MSG_NETLINK_CHANGE);  /* ioctl 設(shè)置關(guān)心網(wǎng)卡熱插拔事件 */  

26.     while (1) {  

27.         sstReadLen = read(iFd, pucMsgBuff, MSG_LEN_MAX);              /* 讀取熱插拔消息               */  

28.         if (sstReadLen < 0) {  

29.             fprintf(stderr, "read hotplug message error.\n");  

30.             close(iFd);  

31.             return (-1);  

32.         }  

33.         if (sstReadLen < 5) {  

34.             continue;  

35.         }  

36.

37.         /* 

38.          * 解析熱插拔消息 

39.          */  

40.         pucTemp   = pucMsgBuff;  

41.         iMsgType  = (pucTemp[0] << 24) | (pucTemp[1] << 16) | (pucTemp[2] << 8) | (pucTemp[3]);  

42.         pucTemp  += 4;  

43.         bInsert   = *pucTemp ? TRUE : FALSE;  

44.         pucTemp  += 1;  

45.         pcDevName = (CHAR *) pucTemp;  

46.         pucArg    = pucTemp + strlen(pcDevName) + 1;  

47.

48.         printf("get new hotplug message >>\n"                         /*  打印熱插拔消息             */  

49.                 " message type: %d\n"  

50.                 "device status: %s\n"  

51.                 " device name: %s\n"  

52.                 " arg0: 0x%01x%01x%01x%01x\n"  

53.                 " arg1: 0x%01x%01x%01x%01x\n"  

54.                 " arg2: 0x%01x%01x%01x%01x\n"  

55.                 " arg3: 0x%01x%01x%01x%01x\n", iMsgType,  

56.                 bInsert ? "insert" : "remove", pcDevName, pucArg[0], pucArg[1],  

57.                 pucArg[2], pucArg[3], pucArg[4], pucArg[5], pucArg[6],  

58.                 pucArg[7], pucArg[8], pucArg[9], pucArg[10], pucArg[11],  

59.                 pucArg[12], pucArg[13], pucArg[14], pucArg[15]);  

60.     }  

61.

62.     close(iFd);  

63.

64.     return (0);  

65. }  

    如代碼清單2-1所示,程序?qū)崿F(xiàn)了應(yīng)用層讀取網(wǎng)卡熱插拔消息的功能,在開發(fā)板上運(yùn)行該程序,當(dāng)發(fā)生網(wǎng)卡熱插拔操作時(shí),會(huì)得到網(wǎng)卡熱插拔消息,實(shí)驗(yàn)現(xiàn)象。

    通過分析代碼清單2-1所示代碼,用戶在讀取設(shè)備熱插拔消息時(shí)應(yīng)注意以下幾點(diǎn):

    1.以只讀方式打開"/dev/hotplug"設(shè)備,SylixOS中熱插拔消息在熱插拔設(shè)備創(chuàng)建時(shí)產(chǎn)生,并且寫入到設(shè)備中緩存區(qū)中。

    2.代碼清單2-1中程序通過ioctl函數(shù)實(shí)現(xiàn)單獨(dú)監(jiān)聽網(wǎng)卡熱插拔消息的功能,應(yīng)用程序可以根據(jù)需要設(shè)置ioctl函數(shù)中的參數(shù)來獲取對(duì)應(yīng)的消息。默認(rèn)情況下是讀取所有類型熱插拔消息。

    3.代碼清單2-1中read函數(shù)實(shí)現(xiàn)讀取網(wǎng)卡熱插拔消息的功能,讀取消息后對(duì)獲得的熱插拔消息進(jìn)行解析,然后輸出打印。SylixOS中對(duì)熱插拔消息格式進(jìn)行特殊規(guī)定,格式分析參照2.2節(jié)。

2.2 熱插拔消息格式

    由2.1節(jié)中讀取網(wǎng)卡熱插拔消息實(shí)例可知,在SylixOS中熱插拔消息有規(guī)定的格式。下面對(duì)SylixOS熱插拔消息格式進(jìn)行分析。

消息的前4個(gè)字節(jié)標(biāo)識(shí)了消息的類型。SylixOS中已經(jīng)定義了USB鍵盤、USB鼠標(biāo)、SD存儲(chǔ)卡、SDIO無線網(wǎng)卡等熱插拔類型。在實(shí)際的硬件平臺(tái)上,設(shè)備驅(qū)動(dòng)也可以定義自己的熱插拔消息類型。

    第5個(gè)字節(jié)為設(shè)備狀態(tài),0表示拔出,1表示插入。

     從第 6 個(gè)字節(jié)開始,表示設(shè)備的名稱,其內(nèi)容為一個(gè)以'\0'結(jié)束的字符串,應(yīng)用程序應(yīng)該以此為結(jié)束符得到完整的名稱。該名稱為一個(gè)設(shè)備的完整路徑名稱, 如"/dev/ttyUSB0"、"/media/sdcard0"等。由于SylixOS中,一個(gè)完整路徑名稱的大長度為512,加上結(jié)束字符'\0',因此,dev name字段的大長度為513。

    緊跟著設(shè)備名稱('\0'字符結(jié)尾)的是 4 個(gè)可用于靈活擴(kuò)展的參數(shù),均為4字節(jié)長度。這4個(gè)參數(shù)可適應(yīng)不同設(shè)備消息的特殊處理。SylixOS未規(guī)定每個(gè)參數(shù)的具體用法和存儲(chǔ)格式(大端或小端),完全由設(shè)備驅(qū)動(dòng)定義。

    綜上論述,一個(gè)熱插拔消息的大長度為:4 + 1 + 513 + 4 + 4 + 4 + 4 = 534字節(jié)。

3 熱插拔消息產(chǎn)生

3.1 網(wǎng)卡熱插拔消息

     前文已經(jīng)介紹了應(yīng)用層如何獲取熱插拔消息,本章介紹SylixOS熱插拔消息的產(chǎn)生流程。SylixOS中,熱插拔消息在熱插拔事件產(chǎn)生時(shí)產(chǎn)生,由熱插拔設(shè)備驅(qū)動(dòng)實(shí)現(xiàn)。

    下面以網(wǎng)卡熱插拔為例,介紹網(wǎng)卡熱插拔消息產(chǎn)生流程,。

在對(duì)網(wǎng)口進(jìn)行必要的初始化后,將循環(huán)檢測函數(shù)dm9000_watchdog注冊(cè)到循環(huán)檢測鏈表中,檢測函數(shù)會(huì)根據(jù)網(wǎng)卡狀態(tài)產(chǎn)生不同的熱插拔消息,然后將熱插拔消息存入緩存區(qū)。

3.2 模擬熱插拔實(shí)現(xiàn)

    下面通過信號(hào)模擬熱插拔事件,用信號(hào)SIGALRM模擬設(shè)備插入,用信號(hào)SIGUSR1模擬設(shè)備拔出。示例代碼清單3-1所示:

代碼清單3-1

[cpp] view plain copy print?

1. #define __SYLIXOS_KERNEL  

2. #include <SylixOS.h>  

3. #include <stdio.h>  

4. #include <string.h>  

5. #include <signal.h>  

6. #include <pthread.h>  

7. #include <unistd.h>  

8.

9. static char      *msg = "Dev";  

10.

11. void send_event (void  *arg)  

12. {  

13.     int signum = (int)arg;  

14.

15.     if (signum == SIGALRM) {  

16.         API_HotplugEventMessage(LW_HOTPLUG_MSG_ALL, 1, msg, 0, 0, 0, 0);  

17.     } else if (signum == SIGUSR1){  

18.         API_HotplugEventMessage(LW_HOTPLUG_MSG_ALL, 0, msg, 0, 0, 0, 0);  

19.     }  

20. }  

21.

22. void pullout_handler (int  signum)  

23. {  

24.     API_HotplugEvent((VOIDFUNCPTR)send_event, (void *)signum, 0, 0, 0, 0, 0);  

25. }  

26.

27. void insert_handler (int  signum)  

28. {  

29.     API_HotplugEvent((VOIDFUNCPTR)send_event, (void *)signum, 0, 0, 0, 0, 0);  

30. }  

31.

32. int main (int argc, char *argv[])  

33. {  

34.     int   i;  

35.

36.     if (signal(SIGALRM, insert_handler) == SIG_ERR) {  

37.         fprintf(stderr, "Install signal handler failed.\n");  

38.         return -1;  

39.     }  

40.     if (signal(SIGUSR1, pullout_handler) == SIG_ERR) {  

41.         fprintf(stderr, "Install signal handler failed.\n");  

42.         return -1;  

43.     }  

44.

45.     for (i = 0; i < 8; ++i) {  

46.         alarm(2);  

47.         pause();  

48.         kill(getpid(), SIGUSR1);  

49.     }  

50.

51.     return  0;  

52. }  

       本例利用信號(hào)模擬熱插拔事件,運(yùn)行2.1節(jié)中程序(注釋掉ioctl函數(shù),獲取所有類型的熱插拔消息),再執(zhí)行代碼清單3-1所示程序。

4 小結(jié)

     本文檔介紹了SylixOS下熱插拔系統(tǒng)實(shí)現(xiàn)原理,以網(wǎng)卡熱插拔為例,分析熱插拔消息產(chǎn)生流程。后通過信號(hào)模擬熱插拔事件,打印出模擬的熱插拔消息。

上一篇:OpenVPN 服務(wù)器搭建

下一篇:yocto編譯總結(jié)

熱點(diǎn)文章推薦
華清學(xué)員就業(yè)榜單
高薪學(xué)員經(jīng)驗(yàn)分享
熱點(diǎn)新聞推薦
前臺(tái)專線:010-82525158 企業(yè)培訓(xùn)洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠(yuǎn)見科技集團(tuán)有限公司 版權(quán)所有 ,京ICP備16055225號(hào)-5京公海網(wǎng)安備11010802025203號(hào)

回到頂部