亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        QNX下PEX8311多路實時數(shù)據(jù)采集的驅(qū)動設(shè)計

        2014-04-29 06:41:36湯文民張海洋
        電子世界 2014年21期
        關(guān)鍵詞:共享內(nèi)存

        湯文民 張海洋

        【摘要】實時操作系統(tǒng)QNX在工業(yè)領(lǐng)域中的應(yīng)用越來越廣泛,在高速數(shù)據(jù)采集方面QNX能最大限度地發(fā)揮實時操作系統(tǒng)的優(yōu)勢。本文介紹了QNX下PEX8311多路實時數(shù)據(jù)采集驅(qū)動的開發(fā)流程。詳細闡述了驅(qū)動程序和應(yīng)用程序之間利用共享內(nèi)存方式完成進程通信的具體實現(xiàn)方法。最后,應(yīng)用程序采用無鎖環(huán)形緩存進行多路數(shù)據(jù)分發(fā)的實現(xiàn)。該方法也為其他操作系統(tǒng)實現(xiàn)多路實時數(shù)據(jù)采集驅(qū)動程序提供了一種全新的方法。

        【關(guān)鍵詞】QNX;PCI;共享內(nèi)存;PEX8311;環(huán)形緩存

        1.QNX多路實時采集卡

        多路實時采集卡由基于PCI接口PEX8311和FPGA的連接組成。FPGA可以同時采集16路數(shù)據(jù),每路數(shù)據(jù)采樣率達到200k且每路可以單獨設(shè)置采用率,因此最高采用率可以達到3.2M。PEX8311采用DMA工作模式中的demand方式將采集到的數(shù)據(jù)傳輸給運行在CPU上的QNX。驅(qū)動程序利用QNX實時性高的特點把采集到的數(shù)據(jù)實時存入到用戶程序和驅(qū)動程序都可以訪問的共享存儲空間中。驅(qū)動進程和應(yīng)用進程利用共享內(nèi)存方式交換采集數(shù)據(jù),避免了不必要的中間環(huán)節(jié),節(jié)省了系統(tǒng)開銷,增強了系統(tǒng)的實時性。

        2.采集卡驅(qū)動設(shè)計

        (1)資源管理器交互建立

        資源管理器是QNX操作系統(tǒng)實現(xiàn)與用戶程序交互數(shù)據(jù)的通道,應(yīng)用程序中使用到的open(),close(),read(),write()等函數(shù)通過資源管理器接口映射到底層函數(shù)對硬件相應(yīng)的操作。實現(xiàn)流程如下:

        dispatch_create();函數(shù)實現(xiàn)用戶程序與資源管理器交互所需要的通道

        iofunc_func_init();該函數(shù)初始化應(yīng)用程序功能函數(shù)層接口

        iofunc_attr_init ();該函數(shù)初始化設(shè)備屬性接口

        resmgr_attach ();該函數(shù)向進程管理器注冊,并使設(shè)備在命名空間中產(chǎn)生相應(yīng)的名稱。

        (2)硬件資源管理和分配

        和其他操作系統(tǒng)類似,QNX提供了豐富的PCI接口函數(shù),可

        以方便地注冊、管理、使用PCI設(shè)備。具體流程如下:

        ThreadCtl(); 設(shè)置線程對IO端口進行操作的權(quán)限

        pci_attach(); 連接到QNX提供的PCI服務(wù)上

        pci_attach_device();

        devinit.port=inf.CpuBaseAddress[0]+(j*0x200);

        devinit.intr=inf.Irq;

        探測PCI設(shè)備并取得相應(yīng)設(shè)備的資源,如設(shè)備首地址、中斷等。

        port_regbase=mmap_device_memory();

        設(shè)備首地址映射到內(nèi)存地址,訪問設(shè)備寄存器用port_regbase+offset即可。

        (3)中斷注冊

        QNX提供了兩種連接中斷的接口:

        Int InterruptAttachEvent(int intr,const struct sigevent *event,unsigned flags);

        Int InterruptAttach(int intr,const struct sigevent*(*handler)(void*, int ), const void *area, int size, unsigned flags);

        其中intr代表了中斷向量號,在讀取設(shè)備信息時已經(jīng)被初始化在了info變量中。兩個函數(shù)分別有自己的優(yōu)缺點,在具體設(shè)計中應(yīng)視具體情況而定。InterruptAttachEvent()函數(shù)用法簡單,運行在用戶空間,可以啟動單獨的線程去處理特定任務(wù),優(yōu)點是其應(yīng)用接近linux操作系統(tǒng)可以方便程序移植,缺點是當中斷發(fā)生時會引起上下文切換,從而使降低效率。對于InterruptAttach()函數(shù)而言,中斷處理函數(shù)首先將原線程打斷,然后判斷中斷是否需要建立新的線程處理此任務(wù)還是原線程處理此任務(wù),所以對于不是自己要處理的中斷,可以減少上下文切換的開支。本論文中采樣InterruptAttach()函數(shù)處理中斷,具體操作流程如圖1所示。

        圖1 InterruptAttach處理過程

        為了減少系統(tǒng)調(diào)度開銷,采用圖1的調(diào)度策略,即中斷返回并沒有創(chuàng)建新的線程來處理中斷后的大量數(shù)據(jù)交換,而是在原線程中處理這些數(shù)據(jù)。

        圖2 共享內(nèi)存示意圖

        (4)共享內(nèi)存

        驅(qū)動進程和應(yīng)用進程采用共享內(nèi)存的方式傳遞采集到的數(shù)據(jù),PEX8311采用DMA方式,傳輸數(shù)據(jù)塊中包含16路的采集數(shù)據(jù),其每次傳輸?shù)臄?shù)據(jù)塊長度為D_size,其中,由于每路的采集率可以設(shè)置為不同的采集率,所以傳輸數(shù)據(jù)塊中包含各路的信息量可以是不同的,例如:第一路采樣率為200k,第十路采樣率為100k,那么數(shù)據(jù)塊中包含第一路和第十路的數(shù)據(jù)量為2:1,圖2表示共享內(nèi)存的示意圖,共享內(nèi)存的大小為Shm_size=Shm_end–Shm_start,寫指針W_ptr和讀指針R_ptr沿著內(nèi)存增加的方向移動,當?shù)竭_共享內(nèi)存底部時環(huán)回到頂端,讀寫指針在共享內(nèi)存初始化時賦值為頂端地址,寫指針W_ptr只能被中斷程序修改,讀指針只能被應(yīng)用程序修改。所以在共享內(nèi)存使用上不需要信號量,只需保證寫指針W_ptr不超過讀指針R_ptr即可。

        當PEX8311用DMA每傳輸完一個數(shù)據(jù)塊后產(chǎn)生一個中斷,在中斷服務(wù)程序中,除了做一些中斷保護外,對共享內(nèi)存的處理描述代碼如下:

        bufFlag = 1;

        W_ptr += D_size;

        if(W_ptr >= Shm_start + Shm_size)

        W_ptr = Shm_start;

        當中斷發(fā)生后,代碼D_size的數(shù)據(jù)已經(jīng)傳輸完畢,寫指針W_ptr需要被重新賦值,指針移到下一位置準備接收,當其到達共享內(nèi)存的的低端時,需要重新賦值Shm_start,然后開始采集下一幀數(shù)據(jù)。然后通過返回一個信號量,退出中斷,為了系統(tǒng)的實時性,中斷處理程序盡量短,在中斷中通過返回return(event)信號量辦法告訴QNX操作系統(tǒng)中斷處理函數(shù)執(zhí)行完畢,需要進行調(diào)用InterruptWait()函數(shù)中斷后的后續(xù)操作,中斷后續(xù)操作的工作就是通知應(yīng)用進程一幀數(shù)據(jù)已經(jīng)采集完畢并存儲在共享內(nèi)存中,可以進行讀操作了。函數(shù)sem_post()用來兩個進程間的通信,其為信號量加1,在應(yīng)用進程里函數(shù)sem_wait()實現(xiàn)信號量減1,函數(shù)sem_post()和函數(shù)sem_wait()均為原子操作,這樣應(yīng)用進程就能和驅(qū)動進程完成一個讀一個寫的操作。變量bufFlag為操作標志,在驅(qū)動進程里可以完成某種判讀的處理。

        3.應(yīng)用進程接口

        應(yīng)用進程把得到的采集數(shù)據(jù)放到16個環(huán)形緩存(buffer)里,每個環(huán)形緩存用一個結(jié)構(gòu)體表示:

        struct kbuf{

        unsigned char *buffer;

        unsigned int size;

        unsigned int in;

        unsigned int out;

        };

        環(huán)形緩存是一個實現(xiàn)無鎖且提供同時讀寫操作的特殊緩存,其容量大小size定義必須為2的冪。in為寫入指針,out為讀出指針。下面列出了環(huán)形緩存的寫入操作代碼:

        len=min(len,k_buf->size-k_buf->in+k_buf->out);

        l=min(len,k_buf->size-(k_buf->in&(k_buf->size-1)));

        memcpy(k_buf->buffer+(k_buf->in &(k_buf->size-1)),data,l);

        memcpy(k_buf->buffer,data+l,len-l);

        k_buf->in+=len;

        return len;

        k_buf為環(huán)形緩存數(shù)據(jù)結(jié)構(gòu),data為要存入數(shù)據(jù)的地址指針,len為要寫入數(shù)據(jù)的長度,該操作返回實際寫入的數(shù)據(jù)長度。

        4.結(jié)束語

        本文介紹了PEX8311多路高速采集卡在QNX操作系統(tǒng)下的驅(qū)動程序設(shè)計。應(yīng)用共享內(nèi)存方式完成驅(qū)動和應(yīng)用之間的進程通信,并利用環(huán)形緩存實現(xiàn)各路數(shù)據(jù)的存取。在實際應(yīng)用中取得良好的效果。

        猜你喜歡
        共享內(nèi)存
        基于共享內(nèi)存的過約束多自由度振動臺解耦控制方法
        通過QT實現(xiàn)進程間的通信
        基于Linux內(nèi)核的文件服務(wù)器模型的研究與構(gòu)建
        科技視界(2018年28期)2018-01-16 12:34:48
        一種基于Tilcon的維護界面設(shè)計
        VB環(huán)境下基于內(nèi)存共享技術(shù)的串行通訊程序設(shè)計
        一種高效RTAI 共享內(nèi)存管理層的研究與實現(xiàn)*
        国产一区二区三区仙踪林| 亚洲精品乱码久久久久久麻豆不卡| 亚洲午夜精品久久久久久抢| 成人国产在线播放自拍| 国产91精品自拍视频| 日出白浆视频在线播放| 亚洲国产综合精品中久| 少妇被按摩出高潮了一区二区| 天天躁夜夜躁狠狠是什么心态| 国产成人a人亚洲精品无码| 大地资源网最新在线播放| 国产一级做a爱视频在线| 国产一区二区三区护士| 久久精品国产亚洲超碰av| 国产乱了真实在线观看| 人妻aⅴ无码一区二区三区| 日韩人妻无码精品系列专区无遮| 丰满人妻被公侵犯的视频 | 日本精品视频免费观看| 国精品午夜福利视频不卡| 亚洲欧洲日产国码高潮αv| 久久久久久人妻一区精品| 亚洲中文字幕精品久久久| 色综合久久网| 人人爽人人爱| 在线av野外国语对白| 国产精品二区三区在线观看| 日产精品高潮一区二区三区5月| 欧美老熟妇喷水| 亚洲国产精品尤物yw在线观看| 日韩精品人妻少妇一区二区| 亚洲视频免费在线观看| 性色欲情网站| 亚洲精品无码国模| 国产免费激情小视频在线观看| 在线观看一区二区中文字幕| 色五月丁香五月综合五月| 欧美v亚洲v日韩v最新在线| 无码一区二区丝袜| 中文字幕亚洲一二三区| 99久热在线精品视频观看|