友善之臂 mini2440 linux led 驱动代码,友善之臂mini2440的LEDdriver驱动分析及测试程序...
一,前言:因为友善尚未公布mini2440开发板上的测试程序,所以我自己就写了一个。还好不是太难。
(WINCE6.0+mini2440)
二,首先来分析一下LEDDriver。
2.1,入口函数:(Sources文件里指明了DLLENTRY=DllEntry)
BOOL WINAPI
DllEntry(HANDLEhinstDLL,
DWORD dwReason,
LPVOID /* lpvReserved */)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
DEBUGREGISTER((HINSTANCE)hinstDLL);
return TRUE;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
#ifdef UNDER_CE
case DLL_PROCESS_EXITING:
break;
case DLL_SYSTEM_STARTED:
break;
#endif
}
return TRUE;
}
这里要对dwReason作一些说明,一个程序要调用Dll里的函数,首先要先把DLL文件映射到进程的地址空间。要把一个DLL文件映射到进程的地址空间,有两种方法:静态链接和动态链接的LoadLibrary。当一个DLL文件被映射到进程的地址空间时,传递的dwReason参数为DLL_PROCESS_ATTACH。这种调用只会发生在第一次映射时。如果同一个进程后来为已经映射进来的DLL再次调用LoadLibrary,操作系统只会增加DLL的使用次数,它不会再用DLL_PROCESS_ATTACH调用DLL的DllMain函数。但如果是不同进程用LoadLibrary同一个DLL时,则每个进程的第一次映射都会调用DllMain函数,并传递DLL_PROCESS_ATTACH。(驱动一般会在这个case下或XXX_Init()里作些初始化的工作)。
相反地,当进程结束或者使用FreeLibrary解除DLL的映射时,系统再次调用DLL的DllMain(),此时传递的dwReason就是DLL_PROCESS_DETACH。
当进程创建一个线程时,系统调用DLL的DllMain(),此时传递的dwReason是DLL_THREAD_ATTACH。
当线程结束时,系统调用DLL的DllMain(),此时传递的dwReason是DLL_THREAD_DETACH。
2.2:
DWORD LED_Init(DWORD dwContext)
{
RETAILMSG(1,(TEXT("LED_Init----\r\n")));
// 1. Virtual Alloc
Virtual_Alloc();
LEDGpioInit();
mInitialized = TRUE;
return TRUE;
}
先看一看
void Virtual_Alloc()
{
// GPIO Virtual alloc
s2440IOP = (volatile IOPreg *) VirtualAlloc(0,sizeof(IOPreg),MEM_RESERVE, PAGE_NOACCESS);
if(s2440IOP == NULL) {
RETAILMSG(1,(TEXT("For s2440IOP: VirtualAlloc faiLED!\r\n")));
}
else {
if(!VirtualCopy((PVOID)s2440IOP,(PVOID)(IOP_BASE),sizeof(IOPreg),PAGE_READWRITE | PAGE_NOCACHE )) {
RETAILMSG(1,(TEXT("For s2440IOP: VirtualCopy faiLED!\r\n")));
}
}
}
先是用VirtualAlloc()来预留一块内存,如果成功则用VirtualCopy()映射IOP_BASE到刚申请的一块内存里。
2.3:
BOOL LEDGpioInit()
{
RETAILMSG(1,(TEXT("LED_Gpio_Setting----\r\n")));
s2440IOP->rGPBCON= (s2440IOP->rGPBCON&~(3 << 10)) | (1<< 10);// GPB5 == OUTPUT.
s2440IOP->rGPBCON= (s2440IOP->rGPBCON&~(3 << 12)) | (1<< 12);// GPB6 == OUTPUT.
s2440IOP->rGPBCON= (s2440IOP->rGPBCON&~(3 << 14)) | (1<< 14);// GPB7 == OUTPUT.
s2440IOP->rGPBCON= (s2440IOP->rGPBCON&~(3 << 16)) | (1<< 16);// GPB8 == OUTPUT.
return TRUE;
}
配置跟LED阴级连接的四个IO管脚为输出方向。这里有意思的是,wince对寄存器的访问方式,s2440IOP是一个指向IOPreg结构体的指针,可以看到该结构体的成员排列顺序和datasheet里的寄存器顺序里一样的,并且IOP_BASE的值是0xB1600000(寄存器rGPACON首地址0x56000000映射到内核中的虚拟地址),所以s2440IOP->rGPBCON就是对应寄存器的值了。这跟linux的(首地址+位移)的访问方式有点不一样。
2.4:
BOOL LED_IOControl(DWORD hOpenContext,
DWORD dwCode,
PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut)
{
LEDGpioInit();
switch(dwCode)
{
case IO_CTL_LED_1_ON:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT&~(0x1<<5);
break;
case IO_CTL_LED_2_ON:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT&~(0x1<<6);
break;
case IO_CTL_LED_3_ON:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT&~(0x1<<7);
break;
case IO_CTL_LED_4_ON:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT&~(0x1<<8);
break;
case IO_CTL_LED_ALL_ON:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT&~(0xF<<5);
break;
case IO_CTL_LED_1_OFF:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT|(0x1<<5);
break;
case IO_CTL_LED_2_OFF:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT|(0x1<<6);
break;
case IO_CTL_LED_3_OFF:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT|(0x1<<7);
break;
case IO_CTL_LED_4_OFF:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT|(0x1<<8);
break;
case IO_CTL_LED_ALL_OFF:
s2440IOP->rGPBDAT=s2440IOP->rGPBDAT|(0xF<<5);
break;
default:
break;
}
RETAILMSG(1,(TEXT("LED:Ioctl code = 0x%x\r\n"), dwCode));
return TRUE;
}
这个就是控制LED亮与灭的接口了,其实就是把相应管脚置低或置高。
三,测试程序分别用了win32 API函数和MFC两种方式来实现。见后面的附件。
Win32 API方式:采用了Boling D.的编程风格,这种方式可以自己掌控窗口的创建,窗口过程,对话框的创建,对话框过程。
MFC:相对来说就简单多了,只要动动鼠标,VS就会帮你生成很多代码。------------------------------------------
本文乃原创!
转载请注明出处:http://sparklecliz.cublog.cn/
------------------------------------------
文件:
ledtest.rar
大小:
57KB
下载:
文件:
LedControl.rar
大小:
160KB
下载:
友善之臂 mini2440 linux led 驱动代码,友善之臂mini2440的LEDdriver驱动分析及测试程序...相关推荐
- 友善之臂 mini2440 linux led 驱动代码,[转]mini2440的LEDS驱动程序和测试程序详解
转自:http://blog.csdn.net/garby2004/article/details/4603996 一 leds的驱动程序 位置:linux 2.6.29/drivers/char/m ...
- 友善之臂 mini2440 linux led 驱动代码,mini2440 led驱动程序
这个led驱动程序只在linux-2.6.32.2内核中测试通过,至于其他的内核可能头文件有一些改动就不能 编译成功了.下面给出源程序: 这是友善之臂提供的源码: #include #include ...
- Android 蓝牙驱动专题分析(1)--- 蓝牙驱动代码流程、kernel dump、tombstone问题分析
同学,别退出呀,我可是全网最牛逼的 Android 蓝牙分析博主,我写了上百篇蓝牙文章,请点击下面了解本专栏,进入本博主主页看看再走呗,一定不会让你后悔的,记得一定要去看主页置顶文章哦. 一.概述 不 ...
- Android驱动代码dump,Android 重学系列 ion驱动源码浅析
前言 上一篇文章,在解析初始化GraphicBuffer中,遇到一个ion驱动,对图元进行管理.首先看看ion是怎么使用的: 1.打开驱动: mIonFd = open(ION_DEVICE, O_R ...
- mini2440 linux移植开发实战指南,Linux-2.6.32.2内核在mini2440上的移植---移植SD卡驱动...
移植环境(红色粗字体字为修改后内容,蓝色粗体字为特别注意内容) 1,主机环境:VMare下CentOS 5.5 ,1G内存. 2,集成开发环境:Elipse IDE 3,编译编译环境:arm-linu ...
- ASoC Platform驱动代码框架图
原址 [前言] 在更深入地阅读了工程中 Audio 部分的驱动代码之后,整理出了一个 ASoC Platform 驱动代码的框架图.类似的 ASoC Machine驱动代码框架图在<ASoC M ...
- ASoC Machine驱动代码框架图
原址 [前言] 较久之前写了一篇<Linux ASoC音频驱动架构 及 Machine驱动代码分析>,那个时候刚开始接触 ALSA,文章写得很粗糙.这段时间以来新看了 HAL层.Frame ...
- ASoC Codec驱动代码框架图
原址 [前言] 上个月写了<Audio驱动开发 之 Codec芯片ALC5677驱动代码分析>,但是感觉那个时候理解得还不够深入.写得很粗糙.这一个月以来新看了 HAL层.Framewor ...
- 11.树莓派博通BCM2835芯片手册导读与IO口驱动代码调试和测试
11.树莓派博通BCM2835芯片手册导读与IO口驱动代码调试和测试 硬件地址的相关概念 总线地址 32位的操作系统 ,cpu最多只能访问2^32bit,即只能访问4G的内存 64位的操作系统 ,cp ...
最新文章
- NeurIPS-21 | MGSSL: 基于官能团的分子属性预测图网络自监督预训练
- 今天开始,GitHub将启用main作为默认分支名,master将成为历史!
- js兼容注意事项--仅供参考
- Flume实操(四)【单数据源多出口案例(选择器)】
- Microsoft的现代数据管理
- 《Dubbo迈出云原生重要一步-应用级服务发现解析》
- Given a list,rotate the list to right by k places, where k is nonegative.
- UE4之批量删除actor
- mootools-1.2.1-core.js在IE中显示不了图像翻页
- java实现端口扫描
- Photoshop cc2019 破解教程
- IDEA突然没有SVN了是怎么回事
- 塞尔之光的树心旋转机关_塞尔之光攻略心得_塞尔之光怎么创建人物 塞尔之光角色创建方法详解-公共游戏资源网...
- 网游服务器维护费巨大,全网首例!玩家氪金金额巨大导致服务器瘫痪,官方单独安排客服!...
- matlab离散点数字微分,MATLAB数值积分与微分
- Catherine 成长记第一篇
- 软件开发人员不愿意写文档
- Lattice ECP5 PLL CLKOP和CLKOS的区别
- java实现QQ登陆界面
- css如何调整红心样式_怎么在css中改变光标样式
热门文章
- 高中数学必修2:平面解析几何之直线与圆、圆与圆的位置关系
- SOLIDWOKS文件高版本转低版本,导入ADAMS的注意事项
- 【硬盘测速】一条命令解决硬盘测速问题
- CNN基础论文 精读+复现----LeNet5 (二)
- java发送邮件将附件变成压缩包_请将实训期间制作的网站打成压缩包以附件形式提交。(含相应的文档资料)...
- python开发mbus程序_MBUS 和MODBUS 什么关系啊
- PMP 考点 第十三章 项目相关方管理
- PHP获取当前时间戳
- 经验总结:深度学习怎么找idea发论文?
- 09 --> OpenWRT 的 linux内核patch方法,添加5G模块驱动