国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

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

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

湯文民 張海洋

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

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

1.QNX多路實(shí)時(shí)采集卡

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

2.采集卡驅(qū)動(dòng)設(shè)計(jì)

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

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

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

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

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

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

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

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

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

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

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

pci_attach_device();

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

devinit.intr=inf.Irq;

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

port_regbase=mmap_device_memory();

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

(3)中斷注冊(cè)

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

圖1 InterruptAttach處理過(guò)程

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

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

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

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

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

bufFlag = 1;

W_ptr += D_size;

if(W_ptr >= Shm_start + Shm_size)

W_ptr = Shm_start;

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

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

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

struct kbuf{

unsigned char *buffer;

unsigned int size;

unsigned int in;

unsigned int out;

};

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

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為要寫(xiě)入數(shù)據(jù)的長(zhǎng)度,該操作返回實(shí)際寫(xiě)入的數(shù)據(jù)長(zhǎng)度。

4.結(jié)束語(yǔ)

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

猜你喜歡
共享內(nèi)存
基于共享內(nèi)存的過(guò)約束多自由度振動(dòng)臺(tái)解耦控制方法
通過(guò)QT實(shí)現(xiàn)進(jìn)程間的通信
基于Linux內(nèi)核的文件服務(wù)器模型的研究與構(gòu)建
科技視界(2018年28期)2018-01-16 12:34:48
一種基于Tilcon的維護(hù)界面設(shè)計(jì)
VB環(huán)境下基于內(nèi)存共享技術(shù)的串行通訊程序設(shè)計(jì)
一種高效RTAI 共享內(nèi)存管理層的研究與實(shí)現(xiàn)*
临潭县| 勐海县| 大足县| 余庆县| 囊谦县| 秦皇岛市| 东乌| 天等县| 宜黄县| 商洛市| 奉节县| 江川县| 迁安市| 崇阳县| 田林县| 甘洛县| 黔西县| 沁源县| 辰溪县| 兴义市| 祁连县| 光泽县| 荣成市| 凌海市| 咸丰县| 西畴县| 抚宁县| 绥芬河市| 信阳市| 兴文县| 阳原县| 遵义市| 安康市| 聂荣县| 富源县| 金塔县| 防城港市| 永胜县| 临夏县| 始兴县| 凉城县|