zoukankan      html  css  js  c++  java
  • 转:WinCE应用程序如何调用驱动程序

    下面针对流式程序:
    流式程序主要是对IO口进行控制的。下面主要是对LED的控制。
        在驱动程序里面有个xxx_iocontrol()函数(xxx为驱动的名字),这个函数主要是对IO口的控制,
    你要对IO口实现怎样的控制都可以在这里编写。比如:
    BOOL LED_IOControl(DWORD hOpenContext, //XXX_Open返回给上层的那个句柄
           DWORD dwCode, //IO操作码
           PBYTE pBufIn, //传入的Buffer,每个IO操作码都会定义自已的Buffer结构
           DWORD dwLenIn, //以字节记的大小
           PBYTE pBufOut, //分别为传出的Buffer,及其以字节记的大小
           DWORD dwLenOut, 
           PDWORD pdwActualOut)
    {
     switch(dwCode)
     {
     case IO_CTL_GPIO_1_ON:
      v_pIOPregs->GPFDAT=v_pIOPregs->GPFDAT&~(0x1<<4);
      break;
     case IO_CTL_GPIO_2_ON:
      v_pIOPregs->GPFDAT=v_pIOPregs->GPFDAT&~(0x1<<5);
      break;
     case IO_CTL_GPIO_3_ON:
      v_pIOPregs->GPFDAT=v_pIOPregs->GPFDAT&~(0x1<<6);
      break;
     case IO_CTL_GPIO_4_ON:
      v_pIOPregs->GPFDAT=v_pIOPregs->GPFDAT&~(0x1<<7);
      break;
     case IO_CTL_GPIO_ALL_ON:
      v_pIOPregs->GPFDAT=v_pIOPregs->GPFDAT&~(0xF<<4);
      break;
     case IO_CTL_GPIO_1_OFF:
      v_pIOPregs->GPFDAT=v_pIOPregs->GPFDAT|(0x1<<4);
      break;
     case IO_CTL_GPIO_2_OFF:
      v_pIOPregs->GPFDAT=v_pIOPregs->GPFDAT|(0x1<<5);
      break;
     case IO_CTL_GPIO_3_OFF:
      v_pIOPregs->GPFDAT=v_pIOPregs->GPFDAT|(0x1<<6);
      break;
     case IO_CTL_GPIO_4_OFF:
      v_pIOPregs->GPFDAT=v_pIOPregs->GPFDAT|(0x1<<7);
      break;
     case IO_CTL_GPIO_ALL_OFF:
      v_pIOPregs->GPFDAT=v_pIOPregs->GPFDAT|(0xF<<4);
      break;
     default:
      break;
     }
        
     RETAILMSG(1,(TEXT("LED_Control:Ioctl code = 0x%x/r/n"), dwCode));
     return TRUE;

      调用它的是DeviceIoControl()在应用程序里面,实现对GPIO的控制(高低电平控制)
    如:
    void CFlowLEDDlg::OnLedOn() 
    {
     // TODO: Add your control notification handler code here
     BOOL ret;
     
     ret=::DeviceIoControl(hFile,IO_CTL_GPIO_ALL_ON,NULL, 1,NULL,0,NULL,NULL);
     
     if(ret!=TRUE)
      
     {
      
      MessageBox(_T("关闭LED失败!"));
      
      MessageBox(_T("请打开GPIO驱动!"));
      
     }


     
    }
    看到没IO_CTL_GPIO_ALL_ON与LED_IOControl()语句是不是对应呢,当你按下该建后,
    就会执行LED_IOControl()中的:
    case IO_CTL_GPIO_1_ON:
    v_pIOPregs->GPFDAT=v_pIOPregs->GPFDAT&~(0x1<<4);
    break;
    也就灯亮。
    解析:ret=::DeviceIoControl(hFile,IO_CTL_GPIO_ALL_ON,NULL, 1,NULL,0,NULL,NULL);
    ret定义的是一个bool值,::是作用域标识符,它的意思是调用的全局函数。调用的系统的API
    从当前窗口中得到该改窗口的值。


     当然在试验之前我们需要打开驱动,像上面一样,在底层驱动里面的函数为:
    DWORD LED_Open(DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode)
    {
     v_pIOPregs->GPFDAT=v_pIOPregs->GPFDAT|(0xF<<4);  //这里是打开gpio的:5 6 7 8

     RETAILMSG(1,(TEXT("LED_Control: LED_Open/r/n")));
     return TRUE;
    }

      同样在应用程序里面调用的是:CreateFile()函数来打开该驱动。
    void CFlowLEDDlg::OnOpenGpio() 
    {
     // TODO: Add your control notification handler code here
     hFile=CreateFile(TEXT("LED0:"),GENERIC_READ | GENERIC_WRITE,0, NULL,OPEN_EXISTING,0,0);
                     //若打开怎返回一个不为INVALID_HANDLE_VALUE的句柄。
     if(hFile==INVALID_HANDLE_VALUE)
     {
              MessageBox(_T("打开GPIO驱动失败!"));
     } 
     else
     {
       MessageBox(_T("打开GPIO驱动成功!")); 
     } 
      
    }
    其中:

     “LED0:”中的表示设备好“0”是必需的,不管你的设备当中是不是刚好只有一个,不然的话
    会出现打开不了这个设备的情况。
       当用户程序调用CreateFile打开这个设备时,设备管理器就会调用此驱动程序的XXX_Open函数
    同理:有打开驱动必然有关闭驱动, 
    在底层驱动里面的函数为:
    BOOL LED_Close(DWORD hOpenContext)
    {
           v_pIOPregs->GPFDAT=v_pIOPregs->GPFDAT&(0xF<<4);
           RETAILMSG(1,(TEXT("LED_Control: LED_Close/r/n")));
           return TRUE;
    }
    在应用程序里面对应的是:
    void CFlowLEDDlg::OnCloseGpio() 
    {
     // TODO: Add your control notification handler code here
     if(hFile!=INVALID_HANDLE_VALUE)
     {
              CloseHandle(hFile);
       MessageBox(_T("关闭GPIO驱动成功!"));
      
     }
     
     else
     { 
        MessageBox(_T("关闭GPIO驱动失败!"));
     }

    }

    总结:
        用应用程序控制GPIO的时候,第一打开驱动,当我们按下打开驱动按键的时候,应用程序执行的
    是CreateFile()函数,当CreateFile()打开设备管理器的时候,设备管理器就会调用XXX_Open()
    函数打开此驱动程序
       关闭驱动的时候可以直接调用CloseHandle关闭这个设备句柄时,LED_Close()函数就会被设备
    管理器调用来关闭驱动。
       当驱动打开后,就可以对GPIO进行操作了,当用户想叫那个LED亮的时候,按下此键,应用程序
    执行DeviceIoControl()函数,通过其第二参数的返回值来调用底层驱动函数LED_IOControl()
    函数。灯灭函数同理。

  • 相关阅读:
    HDU 2896 病毒侵袭 AC自动机
    AC自动机
    BZOJ2337: [HNOI2011]XOR和路径 期望概率dp 高斯
    BZOJ4008. [HNOI2015]亚瑟王 期望概率dp
    BZOJ 2707: [SDOI2012]走迷宫 拓扑+高斯消元+期望概率dp+Tarjan
    CodeForces743E. Vladik and cards 二分+状压dp
    BZOJ 3270 博物馆 && CodeForces 113D. Museum 期望概率dp 高斯消元
    BZOJ1415: [Noi2005]聪聪和可可 最短路 期望概率dp
    CodeForces 167B
    [HEOI2017]分手是祝愿 期望概率dp 差分
  • 原文地址:https://www.cnblogs.com/killer-xc/p/6758652.html
Copyright © 2011-2022 走看看