Chinaunix首页 | 论坛 | 博客
  • 博客访问: 469920
  • 博文数量: 164
  • 博客积分: 4024
  • 博客等级: 上校
  • 技术积分: 1580
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-10 16:27
文章分类

全部博文(164)

文章存档

2011年(1)

2010年(108)

2009年(55)

我的朋友

分类: 嵌入式

2010-04-02 09:58:37

 

一、编写LED驱动程序
具体代码请参考 \WINCE500\PLATFORM\SMDK2440A\Src\Drivers\wyleddrvr
1、Wyleddrvr.cpp LED流驱动文件
标准流接口驱动函数

 

 
 
1) DWORD LED_Init(DWORD dwContext)
   该函数是驱动挂载后第一个被执行的,主要负责完成对设备的初始化操作和驱动的安全性检查。
DWORD LED_Init(DWORD dwContext)

   DWORD isSuccess=1;//assume success
   DWORD error=0;  //接受出错码
     /* IO Register Allocation */
   RETAILMSG(1,(TEXT("LED_init\r\n")));
   //为v_pIOPregs变量分配虚拟空间
   v_pIOPregs = (volatile S3C2440A_IOPORT_REG *)VirtualAlloc(0, sizeof(S3C2440A_IOPORT_REG), MEM_RESERVE,PAGE_NOACCESS);
   if (v_pIOPregs == NULL) //分配虚拟空间不成功
 {
  ERRORMSG(1,(TEXT("For IOPregs : VirtualAlloc failed!\r\n")));
  error=GetLastError();   //获得出错码
  printf("For IOPregs : VirtualAlloc failed!%d\r\n",error);
  isSuccess = 0;
 }
    else
 {
  if(!VirtualCopy((PVOID)v_pIOPregs, (PVOID)(S3C2440A_BASE_REG_PA_IOPORT >> 8), sizeof(S3C2440A_IOPORT_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))  /*把v_pIOPregs虚拟空间映射到物理内存*/
  {
   ERRORMSG(1,(TEXT("For IOPregs: VirtualCopy failed!\r\n")));
   isSuccess = 0;
  }
 }
     if (!isSuccess)  /*分配虚拟空间或映射到物理内存失败*/
 {
  if (v_pIOPregs) /* 如果v_pIOPregs变量非无效*/
  {
   VirtualFree((PVOID) v_pIOPregs, 0, MEM_RELEASE); /*释放虚拟空间*/
  }

 

  v_pIOPregs = NULL;
 }
 return (isSuccess);
}

2) BOOL LED_Deinit( DWORD dwData)
整个驱动中最后执行。用来停止和卸载设备
BOOL LED_Deinit( DWORD dwData)
{
DEBUGMSG(ZONE_PDD, (_T("LED_Deinit: invoked\r\n")));
 if (v_pIOPregs)  /* 如果v_pIOPregs变量非无效*/
   {
     VirtualFree((PVOID) v_pIOPregs, 0, MEM_RELEASE); /*释放虚拟空间*/  
     v_pIOPregs = NULL;
   }
   return true;
}

3)BOOL LED_Open( DWORD dwData,DWORD dwAccess,DWOR dwShareMode)
打开设备,此驱动不需要这个操作直接返回TRUE

4)BOOL LED_Close( DWORD dwData)
关闭设备,此驱动不需要这个操作直接返回TRUE

5)DWORD LED_Read( DWORD dwData,LPVOID pBuf, DWORD dwLen)
读LED状态
DWORD LED_Read( DWORD dwData,LPVOID pBuf, DWORD dwLen)
{
 return (v_pIOPregs->GPBDAT  & 0x01 << 4);  /*返回led灯的状态,返回0表示灯亮,返回非0值表示灯灭*/                                     
}

6) DWORD LED_Write(DWORD dwData,LPCVOID pInBuf,DWOR dwInLen);
    写设备,pInBuf为缓冲区指针,由writefile()函数传递过来
    DWORD LED_Write(DWORD dwData,LPCVOID pInBuf,DWORD dwInLen)
{  
v_pIOPregs->GPFCON |=0x01<< 8; //配置为输出模式
if((v_pIOPregs->GPBDAT & 0x1<< 4)) //读灯的状态,如果是灭的
{
       v_pIOPregs->GPBDAT &=0x0<< 4;   //打开灯
 return true;
}
else
{
       v_pIOPregs->GPBDAT |=0x1 << 4     //否则开闭灯
return true;
}
}

7 )
void LED_PowerUp( DWORD hDeviceContext );
void LED_PowerDown( DWORD hDeviceContext );
DWORD LED_Seek(DWORD dwData,long pos,DWORD type);
BOOL LED_IOControl(DWORD dwData,DWORD dwCode, PBYTE
pBufIn,DWORD dwLenIn,PBYTE pBufOut,
DWORD dwLenOut,PDWORD pdwActualOut); 
上面这些流接口函数是有关电源管理和IO操作的,这里用不到,所以插入空
码或直接返回。

8)
BOOL WINAPI DllMain(HANDLE hInstDLL, DWORD dwReason, LPVOID lpvReserved)
流驱动入口函数

注意:在写流驱动时为了把接口函数暴露出来给应用程序调用,在实现流驱动
之前对流驱动接口函数进行声名。或者写个头文件把接口函数的声名放
这个头文件里,再写个cpp文件包含这个头文件,然后再实现这些流驱动。

 

 

2、wyledrvr.def 接口文件
  .def文件的作用就是把流接口函数暴露出来

 

3、Sources 编译控制文件

 

TARGETNAME=wyleddrvr   指定目标名
TARGETTYPE=DYNLINK     指定编译成dll即动态链接库
DLLENTRY=DllMain       指定DllMain为驱动入口函数
DEFFILE=myleddri.def   指定myleddri.def流接口函数暴露文件
TARGETLIBS=$(_SYSGENSDKROOT)\lib\$(_CPUINDPATH)\coredll.lib \
           $(_SYSGENOAKROOT)\lib\$(_CPUINDPATH)\ceddk.lib \   指定要用到的库

SOURCES = \
        wyleddrvr.cpp    指定要编译的源文件

 4、wyleddrvr.reg 注册表文件

 
 
  "Prefix"="LED"   指定驱动程序的前缀,要跟XXX_init等函数一致
  "Dll"="wyleddrvr.dll" 指定调用的动态库
  "Order"=dword:0   指定加载顺序,0表示最先加载
  "Index"=dword:1   表示索引号,应用程序通过Prefix指定的前缀和索引号来打开此设备,比如之前应用程序CreateFile打开的LED1

二、建立LED流驱动框架
1、在WINCE根目录的PLATFORM\SMDK2440A\Src\Drivers(比如 F:\WINCE500\PLATFORM\SMDK2440A\Src\Drivers)新建一个文件夹wyleddrvr,用来存放驱动程序,把我们编写好的流驱动程序相关的文件wyleddrvr.cpp、myleddrvr.reg、wyleddrvr.def、Sources文件放在些目录下。

2、打开PB5.0,新建一个工程文件,具体操作请参考手册有关wince部分,注意要生成中文的内核,按照手册添加完必要的驱动后,在PB中的Fileview找到PLATFORM\SMDK2440A\drivers\myleddrvr驱动,点右键选择Built Curret Project编译此驱动程序。编译后,在WINCE500\PLATFORM\SMDK2440A\target\ARMV4I\retail生成一个wyleddrvr.dll动态链接库。

 

如果想把驱动程序编译进内核让wince启动自己加载,请按照如下步骤进行:
   a、在WINCE500\PLATFORM\SMDK2440A\Src\Drivers目录下修改dirs文件,在
#     AtapiRomi之前添加wyleddrvr \

 

 

b、打开PB5.0,在ParameterView下修改platform.bib和platform.reg文件,在platform.bib添加如下内容
      wyleddrvr.dll     $(_FLATRELEASEDIR)\wyleddrvr.dll            NK   SH

 

在platform.reg添加如下内容
       [HKEY_LOCAL_MACHINE\Drivers\BuiltIn\WyLedDrvr]
            "Prefix"="LED"
            "Index"=dword:1
            "Dll"="wyleddrvr.dll"
            "Order"=dword:0
    
   c、在菜单上选择Build OS/Sysgen(注意把Copy files to Release Directory After Build 和Make Run-time Image After Build选上)重新编译内核。

三、加载USB同步驱动
1、把编译好的NK.bin烧写到开发板上,烧写步骤参考手册。
2、安装ActiveSync4.5,ActiveSync是USB同步功能
3、安装USB同步驱动。将 USB 打印线一头接在WY2440的 USB DEV口,另一头插
在 PC 的 USB 口上,进入 WINCE5.0 系统后,PC会提供发现新的硬件,如下:
a.选择“否,暂时不”点击下一步;
b.选择“从列表或指定位置安装”点击下一步;
c.点击“浏览”,选择USB同步驱动wceusbsh.inf的目录,点击下一步;
d.提示该驱动“没有通过Windows微标测试”时,点解仍然继续;
e.点击完成,驱动安装完毕。

此时同步软件 Activesync 会自动打开,第一次使用时会提供 USB 同步是否选择同步,选择后要将“文件”部分选上,确定后将出现下面窗口进入。全部使用默认的配置,不需要作修改。 选择是,然后下一步。

 

 

 

 

 

4、完成以上步骤后,打开我的电脑,可以看到有一个“移动设备”的图标,这时打开“移动设备”就可以对wince的目录进行读写操作,把之前生成的wyleddrvr.dll放到wince的windows目录下,把我们提供驱动调试工具DM.exe和myleddrvr.reg放在wince当前目录。

 

5、点击触摸屏100打开“我的设备”,双击运行驱动调试工具DM.exe,打开驱动调试->导入注册表,把led驱动信息添加到注册表中,再点击激活驱动led灯驱动就加载进系统进程了,此时本来亮着的led灯就灭了,led驱动加载正常

 

 

 

 

 

 

 

 

 

 

 


 

 

阅读(1782) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~