🎬 渡水无言个人主页渡水无言

专栏传送门linux专栏
⭐️流水不争先,争的是滔滔不绝

目录

前言

一、为什么要上操作系统呢?

二、裸机驱动开发回顾 

三、Linux驱动开发思维

、Linux驱动开发分类

1、字符设备驱动(最常见)

2、块设备驱动

五、Linux 驱动与软硬件系统的 “朋友圈”

、区别总结

总结


前言

之前我们把linux系统移植介绍完了,现在我们正式开始对Linux驱动开发进行介绍,首先我们先与裸机开发进行区别介绍一下。


一、为什么要上操作系统呢?

在嵌入式开发早期,很多设备是 “裸机运行” 的 —— 没有操作系统,程序直接跑在 CPU 上。这时候的驱动开发更像 “全栈工程师”:既要管硬件寄存器操作,又要处理业务逻辑。

比如做一个智能灯泡,用 51 单片机控制 LED:

首先得配置 GPIO 引脚(通用输入输出口)的寄存器,设置为输出模式;
然后写代码控制引脚的高低电平(高电平亮,低电平灭);
还要处理按键输入,检测用户是否按下开关;
甚至得自己实现 “软定时器”,让灯泡支持闪烁功能。
这种模式下,驱动和业务逻辑完全绑定,代码复用性极差。如果换一款不同型号的单片机(比如从 STC89C52 换成 STM32),GPIO 寄存器的地址和配置方式可能完全不同,几乎要重写整个驱动。

随着嵌入式设备功能越来越复杂,裸机开发的局限性越来越明显:

硬件资源(CPU、内存)需要高效调度,否则多个任务会 “打架”;
不同硬件的驱动代码需要隔离,避免某个驱动崩溃导致整个系统死机;
开发者希望 “一次编写,多处运行”,减少重复劳动。


这时候操作系统(比如 Linux)就登场了。操作系统就像一个 “大管家”,把驱动从业务逻辑中解放出来,让它们专注做一件事:和硬件 “对话”。

比如在 Linux 系统中,驱动只需要负责:

初始化硬件(比如配置摄像头的 I2C 寄存器);
处理硬件中断(比如收到传感器数据时触发中断);
提供统一的接口给上层应用(比如应用调用read()函数就能获取传感器数据)。
而任务调度、内存管理、文件系统这些 “杂活”,都由操作系统内核处理。驱动开发者终于可以 “术业有专攻” 了。

二、裸机驱动开发回顾 

裸机驱动开发更加底层一些,直接跟寄存器打交道,虽然一些MCU提供了库,但相比Linux驱动开发还是更加底层了一些。

三、Linux驱动开发思维

1、Linux下驱动开发一般不直接操作寄存器,比较复杂,不现实。

2、根据Linux下的各种驱动框架进行开发。一定要满足框架,也就是Linux下各种驱动框架的掌握。

3、驱动最终表现就是/dev/xxx文件。打开、关闭、读写。

4、Linux内核支持设备树,这个一个.dts文件,此文件描述了板子的设备信息。

四、Linux驱动开发分类

 Linux 设备的 “三大门派”

Linux 把硬件设备分成了三大类,就像武侠小说里的 “少林、武当、峨眉”,各有各的套路

1、总体框图

2、字符设备驱动(最常见)

特点是数据传输以字节为单位,没有固定的块结构。常见的键盘、鼠标、串口、传感器(如温湿度传感器)都属于这类。

例子:用串口调试助手发送 “Hello”,驱动会把数据拆成’H’、’e’、’l’、’l’、’o’逐个发送,接收方也是逐个字节读取。

字符设备的核心是cdev结构体(字符设备描述符),驱动需要实现file_operations结构体中的函数(比如openreadwrite),这些函数就是上层应用和硬件交互的 “桥梁”。

// 典型的字符设备file_operations实现
static struct file_operations led_fops = {
    .owner = THIS_MODULE,
    .open = led_open,
    .release = led_release,
    .write = led_write,
};

3、块设备驱动

特点是数据传输以块为单位(通常是 512 字节、4KB 等),支持随机访问。最典型的就是硬盘、U 盘、SSD(固态硬盘)。

3、网络设备驱动(玩 “数据包” 的 “通信专家”)

网络设备和前两类不同,它不直接提供read/write接口,而是专注于数据包的收发。常见的网卡、Wi-Fi 模块、蓝牙模块都属于这类。

网络设备驱动的核心是net_device结构体,驱动需要实现ndo_start_xmit(发送数据包)和中断处理函数(接收数据包),Linux 内核还提供了netdev子系统,负责数据包的分片、路由、协议栈处理。

注意:一个设备不说是一定只属于某一个类型。比如USB WIFI,SDIO WIFI,属于网络设备驱动,因为他又有USB和SDIO,因此也属于字符设备驱动。

五、Linux 驱动与软硬件系统的 “朋友圈”

要理解 Linux 驱动的位置,可以想象一个 “三层金字塔”:

顶层:应用程序(各种软件、比如音乐播放器);
中层:操作系统内核(包括进程调度、内存管理、文件系统);
底层:硬件(CPU、内存、外设)。
驱动就 “卡” 在中层和底层之间:

对上,通过系统调用(如open()、ioctl())向内核提供接口,内核再把这些接口暴露给应用程序;
对下,直接操作硬件寄存器(比如通过ioremap()映射物理地址),处理硬件中断(比如设置中断服务函数 ISR)。
 

六、区别总结


总结

本期博客介绍了Linux驱动开发与裸机开发的区别。

Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐