欢迎来到天天文库
浏览记录
ID:58636865
大小:2.76 MB
页数:17页
时间:2020-10-17
《Linux设备树实例分析.docx》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、我们可以从LED程序中榨取很多知识:基本的驱动框架、驱动的简单分层、驱动的分层+分离思想、总线设备驱动模型、设备树等。这大多都是结合韦老师的教程学的。这篇笔记结合LEDdemo(基于设备树)来学习、分析:下面是LED程序的几个层次结构图:注意:层与层之间的箭头指向是相对的,从哪指向哪看你怎么理解。比如有两个函数:函数A和函数B,我们可以说函数A调用函数B,也可以说函数B被函数A调用。本篇基于第⑤个图来分析。我们先来体验一下使用设备树描述引脚信息的方式来点灯。修改内核目录Linux-4.9.88/arch/arm/boot/dts下的100ask_imx6
2、ull-14x14.dts设备树文件。把出厂带的设备树文件的led相关节点给屏蔽掉,然后添加如下节点信息至根节点:#define GROUP_PIN(g,p) ((g<<16)
3、 (p))100ask_led@0 { compatible = "100as,leddrv"; pin = ;};修改后的设备树文件内容如:在内核根目录下使用如下命令编译设备树源文件:makedtbsV=1然后把设备树文件与可加载的led驱动模块、led应用程序上传到板子里:上传成功的文件如下:运行测试:实验过程分析这个实验的le
4、d驱动同样依赖的是总线设备驱动模型。描述设备有两种方法:一种是直接用platform_device结构体来指定,另一种是用设备树来指定。在本次的实验中我们就是用设备树来描述设备。之前我们用platform_device结构体来指定设备信息时,platform_driver是直接从platform_device结构体里拿资源的,如:现在我们用设备树来指定设备信息时,platform_driver是如何获取相关资源的呢?大致过程如下:这里我们还需要注意的一点是:并不是所有的设备树节点都可以转换为platform_device。下面看看几条规则:·根节点下含有
5、compatile属性的子节点能转换为platform_device;·含有特定compatile属性(它的值是"simple-bus","simplemfd","isa","arm,amba-bus"四者之一)的节点的子节点能转换为platform_device;·I2C、SPI总线节点下的子节点 不不不能转换为platform_device,这些总线下的子节点,应该交给对应的总线驱动程序来处理。下面看一个例子:接下来,我们简单来看一下platform_device与platform_driver匹配的函数:这里,我们来看第二种匹配方式(使用设备树时的
6、匹配方式)。下面看看具体如何匹配:其中过程①优先匹配,其次是过程②,最后是过程③。但是,实际上现在主要使用的是过程①的匹配,即匹配compatible属性。过程②与过程③已经过时了,Linux内核不推荐使用这两种匹配方法。在本次实验中,我们的匹配示意图如下:实验代码1、应用程序ledtest.c:int main(int argc, char **argv){ int fd; char status; /* 1. 判断参数 */ if (argc != 3) { printf("Usage: %s 7、 off>", argv8、[0]); return -1; } /* 2. 打开文件 */ fd = open(argv[1], O_RDWR); if (fd == -1) { printf("can not open file %s", argv[1]); return -1; } /* 3. 写文件 */ if (0 == strcmp(argv[2], "on")) { status = 1; write(fd, &status, 1); } else { status = 0; write(fd, &status, 1); } close(fd); 9、 return 0;}运行测试命令:./ledtest /dev/100ask_led0 on./ledtest /dev/100ask_led0 offintmain(intargc,char**argv)形式的main函数相关笔记:main()函数有哪几种形式?。2、驱动层leddrv.c这一层主要是放一些通用的驱动操作函数,核心代码如:驱动程序入口函数:open、write函数:其它代码:其中led的操作结构体如下:3、硬件层:chip_demo_gpio.c这一层主要是一些寄存器相关的操作,及platform_driver相关。与上一个实验代码不10、同的部分就是这个文件。(1)驱动初始化函数:(2)probe函数:当设备树的co
7、 off>", argv
8、[0]); return -1; } /* 2. 打开文件 */ fd = open(argv[1], O_RDWR); if (fd == -1) { printf("can not open file %s", argv[1]); return -1; } /* 3. 写文件 */ if (0 == strcmp(argv[2], "on")) { status = 1; write(fd, &status, 1); } else { status = 0; write(fd, &status, 1); } close(fd);
9、 return 0;}运行测试命令:./ledtest /dev/100ask_led0 on./ledtest /dev/100ask_led0 offintmain(intargc,char**argv)形式的main函数相关笔记:main()函数有哪几种形式?。2、驱动层leddrv.c这一层主要是放一些通用的驱动操作函数,核心代码如:驱动程序入口函数:open、write函数:其它代码:其中led的操作结构体如下:3、硬件层:chip_demo_gpio.c这一层主要是一些寄存器相关的操作,及platform_driver相关。与上一个实验代码不
10、同的部分就是这个文件。(1)驱动初始化函数:(2)probe函数:当设备树的co
此文档下载收益归作者所有