在驱动中调用其它驱动的函数(fastcall)
--作者:赖玉平(Auly)[email protected]
在嵌入式系统中,一些通信口是公用的,如IIC口, 串口等,这些口的驱动一般OEM厂商会帮写好驱动,而且这些驱动是经过测试的,比较稳定,我们在开发其它要用到这些通信口的设备的驱动时,没有必要另外去写一个IIC驱动,只要调用一次相应的IOCtrol就可以像使用自已的函数那样使用相关的操作了,
方法:
(1) 声明一个fastcall变量
I2C_FASTCALL fc; // I2C Fastcall driver-to-driver entrypoints
(2) 在驱动的XXX_Init打开IIC驱动
hI2C = CreateFile( L"I2C0:",
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, 0);
(3) 精髓部份:
if ( !DeviceIoControl(hI2C, IOCTL_I2C_GET_FASTCALL,
NULL, 0,
&fc, sizeof(fc),
&bytes, NULL) )
{
dwErr = GetLastError();
return NULL;
}
经过上面的动作,本驱动就可以很方便地使用IIC驱动里面的Read,Write等函数了
(4) 例如,实现IIC 读操作
// use the driver-to-driver call
retVal = (short int)fc.I2CRead(fc.Context,
SlaveAddr,// SlaveAddress
((PI2C_IO_DESC)lpBuffer)->WordAddr, // WordAddress
puc,
((PI2C_IO_DESC)lpBuffer)->Count);
fc.I2CRead 这就是调用了IIC驱动里对应的HW_Read函数;
写操作也是同样用法:
retVal = (short int)fc.I2CWrite(fc.Context,
SlaveAddr, // SlaveAddress
WordAddr, // WordAddress
WriBuffer,
1);
原理:为什么只通过一次DeviceIoControl()就能实现使用目标驱动里的函数呢?原因是在IIC的驱动里面,I2C_IOControl里面提供了IOCTL_I2C_GET_FASTCALL的接口,在该接口里,给外部调用映射了两个函数的空间:
((PI2C_FASTCALL)pBufOut)->I2CRead = HW_Read;
((PI2C_FASTCALL)pBufOut)->I2CWrite = HW_Write;
这就是精妙所在了。