学习不同的板子我们都是从点灯开始,linux驱动也不例外
驱动开发基础知识
何为驱动?
驱使硬件正常工作的代码就叫做驱动。
在一些mcu里:
无非就是直接操作寄存器,或者用库函数初始化外设,使外设正常工作如初始化iic,spi等,这样的代码就叫驱动。
在linux里:
不像在mcu里,拿一个led灯举例子,
mcu:
操作寄存器初始化gpio(库函数),在main里开灯关灯。
linux下:
也可以像mcu一样在内核层直接开灯,内核不断加载卸载很浪费资源,效率极 低,linux下的内核模块代码,是独立运行的单元,很难像mcu一样一个代码一个工程代表整个单片机运行程序。
就算在内核层把代码写死,系统开发工程师不懂驱动怎么操作led灯。
我写了一个驱动
你作为你个智能家居软件开发工程师想用我写的驱动控制led灯
真正的linux驱动:
不像mcu一样,把代码写死,
首先linux下的驱动符合linux驱动的原则:驱使硬件正常工作的代码,在内核层把led设备抽象一个一个文件,写驱动就是完成这件事,把设备变成文件。软甲就可以直接操作文件,执行一系列操作。
以led灯位列:
led灯->led驱动->文件 /dev/led
应用层开发者->打开/dev/led->灯亮
应用层开发者->关闭/dev/led->灯灭
linux分层思想
直接操作寄存器,高效,便捷,但不利于移植,不通用,换个芯片就得重构代码。
而linux系统其他所有系统都在做软硬件分离
分离就靠中间层
linux不管换什么平台,因为中间层都一样,驱动框架代码都一样
从这方面来讲驱动比mcu简单多了
linux分层处处可见,不仅把驱动做了分层,底层的外设驱动也做了分层,如spi,分为厂家驱动和可供用户操作的API接口。
厂商的驱动也做了分层,分为硬件信息和底层驱动
linux下学的所有API都是通用的。
驱动开发的框架
1.写驱动框架
2.驱动框架,把设备抽象为文件
设备的设备号->设备ID->让内核管理
(设备内核操作接口->文件操作接口(内核你驱动开发者要单独实现一套)
你写的内核层的打开关闭读写跟上层(系统层--对应)
这是也是你留给上层的操作接口!3.编译成.ko->insmod Xxx.ko->生成设备文件(/dev/xxxx)
4:调用加载/入口函数->内核框架->生成设备文件
5:上层/你自己调用文件操作->操作设备
设备驱动文件的特点
系统的特殊文件
管道,套接字,块设备,字符设备
用非缓存io操作。
linu驱动设备文件分为三类
字符设备(char)
一般指的是除了存储网络设备之外的所有的其他设备鼠标按键触摸屛LED灯蜂鸣器键盘摄像头液晶屏
网络设备
wifi 4g
块设备(储存)
正常储存设备,厂商一般完成了初始化
小型储存设备 ,spi_flash eeprom
设备号
设备号是一个无符号的32位的整形,理论上设备最多挂在2^32个设备
设备号分为主设备号和次设备号
主设备号
占32位设备号的高12位,但是他最大255
次设备号
占32位设备号的低20位,最大255
按设备号算最多挂载255^2个设备
字符设备传输
按字节传输