Linux驱动开发-02字符设备驱动开发初步

 一、驱动开发的前期准备

在进入驱动开发之前,需要烧写UBoot、内核、设备树,做一些前期的准备工作,确保我们开发板上的内核版本和Ubuntu上是一致的才能进行正式开发

 1.U-Boot

2.内核版本

 3.使用TFTP挂载的内核和设备树

二、Linux驱动开发与裸机开发的区别

Linux驱动开发和裸机开发的区别主要体现在以下几个方面:

  1. 开发环境
    • Linux驱动开发:在带有Linux操作系统的环境下进行,开发者利用Linux提供的各种驱动框架和API进行开发。这通常意味着开发者需要熟悉Linux内核的工作原理和相关的系统调用。
    • 裸机开发:在没有操作系统支持的环境中直接运行程序,开发者需要直接操作硬件的底层细节,包括寄存器、中断等。裸机开发常见于嵌入式系统、实时控制系统等对系统性能和资源使用有极高要求的场景。
  2. 开发技术
    • Linux驱动开发:主要使用C语言进行开发,并可能使用汇编语言进行某些特定的优化。开发者需要熟悉Linux内核编程和相关的驱动框架,如字符设备驱动、块设备驱动、网络设备驱动等。
    • 裸机开发:可能涉及汇编语言、C语言或更低级别的编程语言,因为需要直接操作硬件的底层细节。开发者需要深入了解硬件的工作原理和如何与之交互。
  3. 开发流程
    • Linux驱动开发:通常包括需求分析、设计、编码、测试等阶段。开发者需要编写符合Linux内核规范的代码,并通过系统调用或设备文件与应用程序进行交互。
    • 裸机开发:开发流程可能更为复杂,因为需要直接操作硬件。这通常包括编写启动代码、初始化硬件、配置中断、编写外设驱动程序等步骤。
  4. 关注点
    • Linux驱动开发:主要关注如何在Linux操作系统下实现对硬件设备的控制和管理,以及与操作系统的交互。
    • 裸机开发:主要关注如何直接操作硬件,实现底层的功能和性能优化。
  5. 可移植性和复用性
    • Linux驱动开发:由于是基于Linux操作系统的,因此驱动程序的可移植性和复用性通常较好。Linux支持多种硬件平台和架构,开发者可以编写通用的驱动程序以支持不同的硬件。
    • 裸机开发:由于直接操作硬件,因此可移植性和复用性通常较差。不同的硬件平台和架构可能需要完全不同的驱动程序。
  6. 调试和测试
    • Linux驱动开发:可以利用Linux提供的各种调试工具和技术进行调试和测试,如GDB、KDB等。此外,由于是在操作系统环境下进行开发,因此可以利用操作系统的功能进行辅助调试和测试。
    • 裸机开发:调试和测试通常更为复杂和困难,因为需要直接操作硬件。开发者可能需要使用专门的调试工具和技术,如JTAG调试器、逻辑分析仪等。

总结来说,Linux驱动开发和裸机开发在开发环境、技术、流程、关注点、可移植性和复用性、调试和测试等方面都存在显著的区别。选择哪种开发方式取决于具体的应用场景和需求

驱动最终表现就是/dev/xxx文件,对文件的读写、打开关闭;现在新的内核支持设备树,这个一个.dts文件,此文件描述了板子的设备信息

驱动加载成功以后会在“/dev”目录下生成一个相应的文件,应用程序通过对这个名为“/dev/xxx”(xxx 是具体的驱动文件名字)的文件进行相应的操作即可实现对硬件的操作

 2.1 驱动设备的分类

字符设备驱动:字符设备就是一个一个字节,按照字节流进行读写操作的设备,读写数据是分先后顺序的

块设备驱动:所谓的块设备驱动就是存储器设备的驱动,比如 EMMC、 NAND、 SD卡和 U盘等存储设备,因为这些存储设备的特点是以存储块为基础,因此叫做块设备。网络设备驱动就更好理

网络设备驱动:就是网络驱动,不管是有线的还是无线的,都属于网络设备驱动的范畴。一个设备可以

一个设备可以属于多种设备驱动类型,比如 USB WIFI,其使用 USB接口,所以属于字符设备,但是其又能上网,所以也属于网络设备驱动。

三、Linux驱动开发的VScode的环境搭建

1.禁止鼠标中键复制与创建驱动文件夹

//禁止鼠标中键复制
alientek@ubuntu16:~/linux/IMX6ULL/Linux_Drivers/1_chrdevbase$ xmodmap -e "pointer = 1 25 3 4 5 6 7 2"
Warning: Only changing the first 8 of 16 buttons.
alientek@ubuntu16:~/linux/IMX6ULL/Linux_Drivers/1_chrdevbase$ pwd
/home/alientek/linux/IMX6ULL/Linux_Drivers/1_chrdevbase
alientek@ubuntu16:~/linux/IMX6ULL/Linux_Drivers/1_chrdevbase$ ls
chrdevbase.c  chrdevbase.code-workspace
///home/alientek/linux/IMX6ULL/Linux_Drivers/1_chrdevbase在该路径下,新建第一个驱动的文件夹,编写代码

 2.将创建的驱动文件夹,添加到Ubuntu的vscode中

 3.将我们的内核源码路径添加到c_cpp_properties.json和Makefile

 (1)c_cpp_properties.json文件

{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/**",
                "/home/alientek/alpha/alientek-zzk/kernel-chao/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek/include", 
                "/home/alientek/alpha/alientek-zzk/kernel-chao/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek/arch/arm/include", 
                "/home/alientek/alpha/alientek-zzk/kernel-chao/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek/arch/arm/include/generated/"
            ],
            "defines": [],
            "compilerPath": "/usr/bin/clang",
            "cStandard": "c11",
            "cppStandard": "c++17",
            "intelliSenseMode": "clang-x64"
        }
    ],
    "version": 4
}

  (2)Makefile文件

KERNELDIR := /home/alientek/alpha/alientek-zzk/kernel-chao/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek
//KERNELDIR表示开发板所使用的 Linux内核源码目录,使用绝对路径

CURRENT_PATH := $(shell pwd)
//CURRENT_PATH表示当前路径,直接通过运行“ pwd”命令来获取当前所处路
径。

obj-m := chrdevbase.o
//obj-m表示将 chrdevbase.c这个文件 编译为 chrdevbase.ko模块。

build: kernel_modules
//表示我们编译的是模块

kernel_modules:
	$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules
//编译时,先把目录切换到源码中,因为使用了源码的一些函数;编译完成后再把目录切换到当前目录,需要把编译生成的文件放在当前目录下,Linux内核中我们已经指定好交叉编译器了
 clean:
	$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean

 3.先清理(make clean)再编译(make)

alientek@ubuntu16:~/linux/IMX6ULL/Linux_Drivers/1_chrdevbase$ make clean
make -C /home/alientek/alpha/alientek-zzk/kernel-chao/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek M=/home/alientek/linux/IMX6ULL/Linux_Drivers/1_chrdevbase clean
make[1]: Entering directory '/home/alientek/alpha/alientek-zzk/kernel-chao/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek'
  CLEAN   /home/alientek/linux/IMX6ULL/Linux_Drivers/1_chrdevbase/.tmp_versions
  CLEAN   /home/alientek/linux/IMX6ULL/Linux_Drivers/1_chrdevbase/Module.symvers
make[1]: Leaving directory '/home/alientek/alpha/alientek-zzk/kernel-chao/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek'
alientek@ubuntu16:~/linux/IMX6ULL/Linux_Drivers/1_chrdevbase$ make
make -C /home/alientek/alpha/alientek-zzk/kernel-chao/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek M=/home/alientek/linux/IMX6ULL/Linux_Drivers/1_chrdevbase modules
make[1]: Entering directory '/home/alientek/alpha/alientek-zzk/kernel-chao/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek'
  CC [M]  /home/alientek/linux/IMX6ULL/Linux_Drivers/1_chrdevbase/chrdevbase.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/alientek/linux/IMX6ULL/Linux_Drivers/1_chrdevbase/chrdevbase.mod.o
  LD [M]  /home/alientek/linux/IMX6ULL/Linux_Drivers/1_chrdevbase/chrdevbase.ko
make[1]: Leaving directory '/home/alientek/alpha/alientek-zzk/kernel-chao/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek'
alientek@ubuntu16:~/linux/IMX6ULL/Linux_Drivers/1_chrdevbase$ ls
chrdevbase.c  chrdevbase.code-workspace  chrdevbase.ko  chrdevbase.mod.c  chrdevbase.mod.o  chrdevbase.o  Makefile  modules.order  Module.symvers
alientek@ubuntu16:~/linux/IMX6ULL/Linux_Drivers/1_chrdevbase$ 

 4.先清理(make clean)再编译(make)

 四、驱动模块加载与卸载

Linux驱动有两种运行方式,第一种就是将驱动编译进 Linux内核中,这样当 Linux内核启动的时候就会自动运行驱动程序。第二种就是将驱动编译成模块 (Linux下模块扩展名为 .ko),在Linux内核启动以后使用“ insmod”命令加载驱动模块。

 1.将我们在vscode中编译出来的文件拷贝到制作好的根文件目录下

alientek@ubuntu16:~/linux/IMX6ULL/Linux_Drivers/1_chrdevbase$ sudo cp chrdevbase.ko /home/alientek/linux/nfs/rootfs/lib/modules/4.1.15 -f

 2.modprobe来加载模块

insmod命令不能解决模块的依赖关系,modprobe会分析模块的依赖关系,然后会将所有的依赖模块都加载到内核中,我们使用modprobe来加载模块;

modprobe命令默认会去/lib/modules/<kernel-version>目录中查找模块,比如本书使用的 Linux kernel的版本号为 4.1.15因此 modprobe命令默认会到 /lib/modules/4.1.15这个目录中查找相应的驱动模块,一般自己制作的根文件系统中是不会有这个目录的,所以需要自己手 动创建。

 对于一个新的模块使用modprobe加载的时候需要先调用一下depmod命令;驱动模块加载成功以后可以使用lsmod查看一下;卸载模块使用rmmod命令

  2.lsmod查看当前驱动模块是否有我们刚刚加载的模块

  3.rmmod查看当前驱动模块

 

 

 4.执行命令

/lib/modules/4.1.15 # modprobe chrdevbase.ko
chrdevbase: module license 'unspecified' taints kernel.
Disabling lock debugging due to kernel taint
module_init!
/lib/modules/4.1.15 # lsmod
Module                  Size  Used by    Tainted: P
chrdevbase               664  0
/lib/modules/4.1.15 # rmmod chrdevbase.ko
module_exit!
/lib/modules/4.1.15 # lsmod
Module                  Size  Used by    Tainted: P
/lib/modules/4.1.15 # ls
8188eu.ko              ft5x06.ko              libcomposite.ko
8189fs.ko              g_audio.ko             modules.alias
8192cu.ko              g_mass_storage.ko      modules.dep
8821cu.ko              gpioled.ko             modules.symbols
adcApp                 ledAPP                 usb_f_mass_storage.ko
chrdevbase.ko          ledApp                 usb_f_uac1.ko
/lib/modules/4.1.15 # lsmod
Module                  Size  Used by    Tainted: P
/lib/modules/4.1.15 # modprobe chrdevbase.ko
module_init!
/lib/modules/4.1.15 # lsmod
Module                  Size  Used by    Tainted: P
chrdevbase               664  0
/lib/modules/4.1.15 # rmmod chrdevbase.ko
module_exit!
/lib/modules/4.1.15 # lsmod
Module                  Size  Used by    Tainted: P

5.在Ubuntu上的根文件系统中同步可以看到文件

alientek@ubuntu16:~/linux/nfs/rootfs/lib/modules/4.1.15$ pwd
/home/alientek/linux/nfs/rootfs/lib/modules/4.1.15
alientek@ubuntu16:~/linux/nfs/rootfs/lib/modules/4.1.15$ ls
8188eu.ko  chrdevbase.ko      ledApp           modules.symbols
8189fs.ko  ft5x06.ko          ledAPP           usb_f_mass_storage.ko
8192cu.ko  g_audio.ko         libcomposite.ko  usb_f_uac1.ko
8821cu.ko  g_mass_storage.ko  modules.alias
adcApp     gpioled.ko         modules.dep
alientek@ubuntu16:~/linux/nfs/rootfs/lib/modules/4.1.15$ ls
8188eu.ko  chrdevbase.ko      ledApp           modules.symbols
8189fs.ko  ft5x06.ko          ledAPP           usb_f_mass_storage.ko
8192cu.ko  g_audio.ko         libcomposite.ko  usb_f_uac1.ko
8821cu.ko  g_mass_storage.ko  modules.alias
adcApp     gpioled.ko         modules.dep

 我们的第一个驱动模块加载与卸载编译完成

 五、代码

chrdevbase.c

#include <linux/module.h>
#include <linux/init.h>//printk函数头文件
static int __init chrdevbase_init(void)
{
    printk("module_init!\r\n");
	return 0;
}

static void __exit chrdevbase_exit(void)
{
	//没有返回值
    printk("module_exit!\r\n");
}
/*
模块的入口与出口
*/
module_init(chrdevbase_init);
module_exit(chrdevbase_exit);
/*
模块的一些许可证信息
*/

MODULE_AUTHOR("Chao");//作者是谁
MODULE_LICENSE("GPL");//开源协议

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/748346.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

合约期VS优惠期,搞明白他们的区别才能避免很多坑!

在购买流量卡时&#xff0c;相信大家也都发现了&#xff0c;市面上的不少套餐都是有合约期和优惠期的&#xff0c;尤其是联通和移动&#xff0c;那么&#xff0c;什么是合约期&#xff1f;什么又是优惠期呢&#xff1f; ​ 其实&#xff0c;目前很多在网上办理的大流量卡都是有…

matlab量子纠缠态以及量子门操作下的量子态

前言 今天我们来聊聊题外话&#xff0c;量子纠缠&#xff0c;在目前物理分支中&#xff0c;要说最深&#xff0c;最能改变人类对宇宙影响的莫过于量子力学了&#xff0c;假如我们可以人为的对两个粒子施加纠缠态&#xff0c;那么我们将可以足不出户的完成对外界的操控 简介 …

Arm Linux 修改 网络 mac 地址的方式方法

一、指令修改 查看网络信息指令 ifconfig修改网络 mac 地址&#xff0c;指令 ifconfig 网卡名 hw ether mac地址例如&#xff1a; ifconfig eth0 hw ether 08:00:27:00:01:96二、C语言程序修改 1.使用 ioctl 和 SIOCSIFHWADDR 来设置MAC地址&#xff0c;示例代码如下&…

空间转录组学联合单细胞转录组学揭示卵巢癌生存相关受配体对

卵巢癌&#xff0c;作为女性生殖系统中的一种常见恶性肿瘤&#xff0c;其高级别浆液性卵巢癌&#xff08;HGSC&#xff09;亚型尤其致命。尽管多数患者对初次治疗反应良好&#xff0c;但超过75%的晚期HGSC患者会在治疗后复发&#xff0c;并且对化疗药物产生耐药性。然而&#x…

信息系统项目管理师(项目管理师)

项目管理者再坚持“聚焦于价值”原则时&#xff0c;应该关注的关键点包括&#xff1a;1价值是项目成功的最终指标&#xff1b;2价值可以再整个项目进行期间、项目结束或完成后实现&#xff1b;3价值可以从定性和/或定量的角度进行定义和衡量&#xff1b;4以成果为导向&#xff…

【前端】实现时钟网页

【前端】实现时钟网页 文章目录 【前端】实现时钟网页项目介绍代码效果图 项目介绍 时钟显示在网页中央&#xff0c;并且使网页能够切换白天和夜晚两种模式。搭建基本的html结构&#xff0c;动态得到实时的时&#xff0c;分&#xff0c;秒 通过Date()函数获得。将得到的数字根…

手机定位技术全解析:原理、发展与应用

1. 引言 背景介绍 最近&#xff0c;神仙姐姐刘亦菲主演的电视剧《玫瑰的故事》中的一段情节引发了广泛讨论。剧中&#xff0c;方协文&#xff08;丈夫&#xff09;对玫瑰&#xff08;妻子&#xff09;的控制欲变本加厉&#xff0c;竟然偷偷在她的手机上安装监控软件&#xff…

考研数学(4/9):微分方程

微分方程 微分方程是高等数学中一个重要的分支&#xff0c;也是考研数学数一中必考的内容。本章主要介绍微分方程的概念、一阶微分方程、高阶线性微分方程以及微分方程的应用。 1. 微分方程的概念 1.1 微分方程的定义 微分方程 是指包含未知函数及其导数的方程。 更准确地说&am…

宠物领养救助管理系带万字文档java项目基于springboot+vue的宠物管理系统java课程设计java毕业设计

文章目录 宠物领养救助管理系统一、项目演示二、项目介绍三、万字项目文档四、部分功能截图五、部分代码展示六、底部获取项目源码带万字文档&#xff08;9.9&#xffe5;带走&#xff09; 宠物领养救助管理系统 一、项目演示 宠物领养救助系统 二、项目介绍 基于springbootv…

Linux基础 - iptables 与 firewalld 防火墙

目录 零. 简介 一. iptables 二. firewalld 三. 总结 零. 简介 iptables iptables 是 Linux 内核中集成的一种基于命令行的防火墙工具。它通过一系列规则来控制网络数据包的流动&#xff0c;包括允许、拒绝、修改数据包等操作。iptables 可以对入站、出站和转发的数据包进…

数据驭王: PostgreSQL教程指南解密

PostgreSQL教程大纲 一、介绍1.1 什么是PostgreSQL&#xff1f;1.2 PostgreSQL的历史和发展1.3 为什么选择PostgreSQL&#xff1f; 二、安装和设置2.1 下载和安装PostgreSQL2.2 配置PostgreSQL2.3 测试PostgreSQL 三、基本操作3.1 连接到PostgreSQL数据库步骤一&#xff1a;安装…

算法刷题笔记--二叉树篇

感觉树这一章还是没搞清楚&#xff0c;可能是基础不扎实的缘故&#xff0c;学完C巩固底层知识后二刷 理论基础 确定递归函数的参数和返回值 :确定哪些参数是递归的过程中需要处理的&#xff0c;那么就在递归函数里加上这个参数&#xff0c; 并且还要明确每次递归的返回值是什么…

2024软件设计师笔记之考点版(一考就过):26-39

软件设计师之一考就过:成绩版 考点26:类、封装、继承、多态 真题1:在面向对象方法中,两个及以上的类作为一个类的超类时,称为(多重继承),使用它可能造成子类中存在(二义性)的成员。 真题2:在面向对象方法中,多态指的是(客户类无需知道所调用方法的特定子类的实现…

【项目实训】falsk后端连接数据库以及与前端vue进行通信

falsk连接数据库 我们整个项目采用vueflaskmysql的框架&#xff0c;之前已经搭建好了mysql数据库&#xff0c;现在要做的是使用flask连接到数据库并测试 安装flask 首先安装flask pip install flask 进行数据库连接 数据库连接需要使用到pymysql库以及flask库 连接数据库…

原创作品—医疗行业软件界面UI、交互设计

在医疗行业大屏UI设计中&#xff0c;首要的是以用户为中心&#xff0c;深入理解医生、护士、管理层等用户群体的具体需求和工作流程。大屏设计应直观展示关键医疗数据、患者信息、设备状态等&#xff0c;确保用户能够迅速、准确地获取所需信息。同时&#xff0c;功能布局应合理…

字节豆包 MarsCode:AI 开发工具

MarsCode 是豆包旗下的智能编程助手&#xff0c;类似 GitHub Copilot 提供以智能代码补全为代表的核心能力&#xff0c;简单试用了下&#xff0c;免费&#xff0c;使用时需要手机号登录&#xff0c;代码补全还算 ok&#xff0c;聊天功能就有点差了。 还包括一个 AI 原生 IDE&am…

【Qt之·类QTableWidget】

系列文章目录 文章目录 前言一、常用属性二、成员函数2.1 左上角空白区域 三、实例演示总结 前言 一、常用属性 二、成员函数 方法描述selectRow选中行removeRow移除行insertRow插入行rowCount总行数 2.1 左上角空白区域 QTableCornerButton即不属于列表头&#xff0c;也不…

Vue移动端动态表单生成组件

FormCreate 是一个可以通过 JSON 生成具有动态渲染、数据收集、验证和提交功能的表单生成组件。支持6个UI框架&#xff0c;适配移动端&#xff0c;并且支持生成任何 Vue 组件。内置20种常用表单组件和自定义组件&#xff0c;再复杂的表单都可以轻松搞定。 帮助文档 | 源码下载…

如何提取mac app中的应用程序图标 x.app图标位置

在macos系统中安装的应用程序 .app的图标都是 以 .icns结尾的&#xff0c;默认位于 .app应用程序包中的Contents/Resources/目录下&#xff0c;只要是在这个目录下的 .icns文件就是这个应用的图标&#xff0c;如&#xff1a;mac版微信的图标就是 /Applications/WeChat.app/Co…

【Java中导出Excel导出多个sheet页】

Java中导出Excel导出多个sheet页 序言如何处理多个sheet页的导出期间遇到了一个sheet页相关的问题&#xff0c;以及解决办法多sheet页导出遇到&#xff0c;第二个sheet页的标题名称会把第一个的覆盖的问题 结语 序言 在日常工作中经常有导出数据文件的需求&#xff0c;避免不了…