应用程序是如何调用驱动的?

作者:gooogleman@foxmail.com 2008-12-04

          最近,越来越感觉作为一个好的驱动工程师,必须会写一些应用程序来配合调试才行,达到事半功倍的效果。下面就拿个例子来分析。

 

          在这方面,做的最好的应该是周立功的2410开发板,就拿他的代码来看看吧。

           以GPIO驱动为例子。

          

  1. /*******************************************************************************************
  2. 函数名称: PIO_IOControl
  3. 描    述: 驱动程序 I/O 请求
  4. 输入参数: DWORD dwIoControlCode:  见本文件的头文件gpio.h
  5. 输出参数:
  6. 返    回: TRUE: 操作成功    FALSE: 操作失败
  7. *******************************************************************************************/
  8. BOOL
  9. PIO_IOControl(
  10.     DWORD Handle,
  11.     DWORD dwIoControlCode,
  12.     PBYTE pInBuf,
  13.     DWORD nInBufSize,
  14.     PBYTE pOutBuf,
  15.     DWORD nOutBufSize,
  16.     PDWORD pBytesReturned
  17.     )
  18. {
  19.     BOOL bErr = FALSE;  
  20.     switch(dwIoControlCode & IOCTL_GPIO_FUN_MASK)
  21.     {   
  22.         /*
  23.         *   设置引脚为输出
  24.         */
  25.         case IOCTL_GPIO_SET_PIN_OUT:
  26.             if (nInBufSize > 0)
  27.                 bErr = GPIO_SetPinOut(dwIoControlCode, *pInBuf);    
  28.         break;          
  29.         case IOCTL_GPIO_SET_MULTI_PIN_OUT:                    /* pInBuf 必须为4字节 */
  30.             if (nInBufSize > 0)
  31.                 bErr = GPIO_SetMultiPinOut(dwIoControlCode, *(DWORD *)pInBuf);  
  32.             //RETAILMSG(TRUE, (TEXT("*(DWORD *)pInBuf is 0x%x)./r/n"), *(DWORD *)pInBuf)); 
  33.         break;
  34.         /*
  35.         *   设置引脚为输入
  36.         */
  37.         case IOCTL_GPIO_SET_PIN_IN:
  38.             if (nInBufSize > 0)
  39.                 bErr = GPIO_SetPinIn(dwIoControlCode, *pInBuf);
  40.         break;
  41.         case IOCTL_GPIO_SET_MULTI_PIN_IN:                     /* pInBuf 必须为4字节 */
  42.             if (nInBufSize > 0)
  43.                 bErr = GPIO_SetMultiPinIn(dwIoControlCode, *(DWORD *)pInBuf);
  44.             //RETAILMSG(TRUE, (TEXT("*(DWORD *)pInBuf is 0x%x)./r/n"), *(DWORD *)pInBuf));  
  45.         break;
  46.         /* 
  47.         *   设置引脚输出高电平
  48.         */
  49.         case IOCTL_GPIO_SET_PIN:
  50.             if (nInBufSize > 0)
  51.                 bErr = GPIO_SetPin(dwIoControlCode, *pInBuf);
  52.         break;
  53.         case IOCTL_GPIO_SET_MULTI_PIN:                          /* pInBuf 必须为4字节 */
  54.             if (nInBufSize >= 0)
  55.                 bErr = GPIO_SetAllPin(dwIoControlCode, *(DWORD *)pInBuf);
  56.             //RETAILMSG(TRUE, (TEXT("*(DWORD *)pInBuf is 0x%x)./r/n"), *(DWORD *)pInBuf)); 
  57.         break;
  58.         /*
  59.         *   设置引脚输出低电平
  60.         */
  61.         case IOCTL_GPIO_CLR_PIN:
  62.             if (nInBufSize > 0)
  63.                 bErr = GPIO_ClrPin(dwIoControlCode, *pInBuf);
  64.         break;
  65.         case IOCTL_GPIO_CLR_MULTI_PIN:                          /* pInBuf 必须为4字节 */
  66.             if (nInBufSize > 0)          
  67.                 bErr = GPIO_ClrAllPin(dwIoControlCode, *(DWORD *)pInBuf);
  68.             //RETAILMSG(TRUE, (TEXT("*(DWORD *)pInBuf is 0x%x)./r/n"), *(DWORD *)pInBuf)); 
  69.         break;
  70.         /*
  71.         *   读取引脚电平状态
  72.         */
  73.         case IOCTL_GPIO_READ_PIN:
  74.             if ((nOutBufSize > 0) && (nInBufSize > 0)) 
  75.             {
  76.                 bErr = GPIO_ReadPin(dwIoControlCode, *pInBuf, pOutBuf);
  77.                 *pBytesReturned = 1;
  78.             }
  79.         break;
  80.         case IOCTL_GPIO_READ_ALL_PIN:                         /* pOutBuf 必须为2字节 */
  81.             if (nOutBufSize > 0)   
  82.             {
  83.                 bErr = GPIO_ReadAllPin(dwIoControlCode, (ushort *)pOutBuf, 1);
  84.                 *pBytesReturned = 1;
  85.             }
  86.         break;
  87.         /*  
  88.         *   使能引脚内部上拉
  89.         */
  90.         case IOCTL_GPIO_EN_PULLUP:                            /* *pInBuf 为1字节 */
  91.             if (nInBufSize > 0) 
  92.                 bErr = GPIO_ConfigPullUp(dwIoControlCode, *pInBuf, TRUE);
  93.         break;
  94.         case IOCTL_GPIO_EN_MULTI_PIN_PULLUP:                  /* pInBuf 必须为4字节 */
  95.             if (nInBufSize > 0)  
  96.                 bErr = GPIO_ConfigMultiPinPullup(dwIoControlCode, *(DWORD *)pInBuf, TRUE);
  97.         break;
  98.         /*   
  99.         *   禁止引脚内部上拉
  100.         */
  101.         case IOCTL_GPIO_DIS_PULLUP:
  102.             if (nInBufSize > 0)                               /* *pInBuf 为1字节 */
  103.                 bErr = GPIO_ConfigPullUp(dwIoControlCode, *pInBuf, FALSE);
  104.         break;
  105.         case IOCTL_GPIO_DIS_MULTI_PIN_PULLUP:                 /* pInBuf 必须为4字节 */
  106.             if (nInBufSize > 0)  
  107.                 bErr = GPIO_ConfigMultiPinPullup(dwIoControlCode, *(DWORD *)pInBuf, FALSE);
  108.         break;
  109.         default:
  110.         break;
  111.     }
  112.     return bErr;
  113. }   // PIO_IOControl

周在GPIO的驱动中着重实现了这个接口函数,其余的PIO_Read等函数为空函数。

现在来看看这个应用程序

...........................................

...........................................

在应用程序中,使用了CreateFile函数来以文件形式打开驱动,然后再用deviceiocontrol函数来传递参数控制驱动中的PIO_IOControl函数。这样就实现了功能。

 

在这里值得注意的是,应用和驱动都包含了一个一模一样的gpio.h文件,这个文件是一些命令宏定义,

这个就说明deviceiocontrol传递这些参数给驱动,和PIO_IOControl使用到的参数匹配,这样就完成了整个任务。

哈哈,本文只对初学者有帮助。牛人们千万别笑话。

转载请标明:作gooogleman@foxmail.com 。如有错误,希望能够留言指出。

 

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值