08 GPIO子系统
GPIO子系统GPIO子系统是 Linux 内核中用于管理和控制通用输入/输出引脚的核心框架,它为开发者提供了统一的接口来操作硬件上的 GPIO 引脚,使用前需要用pinctrl将该引脚的复用配置成GPIO 驱动架构GPIO子系统的驱动同样遵循着“主机驱动和设备驱动分离”和“驱动分层”的思想,分为主机驱动层、核心层、设备驱动层 主机驱动层主机(GPIO控制器)驱动一般由原厂提供,且也作为设备树中的一个节点 SoC内部对于GPIO一般都有专门的控制器外设,它直接位于SoC的内存空间,通过配置该外设的寄存器,从而控制某个具体的GPIO 12345678910111213141516/{ soc{ aips1{ gpio1: gpio@0209c000 { compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio"; reg = <0x0209c000 0x4000>; interrupts =...
10 Linux内核定时器
Linux内核定时器 在编写驱动的时候,可能也会用到定时器,比如按键消抖…由于驱动的代码是在内核态,所以就需要使用内核态的定时器,而不是用户态的定时器 Linux内核的定时器相对于以前STM32用的定时器,有以下区别: 内核定时器是软件定时器,采用系统时钟实现,并不是硬件定时器 定时器超时是由软件设置和管理的,通过内核或者应用程序来控制,而回调函数的执行是在预定的时间点或者时间间隔后发生的,不算中断 内核定时器不是周期运行的,超时后就会停止,需要手动再次开启(如果还需要用的话) 1.基本数据结构Linux内核使用如下的结构体来描述一个定时器: 12345678struct timer_list { struct list_head entry; unsigned long expires; /* 定时器超时时间,单位是节拍数 */ struct tvec_base *base; void (*function)(unsigned long); /* 定时处理函数 */ unsigned long data; /*...
09 MISC设备驱动框架
MISC设备驱动框架 MISC设备又称杂项设备,由于一些设备不好分类,所有可以把他们都归到杂项设备里面。字符设备也可以看成一种杂项设备,使用MISC驱动框架时,可以简化字符设备驱动的开发 Misc是Linux驱动开发里的一个子系统,它也遵循了驱动分层的思想,用一个核心层来完成对此类设备IO操作之类的通用操作的封装,用户只需要写简单的驱动实例层并注册设备到该子系统就行了 1.MISC设备简介Linux内核提供了struct miscdevice来定义杂项设备 可以看到,misc框架其实把字符设备驱动框架和Linux设备驱动模型==封装到了一起==,可以同时向用户层提供I/O操作的接口,并完成驱动和设备的匹配 1234567891011struct miscdevice { int minor; const char *name; const struct file_operations *fops; struct list_head list; struct device...
11 Linux内核中断
Linux内核中断总览Linux驱动开发中,对于中断,同样遵循着“驱动分层”和“主机驱动和设备驱动分离”的思想,可以分为以下几层: 1.硬件/架构相关层(最底层) 这是与具体CPU架构相关的实现层,负责: 处理器特定的中断控制器操作(如x86的APIC、ARM的GIC) 中断向量表的设置 底层中断启用/禁用 中断上下文保存与恢复 文件位置:arch/xxx/kernel/irq.c(如arch/arm/kernel/irq.c) 2.中断控制器驱动层(irqchip driver) 这是针对具体SoC的中断控制器的驱动层,例如: ARM GIC驱动(drivers/irqchip/irq-gic.c) x86 IOAPIC驱动 其他SoC专用中断控制器 这些驱动需要: 初始化硬件中断控制器 实现irq_chip操作集(如mask/unmask中断) 处理硬件级中断路由 3.中断核心层(irq core) 这是Linux内核提供的通用中断子系统核心,负责: 中断描述符管理(struct...
00 Linux内核模块
Linux内核模块Linux内核本身非常庞大,包含了很多东西,这带了一些问题: 许多功能我们可能并不需要,如果每次都把所有东西一起编译了,一是十分耗时,二是编译出来的镜像太大了 因此,Linux内核引入了“模块”机制,对于一些功能,它本身不直接编译进内核,而是以模块(.ko)的形式存在内核之外,一旦需要这些功能,可以动态将其加载进内核。一旦被加载,他们就和内核中其他部分没有区别 内核模块程序结构12345678910111213141516#include <linux/module.h>#include <linux/fs.h>static int __init mydriver_init(void) { printk(KERN_INFO "Driver loaded\n"); return 0;}static void __exit mydriver_exit(void) { printk(KERN_INFO "Driver...
01 驱动开发概述
Linux驱动开发概述简介Linux驱动开发是设备驱动模型、驱动子系统、内核基础设施三者的深度整合: 设备驱动模型提供通用框架,实现驱动与设备的匹配 各个子系统实现垂直领域优化(如输入、存储、网络) 内核设施与硬件操作解决并发、内存、中断等底层问题 驱动开发子系统定义 子系统是指针对特定功能领域或硬件类型设计的软件框架。其核心目标是解耦硬件差异,提供统一的API,使得驱动开发者无需直接操作底层寄存器或硬件细节,而是通过标准化API完成功能开发 所有的驱动子系统的实现均遵循分层架构原则 用户接口层:通过sysfs或/dev节点提供控制接口 核心层:实现事件队列、资源分配等通用逻辑 硬件驱动层:厂商实现具体寄存器操作 123456789 用户空间 │ ▼ 用户口层(如VFS、sysfs) │ ▼ 子系统核心层(标准API) ↗ ↖ ↖设备驱动层A 驱动层B ...
02 Linux设备驱动模型
Linux设备驱动模型简介Linux 设备驱动模型是内核中用于统一管理硬件设备、驱动程序和总线关系的核心框架。它通过一系列抽象结构(如struct device、struct driver、struct class、struct bus_type等)构建了一个层次化的设备拓扑,使内核能够动态管理设备的生命周期(如热插拔、电源管理),并为用户空间(通过 /sys)提供标准化的设备信息接口。 设备驱动框架和设备驱动模型不是一个东西,前者指的是GPIO、Input、Pinctl等子系统,而后者主要是Linux内核对于驱动开发中的一种设计模式 Linux设备驱动模型的核心思想是把我们编写的驱动代码进行分层解耦: 设备:提供硬件资源 驱动:使用设备提供的硬件资源进行初始化等操作 总线:将设备和驱动匹配起来 任何设备都挂在在某个总线上,即使物理上没有总线,也要虚拟出来个总线(platform) 核心目标 统一管理硬件:无论设备是 PCI、USB、I2C...
04 设备树
...
00 开发板启动方式选择
开发板启动流程Linux(Cortex A系列)芯片和STM32不一样,除了能从内部Flash启动,还可以从其他多种外部介质中启动,比如SD卡,EMMC,NAND Flash等。 芯片的启动可以分为启动方式选择、启动设备选择2个问题 1.启动方式以I.MAX6ULL为例,它的启动方式有4种,具体选择哪种由芯片上特定的引脚BOOT_MODE0和1决定,这点和STM32类似,STM32芯片上也有BOOT0和BOOT1这样的引脚。 通常只使用方式2和3,绝对不能使用方式1。 1.1串行下载就是通过USB或者串口将代码下载到板子上的SD卡之类的存储设备上,这个下载需要用NXP提供的软件。一般用于设备最终量产时。 1.2内部BOOT模式该模式会执行内部的boot ROM中的代码,将一部分外设初始化(比如SD卡这样的boot设备),再从对应的boot设备中将代码拷贝到指定的RAM(一般是DDR)中运行。 1.2.1Boot...