資源描述:
《qnx 4.25設(shè)備驅(qū)動程序的編寫》由會員上傳分享,免費在線閱讀,更多相關(guān)內(nèi)容在工程資料-天天文庫。
1、QNX4.25設(shè)備驅(qū)動程序的編寫摘要:介紹實時操作系統(tǒng)QNX4.25下編寫設(shè)備驅(qū)動程序的大體框架、底層細節(jié)以及諸多注意點。針對使用較為普遍的PCI設(shè)備作為較為詳細的描述。關(guān)鍵詞:驅(qū)動程序QNX實時操作系統(tǒng)PCI引言QNX是一個多任務(wù)、多用戶、分布式、可嵌入式符合POSIX標準的微內(nèi)核的主流實時操作系統(tǒng),廣泛用于實時性能、開發(fā)靈活性、網(wǎng)絡(luò)靈活性要求較高的場合,如電信系統(tǒng)、醫(yī)療儀器、航空航天、工業(yè)自動化、交通運輸、POS機、信息家電等。QNX是一個適合軟件/硬件定制的實時操作系統(tǒng)。如果你曾經(jīng)試圖在傳統(tǒng)的UNIX或an.h>#include
2、<sys/osinfo.h>#include<sys/pci.h>#include<i86.h>#defineYOUR_PCI_DEVICE_ID0x1713//根據(jù)具體設(shè)備提供對應(yīng)的廠商標識及設(shè)備標識#defineYOUR_PCI_VENDOR_ID0x13feintmain(void){unsignedbusnum,devfunum;//總線號(PC僅有一條)及設(shè)備功能號longaddress;longio_base;//I/O基地址unsignedcharirq;//中斷號intpci_index=
3、0//標識為零標識第一塊此種型號設(shè)備if(_CA_PCI_Find_Device(YOUR_PCI_DEVICE_ID,YOUR_PCI_VENDOR_ID,pci_index,busnum,devfunum)!=PCI_SUCCESS){printf("Cannotfinddevice");exit(EXIT_FAILURE);}//偵測設(shè)備中斷if(_CA_PCI_Read_Config_Byte(busnum,devfunum,offsetof(struct_pci_config_regs,Interrupt_Line),1,irq)
4、!=PCI_SUCCESS){printf("Errorreadinginterrupt");exit(EXIT_FAILURE);}//偵測設(shè)備I/O基地址if_CA_PCI_Read_Config_D,devfunum,offsetof(struct_pci_config_regs,Base_[2]),1,(char*)address)!=PCI_SUCCESS){printf("Errorreadingaddress");exit(EXIT_FAILURE);}io_base=PCI_IO_ADDR(adress);printf("I
5、Oaddress:%x",io_base);printf("IRQ:"%x",irq);exit(EXIT_SUCCESS);}注意:各種設(shè)備的Base_Address_Regs[x],x可能不盡相同,需要查看具體的硬件手冊決定。2進入硬件一旦獲得了系統(tǒng)分配給某個硬件設(shè)備的資源信息,就可以同這個設(shè)備進行通信了。至于如何做取決于需要訪問的硬件資源。2.1I/O資源一個進程試圖進行I/O操作,必須具有正確的權(quán)限等級。你必須是超及用戶(root),在編譯的時候加上適當(dāng)參數(shù)T1,以確何該進程擁有訪問I/O口的權(quán)限。若忽視這一點,該運行進程將獲得一個
6、口的權(quán)限。若忽視這一點,該運行進行將獲得一個SIGSEGV信號,表示一個非法的內(nèi)存引用,并結(jié)束進程運行?,F(xiàn)在就可以利用inp()、inpd()、inpp;~0x80);2.2存儲映射資源某些設(shè)備,可以通過一般的內(nèi)存操作進入寄存器,這就需要獲得內(nèi)存基地址(memorybaseaddress)。為了能夠獲進入此類設(shè)備的寄存器,需要將其映射到驅(qū)動程序虛擬地址空間。QNX下的技術(shù)資料/etc/readme/technotes/shmem.txt描述了如何創(chuàng)建一個共享內(nèi)存對象,然后將這個內(nèi)存對象的一段內(nèi)存映射到PCI卡中,以便能夠進入這個PCI設(shè)備。
7、(接著上面的代碼)可以利用mmap():char*mem_base;if(PCI_IS_MEM(address)){//判斷內(nèi)存基地址intfd;char*page_ptr;fd=shm_open("Physical",O_RDAP_SHARED,fd,PCI_MEM_ADDR(address)~0xfff);//將內(nèi)存基地址映射if(page_ptr==(char*)perror("Errormmap:");exit(EXIT_FAILURE);}mem_base=page_ptr+(PCI_MEM_ADDR(address)0xfff)
8、;close(fd);}printf("MEM"address:%lx",PCI_MEM_ADDR(address));if(PCI_IS_MEM(address))printf