驱动基础认知

为什么要将驱动和应用分开?都是操作变量(驱动操作的寄存器变量【应用层也可以去设法去操作】变成二进制时,通过形成不同的0和1去访问不同的门电路,最后将某一硬件引脚拉高拉低)。

答:普通应用和驱动所在的用户模式不同,导致在代码允许中使用的cpu寄存器不同,可以有效防止当应用进程当机影响到内核的正常运行。

1.常规分类:1.1字符设备:最小访问单位为一个字节,支持open,close, read,write 等系统调用。例:串口,按键,led

1.2 块设备:最小访问单位为块(通常为512字节),不能按字节 访问。但是Linux允许块设备按任意字节访问,因此,块设备与字符设备的区别为接口不同,硬盘,flash,SD卡。

1.3 网络接口:用来接收和发送数据报文,可以是硬件接口如:eth0(网卡),也可以是软件接口如LO(回环接口模拟的网卡)。

2.总线分类:usb设备,pci设备,平台总线设备。

3.学习方法:3.1 驱动模型 3.2 硬件操作  3.3编写应用程序测试驱动

3.1硬件访问流程:先将物理地址映射到虚拟地址,然后操作虚拟地址(寄存器)。

3.1.1 动态映射 :使用函数 void * ioremap(physaddr, size)

physaddr:物理地址 size 长度 返回虚拟地址

3.1.2 静态映射 :一个静态映射就有一个结构体来保存映射关系,然后在内核代码中有一个这样的结构体数组,保存了所有静态映射结构体,在内核中调用映射初始化函数时,将这个结构体作为参数就又可以实现静态映射了。单个结构体如下:

struct map_desc {

unsigned long virtual; /*  映射后的址虚拟地址 */

unsigned long pfn; /* 物理地址所在的页帧号*/

unsigned long pfn; /* 物理地址所在的页帧号*/

unsigned long length; /* 度映射长度 */

unsigned int type; /*  映射的设备类型 */

};

pfn: 利用__phys_to_pfn(物 物 理地址) 可以计算出物

理地址所在的物理页帧号

3.1.3 访问虚拟地址:通过系统给的读写函数就能访问虚拟地址。

unsigned ioread8(void *addr)

unsigned ioread16(void *addr)

unsigned ioread32(void *addr)

unsigned readb(address)

unsigned readw(address)

unsigned readw(address)

unsigned readl(address)

void iowrite8(u8 value, void *addr)

void iowrite16(u16 value, void *addr)

void iowrite32(u32 value, void *addr)

void writeb(unsigned value, address)

void writew(unsigned value, address)

void writel(unsigned value, address)

4.设备驱动模型分为:驱动模块初始化 实现设备操作 驱动注销 三步

4.1.驱动模块初始化分为:

4.1.1 分配设备的描述结构:不同的设备驱动类型,其描述结构不同

4.1.2 初始化描述结构

4.1.3 注册设备描述结构

4.1.4 硬件初始化

5.驱动执行生效的三个大步骤:编写好驱动模块编译好安装到开发板

建立与驱动模块对应的的设备驱动文件

编写应用程序对驱动文件进行读写操作

猜你喜欢

转载自blog.csdn.net/qq_43706825/article/details/103717146