2 开发步骤
a.根据WinDriver的文档,建议开发步骤如下:
·修改代码,加入定制功能;
·在用户态执行与调试代码;
·将性能苛刻部分插入到核心态;
b.我们在实际编写驱动程序的过程中发现,完全用WinDriver提供API来写驱动程序比在Wizard生成的框架代码上修改更为灵活。一般来说,PCI驱动程序分成3个部分:初始化部分,对硬件资源的访问函数库、具体调用部分。其中,后面两个部分对于不同的硬件都是基本一致的。比如说,我们先后开发的基于AMCC5933与PLX9052的PCI接口卡,对于他们的硬件资源访问,用的都是WinDriver下面相同的API;两者开发的不同只在于初始化时对于硬件资源的锁定。所以只要开发出了针对一种接口芯片的系统的驱动代码后,以后一般只要修改接口芯片的ID值及一些寄存器的偏移值,就能够移植了,比每次生成不同的框架代码再改动也许要更简便。
3 实例分析
整个驱动程序的结构大致如下:
·打开WinDriver设备;
·查找我们要访问的PCI设备;
·枚举该设备的资源(内存、I/O、中断);
·锁定该设备的资源只能为我们所用,不能被其他程序访问;
·访问板上的资源;
·解锁资源;
·关闭WinDriver设备。
以下为一段使用WinDriver开发的AMCC5933DMA的驱动代码,利用这个程序来演示WinDriver的程序结构。这个程序只要稍加修改,就可以用来作为其他PCI卡的驱动程序的一部分,例如PLX9050、9054。为了节省篇幅,省略了变量说明部分。程序中出现的变量大都由其名称可以反映含义,具体可以参见WinDriver的设计文档中的说明。
hWD=WD_Open(); //打开WinDriver设备,每次使用前必须调用;
pciScan.searched.dwVendorId=0x10e8; //AMCC公司供货号
pciScan.searched.dwDeviceId=0x4750; //AMCC5933的设备号
WD_PciScanCards (hWD,&pciSxcan); //枚举PCI槽上的设备
pciSlot =pciScan.cardSilt[0]; //假设只有我们一个设备得到设备槽的号码
pciCardInfo.pciSlot=pciSlot;
WD_PciGetCardInfo(hWD,&pciCardInfo); //得到该设备槽上的设备信息
Card=pciCardInfo.Card; //Card为一个反映PCI卡上资源的结构
cardReg.Card=Card;
WD_CardRegister(hWD,&cardReg); //向核心态登记,锁定卡上资源
Item=Card.Item[2]; //将卡上的号为2的资源赋给Item
if(Item.item==ITEM_MEMORY)
{
regAddr=Item.I.Mem.dwUserDirectAddr; //得到PCI卡上的内存映射到用户态的地址
}
Dma1.dwBytes=4*dwDWord;
Dma1.pUserAddr=pBuffer1;
Dma1.dwOptions=0;
WD_DMALock(hWD,&Dma1); //锁定用于DMA的内存资源
至此与PCI卡上的内存进行DMA传输的准备已经完成,下面只要写相应的控制字就可以启动DMA操作了。
2 开发步骤
a.根据WinDriver的文档,建议开发步骤如下:
·修改代码,加入定制功能;
·在用户态执行与调试代码;
·将性能苛刻部分插入到核心态;
b.我们在实际编写驱动程序的过程中发现,完全用WinDriver提供API来写驱动程序比在Wizard生成的框架代码上修改更为灵活。一般来说,PCI驱动程序分成3个部分:初始化部分,对硬件资源的访问函数库、具体调用部分。其中,后面两个部分对于不同的硬件都是基本一致的。比如说,我们先后开发的基于AMCC5933与PLX9052的PCI接口卡,对于他们的硬件资源访问,用的都是WinDriver下面相同的API;两者开发的不同只在于初始化时对于硬件资源的锁定。所以只要开发出了针对一种接口芯片的系统的驱动代码后,以后一般只要修改接口芯片的ID值及一些寄存器的偏移值,就能够移植了,比每次生成不同的框架代码再改动也许要更简便。
3 实例分析
整个驱动程序的结构大致如下:
·打开WinDriver设备;
·查找我们要访问的PCI设备;
·枚举该设备的资源(内存、I/O、中断);
·锁定该设备的资源只能为我们所用,不能被其他程序访问;
·访问板上的资源;
·解锁资源;
·关闭WinDriver设备。
以下为一段使用WinDriver开发的AMCC5933DMA的驱动代码,利用这个程序来演示WinDriver的程序结构。这个程序只要稍加修改,就可以用来作为其他PCI卡的驱动程序的一部分,例如PLX9050、9054。为了节省篇幅,省略了变量说明部分。程序中出现的变量大都由其名称可以反映含义,具体可以参见WinDriver的设计文档中的说明。
hWD=WD_Open(); //打开WinDriver设备,每次使用前必须调用;
pciScan.searched.dwVendorId=0x10e8; //AMCC公司供货号
pciScan.searched.dwDeviceId=0x4750; //AMCC5933的设备号
WD_PciScanCards (hWD,&pciSxcan); //枚举PCI槽上的设备
pciSlot =pciScan.cardSilt[0]; //假设只有我们一个设备得到设备槽的号码
pciCardInfo.pciSlot=pciSlot;
WD_PciGetCardInfo(hWD,&pciCardInfo); //得到该设备槽上的设备信息
Card=pciCardInfo.Card; //Card为一个反映PCI卡上资源的结构
cardReg.Card=Card;
WD_CardRegister(hWD,&cardReg); //向核心态登记,锁定卡上资源
Item=Card.Item[2]; //将卡上的号为2的资源赋给Item
if(Item.item==ITEM_MEMORY)
{
regAddr=Item.I.Mem.dwUserDirectAddr; //得到PCI卡上的内存映射到用户态的地址
}
Dma1.dwBytes=4*dwDWord;
Dma1.pUserAddr=pBuffer1;
Dma1.dwOptions=0;
WD_DMALock(hWD,&Dma1); //锁定用于DMA的内存资源
至此与PCI卡上的内存进行DMA传输的准备已经完成,下面只要写相应的控制字就可以启动DMA操作了。
举报