wince +arm 开发流程
2010-08-27 14:15
253 查看
一、编写LED驱动程序
具体代码请参考 /WINCE500/PLATFORM/SMDK2440A/Src/Drivers/wyleddrvr
1、Wyleddrvr.cpp LED流驱动文件
标准流接口驱动函数
![](http://www.gzweiyan.com/uploads/userup/0809/0ZR2034942.jpg)
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文件包含这个头文件,然后再实现这些流驱动。
![](http://www.gzweiyan.com/uploads/userup/0809/0ZR30H614.jpg)
2、wyledrvr.def 接口文件
.def文件的作用就是把流接口函数暴露出来
![](http://www.gzweiyan.com/uploads/userup/0809/0ZR351G42.jpg)
3、Sources 编译控制文件
![](http://www.gzweiyan.com/uploads/userup/0809/0ZR44B5L.jpg)
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 注册表文件
![](http://www.gzweiyan.com/uploads/userup/0809/0ZS21394V.jpg)
"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动态链接库。
![](http://www.gzweiyan.com/uploads/userup/0809/0ZR64D617.jpg)
如果想把驱动程序编译进内核让wince启动自己加载,请按照如下步骤进行:
a、在WINCE500/PLATFORM/SMDK2440A/Src/Drivers目录下修改dirs文件,在
# AtapiRomi之前添加wyleddrvr /
![](http://www.gzweiyan.com/uploads/userup/0809/06231Q3aT.jpg)
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 同步是否选择同步,选择后要将“文件”部分选上,确定后将出现下面窗口进入。全部使用默认的配置,不需要作修改。 选择是,然后下一步。
![](http://www.gzweiyan.com/uploads/userup/0809/0ZR9111138.jpg)
![](http://www.gzweiyan.com/uploads/userup/0809/0ZR9294G9.jpg)
![](http://www.gzweiyan.com/uploads/userup/0809/0ZS014Z07.jpg)
![](http://www.gzweiyan.com/uploads/userup/0809/0ZR9493504.jpg)
4、完成以上步骤后,打开我的电脑,可以看到有一个“移动设备”的图标,这时打开“移动设备”就可以对wince的目录进行读写操作,把之前生成的wyleddrvr.dll放到wince的windows目录下,把我们提供驱动调试工具DM.exe和myleddrvr.reg放在wince当前目录。
![](http://www.gzweiyan.com/uploads/userup/0809/0ZS1003111.jpg)
5、点击触摸屏100打开“我的设备”,双击运行驱动调试工具DM.exe,打开驱动调试->导入注册表,把led驱动信息添加到注册表中,再点击激活驱动led灯驱动就加载进系统进程了,此时本来亮着的led灯就灭了,led驱动加载正常
![](http://www.gzweiyan.com/uploads/userup/0809/06232435S26.jpg)
![](http://www.gzweiyan.com/uploads/userup/0809/0FQ2061931.jpg)
具体代码请参考 /WINCE500/PLATFORM/SMDK2440A/Src/Drivers/wyleddrvr
1、Wyleddrvr.cpp LED流驱动文件
标准流接口驱动函数
![](http://www.gzweiyan.com/uploads/userup/0809/0ZR2034942.jpg)
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文件包含这个头文件,然后再实现这些流驱动。
![](http://www.gzweiyan.com/uploads/userup/0809/0ZR30H614.jpg)
2、wyledrvr.def 接口文件
.def文件的作用就是把流接口函数暴露出来
![](http://www.gzweiyan.com/uploads/userup/0809/0ZR351G42.jpg)
3、Sources 编译控制文件
![](http://www.gzweiyan.com/uploads/userup/0809/0ZR44B5L.jpg)
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 注册表文件
![](http://www.gzweiyan.com/uploads/userup/0809/0ZS21394V.jpg)
"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动态链接库。
![](http://www.gzweiyan.com/uploads/userup/0809/0ZR64D617.jpg)
如果想把驱动程序编译进内核让wince启动自己加载,请按照如下步骤进行:
a、在WINCE500/PLATFORM/SMDK2440A/Src/Drivers目录下修改dirs文件,在
# AtapiRomi之前添加wyleddrvr /
![](http://www.gzweiyan.com/uploads/userup/0809/06231Q3aT.jpg)
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 同步是否选择同步,选择后要将“文件”部分选上,确定后将出现下面窗口进入。全部使用默认的配置,不需要作修改。 选择是,然后下一步。
![](http://www.gzweiyan.com/uploads/userup/0809/0ZR9111138.jpg)
![](http://www.gzweiyan.com/uploads/userup/0809/0ZR9294G9.jpg)
![](http://www.gzweiyan.com/uploads/userup/0809/0ZS014Z07.jpg)
![](http://www.gzweiyan.com/uploads/userup/0809/0ZR9493504.jpg)
4、完成以上步骤后,打开我的电脑,可以看到有一个“移动设备”的图标,这时打开“移动设备”就可以对wince的目录进行读写操作,把之前生成的wyleddrvr.dll放到wince的windows目录下,把我们提供驱动调试工具DM.exe和myleddrvr.reg放在wince当前目录。
![](http://www.gzweiyan.com/uploads/userup/0809/0ZS1003111.jpg)
5、点击触摸屏100打开“我的设备”,双击运行驱动调试工具DM.exe,打开驱动调试->导入注册表,把led驱动信息添加到注册表中,再点击激活驱动led灯驱动就加载进系统进程了,此时本来亮着的led灯就灭了,led驱动加载正常
![](http://www.gzweiyan.com/uploads/userup/0809/06232435S26.jpg)
![](http://www.gzweiyan.com/uploads/userup/0809/0FQ2061931.jpg)
相关文章推荐
- Pascal 的春天 -- Freepascal 可开发 WinCE/ARM-Linux程序
- ARM嵌入式常用开发工具介绍及插画开发流程(更新)
- ARM 中断驱动程序的开发流程(以s3c2440开发板为例)
- ARM裸板开发配置流程一
- Wince 嵌入式系统开发流程
- WINCE+ARM开发工作概要
- ARM-Linux开发环境的介绍:启动的流程
- WinCE的开发流程
- arm wince smartphone开发环境配置 evc4.0通过ActiveSync连接仿真器,模拟器
- 详解 Arm linux QT 程序开发流程(转)
- ARM+WinCE+Linux嵌入式技术开发交流群
- 在基于ARM的Wince开发中,遇到“本机异常”……
- ARM-LINUX环境塔建开发流程
- 也谈WinCE底层开发学习流程
- VS2005 WINCE 流驱动开发流程 转载
- 【嵌入式开发】 Bootloader 详解 ( 代码环境 | ARM 启动流程 | uboot 工作流程 | 架构设计)
- 在arm linux QT开发流程
- WinCE板级支持包开发学习之WinCE的初始化驱动流程
- 基于ARM和WINCE的开发
- 详解 Arm linux QT 程序开发流程