作者:gooogleman@foxmail.com 2008-12-04
最近,越来越感觉作为一个好的驱动工程师,必须会写一些应用程序来配合调试才行,达到事半功倍的效果。下面就拿个例子来分析。
在这方面,做的最好的应该是周立功的2410开发板,就拿他的代码来看看吧。
以GPIO驱动为例子。
- /*******************************************************************************************
- 函数名称: PIO_IOControl
- 描 述: 驱动程序 I/O 请求
- 输入参数: DWORD dwIoControlCode: 见本文件的头文件gpio.h
- 输出参数:
- 返 回: TRUE: 操作成功 FALSE: 操作失败
- *******************************************************************************************/
- BOOL
- PIO_IOControl(
- DWORD Handle,
- DWORD dwIoControlCode,
- PBYTE pInBuf,
- DWORD nInBufSize,
- PBYTE pOutBuf,
- DWORD nOutBufSize,
- PDWORD pBytesReturned
- )
- {
- BOOL bErr = FALSE;
- switch(dwIoControlCode & IOCTL_GPIO_FUN_MASK)
- {
- /*
- * 设置引脚为输出
- */
- case IOCTL_GPIO_SET_PIN_OUT:
- if (nInBufSize > 0)
- bErr = GPIO_SetPinOut(dwIoControlCode, *pInBuf);
- break;
- case IOCTL_GPIO_SET_MULTI_PIN_OUT: /* pInBuf 必须为4字节 */
- if (nInBufSize > 0)
- bErr = GPIO_SetMultiPinOut(dwIoControlCode, *(DWORD *)pInBuf);
- //RETAILMSG(TRUE, (TEXT("*(DWORD *)pInBuf is 0x%x)./r/n"), *(DWORD *)pInBuf));
- break;
- /*
- * 设置引脚为输入
- */
- case IOCTL_GPIO_SET_PIN_IN:
- if (nInBufSize > 0)
- bErr = GPIO_SetPinIn(dwIoControlCode, *pInBuf);
- break;
- case IOCTL_GPIO_SET_MULTI_PIN_IN: /* pInBuf 必须为4字节 */
- if (nInBufSize > 0)
- bErr = GPIO_SetMultiPinIn(dwIoControlCode, *(DWORD *)pInBuf);
- //RETAILMSG(TRUE, (TEXT("*(DWORD *)pInBuf is 0x%x)./r/n"), *(DWORD *)pInBuf));
- break;
- /*
- * 设置引脚输出高电平
- */
- case IOCTL_GPIO_SET_PIN:
- if (nInBufSize > 0)
- bErr = GPIO_SetPin(dwIoControlCode, *pInBuf);
- break;
- case IOCTL_GPIO_SET_MULTI_PIN: /* pInBuf 必须为4字节 */
- if (nInBufSize >= 0)
- bErr = GPIO_SetAllPin(dwIoControlCode, *(DWORD *)pInBuf);
- //RETAILMSG(TRUE, (TEXT("*(DWORD *)pInBuf is 0x%x)./r/n"), *(DWORD *)pInBuf));
- break;
- /*
- * 设置引脚输出低电平
- */
- case IOCTL_GPIO_CLR_PIN:
- if (nInBufSize > 0)
- bErr = GPIO_ClrPin(dwIoControlCode, *pInBuf);
- break;
- case IOCTL_GPIO_CLR_MULTI_PIN: /* pInBuf 必须为4字节 */
- if (nInBufSize > 0)
- bErr = GPIO_ClrAllPin(dwIoControlCode, *(DWORD *)pInBuf);
- //RETAILMSG(TRUE, (TEXT("*(DWORD *)pInBuf is 0x%x)./r/n"), *(DWORD *)pInBuf));
- break;
- /*
- * 读取引脚电平状态
- */
- case IOCTL_GPIO_READ_PIN:
- if ((nOutBufSize > 0) && (nInBufSize > 0))
- {
- bErr = GPIO_ReadPin(dwIoControlCode, *pInBuf, pOutBuf);
- *pBytesReturned = 1;
- }
- break;
- case IOCTL_GPIO_READ_ALL_PIN: /* pOutBuf 必须为2字节 */
- if (nOutBufSize > 0)
- {
- bErr = GPIO_ReadAllPin(dwIoControlCode, (ushort *)pOutBuf, 1);
- *pBytesReturned = 1;
- }
- break;
- /*
- * 使能引脚内部上拉
- */
- case IOCTL_GPIO_EN_PULLUP: /* *pInBuf 为1字节 */
- if (nInBufSize > 0)
- bErr = GPIO_ConfigPullUp(dwIoControlCode, *pInBuf, TRUE);
- break;
- case IOCTL_GPIO_EN_MULTI_PIN_PULLUP: /* pInBuf 必须为4字节 */
- if (nInBufSize > 0)
- bErr = GPIO_ConfigMultiPinPullup(dwIoControlCode, *(DWORD *)pInBuf, TRUE);
- break;
- /*
- * 禁止引脚内部上拉
- */
- case IOCTL_GPIO_DIS_PULLUP:
- if (nInBufSize > 0) /* *pInBuf 为1字节 */
- bErr = GPIO_ConfigPullUp(dwIoControlCode, *pInBuf, FALSE);
- break;
- case IOCTL_GPIO_DIS_MULTI_PIN_PULLUP: /* pInBuf 必须为4字节 */
- if (nInBufSize > 0)
- bErr = GPIO_ConfigMultiPinPullup(dwIoControlCode, *(DWORD *)pInBuf, FALSE);
- break;
- default:
- break;
- }
- return bErr;
- } // PIO_IOControl
周在GPIO的驱动中着重实现了这个接口函数,其余的PIO_Read等函数为空函数。
现在来看看这个应用程序
...........................................
...........................................
在应用程序中,使用了CreateFile函数来以文件形式打开驱动,然后再用deviceiocontrol函数来传递参数控制驱动中的PIO_IOControl函数。这样就实现了功能。
在这里值得注意的是,应用和驱动都包含了一个一模一样的gpio.h文件,这个文件是一些命令宏定义,
这个就说明deviceiocontrol传递这些参数给驱动,和PIO_IOControl使用到的参数匹配,这样就完成了整个任务。
哈哈,本文只对初学者有帮助。牛人们千万别笑话。
转载请标明:作gooogleman@foxmail.com 。如有错误,希望能够留言指出。