Linux驱动11 --- buildroot&杂项驱动开发方法

目录

一、Buildroot

1.1介绍

文件系统

1.一个完整的操作系统需要包含大量的文件

[2.在嵌入式开发中目前应用最广泛的文件系统制作工具就是 buildroot,busybox](#2.在嵌入式开发中目前应用最广泛的文件系统制作工具就是 buildroot,busybox)

[3.buildroot 制作文件系统(了解)](#3.buildroot 制作文件系统(了解))

二、杂项驱动编程

[1.1 驱动编程做的内容](#1.1 驱动编程做的内容)

[2.2 特点](#2.2 特点)

[2.3 设备号](#2.3 设备号)

[2.4 相关 API](#2.4 相关 API)

杂项设备注册

杂项设备注销

[三、GPIO 子系统](#三、GPIO 子系统)

[3.1 介绍](#3.1 介绍)

[3.2 GPIO 号](#3.2 GPIO 号)

[3.3 相关 API](#3.3 相关 API)

[GPIO 号的申请](#GPIO 号的申请)

[GPIO 输出方向的设置](#GPIO 输出方向的设置)

[GPIO 电平的设置](#GPIO 电平的设置)

[GPIO 的释放](#GPIO 的释放)

四、文件接口


一、Buildroot

1.1介绍

环境搭建过程,是根据板子官方的《用户手册》/《快速入门手册》

环境搭建中不可避免的要遇到问题:

1、给售后打电话 2、百度/看板子官方的论坛 3、凭经验

文件系统

1.一个完整的操作系统需要包含大量的文件

例如:Linux 系统

etc:环境配置文件

lib:库文件

bin:二进制文件 --- 里面是各种各样的可执行程序 --- 系统的部分指令 ls

sbin:管理员用户可以执行的一部分指令 reboot

dev:设备文件 等

这些系统必要的文件中有大量的子文件/目录,而我们是无法完全掌握每个文件的具体内容 ,所以文件系统的制作是需要依靠工具的

每个系统的文件,大体相同,局部不同

不同:系统中集成的库

相同:可以依赖文件系统制作工具完成

2.在嵌入式开发中目前应用最广泛的文件系统制作工具就是 buildroot,busybox

busybox 是比较早的文件系统制作工具

制作的文件系统非常纯粹 --- 基本没有其它的工具库,都需要开发者自己去移植,移植库需要不停的编译和复制

buildroot 给开发者降低了开发难度

buildroot 的文件系统其实也是由 busybox 做的,buildroot 集成了 busybox

buildroot 的优势在于可以直接通过 make menuconfig 图形化配置界面,去勾选系统中想要加入的库文件,在编译过程中会直接将勾选的库加入到文件系统中,不需要移植,不需要适配

buildroot 的缺点:编译时间非常长,并且对硬件要求比较高

buildroot 第一次编译的时间在 8~12 小时

大部分编译对运行内存要求极高 --- 是为了 build(编译)库

内核数越多,相对来说,编译的越快

一部分库他需要去外国网站下载,速度极慢,慢到一定程度,就断开了

dl 文件就是影响编译比较大的因素,其中放的都是下载的各种各样的库

buildroot 是开源的,也可以去下载,将已经下载好的 dl 库放进来,可以大大减少 buildroot 的编译时间

3.buildroot 制作文件系统(了解)

如果制作了后,后续需要重新编译 SDK,自己做的文件系统仅仅可以让系统运行起来,还需要加各种库,需要百度搜索,在制作之前先把 SDK 生成的配置文件给删除

解决 Buildroot 终端没有终端提示符,在板子的终端

cpp 复制代码
vi /etc/profile.d/myprofile.sh

PS1='[\u@\h]:\w$ '

export PS1

保存退出 

文件系统复原

gedit device/rockchip/rk3588/BoardConfig-rk3588s-evb1-lp4x-v10-yyt.mk

cpp 复制代码
export RK_CFG_BUILDR00T=rockchip_rk3588s
然后
./build.sh lunch 选5
然后
./build.sh

LVGL 在 buildroot 中选中

嵌入式设备才支持 LVGL 生成的可执行程序

除此之外还需要勾选 SDL 库

这样 buildroot 生成的文件系统中的交叉编译工具才支持编译 LVGL 的程序,这个交叉编译工具的名字带有 build

二、杂项驱动编程

1.1 驱动编程做的内容

Linux 下一切皆文件

每一个硬件设备在系统中用文件体现的:

键盘(/dev/input/event1)和鼠标(/dev/input/event2)

驱动开发就是将硬件设备 --- 描述在系统中

例如:让一个 LED 灯用文件控制 --- 本质依然是 GPIO 操作

上系统之后,无法直接使用 GPIO

在系统中只能通过文件间接控制

将硬件设备变成一个文件

通过操作文件去操作这个设备

通过 open、read、write、close 实现不同的操作

例如:可以通过 open 文件接口去开灯

通过 close 文件接口去关灯

用单片机直接可以控制 GPIO,也可以开关灯

那么我为什么要做驱动:MCU 性能有限 --- 可以做控制,但是做 UI 一类的比较弱

在字符设备驱动开发中有三种开发方法 :杂项 Linux2.6 经典

演示:杂项和 Linux2.6

2.2 特点

1、最简单的驱动开发方法

2、唯一 一个可以主动生成设备文件的驱动开发方法

3、主设备号固定为 10,次设备号 0~255

杂项设备开发方法的缺点:设备文件有限

0~255 还有系统占用的次设备号

设备文件:

字符设备文件开发 --- ✓

块设备文件开发

网络设备文件开发

2.3 设备号

设备号是区分不同设备文件的唯一标识

完整的设备号总共 32 位

高 12 位是主设备号,低 20 位是次设备号

区分不同文件的唯一标识 --- 节点号

节点号的查看 --- ls -i

目前做的是字符设备编程 --- 会向系统注册设备文件

开发方放的学习就像 MCU 的不同编程方式

寄存器:代码及其简洁,代码可读性极差

库函数:好记,代码可读性强,代码篇幅过长

HAL 库:通过点一点就可以完成简单的功能 --- 代码必须写在固定位置

学习的是一个框架 --- 固化的流程

杂项的开发流程

1、搭建驱动开发的框架

2、杂项设备注册

3、杂项核心结构体定义

4、杂项核心结构体填充

5、杂项设备注销

2.4 相关 API

关键字:misc

头文件:#include <linux/miscdevice.h>

杂项设备注册

函数原型

int misc_register(struct miscdevice *misc)

函数参数

cpp 复制代码
struct miscdevice
{

//杂项驱动编程的核心结构体

    int minor;    //次级的 --- 次设备号
    
                    //次设备号会被占用 --- 255 表示随机分配

    const char *name;        //生成的设备文件名

                            //这个名字会出现在/dev/下

    const struct file_operations *fops; //文件接口核心结构体

    {

        使用的头文件是:#include <linux/fs.h>

        对于当前情况下,只需要填写一个内容

        struct module *owner;    //在内核中固定填写 THIS_MODULE

    }

} 

函数返回值

成功返回 0,失败返回负的错误码

杂项设备注销

函数原型

void misc_deregister(struct miscdevice *misc)

函数参数

同上

三、GPIO 子系统

3.1 介绍

GPIO 子系统是 Linux 内核中用于管理通用输入输出(GPIO)引脚的核心框架,提

供标准化的 API 接口以简化硬件操作。它通过抽象硬件细节,允许开发者通过设备树

配置和驱动接口控制引脚方向、电平读写及中断功能,并与 Pinctrl 子系统协同完成引

脚复用与配置。

用于控制 GPIO

四个 LED 灯:核心板有两个,底板有两个,蜂鸣器在底板

两个用户按键:在底板

哪个板子就看哪个板子的原理图(核心板、底板)

LED1 对应的是 --- GPIO0_D0 LED2 对应的是 --- GPIO1_D5

GPIO 子系统使用的主要是 GPIO 号

3.2 GPIO 号

GPIO 号在瑞芯微系列的芯片(RK,RV rockchip)中是可以根据 GPIO 的名字算出来的

GPIO 号的计算方式

GPIO**x_yz :**x*32+(y-A)*8+z

例如:LED1 的 GPIO0_D0 0*32+(D-A)*8+0 = 3*8 = 24

GPIO1_D5 → 1*32+(D-A)*8+5 = 61

GPIO 的使用过程

GPIO 号的申请

GPIO 输出方向的设置

GPIO 电平的设置

GPIO 的释放

3.3 相关 API

关键字:gpio

头文件:#include <linux/gpio.h>

GPIO 号的申请

函数原型

int gpio_request(unsigned int gpio, const char *label)

函数参数

gpio:要申请 GPIO 的 GPIO 号

label:是一个标签,不要重复,给个字符串就行

函数返回值

成功返回 0,失败返回负数

GPIO 输出方向的设置

函数原型

int gpio_direction_output(unsigned int gpio, int value)

函数参数

gpio:要设置的 GPIO 号

value:初始电平

1 高电平

0 低电平

函数返回值

成功返回 0,失败返回负数

GPIO 电平的设置

函数原型

void gpio_set_value(unsigned int gpio, int value)

函数参数

gpio:要设置的 GPIO 号

value:设置电平值

GPIO 的释放

函数原型

void gpio_free(unsigned gpio)

函数参数

gpio:要释放的 GPIO 号

四、文件接口

用户直接操作的是系统,系统会通过文件接口(open,close 等)和内核的文件接口(重新定义 struct file_operations 结构体中的文件指针),完成控制硬件设备

复制代码
struct file_operations {

int (*open) (struct inode *, struct file *)

int (*release) (struct inode *, struct file *)

} 

struct inode --- 在系统中调用 open 文件接口其实本质上是调用内核的(*open)接口,这个结构体中存放了应用层文件的信息 --- 其中就有设备号 --- 在多节点会用到

struct file --- 在多节点会用到,更多的时候这个结构体会作为形参作为实参传入另外一个函数中

注意 :

在加载函数中,先申请的资源,在卸载函数中,后释放

先申请的资源有可能会让后申请的资源使用,在使用过程中被释放可能会导致内核错误

相关推荐
Two_brushes.9 分钟前
【Linux】线程机制深度实践:创建、等待、互斥与同步
linux·运维·服务器·多线程
会编程的小孩2 小时前
STM32用PWM驱动步进电机
stm32·单片机·嵌入式硬件
设计师小聂!2 小时前
Linux系统中部署Redis详解
linux·运维·数据库·redis
kfepiza2 小时前
Debian-10编译安装Mysql-5.7.44 笔记250706
linux·数据库·笔记·mysql·debian·bash
闻道且行之2 小时前
驱动开发(3)|rk356x驱动GPIO基础应用之点亮led灯
驱动开发
Sally璐璐4 小时前
Memcache核心技术解析与实战应用
运维·wpf·memcached
帽儿山的枪手4 小时前
追踪网络流量就这么简单 | 进阶篇 | conntrack
linux·windows·网络协议
哈哈浩丶4 小时前
Linux驱动开发1:设备驱动模块加载与卸载
linux·运维·驱动开发
Bulestar_xx4 小时前
20250711_Sudo 靶机复盘
linux·安全·web安全