PCI设备驱动代码
《PCI设备驱动代码》由会员分享,可在线阅读,更多相关《PCI设备驱动代码(13页珍藏版)》请在装配图网上搜索。
1、1、搜索设备根据PCI设备的VendorlD和DevicelD搜索PCI设备,返回PCI配置信息和 Slot Number : int DeviceSearch (int vendorID,int deviceID,PCI_SLOT_NUMBER*pSlotNumber,PPCI_COMMON_CONFIG pPcidata)ULONG bus;ULONG deviceNunber;ULONG functionNumber;ULONG bytesREAD;BOOL bFlag=TURE;pSlotNumber-u.bits.Reserved=0;for(bus=0;bFlag;bus+) fo
2、r(deviceNumber=0;deviceNumberu.bits.DeviceNumber=deviceNumber; for(functionNumber=0;functionNumberu.bits.FunctionNumber=functionNumber;bytesRead=RtGetBusDataByOffset(PCIConfiguration,bus,pSlotNumber-u.AsULONG,pPciData ,0,PCI_COMMON_HDR_LENGTH);If(bytesRead=0)bFlag=FALSE;break;没有发现 busif(bytesRead=VE
3、NDOR_ID_SIZE&pPciData-Vendor=PCI_INVALID_VENDORID) 没有发现 deviceif(pPciData-VendorID=vendorID)&(pPciData-DeviceID=deviceID) return bus;发现 deviceReturn DEVICE_NOT_FOUND;2、初始化设备利用 RtTranslateBusAddress(和 RtMapMemory(),RtTranslateBusAddress。把 PCI设备地址转化为 CPU可直 接访问 的物理地址,RtMapMemory() 把物理地址映射到虚拟地址。物理地址映射到虚
4、拟地址映射范围一般为4K, RtMapMemory() 函数默认最大可以映射的范围 64M 字节:BOOL DeviceStartup(int busNumber,PCI_SLOT_NUMBER*pSlotNumber,PPCI_COMMON_ CONFIG pPciData) LARGE_INTEGER baseMemAddr;LARGE_INTEGER PhysMemAddr;ULONG AddressSpace=0;Int addressRange=4*1024;Int memoryRange=60*1024*1024;ULONG bytesWritten;Int i;If(!RTEna
5、blePortlo(PCHAR)IOAddress,sizeof(DeviceIORegs)Return FALSE; I/O 允许for(i=0;iu.type0.BaseAddressesi; if(!RtTranslateBusAddress(PCIBus,busNumber,baseMemAddr,&AddressSpace, &PhysMemAddr) vMemAddri=NULL;continue; if(i!=BASE_MEMORY_RSG) vMemAddri=RtMapMemory(PhysMemAddr,addressRange,0);vMemAddri=RtMapMemo
6、ry(PhysMemAddr,memoryRange,0);基地址转换 设备-物理 -IOpPciData-Command=(PCI_ENABLE_IO_SPACE|PCI_ENABLE_MEMORY_SPACE| PCI_ENABLE_BUS_MASTER|PCI_ENABLEWRITE_AND_INVALIDATE);bytesWritten=RtSetBusDataByOffset(PCIConfiguration,busNumber,pSlotNumber-u.AsULONG, pPciData,0,PCI_COMMON_HDR_LENGTH);if(bytesWritten=0)re
7、turn FALSE;RtSleep(500);return TURE;3、打开设备为 DMA 通道发送、接受网络中断等硬件功能模块创建信号量。int RFM2gOpen()int EventType;char *MsgWaitRFM2GEVENT_LAST;DMABusy=RtCreateSemaphore(NULL,1,1,” Message.DMA0busy ” );if (DMABusy=NULL)MsgAndExit( “ RtCreateSemaphore for DMA0Busy failed.DMA 忙” );DMADone=RtCreateSemaphore(NULL,0,1
8、,” Message.DMA0done ” );if (DMADone=NULL)MsgAndExit( “ RtCreateSemaphore for DMADone failed.DMA 完”成)中; 断sendEvent=RtCreateSemaphore(NULL,1,1,” Message.sen;devent ”)if (sendEvent=NULL)MasAndExit( “ RtCreateSemaphore for sendEvent failed. 发送中断 ” );MsgWait*0+= ” Message.eventtype0MsgWait*1+=MsgWait*2+=
9、MsgWait*3+=MsgWait*4+=MsgWait*5+=MsgWait*6+=MsgWait*7+=Message.eventtype1Message.eventtype2Message.eventtype3Message.eventtype4Message.eventtype5Message.eventtype6Message.eventtype7for (EventType=RFM2GEVENT_RESET;EventTypeRFM2GEVENT_LATS;EventType+)waitingSemEventType=RtCreateSemaphore(NULL,0,1,MsgW
10、aitEventType);If(waitingSemEventType=NULL)MsgAndExit(RtCreateSemaphore for waitingSem failed.” );NodeID=vMenAddrBASE_CONFIG_REGRFM2G_NID;接受中断4、打开中断使能 DMA 中断和网络中断void EnableInterruptsOnChip()Unsigned int oldnumber,masknumber,confignumber;oldnumber=GetConfig(BASE_CONTRL_REG,RFM2G_DMA0MODE);masknumber=
11、RFM2G_BIT0|RFM2G_BIT1|RFM2G_BIT7|RFM2G_BIT10|RFM2G_BIT17; confignumber=oldnember|masknumber;confignumber=confignumber&0xfffffdff;SetConfig(BASE_CONTRL_REG,RFM2G_DMA0MODE,confignumber):SetConfig(BASE_CONTRL_REG,RFM2GDMAODAC,OxO);DM通道 0 模式SetConfig(BASE_CONFIG_REG,RFN2G_SID1,0x0);SetConfig(BASE_CONFIG
12、_REG,RFN2G_SID2,0x0);SetConfig(BASE_CONFIG_REG,RFN2G_SID3,0x0);SetConfig(BASE_CONFIG_REG,RFN2G_SID4,0x0);SetConfig(BASE_CONFIG_REG,RFN2G_SIDLIER,0x0);SetConfig(BASE_CONFIG_REG,RFN2G_SIDLISR,0x0);oldnumber =GetConfig (BASE_CONFIG_REG,RFM2G_LIER);masknumber =RFM2G_BIT0 | RFM2G_BIT1 |RFM2G_BIT2 | RFM2G
13、_BIT7; confignumber=oldnumber|masknumber;SetConfig (BASE_CONFIG_REG,RFM2G_LIER,confignumber);LIERoldnumber= GetConfig(BASE_CONFIG_REG,RFM2G_LISR); masknumber=RFM2G_BIT14;confignumber=oldnumber|masknumber;SetConfig (BASE_CONFIG_REG,RF M2G_LISR,confignumber);LISRoldnumber = GetConfig (BASE_CONTRL_REG,
14、RFM2G_INTCSR); masknumber =RFM2G_BIT8 | RFM2G_BIT11 |RFM2G_BIT18; confignumber=oldnumber|masknumber;SetConfig (BASE_CONTRL_REG,RFM2G_INTCSR,confignumber);5、发送和接受中断int RFM2gSendEvent(HANDLE rh,int ToNode,RFM2GEVENTTYPe EventType,unsignedint ExtendedData)Unsigned char cmd=;If(ToNodeEventEvent=RFM2GEVE
15、NT_LAST) ) MsgAndExit( “pEventInfo error.”);if (RtWaitForSingleObject ( waitingSem pEventInfo-Event, INFINITE)=WAIT_FAILED) MsgAndExit (RtWaitForSingleObject waitingSemfailed.);switch(pEventInfo-Event)case RFM2GEVENT_INTR1: pEventInfo -ExtendedInfo =GetConfig(BASE_CONFIG_REG,RFM2G_ISD1); pEventInfo-
16、NodeId = vMemAddrBASE_CONFIG_REGRFM2G_SID1;oldnumber= GetConfig(BASE_CONFIG_REG,RFM2G_LISR); masknumber=RFM2G_BIT14;confignumber=oldnumber|masknumber; confignumber=confignumber & 0xfffffffe;SetConfig (BASE_CONFIG_REG,RFM2G_LISR,confignumber); break;case RFM2GEVENT_INTR2:pEventInfo -ExtendedInfo =Get
17、Config(BASE_CONFIG_REG,RFM2G_ISD2); pEventInfo-NodeId = vMemAddrBASE_CONFIG_REGRFM2G_SID2;oldnumber= GetConfig(BASE_CONFIG_REG,RFM2G_LISR); masknumber=RFM2G_BIT14;confignumber=oldnumber|masknumber; confignumber=confignumber & 0xfffffffd;SetConfig (BASE_CONFIG_REG,RFM2G_LISR,confignumber); break;case
18、 RFM2GEVENT_INTR3:pEventInfo -ExtendedInfo =GetConfig(BASE_CONFIG_REG,RFM2G_ISD3); pEventInfo -NodeId = vMemAddrBASE_CONFIG_REGRFM2G_SID3;oldnumber= GetConfig(BASE_CONFIG_REG,RFM2G_LISR); masknumber=RFM2G_BIT14;confignumber=oldnumber|masknumber; confignumber=confignumber & 0xfffffffb;SetConfig (BASE
19、_CONFIG_REG,RFM2G_LISR,confignumber); break;case RFM2GEVENT_INTR4: pEventInfo -ExtendedInfo =GetConfig(BASE_CONFIG_REG,RFM2G_ISD4); pEventInfo-NodeId = vMemAddrBASE_CONFIG_REGRFM2G_SID4;oldnumber= GetConfig(BASE_CONFIG_REG,RFM2G_LISR); masknumber=RFM2G_BIT14;confignumber=oldnumber|masknumber;confign
20、umber=confignumber & 0xffffff7f;SetConfig (BASE_CONFIG_REG,RFM2G_LISR,confignumber);break;case RFM2GEVENT_RESET:break;default:break;return 0;接受中断6、读写操作通过DMA或者CPU读写节点数据或将数据写入本地节点int RFM2gRead ( HANDLE rh, unsigned int Offset, void*Buffer, unsigned int Length ) if(Length = DEFAULT_DMA_THRESH) if (RFM2
21、gDMA ( rh, RFM2G_TO_PCI, Buffer,Offset, Length) ! = 0) MsgAndExit(RFM2gDMA Read failed.);elsememcpy ( (void*)Buffer, (void*) (vMemAddrBASE_MEMORY_REG+Offset), Length ); return 0;/ 读入板卡数据int RFM2gWrite ( HANDLE rh, unsigned int Offset, void*Buffer, unsigned int Length ) if(Length=DEFAULT_DMA_THRESH)i
22、f(RFM2gDMA(rh, PCI_TO_RFM2G, Buffer, Offset,Length) ! = 0)MsgAndExit(RFM2gDMA Write failed.);elsememcpy (void*)(vMemAddr BASE_MEMORY_REG+Offset), (void*)Buffer, Length); return 0;写入板卡数据static int RFM2gDMA( HANDLE rh, int direction, void *pBuff,unsigned int rfmOffset, unsigned int length)LARGE_INTEGE
23、R physaddrTo;DWORD lpBuff;unsigned int lRfmOffset;int dmaComplete;unsigned int bytesLeft2DMA; / 尚未传输的字节数unsigned int bytes2Send; / 将要传输的字节数unsigned int bytesSent; / 完成传输的字节数if (RtWaitForSingleObject ( DMABusy, INFINITE)= WAIT_FAILED)MsgAndExit(RtWaitForSingleObject failed.);if (direction = PCI_TO_RF
24、M2G)SetConfig (BASE_CONTRL_REG,RFM2G_DMA0DESCPTR,0x0);elseSetCo nfig (BASE_CONTRL_REG,RFM2G_DMAODESCPTR,Ox8); /DM传输方向physaddrTo = RtGetPhysicalAddress( pBuff );lpBuff = physaddrTo.LowPart;lRfmOffset = rfmOffset;dmaComplete = 0;bytesLeft2DMA = length;bytes2Send = 0;bytesSent=0;while(dmaComplete = 0)i
25、f(bytesLeft2DMA DMATxferSize)bytes2Send = bytesLeft2DMA;elsebytes2Send = DMATxferSize;bytesLeft2DMA -= bytes2Send;bytesSent += bytes2Send;SetConfig (BASE_CONTRL_REG,RFM2G_DMA0PCIADDR,lpBuff);SetConfig (BASE_CONTRL_REG,RFM2G_DMA0LOCALADDR,lRfmOffset);SetConfig(BASE_CONTRL_REG,RFM2G_DMA0COUNT,(bytes2S
26、end& RFM2G_DMA_SIZE_MAX);SetConfig (BASE_CONTRL_REG,RFM2G_DMA0CSR,0x3);RtWaitForSingleObject( DMADone, INFINITE);SetConfig (BASE_CONTRL_REG,RFM2G_DMAOCSR,Ox8)清除 DMA 完成中断 if(bytesSent = length)dmaComplete = 1;elselpBuff += bytes2Send;lRfmOffset += bytes2Send;if(RtReleaseSemaphore(DMABusy,1,NULL) ! =
27、TRUE)MsgAndExit(RtReleaseSemaphore ch0Busy failed.);return 0;DMA 数据传输unsigned GetConfig(unsigned Base,unsigned offset)unsigned int get;memcpy (void*)(&get), (void*)(vMemAddr Base+offset), 4);return get;读 32bits 数void SetConfig (unsigned Base,unsigned offset, unsignedconfig_number)unsigned int set=co
28、nfig_number;memcpy (void*) (vMemAddr Base +offset), (void*)(&set), 4);/ 写 32bits 数void MsgAndExit ( char *msg )RtPrintf( “Error:%s(0x%X)n”,smg,RtGetLastError();RtExitProcess(1); 错误信息输出7、中断服务程序ISR、线程1ST中断服务程序ISR接收到中断后交给中断服务线程1ST来处理,用户一般不需要改动。INTERRUPT_DISPOSITION RTFCNDCL DeviceISR (PVOIDpContext)BOO
29、LEAN bIstHandling = TRUE; if(bIstHandling) return CallInterruptThread; return Dismiss;中断服务例程BOOLEAN RTAPI DeviceIST(PVOID pContext)unsigned int dmaINTCSR;dmalNTCSR =GetCo nfig (BASE_C0NTRL_REG,RFM2GN TCSR);地配置寄存器: if( dmaINTCSR & RFM2G_BIT21 ) RtReleaseSemaphore(DMADone,1,NULL);RtPrintf(0Kiiiiiist-D
30、MA-DMA-INT! n);DMA 中断if( dmaINTCSR & RFM2G_BIT15 )unsigned int dLISR;dLISR = GetConfig(BASE_C0NFIG_REG, RFM2G_LISR);if(dLISR & RFM2G_LISR_RESET)RtReleaseSemaphore (waitingSemRFM2GEVENT_RESET,1,NULL); if(dLISR & RFM2G_LISR_INT1)RtReleaseSemaphore (waitingSemRFM2GEVENT_INTR1,1,NULL);if(dLISR & RFM2G_L
31、ISR_INT2) RtReleaseSemaphore (waitingSemRFM2GEVENT_INTR2,1,NULL);if(dLISR & RFM2G_LISR_INT3) RtReleaseSemaphore (waitingSemRFM2GEVENT_INTR3,1,NULL);if(dLISR & RFM2G_LISR_INT4) RtReleaseSemaphore (waitingSemRFM2GEVENT_INTR4,1,NULL); RtPrintf(OKiiiiiist-NETint-NETint-INT! n);网络中断 return TRUE; 中断服务线程8、
32、挂接中断 挂接硬件中断,保证 RTX正确分配给了中断信号反射内存卡,采用独占模式:HANDLE Hang_Interrupt ( ULONG irqLevel, ULONG irqVector,ULONG busNumber, PCI_SLOT_NUMBER slotNumber ) ATTACH_INTERRUPT_PARAMETERS AttachParams;HANDLE intHandler;if(! RtQueryPciMsiCapability(busNumber, slotNumber) AttachParams.AttachVersion = ATTACH_LINE_BASED
33、; AttachParams.LineBased.pThreadAttributes = NULL; AttachParams.LineBased.StackSize = 0;AttachParams.LineBased.pRoutine = (PVOID )DeviceIST; AttachParams.LineBased.Context = NULL;AttachParams.LineBased.Priority = IST_PRIORITY; AttachParams.LineBased.InterfaceType = PCIBus; AttachParams.LineBased.Bus
34、Number = busNumber; AttachParams.LineBased.SlotNumber = slotNumber; AttachParams.LineBased.BusInterruptLevel = irqLevel; AttachParams.LineBased.BusInterruptVector = irqVector;AttachParams.LineBased.Shared = FALSE; AttachParams.LineBased.InterruptMode = LevelSensitive; AttachParams.LineBased.MyInterr
35、upt = DeviceISR;AttachParams.LineBased.ProcessorEnableMask= 1 RtGetCurrentProcessorNumber(); elseAttachParams.AttachVersion = ATTACH_MESSAGE_BASED; AttachParams.MessageBased.pThreadAttributes =NULL; AttachParams.MessageBased.StackSize = 0;AttachParams.MessageBased.pRoutine = (PVOID)DeviceIST; Attach
36、Params.MessageBased.Context = NULL;AttachParams.MessageBased.Priority = IST_PRIORITY;AttachParams.MessageBased.BusNumber = busNumber;AttachParams.MessageBased.SlotNumber = slotNumber;AttachParams.MessageBased.MyInterrupt = DeviceISR;AttachParams.MessageBased.ProcessorEnableMask =1u.type0.InterruptLi
37、ne;irqVector = irqLevel;ntHandler = Hang_Interrupt(irqLevel,irqVector,busNumber,slotNumber);if( intHandler = NULL )DeviceCleanup( NULL );MsgAndExit( Could not attach to the interrupt forthis device. );elseRtPrintf (OK -Attach to the interrupt for thisdevice (IntNo. %x)n,irqLevel);RtEnableInterrupts(
38、); / 中断允许/ 打开中断EnableInterruptsOnChip();RtPrintf(OK-Open interrupt for this devicen);/ 打开接收信号量SemRecieve = RtOpenSemaphore (0, FALSE, Message.WinSemRecieve); if(SemRecieve)RtPrintf(OK-Open SemRecieve! n);/ 打开发送信号量SemSend = RtOpenSemaphore (0, FALSE, Message.WinSemSend);if(SemSend)RtPrintf(OK-Open Se
39、mSend! n);/ 打开共享内存if (hSM = RtOpenSharedMemory (SHM_MAP_WRITE,FALSE, sharedmemory, &pSM) = NULL) RtPrintf(error Open shared memory! n);RtPrintf(ComRtx Close! n);ExitProcess(1);elseRtPrintf(OK-Open shared memory! n);strcpy(pSM-recievedBuffer, 成 功 打 开 共 享 内 存 !( RTSS) rn); RtReleaseSemaphore(SemReciev
40、e,1,NULL);RtSleep(50);/ 创建发送线程hSendThread = CreateThread(NULL, 0,(LPTHREAD_START_ROUTINE)onSend, NULL,0, &dwSendThreadID);RtSleep(50);/ 创建接收线程hReceiveThread = CreateThread(NULL, 0,(LPTHREAD_START_ROUTINE)onReceiveN, ULL,0, &dwReceiveThreadID);while(pSM-bExit = FALSE)RtSleep(1000);/ 释放发送信号量 RtRelease
41、Semaphore(SemSend,1,NULL);/ 释放接收信号量RtReleaseSemaphore(waitingSemEventInfo.Event,1,NULL);/ 关闭中断DisableInterruptsOnChip( );RtPrintf(OK-Close interrupt for this devicen);/ 关闭设备RFM2gClose( );RtPrintf(OK-Close device Sem n);/ 清除设备DeviceCleanup( intHandler );RtPrintf(OK-Cleanup device Int Mapn);/ 关闭线程 if(
42、hSendThread)RtCloseHandle(hSendThread);if(hReceiveThread)RtCloseHandle(hReceiveThread);/ 关闭共享内存if(hSM)RtCloseHandle(hSM);/ 退出ExitProcess( 0 );发送线程调用驱动函数完成信息的网络发送。 代码如下:/ 发送信息线程DWORD onSend(LPVOID lpvThreadParm)RtPrintf(OK-Create Send Thread! n);strcpy(pSM-recievedBuffer, 成 功 创 建 发 送 信 息 线 程 !( RTSS)
43、 rn); RtReleaseSemaphore(SemRecieve,1,NULL);/ 发送信息while(pSM-bExit = FALSE)RtWaitForSingleObject( SemSend, INFINITE);/ 写数据RFM2gWrite (0,0x10000,pSM-sendBuffer,sizeof(pSM-sendBuffer);/ 发送中断RFM2gSendEvent (0,RFM2G_NODE_ALL,RFM2GEVENT_INTR1,0);RtPrintf(OK-Close Send Thread ! n);/ 接收信息线程DWORD onReceive(L
44、PVOID lpvThreadParm)char str1500;RtPrintf(OK-Create Receive Thread! n); strcpy(pSM-recievedBuffer, 成 功 创 建 接 收 信 息 线 程 !(RTSS) rn =rn);RtReleaseSemaphore(SemRecieve,1,NULL); EventInfo.Event=RFM2GEVENT_INTR1;/ 接收信息 while(pSM-bExit = FALSE)/ 接收中断RFM2gWaitForEvent(0, &EventInfo);/ 读数据RFM2gRead (0,0x10000,pSM -recievedBuffer,sizeof(pSM-recievedBuffer); strcpy(str1, 【接收信息】 : );strcat(str1,pSM-recievedBuffer); strcat(str1, (RTSS) rn);strcpy(pSM-recievedBuffer,str1); RtReleaseSemaphore(SemRecieve,1,NULL);RtPrintf(OK-Close Receive Thread ! n); return 0;
- 温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。