硬件驱动——驱动(1)
一.驱动的基本概念
(1)驱动分类:
①字符设备驱动:按照单个字符扫描设备信息
②块设备驱动:按照块(512字节)扫描设备信息,用于存储设备
③网络设备驱动:需要网络协议栈支持,TCP/IP、CAN
※(2)驱动编译:
①静态编译:将驱动代码加入到zImage的内核中
在合适的内核目录下编写驱动代码hello.c
修改Kconfig,新增配置项
make menuconfig选中改配置项
对应配置项的CONFIG__XXX会加入.config文件当中
在驱动代码对应的Makefile中加入编译规则 obj-$(CONFIG__XXX)+= hello.o
②动态编译:将驱动代码以模块的方式编译,动态加入内核或者从内核中去除
编写hello.o
修改Kconfig,新增配置项
通过make menuconfig 选择M,以模式形式编译
对应配置项的CONFIG__XXX会加入.config文件中 CONFIG_XXX = m
在Makefile中 obj-$(CONFIG_XXX),以模块形式编译
make modules内核会编译所有模块生成一个.ko驱动文件
将驱动文件动态加载到执行的内核中,从内核中去除该驱动模块
※二.驱动的分类
Linux系统中驱动分为三类:
1.字符设备驱动:
GPIO驱动,LCD驱动,Cemera驱动
2.块设备驱动
存储
3.网络设备驱动
支持协议栈
※三.字符设备驱动框架
1.驱动根据设备功能分为不同类型的设备:
cat /proc/devices 查看设备类型
2.linux系统下的设备都有一个设备号:
设备号=主设备号(设备类型)+ 次设备号(该种设备类型的第几个设备)
3.添加设备
每添加一个设备就需要在文件系统中添加一个该设备的设备节点
/dev/led0 查看设备节点
4.应用层通过文件IO操作设备节点
open read write ioctl close ---> /dev/led0
四.字符设备驱动编写流程
1.alloc_chrdev_region:让系统分配主设备号,并占用出设备号开始的前n个设备编号
2.cdev_alloc:申请cdev结构
3.cdev_add:将cdev加入cdev列表中
4.自己通过mknode创建设备,对应设备节点
5.编写应用层代码操作设备 open read write close
五.Linux查看内核驱动信息的常用命令
1.cat /proc/devices
查看所有设备类型
2.ls /sys/class
查看sys文件系统中的设备类型
3.cat /sys/firmware/devicetree/base/节点名
查看设备树中是否包含该节点
4.cat /proc/interrupts
查看当前系统中所有注册的中断号信息
六.设备树
※设备树的功能:记录硬件资源信息的一种文件形式,搭配驱动使用
1.设备树文件类型
dts:设备树源代码
dtsi:设备树文件的头文件(包含多个芯片共用的资源信息)
dtb:编译生成二进制设备树文件
DTC:设备树的编译工具
2.我们使用的是:imx6ull-alitentek-emmc.dtb
①源码:imx6ull-alientek-emmc.dts
②公共:imx6ull.dtsi
※3.语法规则:
节点 {属性1;属性2 = 整形值;属性3 = 字符值;属性4 = 数组;属性5 = &节点名;};
puteled {#address-cells = <1>;#size-cells = <1>;compatible = "pute-led";reg = <0x20E0068 0x4 0x20E02F4 0x4 0x209C004 0x4 0x209C000 0x4>;status = "okay";
};
puteled:节点
#address-cells:该节点下的reg属性中的地址占1个字(4个字节)
#size-cells:该节点下的reg属性中的地址大小占1个字(4个字节)
compatible:将来用于总线驱动中设备与驱动的匹配
reg:寄存器地址和寄存器地址的大小
status:使能该节点 okay disable关闭该节点
4.编译设备树
make dtbs
5.将编译好的设备树文件拷贝到tftpboot目录下
cp arch/arm/boot/dts/imx6ull-alientek-emmc.dtb ~/tftpboot
七.工程搭建
驱动的三步骤:
1.满足linux驱动开发框架实现代码编写
2.将编译好的代码,正常加入正在运行的内核中
3.虚拟地址与物理地址之间的映射