【设备树笔记整理7】实践操作

news2024/11/20 3:24:37

1 使用设备树给DM9000网卡_触摸屏指定中断

1.1 修改方法

        根据设备节点的compatible属性,在驱动程序中构造/注册 platform_driver,在 platform_driver 的 probe 函数中获得中断资源。

1.2 实验方法

以下是修改好的代码:第6课第1节_网卡_触摸屏驱动\001th_dm9000\dm9dev9000c.c

第6课第1节_网卡_触摸屏驱动\002th_touchscreen\s3c_ts.c

分别上传到内核如下目录:

drivers/net/ethernet/davicom
drivers/input/touchscreen

(1)编译内核

(2)使用新的uImage启动

(3)测试网卡

ifconfig eth0 192.168.1.101
ping 192.168.1.1

(4)测试触摸屏

hexdump /dev/evetn0 // 然后点击触摸屏

1.3 图示 

(1)图1

(2)图2

(3)图3

2 在设备树中时钟的简单使用

2.1 笔记

(1)设备树中定义了各种时钟,在文档中称之为"Clock providers",比如:

	clocks: clock-controller@4c000000 {
		compatible = "samsung,s3c2440-clock";
		reg = <0x4c000000 0x20>;
		#clock-cells = <1>;      // 想使用这个clocks时要提供1个u32来指定它, 比如选择这个clocks中发出的LCD时钟、PWM时钟
	};

(2)设备需要时钟时,它是"Clock consumers",它描述了使用哪一个"Clock providers"中的哪一个时钟(id),比如:

    fb0: fb@4d000000{
        compatible = "jz2440,lcd";
        reg = <0x4D000000 0x60>;
        interrupts = <0 0 16 3>;
        clocks = <&clocks HCLK_LCD>;  // 使用clocks即clock-controller@4c000000中的HCLK_LCD		
	};

(3)驱动中获得/使能时钟:

	// 确定时钟个数
	int nr_pclks = of_count_phandle_with_args(dev->of_node, "clocks",
						"#clock-cells");
	// 获得时钟
	for (i = 0; i < nr_pclks; i++) {
		struct clk *clk = of_clk_get(dev->of_node, i);
	}

	// 使能时钟
	clk_prepare_enable(clk);

	// 禁止时钟
	clk_disable_unprepare(clk);

(4)参考文档:

  • 内核 Documentation/devicetree/bindings/clock/clock-bindings.txt
  • 内核 Documentation/devicetree/bindings/clock/samsung,s3c2410-clock.txt

2.2 图示 

3 在设备树中pinctrl的简单使用 

3.1 笔记

3.1.1 几个概念

(1)Bank

        以引脚名为依据, 这些引脚分为若干组, 每组称为一个Bank,比如s3c2440里有GPA、GPB、GPC等Bank,每个Bank中有若干个引脚,比如GPA0,GPA1, ...,GPC0,GPC1,... 等引脚。

(2) Group

        以功能为依据, 具有相同功能的引脚称为一个Group,比如s3c2440中串口0的TxD、RxD引脚使用 GPH2,GPH3,那这2个引脚可以列为一组,比如s3c2440中串口0的流量控制引脚使用GPH0,GPH1,那这2个引脚也可以列为一组。

(3)State

        设备的某种状态,比如内核自己定义的"default","init","idel","sleep"状态;也可以是其他自己定义的状态,比如串口的"flow_ctrl"状态(使用流量控制)。设备处于某种状态时,它可以使用若干个Group引脚。

3.1.2 设备树中 pinctrl 节点

(1)它定义了各种 pin bank,比如s3c2440有GPA,GPB,GPC,...,GPB各种BANK,每个BANK中有若干引脚:

	pinctrl_0: pinctrl@56000000 {
		reg = <0x56000000 0x1000>;

		gpa: gpa {
			gpio-controller;
			#gpio-cells = <2>;  /* 以后想使用gpa bank中的引脚时, 需要2个u32来指定引脚 */
		};

		gpb: gpb {
			gpio-controller;
			#gpio-cells = <2>;
		};

		gpc: gpc {
			gpio-controller;
			#gpio-cells = <2>;
		};

		gpd: gpd {
			gpio-controller;
			#gpio-cells = <2>;
		};
	};

(2)它还定义了各种group(组合),某种功能所涉及的引脚称为group,比如串口0要用到2个引脚:gph0,gph1:

	uart0_data: uart0-data {
		samsung,pins = "gph-0", "gph-0";
		samsung,pin-function = <2>;   /* 在GPHCON寄存器中gph0,gph1可以设置以下值:
		                                     0 --- 输入功能
		                                     1 --- 输出功能
		                                     2 --- 串口功能
										  我们要使用串口功能,  
										  samsung,pin-function 设置为2
        	                           */
	};

	uart0_sleep: uart0_sleep {
		samsung,pins = "gph-0", "gph-1";
		samsung,pin-function = <0>;   /* 在GPHCON寄存器中gph0,gph1可以设置以下值:
		                                     0 --- 输入功能
		                                     1 --- 输出功能
		                                     2 --- 串口功能
										  我们要使用输入功能,  
										  samsung,pin-function 设置为0
        	                           */
	};

3.1.3 设备节点中要使用某一个 pin group:

	serial@50000000 {
	    ......
		pinctrl-names = "default", "sleep";  /* 既是名字, 也称为state(状态) */
		pinctrl-0 = <&uart0_data>;
		pinctrl-1 = <&uart0_sleep>;
	};
	
	# pinctrl-names中定义了2种state: default 和 sleep,
	# default 对应的引脚是: pinctrl-0, 它指定了使用哪些pin group: uart0_data
	# sleep   对应的引脚是: pinctrl-1, 它指定了使用哪些pin group: uart0_sleep

3.1.4 platform_device,platform_driver匹配时:

really_probe:
	/* If using pinctrl, bind pins now before probing */
	ret = pinctrl_bind_pins(dev);
				dev->pins->default_state = pinctrl_lookup_state(dev->pins->p,
								PINCTRL_STATE_DEFAULT);  /* 获得"default"状态的pinctrl */
				dev->pins->init_state = pinctrl_lookup_state(dev->pins->p,
								PINCTRL_STATE_INIT);    /* 获得"init"状态的pinctrl */

				ret = pinctrl_select_state(dev->pins->p, dev->pins->init_state);    /* 优先设置"init"状态的引脚 */
				ret = pinctrl_select_state(dev->pins->p, dev->pins->default_state); /* 如果没有init状态, 则设置"default"状态的引脚 */
								
	......
	ret = drv->probe(dev);

所以:如果设备节点中指定了pinctrl,在对应的probe函数被调用之前,先"bind pins",即先绑定、设置引脚。

3.1.5 驱动中想选择、设置某个状态的引脚:

   devm_pinctrl_get_select_default(struct device *dev);      // 使用"default"状态的引脚
   pinctrl_get_select(struct device *dev, const char *name); // 根据name选择某种状态的引脚
   
   pinctrl_put(struct pinctrl *p);   // 不再使用, 退出时调用

3.1.6 参考文档

  • 内核 Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt

3.2 图示

(1)Bank

(2)Group

 (3)State

(4)设备结点

4 使用设备树给LCD指定各种参数

4.1 参考文章

讓TQ2440也用上設備樹(1) - 摩斯电码 - 博客园

4.2 参考代码

https://github.com/pengdonglin137/linux-4.9/blob/tq2440_dt/drivers/video/fbdev/s3c2410fb.c

4.3 实验方法 

(1)替换dts文件

把"jz2440_irq.dts" 放入内核 arch/arm/boot/dts目录

(2)替换驱动文件

把"s3c2410fb.c" 放入内核 drivers/video/fbdev/ 目录,修改内核 drivers/video/fbdev/Makefile:

obj-$(CONFIG_FB_S3C2410)          += lcd_4.3.o

改为:

obj-$(CONFIG_FB_S3C2410)          += s3c2410fb.o

(3)编译驱动、编译dtbs

export  PATH=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/work/system/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin
cp config_ok  .config
make uImage   // 生成 arch/arm/boot/uImage
make dtbs     // 生成 arch/arm/boot/dts/jz2440_irq.dtb

(4)使用上述uImage,dtb启动内核即可看到LCD有企鹅出现

4.4 设备树相关

(1)设备树中的描述

    fb0: fb@4d000000{
        compatible = "jz2440,lcd";
        reg = <0x4D000000 0x60>;
        interrupts = <0 0 16 3>;
        clocks = <&clocks HCLK_LCD>;   /* a. 时钟 */
        clock-names = "lcd";
        pinctrl-names = "default";     /* b. pinctrl */
        pinctrl-0 = <&lcd_pinctrl &lcd_backlight &gpb0_backlight>;
        status = "okay";

		/* c. 根据LCD引脚特性设置lcdcon5, 指定lcd时序参数 */
        lcdcon5 = <0xb09>;
        type = <0x60>;
        width = /bits/ 16 <480>;
        height = /bits/ 16 <272>;
        pixclock = <100000>;       /* 单位: ps, 10^-12 S,  */
        xres = /bits/ 16 <480>;
        yres = /bits/ 16 <272>;
        bpp = /bits/ 16 <16>;
        left_margin = /bits/ 16 <2>;
        right_margin =/bits/ 16  <2>;
        hsync_len = /bits/ 16 <41>;
        upper_margin = /bits/ 16 <2>;
        lower_margin = /bits/ 16 <2>;
        vsync_len = /bits/ 16 <10>;
    };

&pinctrl_0 {
	gpb0_backlight: gpb0_backlight {
		samsung,pins = "gpb-0";
		samsung,pin-function = <1>;
		samsung,pin-val = <1>;
	};
};

4.5 代码中的处理

(1)时钟

info->clk = of_clk_get(dev->of_node, 0);
clk_prepare_enable(info->clk);

(2)pinctrl

代码中无需处理,在platform_device/platform_driver匹配之后就会设置"default"状态对应的pinctrl

(3)根据LCD引脚特性设置lcdcon5,指定lcd时序参数,直接读设备树节点中的各种属性值, 用来设置驱动参数:

	of_property_read_u32(np, "lcdcon5", (u32 *)(&display->lcdcon5));
	of_property_read_u32(np, "type", &display->type);
	of_property_read_u16(np, "width", &display->width);
	of_property_read_u16(np, "height", &display->height);
	of_property_read_u32(np, "pixclock", &display->pixclock);
	of_property_read_u16(np, "xres", &display->xres);
	of_property_read_u16(np, "yres", &display->yres);
	of_property_read_u16(np, "bpp", &display->bpp);
	of_property_read_u16(np, "left_margin", &display->left_margin);
	of_property_read_u16(np, "right_margin", &display->right_margin);
	of_property_read_u16(np, "hsync_len", &display->hsync_len);
	of_property_read_u16(np, "upper_margin", &display->upper_margin);
	of_property_read_u16(np, "lower_margin", &display->lower_margin);
	of_property_read_u16(np, "vsync_len", &display->vsync_len);

4.6 图示 

5 补充笔记

5.1 确定内核的虚拟地址、物理地址的关键信息 

vmlinux虚拟地址的确定,内核源码:

.config :
     CONFIG_PAGE_OFFSET=0xC0000000
     
arch/arm/include/asm/memory.h
    #define PAGE_OFFSET     UL(CONFIG_PAGE_OFFSET)

arch/arm/Makefile
    textofs-y       := 0x00008000
    TEXT_OFFSET := $(textofs-y)

arch/arm/kernel/vmlinux.lds.S:
    . = PAGE_OFFSET + TEXT_OFFSET;   // // 即0xC0000000+0x00008000 = 0xC0008000, vmlinux的虚拟地址为0xC0008000

arch/arm/kernel/head.S
    #define KERNEL_RAM_VADDR       (PAGE_OFFSET + TEXT_OFFSET)  // 即0xC0000000+0x00008000 = 0xC0008000
    
vmlinux物理地址的确定:
内核源码: 
arch/arm/mach-s3c24xx/Makefile.boot :
    zreladdr-y      += 0x30008000   // zImage自解压后得到vmlinux, vmlinux的存放位置
    params_phys-y   := 0x30000100   // tag参数的存放位置, 使用dtb时不再需要tag

arch/arm/boot/Makefile:
    ZRELADDR    := $(zreladdr-y)

arch/arm/boot/Makefile:
    UIMAGE_LOADADDR=$(ZRELADDR)

scripts/Makefile.lib:
    UIMAGE_ENTRYADDR ?= $(UIMAGE_LOADADDR)  

    // 制作uImage的命令, uImage = 64字节的头部 + zImage,  头部信息中含有内核的入口地址(就是vmlinux的物理地址)
    cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(UIMAGE_ARCH) -O linux \
                         -C $(UIMAGE_COMPRESSION) $(UIMAGE_OPTS-y) \
                         -T $(UIMAGE_TYPE) \
                         -a $(UIMAGE_LOADADDR) -e $(UIMAGE_ENTRYADDR) \
                         -n $(UIMAGE_NAME) -d $(UIMAGE_IN) $(UIMAGE_OUT)

5.2 参考

00-Linux设备树系列-简介 - 飞翔de刺猬 - CSDN博客.html
https://blog.csdn.net/lhl_blog/article/details/82387486

Linux kernel的中断子系统之(二):IRQ Domain介绍_搜狐科技_搜狐网.html
http://www.sohu.com/a/201793206_467784

基于设备树的TQ2440的中断(1)
https://www.cnblogs.com/pengdonglin137/p/6847685.html

基于设备树的TQ2440的中断(2)
https://www.cnblogs.com/pengdonglin137/p/6848851.html

基於tiny4412的Linux內核移植 --- 实例学习中断背后的知识(1)
http://www.cnblogs.com/pengdonglin137/p/6349209.html

Linux kernel的中断子系统之(一):综述
http://www.wowotech.net/irq_subsystem/interrupt_subsystem_architecture.html

Linux kernel的中断子系统之(二):IRQ Domain介绍

linux kernel的中断子系统之(三):IRQ number和中断描述符

linux kernel的中断子系统之(四):High level irq event handler

Linux kernel中断子系统之(五):驱动申请中断API

Linux kernel的中断子系统之(六):ARM中断处理过程

linux kernel的中断子系统之(七):GIC代码分析

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/961796.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

1.硬件结构

1.CPU如何执行程序&#xff1f; 图灵机的工作方式 纸带&#xff1a;一个一个连续的格子存放数据&#xff1b; 读写头&#xff1a;读取纸带上格子字符&#xff0c;读写头上有一些部件&#xff0c;比如存储单元、控制单元及运算流程 1、存储单元用于存放数据&#xff1b; 2、控…

《向量数据库指南》——向量数据库与人工智能是一对“双生子

在信息化社会中,数据的产生、储存和处理都成为了现代生活和工作中不可或缺的一部分。在这背景下,向量数据和向量数据库出现并发展起来,为我们解决了大量的问题,但同时也引出了新的问题和挑战。 首先,我们需要明白什么是向量数据。在人工智能时代,传统的结构化数据(如文本…

C++面试题(陆)-数据库(一)

目录 数据库 1.1SQL 1.1.1 介绍一下数据库分页 1.1.2 介绍一下SQL中的聚合函数 1.1.3 表跟表是怎么关联的&#xff1f; 1.1.4 说一说你对外连接的了解 1.1.6 SQL中怎么将行转成列&#xff1f; 1.1.7 谈谈你对SQL注入的理解 1.1.8 将一张表的部分数据更新到另一张表&am…

【wireshark抓取数据包-PGSQL协议】

测试查看PGSQL协议的网络流量数据明细 &#xff11;&#xff09;捕获过滤的条件设置&#xff0c;tcp.port5432(数据库的端口&#xff09; &#xff12;&#xff09;上面是wireshark的主窗口&#xff0c;分三大主块&#xff1a;Packlist List&#xff08;数据包列表&#xff09…

Java设计模式:四、行为型模式-10:访问者模式

一、定义&#xff1a;访问者模式 访问者模式&#xff1a;核心在于同一个事物不同视角下的访问信息不同。 在一个稳定的数据结构下&#xff0c;例如用户信息、雇员信息等&#xff0c;增加易变的业务访问逻辑。为了增强扩展性&#xff0c;将两部分的业务解耦的一种设计模式。 二…

422规范详解

概述&#xff1a; 全称为EIA-TIA-422-B&#xff0c;于1994年发布。 典型电路由一个发送器和N个接收器以及一个中断匹配电阻组成。 发送器&#xff1a; 差分输出电压值在2V~10V之间。 4.1.1 发送器输出阻抗 要求A/B之间的差分阻抗≤100Ω。 4.1.2 开路特性 要求差分电压≤…

高阶MySQL语句

数据准备 create table ky30 (id int,name varchar(10) primary key not null ,score decimal(5,2),address varchar(20),hobbid int(5)); insert into ky30 values(1,liuyi,80,beijing,2); insert into ky30 values(2,wangwu,90,shengzheng,2); insert into ky30 values(3,lis…

手写Mybatis:第8章-把反射用到出神入化

文章目录 一、目标&#xff1a;元对象反射类二、设计&#xff1a;元对象反射类三、实现&#xff1a;元对象反射类3.1 工程结构3.2 元对象反射类关系图3.3 反射调用者3.3.1 统一调用者接口3.3.2 方法调用者3.3.3 getter 调用者3.3.4 setter 调用者 3.4 属性命名和分解标记3.4.1 …

Modbus TCP通信笔记

目录 1 Modbus TCP 数据协议1.1 数据格式1.2 报文头(MBAP头)1.3 功能码1.4 Modbus 地址映射到 CPU 地址 2 Modbus TCP 通讯数据示例2.1 功能码01 读离散输出线圈2.2 功能码02 读离散输入线圈2.3 功能码03 读保持寄存器2.4 功能码04 读输入寄存器2.5 功能码05 写单个离散输出寄存…

DevOps理念:开发与运维的融合

在现代软件开发领域&#xff0c;DevOps 不仅仅是一个流行的词汇&#xff0c;更是一种文化、一种哲学和一种方法论。DevOps 的核心理念是通过开发和运维之间的紧密合作&#xff0c;实现快速交付、高质量和持续创新。本文将深入探讨 DevOps 文化的重要性、原则以及如何在团队中实…

用Rust打印hello world!

步骤1 桌面新建1个名为 rustDemo 的文件夹&#xff08;文件夹名字随便取&#xff09; 步骤2 打开新建的文件夹&#xff0c;在地址输入栏输入 cmd 按回车键进入命令行窗口 步骤3 打开编译器&#xff0c;按 Ctrl S&#xff0c;保存文件到 rustDemo 文件夹中&#xff0c;保存的…

C++算法 —— 分治(1)快排

文章目录 1、颜色分类2、排序数组3、第k个最大的元素&#xff08;快速选择&#xff09;4、最小的k个数&#xff08;快速选择&#xff09; 分治&#xff0c;就是分而治之&#xff0c;把大问题划分成多个小问题&#xff0c;小问题再划分成更小的问题。像快排和归并排序就是分治思…

Linux网络编程 网络基础知识

目录 1.网络的历史和协议的分成 2.网络互联促成了TCP/IP协议的产生 3.网络的体系结构 4.TCP/IP协议族体系 5.网络各层的协议解释 6.网络的封包和拆包 7.网络预备知识 1.网络的历史和协议的分成 Internet-"冷战"的产物 1957年十月和十一月&#xff0c;前苏…

centOS下载与安装

1 下载centOS镜像 The CentOS Project 选择阿里云的镜像 2 下载虚拟机 Vmware workstation VMware - Delivering a Digital Foundation For Businesses 1 下载安装 centOs是一个操作系统&#xff0c;操作硬件的。所以需要有机器&#xff0c;可以使用虚拟机。 2 创建新的虚…

org.mockito:mockito-core 组件安全漏洞及健康度分析

组件简介 维护者mockito组织许可证类型MIT首次发布2008 年 4 月 29 日最新发布时间2023 年 8 月 27 日GitHub Star14159GitHub Fork2478依赖包24,748依赖存储库145,258 org.mockito:mockito-core是一个流行的 Java 模拟框架&#xff0c;它提供了一个简洁的 API 来创建和使用模拟…

【笔记】常用 js 函数

数组去重 Array.from(new Set()) 对象合并 Object.assign . 这里有个细节&#xff1a;当两个对象中含有key相同value不同时&#xff0c;会以 后面对象的key&#xff1a;value为准 保留小数点后几位 toFixed 注意&#xff1a; Number型&#xff0c;用该方法处理完&#xff0c;会…

Windows右键添加用 VSCODE 打开

1.安装VSCODE时 安装时会有个选项来添加&#xff0c;如下&#xff1a; ①将“通过code 打开“操作添加到windows资源管理器文件上下文菜单 ②将“通过code 打开”操作添加到windows资源管理器目录上下文菜单 说明&#xff1a;①②勾选上&#xff0c;可以对文件&#xff0c;目…

O2OA(翱途)开发平台 V8.1正式发布

尊敬的O2OA(翱途)平台合作伙伴、用户以及亲爱的开发小伙伴们&#xff0c;平台 V8.1版本已正式发布。正值8月的最后一周&#xff0c;我们以更安全、更高效、更好用的崭新面貌迎接9月的到来。 O2OA开发平台v8.1版本更注重于对系统级别的安全防护。其中重大的更新&#xff0c;是对…

Re44:数据集 GSM8K 和 论文 Training Verifiers to Solve Math Word Problems

诸神缄默不语-个人CSDN博文目录 论文全名&#xff1a;Training Verifiers to Solve Math Word Problems GSM8K数据集原始论文 OpenAI 2021年的工作&#xff0c;关注解决MWP问题&#xff08;具体场景是小学&#xff08;grade school&#xff09;数学题&#xff09;&#xff0c…

Java设计模式:四、行为型模式-09:模板模式

文章目录 一、定义&#xff1a;模板模式二、模拟场景&#xff1a;模板模式三、改善代码&#xff1a;模板模式3.0 引入依赖3.1 工程结构3.2 模板模式结构图3.3 爬取商品生成海报实现3.3.1 HTTP获取连接类3.3.2 定义执行顺序的抽象类3.3.3 当当爬取抽象实现类3.3.4 京东爬取抽象实…