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 --- 在多节点会用到,更多的时候这个结构体会作为形参作为实参传入另外一个函数中

注意 :

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

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

相关推荐
骑上单车去旅行5 小时前
MD5校验对比脚本
linux·服务器·windows
平生幻5 小时前
Linux 常用命令
linux
期待着20135 小时前
docker 安装 ,在centos7.9
运维·docker·容器
踏月的造梦星球6 小时前
DM8 DSC 单机双实例部署
运维·开发语言·数据库
科芯创展6 小时前
3.5A,60VIN,异步降压芯片,XZ1815
单片机·嵌入式硬件
茯苓gao6 小时前
嵌入式开发笔记:Qt信号槽机制深度解析——从原理到实战的全方位指南
开发语言·笔记·嵌入式硬件·qt·学习
MXsoft6186 小时前
平台化是智能运维发展的必然趋势吗?
运维
ShirleyWang0127 小时前
让headlamp控制台能访问
linux·服务器·python·k8s·k3s
liuccn7 小时前
Linux 存储系统:LVM 与直接分区
linux·运维
浅止菌7 小时前
海思回归第二弹:瑞芯微的隐忧与对手的反击
嵌入式硬件