本文主要是讲解CPCI驱动的知识点。本人也是在学习中,欢迎大家来交流指正。
例程使用Windriver10.21生成cpci驱动,cpci桥芯片使用的是9054。
驱动知识点说明:
1.def和__declspec(dllimport)是两种导出方式。
__declspec(dllimport):兼容性强,但是在某些编译器,例如CVI会产生识别不了的修饰符。
所以在驱动中两种导出方式都设置了。
2.#define HSI_PXIDLL_API extern"C" __declspec(dllimport):
extern"C":使用标准C导出。
3.__stdcall:驱动编写方和驱动调用方要约定同样的调用方法,一般使用stdcall。
4.打开板卡、关闭板卡、复位函数是从windriver例程的源码找出来的。
5.PLX_WriteAddrLocal32和PLX_ReadAddrLocal32:
使用32位的读写函数,因为FPGA中使用的是读写32位数据时的时序要求。
PLX_ReadAddrLocal32:读函数。读取32位数据线上的数据,如果硬件设计只有16位数据线,那么其他16位数据线上的数据是无效的,需要在程序是做处理,只取有用的数据位。
PLX_WriteAddrLocal32(pci9054card[CardNumber],2, 0x20, 0x1)参数说明:
pci9054card[CardNumber]:板卡的句柄。
2:数据的地址空间。因为初始化的时候设置的是地址块2有效,所以使用此函数时将第二个参数写为2。
0x20:地址,跟fpga程序相对应。
0x1:数据,跟fpga程序相对应。
UINT32 data;
PLX_ReadAddrLocal32 (pci9054card[CardNumber],2, 0x20, &data);
pci9054card[CardNumber]:板卡的句柄。
2:数据的地址空间。因为初始化的时候设置的是地址块2有效,所以使用此函数时将第二个参数写为2。
0x20:地址,跟fpga程序相对应。
&data:接收数据的变量,用来接收fpga传回来的数据。接收后应做处理,只取有效位上的数据。
6.头文件设置导入导出:
#ifdef DLL_EXPORTS
#define HSI_PXIDLL_API extern"C" __declspec(dllexport)
#else
#define HSI_PXIDLL_API extern"C" __declspec(dllimport)
#endif
HSI_PXIDLL_API依赖于是否定义了DLL_EXPORTS。
展开为Dllexport是dll编译时的需要,通知编译器该函数是需要导出供外部调用的。
展开为dllimport是给调用者用的,通知编译器该函数是外部导入函数。
这样做的目的是为了让dll开发者和使用者使用同一个h文件。
在dll的工程中,在预处理定义中定义DLL_EXPORTS,HSI_PXIDLL_API就是导出。在调用dll的工程中,不定义DLL_EXPORTS,HSI_PXIDLL_API就是导入。
7.32位程序只能调用32位dll,64位程序只能调用64位dll。如果使用调用dll错误,将导致编译器识别不了函数或者识别到的函数带有其他修饰符,如函数add变成“_add@0”