Linux驱动开发简易流程
推荐视频:
正点原子【第四期】手把手教你学 Linux之驱动开发篇
小智-学长嵌入式Linux&Android底层开发入门教程
能力矩阵
基础能力矩阵
熟悉c/c++、熟悉数据结构
熟悉linux系统,Shell脚本,Makefile/cmake/mk
文件IO、多线程、竞争、并发、阻塞、同步、中断、网络
熟悉调试工具,gdb、gdbserver、tcpdump
行业能力矩阵
平台相关:海思/君正/安霸MTK/NXP/高通/全志/瑞芯微/展讯等平台
系统相关:bootloader、kernel、文件系统,定制、移植、开发与适配
Android相关:HAL、Services、Framework
驱动相关:驱动设备模型、GPIO、I2C、SPL、UART、WIFl、LCD、USB
物联网相关:TCP/IP、UDP、COAP、MQTT、HTTP
流媒体相关:RTMP、RTSP、Iive555
视频编码:H264、H265、MJPEG
音频编码:PCM、AAC、G711
流媒体框架:FFMEPG、GStreamer、WebRTC
开发流程
- 编译系统,跑起来(编译从原厂拿来的SDK,看看有没有报错,做好一些必要的ignore管理)
- 按照需求将项目外设逐个调通(遥控,WIFI,蓝牙,LED灯光等等)
- 封装Android接口,让应用能用上驱动(这个一般是移植的芯片厂家的驱动,适配好就行)
- 应用实现(根据客户的需求定制各种功能)
Linux驱动开发思维
1、Liuⅸ下驱动开发直接操作寄存器不现实。
2、根据Linuⅸ下的各种驱动框架进行开发。一定要满足框架,也就是Linux下各种驱动框架的掌握。
3、驱动最终表现就是/dev/xxx文件。打开、关闭、读写。
4、现在新的内核支持设备树,这个一个dts文件,此文件描述了板子的设备信息。
linux驱动开发分类
linux驱动分为三大类:
1、字符设备驱动,最多的。
2、块设备驱动,存储
3、网络设备驱动,
一个设备不说是一定只属于某一个类型。比如USB WIFI,SDIO WIFI,属于网络设备驱动,因为他又有USB和SDIO,因此也属于字符设备驱动。
应用程序和驱动交互原理
用户空间(用户态)和内核空间(内核态):
Linux操作系统内核和驱动程序运行在内核空间、应用程序运行在用户空间。
应用程序想要访问内核资源,怎么办,有三种方法:系统调用、异常(中断)和陷入。我们一般都是系统调用的方式。
Linux 驱动属于内核的一部分,因此驱动运行于内核空间。
当我们在用户空间想要实现对内核的操作,比如使用 open 函数打开/dev/led 这个驱动,因为用户空间不能直接对内核进行操作,因此必须使用一个叫做“系统调用”的方法来实现从用户空间“陷入”到内核空间,这样才能实现对底层驱动的操作。
驱动的加载与卸载
Linux 驱动有两种运行方式。
- 将驱动编译进 Linux 内核中,这样当 Linux 内核启动的时候就会自动运行驱动程序。
- 将驱动编译成模块(Linux 下模块扩展名为.ko),在Linux 内核启动以后使用“insmod”命令加载驱动模块。
驱动编译完成以后扩展名为.ko,有两种命令可以加载驱动模块:insmod和modprobe。insmod 命令不能解决模块的依赖关系,modprobe 会分析模块的依赖关系,然后会将所有的依赖模块都加载到内核中。驱动模块的卸载使用命令“rmmod”即可
简单看懂驱动代码
/* 驱动入口函数 */ static int __init xxx_init(void) { /* 入口函数具体内容 */ return 0; } /* 驱动出口函数 */ static void __exit xxx_exit(void) { /* 出口函数具体内容 */ } /* 将上面两个函数指定为驱动的入口和出口函数 */ module_init(xxx_init); module_exit(xxx_exit);
设备号的分配
- 静态分配设备号
注册字符设备的时候需要给设备指定一个设备号,这个设备号可以是驱动开发者静态的指定一个设备号,比如选择 200 这个主设备号。有一些常用的设备号已经被 Linux 内核开发者给分配掉了,具体分配的内容可以查看文档 Documentation/devices.txt。
使用“cat /proc/devices”命令即可查看当前系统中所有已经使用了的设备号。 - 动态分配设备号
静态分配设备号需要我们检查当前系统中所有被使用了的设备号,然后挑选一个没有使用的。而且静态分配设备号很容易带来冲突问题,Linux 社区推荐使用动态分配设备号,在注册字符设备之前先申请一个设备号,系统会自动给你一个没有被使用的设备号,这样就避免了冲突。
设备号的申请函数如下:
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name)
注销字符设备之后要释放掉设备号,设备号释放函数如下:
void unregister_chrdev_region(dev_t from, unsigned count)
内核打印
在驱动中可以使用printk 来输出信息,而不用printf。因为在 Linux 内核中没有 printf 这个函数。printk 相当于printf 的孪生兄妹,printf运行在用户态,printk 运行在内核态。在内核中想要向控制台输出或显示一些内容,必须使用printk 这个函数。不同之处在于,printk 可以根据日志级别对消息进行分类,一共有 8 个消息级别,这 8 个消息级别定义在文件 include/linux/kern_levels.h 里面,定义如下:
#define KERN_SOH "\001"
#define KERN_EMERG KERN_SOH "0" /* 紧急事件,一般是内核崩溃 */
#define KERN_ALERT KERN_SOH "1" /* 必须立即采取行动 */
#define KERN_CRIT KERN_SOH "2" /* 临界条件,比如严重的软件或硬件错误*/
#define KERN_ERR KERN_SOH "3" /* 错误状态,一般设备驱动程序中使用 KERN_ERR 报告硬件错误 */
#define KERN_WARNING KERN_SOH "4" /* 警告信息,不会对系统造成严重影响 */
#define KERN_NOTICE KERN_SOH "5" /* 有必要进行提示的一些信息 */
#define KERN_INFO KERN_SOH "6" /* 提示性的信息 */
#define KERN_DEBUG KERN_SOH "7" /* 调试信息 */
一共定义了 8 个级别,其中 0 的优先级最高,7 的优先级最低。如果要设置消息级别,参考如下示例:
printk(KERN_EMERG "gsmi: Log Shutdown Reason\n");
上述代码就是设置“gsmi: Log Shutdown Reason\n”这行消息的级别为 KERN_EMERG。在具体的消息前面加上 KERN_EMERG 就可以将这条消息的级别设置为 KERN_EMERG。
如果使用 printk 的 时 候 不 显 式 的 设 置 消 息 级 别 , 那 么 printk 将 会 采 用 默 认 级 别MESSAGE_LOGLEVEL_DEFAULT,MESSAGE_LOGLEVEL_DEFAULT 默认为 4
在控制台修改内核打印级别:
echo 7 > echo 7 > /proc/sys/kernel/printk
在uboot下改变内核打印级别:
env set loglevel7
env save
编译驱动程序和测试 APP
编译驱动程序
当我们编写完一个驱动程序之后会生成.c文件,比如chrdevbase.c 这个文件。我们需要将其编译为.ko 模块.
- 创建Makefile 文件,然后在其中输入如下内容:
KERNELDIR := /home/zuozhongkai/linux/IMX6ULL/linux/temp/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek CURRENT_PATH := $(shell pwd) obj-m := chrdevbase.o build: kernel_modules kernel_modules:
$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules clean:
$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean
第 1 行,KERNELDIR 表示开发板所使用的 Linux 内核源码目录,使用绝对路径,大家根据自己的实际情况填写即可。
第 2 行,CURRENT_PATH 表示当前路径,直接通过运行“pwd”命令来获取当前所处路径。
第 3 行,obj-m 表示将 chrdevbase.c 这个文件编译为 chrdevbase.ko 模块。
第 8 行,具体的编译命令,后面的 modules 表示编译模块,-C 表示将当前的工作目录切换到指定目录中,也就是 KERNERLDIR 目录。M 表示模块源码目录,“make modules”命令中加入 M=dir 以后程序会自动到指定的 dir 目录中读取模块的源码并将其编译为.ko 文件。
2. Makefile 编写好以后输入“make”命令编译驱动模块,
3. 编译成功以后就会生成一个叫做 chrdevbaes.ko 的文件,此文件就是 chrdevbase 设备的驱动模块。至此,chrdevbase 设备的驱动就编译成功。
编译测试 APP
测试 APP 比较简单,只有一个文件,因此就不需要编写 Makefile 了,直接输入命令编译。
因为测试 APP 是要在 ARM 开发板上运行的,所以需要使用 arm-linux-gnueabihf-gcc 来编译,输入如下命令:
arm-linux-gnueabihf-gcc chrdevbaseApp.c -o chrdevbaseApp
编译完成以后会生成一个叫做 chrdevbaseApp 的可执行程序,输入如下命令查看chrdevbaseAPP 这个程序的文件信息:
file chrdevbaseApp
运行测试
-
拷贝文件
-
加载 chrdevbase.ko 驱动文件
insmod chrdevbase.ko
或者
modprobe chrdevbase.ko
如果使用 modprobe 加载驱动的话,可能会出现如下的提示:
modprobe 提示无法打开“modules.dep”这个文件,因此驱动挂载失败了。我们不用手动创建 modules.dep 这个文件,直接输入 depmod 命令即可自动生成modules.dep,有些根文件系统可能没有 depmod 这个命令,如果没有这个命令就只能重新配置busybox,使能此命令,然后重新编译 busybox。输入“depmod”命令以后会自动生成 modules.alias、modules.symbols 和 modules.dep 这三个文件,
然后重新使用modprobe 加载 chrdevbase.ko
输入如下命令查看当前系统中有没有 chrdevbase 这个设备:
cat /proc/devices
创建设备节点文件
驱动加载成功需要在/dev 目录下创建一个与之对应的设备节点文件,应用程序就是通过操作这个设备节点文件来完成对具体设备的操作。输入如下命令创建/dev/chrdevbase 这个设备节点文件:
mknod /dev/chrdevbase c 200 0
其中“mknod”是创建节点命令,“/dev/chrdevbase”是要创建的节点文件,“c”表示这是个字符设备,“200”是设备的主设备号,“0”是设备的次设备号。创建完成以后就会存在/dev/chrdevbase 这个文件,可以使用“ls /dev/chrdevbase -l”命令查看,
如果 chrdevbaseAPP 想要读写 chrdevbase 设备,直接对/dev/chrdevbase 进行读写操作即可。
设备操作测试
./chrdevbaseApp /dev/chrdevbase 1
./chrdevbaseApp /dev/chrdevbase 2
卸载驱动模块
如果不再使用某个设备的话可以将其驱动卸载掉,比如输入如下命令卸载掉 chrdevbase 这个设备
rmmod chrdevbase.ko
相关文章:
Linux驱动开发简易流程
推荐视频: 正点原子【第四期】手把手教你学 Linux之驱动开发篇 小智-学长嵌入式Linux&Android底层开发入门教程 能力矩阵 基础能力矩阵 熟悉c/c、熟悉数据结构 熟悉linux系统,Shell脚本,Makefile/cmake/mk 文件IO、多线程、竞争、并发…...
基于springboot的靓车汽车销售网站
🍅点赞收藏关注 → 私信领取本源代码、数据库🍅 本人在Java毕业设计领域有多年的经验,陆续会更新更多优质的Java实战项目希望你能有所收获,少走一些弯路。🍅关注我不迷路🍅一 、设计说明 1.1 研究背景 随…...
爬取涛声网音频
代码展现: 代码详情: import requests import re import os filename 声音// if not os.path.exists(filename): os.mkdir(filename) def down_load(page): for page in range(page): page page1 url https://www.tosound.…...
如何快速且有效的学习自动化测试?
我写一个学习路线吧: 1.学习python基本语法。 2学习路线图 https://www.processon.com/view/link/64e729486ece22263c3e 学习HTML/CSS下的html、xml、webservice三个教程。 3. 然后下一个python的requests库学习写最简单的网络爬虫。知乎上爬虫教程一大堆。 3是…...
openmmlab大模型实战营01
与环境进行交互——智能体更合适 模型微调常见方式 模型评测 模型部署常见问题你 大语言模型本身不具备最新信息和知识的获取,此时需要搭建包含不同模块的智能体框架 智能体:以大语言模型为核心,进行规划、推理和执行...
HarmonyOS-ArkTS基本语法及声明式UI描述
初识ArkTS语言 ArkTS是HarmonyOS优选的主力应用开发语言。ArkTS围绕应用开发在TypeScript(简称TS)生态基础上做了进一步扩展,继承了TS的所有特性,是TS的超集。因此,在学习ArkTS语言之前,建议开发者具备TS语…...
字符串转成时间的SQL,一个多种数据库通用的函数
select date 2010-10-06 from dual; date 函数,此函数适用于: 1.MySQL数据库 2.Oracle数据库 3.达梦数据库 4.人大金仓数据库...
CMake入门教程【核心篇】查找包(find_package)
😈「CSDN主页」:传送门 😈「Bilibil首页」:传送门 😈「本文的内容」:CMake入门教程 😈「动动你的小手」:点赞👍收藏⭐️评论📝 文章目录 1.使用方法1.1基本用…...
Stable Diffusion好用的显卡推荐
Stable Diffusion 是一款顶级的人工智能艺术生成工具,以其快速的性能、用户友好的界面和显着的效果而闻名。然而,在沉浸体验之前,有必要验证您的计算机(显卡)是否符合最佳功能所需的严格规范。今天我们将介绍三款高性价…...
Spring 对请求参数的优雅处方式(重写序列化方法)
Spring 对请求参数的优雅处方式(重写序列化方法) 描述前端传参方式介绍代码实现:1、重写序列化方式代码2、设置类自动加载到 Spring 中 描述 在我们日常项目开发过程中,往往会遇到前端请求参数中有空格的情况,前端提交…...
2024年中职“网络安全“—数字调查取证(attack817.pcapng)
目录 1.通过分析数据包找出恶意用户最初访问HTTP服务的包号,将该值作为Flag值提交, Flag格式为flag{xxx}; 2.继续查看数据包文件分析出恶意用户扫描了哪些端口,将全部的端口号按照一定顺序作为Flag值,提示:注意端口…...
如何使用VsCode编译C语言?
下载VsCode (1) 解压到D盘跟目录 (2) 运行[vscode.reg],注册右键菜单 (3) 进入[pack]文件夹,运行[install.bat]。安装基本插件。 下载mingw32 (1) 解压任意目录 (2) 我的电脑右键–高级系统设置–高级–环境变量–系统变量–Path(双击)–空白行(双击)–…...
SpringCloud 和 Linux 八股文第三期五问五答
SpringCloud 和 Linux 八股文第三期五问五答 作者:程序员小白条,个人博客 相信看了本文后,对你的面试是有一定帮助的! ⭐点赞⭐收藏⭐不迷路!⭐ 1)Linux常用命令 2)如何查看测试项目的日志 一…...
组件通信方式
组件通信方式有:vuex,ref,父子通信(父传子、子传父),兄弟通信(eventBus), 祖先后代通信(依赖注入) 父传子:父组件内:在子组件标签上设置自定义属…...
kbdnecnt.DLL文件缺失,软件或游戏无法启动运行,怎样快速修复?
不少人都在问“kbdnecnt.DLL文件”是什么?为什么电脑总是报错提示说“kbdnecnt.DLL文件缺失,软件无法启动”? 首先,先来了解“kbdnecnt.DLL文件”是什么? kbdnecnt.DLL是Windows操作系统中的一个动态链接库文件&#…...
Linux账户安全
一.Linux账户与组的基本概念 在Limux操作系统中,每一个文件和程序都归属于一个特定的 “用户”。每个用户都由一个唯一的身份来标识,这个标识称为用户ID (UserID, UID )。系统中的每一个用户也至少需要属于一个“用户分组”,即由系统管理员所…...
深度生成模型之GAN优化目标设计与改进 ->(个人学习记录笔记)
文章目录 深度生成模型之GAN优化目标设计与改进原始GAN优化目标的问题1. JS散度度量问题2. 梯度问题 优化目标的设计与改进1. 最小二乘损失GAN2. Energy-based GAN(EBGAN)3. Wasserstein GAN4. WGAN-GP5. Boundary Equilibrium GAN(BEGAN)6. Loss Sensitive GAN7. Relativeisti…...
程序员如何高效学习技术?
我们相信努力学习一定会有收获,但是方法不当,既让人身心疲惫,也没有切实的回报。 不少朋友每天都阅读技术文章,但是第二天就忘干净了。工作中领导和同事都认可你的沟通和技术能力,但是跳槽面试却屡屡碰壁。面试官问技术…...
一个无经验的大学毕业生,可以转行做软件测试吗?我的真实案例
在转行之前,我一直在思考,当代年轻人的真实生活情况究竟是什么样的。 朝九晚六,无休止的加班,每天往返于公司与家,没有一点点自己的生活,只能从心里面麻痹自己,以求得最后的慰籍。 这就是我之…...
三.Linux无名管道(PIPE)和有名管道(FIFO)的区别
目录 命名管道(Named Pipe): 无名管道(Anonymous Pipe): 总结: 无名管道(Anonymous Pipe)和命名管道(Named Pipe)都是进程间通信的机制&#x…...
英文字母替换加密(后移n位)
思路:首先写出后移(前移)1位的情况 , 然后逐渐累加至N位情况 #include <stdio.h> void test(char arr[] , int n ) { int i 0; int z 0; if( n < 0 ) { while( i ! n ) { …...
HAproxy群集
HAproxy群集 常见的集群调度器HAproxy 、nginx、LVS区别HAproxynginxlvs HAproxy介绍HAproxy特点HAproxy常见的负载均衡策略HAproxy会话保持HAproxy配置实例 常见的集群调度器 常见的web集群调度器分为软件和硬件 软件:LVS Haproxy nginx 硬件: F5 Ar…...
LeetCode2469. Convert the Temperature
文章目录 一、题目二、题解 一、题目 You are given a non-negative floating point number rounded to two decimal places celsius, that denotes the temperature in Celsius. You should convert Celsius into Kelvin and Fahrenheit and return it as an array ans [ke…...
【ROS2】MOMO的鱼香ROS2(五)ROS2入门篇——ROS2接口与自定义
ROS2接口与自定义 引言1 ROS2自带接口1.1 ROS2通用标准消息包1.2 ROS2传感器消息包1.3 ROS2几何相关消息包 2 ROS2接口介绍2.1 常用CLI命令2.2 原始数据类型与包装类型 3 自定义接口示例3.1 接口定义3.2 自定义接口RCLPY 引言 笔者跟着鱼香ROS的ROS2学习之旅 学习参考…...
python c语言 代码动态检查,python c语言语法分析
大家好,小编来为大家解答以下问题,python c语言 代码动态检查,python c语言语法分析,今天让我们一起来看看吧! Source code download: 本文相关源码 初学编程,应该学习哪一门编程语言,有不少人感…...
C++ DAY6 作业
1.用模板类写顺序表 #include <iostream>using namespace std;#define MAXSIZE 10 template <typename T> class Arr {T *data NULL;int len 0; public://构造函数Arr():data(new T){}Arr(T a,int len):data(new T(a)),len(len){}//析构函数~Arr(){delete data;}…...
华为服务器安装银河麒麟V10操作系统(IBMC安装)
iBMC是华为面向服务器全生命周期的服务器嵌入式管理系统。提供硬件状态监控、部署、节能、安全等系列管理工具,标准化接口构建服务器管理更加完善的生态系统。 服务器BMC IP:192.168.2.100 一、准备工作 1、确保本机和服务器BMC管理口在同一网络 2、银…...
macos下php 5.6 7.0 7.4 8.0 8.3 8.4全版本PHP开发环境安装方法
在macos中如果使用brew 官方默认的core tap 只可以安装官方最新的稳定版PHP, 如果想要安装 php 5.6 或者 php 8.4版本的PHP就需要使用第三方的tap , 这里分享一个比较全面的brew tap shivammathur/php 这个tap里面包含了从php5.6到最新版php8.4的所有可用最新版本PHP, 而且是同…...
Chatgpt为什么像打字机逐字输出?磨洋工,防止数据库被盗
在他后台的数据库里肯定是完整的结果,每次只给你一个单词一个单词的输送,一方面是为了耍酷,好像真的是一个人在那给你说话,另一方面也是防止第三方的抄袭者最快速度盗取采集偷走数据库。防止他们的服务器崩溃,可以多收几个月会员费。 都说搞…...
ubuntu 卸载桌面
要卸载Ubuntu上的桌面环境,您可以按照以下步骤进行操作: 登录到您的Ubuntu系统,并打开终端。 确认您当前正在使用的桌面环境。可以运行以下命令来查看已安装的桌面环境: s /usr/share/xsessions/ 根据您当前使用的桌面环境&…...
网站建设销售工作内容/网络热词的利弊
Portal -->bzoj2893 Descripiton 给你一个\(n\)个点\(m\)条边的有向图,有一些点是起始点,有一些点是终止点,一次操作可以从一个起始点开始沿着有向图的边走到一个终止点(中途可以经过终止点),求需要至少…...
免费建站网站一级大录像不卡/百度一下百度主页官网
背景當我再搭建WSUS的時候,搭建Vcenter的時候,等等,如果提示你80端口被佔用,或者報端口佔用的error的時候。如何去查找哪個程序佔用了這個端口呢?命令:netstat -ano : 查看所有連接的PID 及端口號 1、netst…...
wordpress __file__/湖南企业竞价优化首选
AI通用文字识别初体验一、功能简介二、搭建HarmonyOS环境1.安装DevEco Studio2.设置DevEco Studio开发环境三、代码结构解析四、代码实践1.添加并展示图片2.识别图片中的文字一、功能简介 文字识别的核心技术是OCR(Optical Character Recognition,光学字…...
营销系统有哪些/百度的seo关键词优化怎么弄
1.清除阶段—标记清除算法: 2. 清除阶段—复制算法: 3.清除阶段—标记压缩算法: 4.三种算法比较:...
济南网站建设直播/seo网站排名优化公司
理解 C# 项目 csproj 文件格式的本质和编译流程 2018年05月19日 07:58:23 walter lv 阅读数 1901更多 所属专栏: NuGet .NET 编译过程 版权声明:本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发…...
企业电子商务网站优化方案/seo自学网免费
模块化编程编辑 模块化编程是一种软件设计技术,它强调将程序的功能分为独立的,可互换的模块,以使每个模块都包含执行所需功能的一个方面所必需的一切。 模块接口表示该模块提供和需要的元素。接口中定义的元素可由其他模块检测。该实现包含与…...