零基础学Linux内核之设备驱动篇(1)_设备驱动概述

零基础学Linux内核系列文章目录

前置知识篇
1. 进程
2. 线程
进程间通信篇
1. IPC概述
2. 信号
3. 消息传递
4. 同步
5. 共享内存区
编译相关篇
1. GCC编译
2. 静态链接与动态链接
3. makefile入门基础
设备驱动篇
1. 设备驱动概述


一、前言

本节主要介绍一下设备驱动的基本概念,为后续的内核设备、字符设备乃至设备树做铺垫。


二、前置条件


三、本文参考资料

《 [野火]i.MX Linux开发实战指南》
百度
《通俗易懂,嵌入式Linux驱动基础》


四、正文部分

4.1 设备驱动的作用与本质

驱动就是对底层硬件设备的操作进行封装,并向上层提供函数接口。

在控制硬件时我们根本不需要知道具体硬件连接,只要知道哪个文件代表哪个设备, 然后就可以通过文件以同样的方式操控同类设备。
这就是驱动的作用,它把硬件设备与Linux文件建立了映射关系。

设备驱动与底层硬件直接打交道,按照硬件设备的具体工作方式读写设备寄存器, 完成设备的轮询、中断处理、DMA通信,进行物理内存向虚拟内存的映射,
最终使通信设备能够收发数据, 使显示设备能够显示文字和画面,使存储设备能够记录文件和数据。

 

4.2 裸机与linux驱动的区别

4.2.1 裸机(无操作系统)

在MCU的裸机程序中,要控制硬件,需要以下几个步骤:

  1. 需要先了解它们与MCU硬件是如何连接的,即要知道连接的具体的IO引脚,
  2. 修改寄存器配置IO的输入输出,工作模式等,
  3. 编写相关的控制函数API提供给上层调用。
    在这里插入图片描述

编写应用时用户通过 函数API 去控制硬件。
一般情况下,对每一种设备驱动都会定义为一个软件模块,包含.h文件和.c文件,前者定义该设备驱动的数据结构并声明外部函数, 后者进行设备驱动的具体实现。
其他模块需要使用这个设备的时候,只需要包含设备驱动的头文件然后调用其中的外部接口函数即可。

4.2.2 linux(有操作系统)

在Linux系统下,驱动工程师的工作其实类似,他们也需要了解LED或按键是如何与CPU连接的, 也得配置好IO的工作模式,

区别在于还需要按照Linux系统的接口要求编写相关控制函数提供给Linux的 虚拟文件系统 , 使得硬件与文件建立起联系,提供给Linux用户。
为了实现这种融合,必须在所有的设备驱动中设计面向操作系统内核的接口,这样的接口由操作系统规定,对一类设备而言结构一致,独立于具体的设备。

编写应用时用户通过 设备文件 即可控制硬件。
所以说,驱动工程师所做的工作就是把硬件的控制方式抽象、封装成为函数API或者文件
只不过Linux驱动工程师在封装时需要按照Linux的规范去编写,而且在编写时需要了解Linux内核的一些机制。
操作系统的存在势必要求设备驱动附加更多的代码和功能, 把单一的驱动变成了操作系统内与硬件交互的模块,它对外呈现为操作系统的API。

驱动模块的加载有两种方式:第一种方式是动态加载的方式,即驱动程序与内核分开编译,在内核运行的过程中加载;第二种方式是静态加载的方式,即驱动程序与内核一同编译,在内核启动过程中加载驱动。

在调试驱动阶段常常选用第一种方式,因为较为方便;在调试完成之后才采用第二种方式与内核一同编译。

STM32裸机开发与嵌入式Linux开发还有一点不同的就是:STM32裸机开发最终要烧到板子的常常只有一个文件(除开含有IAP程序的情况或者其它情况),嵌入式Linux就需要分开编译、烧写。
在这里插入图片描述
在这里插入图片描述

 

4.3 Linux设备分类

4.3.1 设备分类

linux是文件型系统,所有硬件都会在对应的目录(/dev)下面用相应的文件表示

在文件系统的linux下面,都有对于文件与这些设备关联的,访问这些文件就可以访问实际硬件。
像访问文件那样去操作硬件设备,一切都会简单很多,不需要再调用以前com,port等接口了。
直接读文件,写文件就可以向设备发送、接收数据。

按照读写存储数据方式,我们可以把设备分为以下几种:字符设备、块设备和网络设备。
在这里插入图片描述

  • 字符设备(struct cdev):
    指应用程序按字节/字符来读写数据的设备。
    这些设备节点通常为传真、虚拟终端和串口调制解调器、键盘之类设备提供流通信服务, 它通常不支持随机存取数据。
    字符设备在实现时,大多不使用缓存器。系统直接从设备读取/写入每一个字符(即一般不挂载,直接和设备交互)。
    例如,键盘这种设备提供的就是一个数据流,当你敲入“cnblogs”这个字符串时, 键盘驱动程序会按照和输入完全相同的顺序返回这个由七个字符组成的数据流。
    它们是顺序的,先返回c,最后是s。

  • 块设备(struct block_device):
    通常支持随机存取和寻址,并使用缓存器。
    操作系统为输入输出分配了缓存以存储一块数据。
    当程序向设备发送了读取或者写入数据的请求时, 系统把数据中的每一个字符存储在适当的缓存中。
    当缓存被填满时,会采取适当的操作(把数据传走), 而后系统清空缓存。
    它与字符设备不同之处就是,是否支持随机存储,以及一般都是把设备挂载为文件系统后再访问
    字符型是流形式,逐一存储。
    典型的块设备有硬盘、SD卡、闪存等,应用程序可以寻址磁盘上的任何位置,并由此读取数据。
    此外,数据的读写只能以块的倍数进行。

  • 网络设备(struct net_devce):
    是一种特殊设备,它并不存在于/dev下面,主要用于网络数据的收发。
    打破了Unix “一切皆文件” 的设计原则。
    通过套接字API来访问

  • 伪设备
    所谓"伪设备",其实就是一些虚拟的设备,仅提供访问内核功能而已,没有物理设备与之关联。
    典型的"伪设备"就是
    /dev/random(内核随机数发生器)
    /dev/null(空设备) 黑洞
    /dev/zero(零设备)
    /dev/full(满设备)

4.3.2 面向对象的设计思想

为了统一形形色色的设备,Linux系统将设备分别抽象为struct cdev, struct block_device, struct net_devce三个对象,
具体的设备都可以包含着三种对象从而继承和三种对象属性和操作, 并通过各自的对象添加到相应的驱动模型中,从而进行统一的管理和操作

 


五、总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值