继续来点灯 我们可以从LED程序中榨取很多知识:基本的驱动框架、驱动的简单分层、驱动的分层分离思想、总线设备驱动模型、设备树等。这大多都是结合韦老师的教程学的,这篇笔记结合第5个demo来学习、分析: 框图 LED程序的几个层次结构图: 本篇笔记基于第个图来分析。程序分析 关于总线设备驱动模型的理论知识我们在上一篇笔记Linux总线设备驱动模型中也有简单地学习过了。这篇笔记我们来分析、学习程序。下面分析主要基于上面的框图4。应用程序ledtest。c:intmain(intargc,charargv){1。判断参数if(argc!3){printf(Usage:sdevonoff,argv〔0〕);return1;}2。打开文件fdopen(argv〔1〕,ORDWR);if(fd1){printf(cannotopenfiles,argv〔1〕);return1;}3。写文件if(0strcmp(argv〔2〕,on)){status1;write(fd,status,1);}else{status0;write(fd,status,1);}close(fd);return0;} 运行测试命令:。ledtestdev100askled0on。ledtestdev100askled0off 驱动层leddrv。c 这一层主要是放一些通用的驱动操作函数,核心代码如: 驱动程序入口函数: open、write函数: 其它代码: 其中led的操作结构体如下: 硬件层2:chipdemogpio。c 这一层主要是一些寄存器相关的操作,及platformdriver相关。 驱动初始化函数: probe函数: platformdriver与platformdevice匹配时会执行此函数获取资源。 led寄存器操作相关的代码:寄存器物理地址defineCCMCCGR1BASE(0X020C406C)defineSWMUXGPIO5IO03BASE(0X02290014)defineGPIO5DRBASE(0X020AC000)defineGPIO5GDIRBASE(0X020AC004)映射后的寄存器虚拟地址指针staticvoidiomemCCMCCGR1;staticvoidiomemSWMUXGPIO5IO03;staticvoidiomemGPIO5DR;staticvoidiomemGPIO5GDIR;初始化LED,which哪个LEDstaticintboarddemoledinit(intwhich){intgroup,groupGROUP(gledpins〔which〕);pinPIN(gledpins〔which〕);printk(initgpio:groupd,pind,group,pin);100askIMX6uLLBoardLED:GPIO53if((5group)(3pin)){相关寄存器物理地址与虚拟地址之间的映射1、地址映射:时钟寄存器CCMCCGR1ioremap(CCMCCGR1BASE,4);2、地址映射:模式寄存器SWMUXGPIO5IO03ioremap(SWMUXGPIO5IO03BASE,4);3、地址映射:数据寄存器GPIO5DRioremap(GPIO5DRBASE,4);地址映射:方向寄存器GPIO5GDIRioremap(GPIO5GDIRBASE,4);使能GPIO5时钟valreadl(CCMCCGR1);读出当前CCMCCGR1配置值val(330);清除以前的设置val(330);设置新值writel(val,CCMCCGR1);设置GPIO5IO03的为IO模式writel(5,SWMUXGPIO5IO03);设置GPIO5IO03方向为输出valreadl(GPIO5GDIR);val(13);val(13);writel(val,GPIO5GDIR);}else{printk(Thisisnot100askIMX6ULLBoard!);}return0;}控制LED,which哪个LED,status:1亮,0灭staticintboarddemoledctl(intwhich,charstatus){intgroup,groupGROUP(gledpins〔which〕);pinPIN(gledpins〔which〕);printk(initgpio:groupd,pind,group,pin);100askIMX6uLLBoardLED:GPIO53if((5group)(3pin)){点灯if(1status){printk(ledon);valreadl(GPIO5DR);val(13);writel(val,GPIO5DR);}灭灯elseif(0status){printk(ledoff);valreadl(GPIO5DR);val(13);writel(val,GPIO5DR);}else{}}else{printk(Thisisnot100askIMX6ULLBoard!);}return0;}硬件层1:boardAled 这一层主要是一些资源及platformdevice相关的代码。 核心代码: Makefile文件 运行测试 首先把编译生成以下几个文件上传到板子里:boardAled。ko chipdemogpio。ko leddrv。ko ledtest 这里我们使用百问网开发的100askimx6ullflashingtool工具来上传,如: 也可以使用开发板挂载NFS来上传这几个文件,关于NFS可查看往期笔记:如何挂载网络文件系统? 100askimx6ullflashingtool工具默认把文件上传到根目录,我们上传成功的文件如下: 接下来,使用insmod命令来安装驱动模块leddrv。ko、chipdemogpio。ko、boardAled。ko,安装这几个模块是有顺序的,需要先安装leddrv。ko模块。 假如我们先安装chipdemogpio。ko模块,就会出现如下提示信息: 提示说明chipdemogpio模块中找不到ledclasscreatedevice等函数,那是因为这几个函数是从leddrv模块中导出来的: 所以需要先安装leddrv。ko模块,再安装chipdemogpio。ko模块。安装模块成功的结果如下: 最后,输入测试命令进行测试: 打印信息表明测试成功、同时板子上的led也相应的亮、灭。 以上就是本次的实验分享,如有错误,欢迎指出!谢谢 1024G嵌入式资源大放送!包括但不限于CC、单片机、Linux等。私信回复1024,即可免费获取!