#驱动开发

内核模块
字符设备驱动

中断、内核定时器

裸机开发和驱动开发的区别?

裸机开发

驱动开发(基于内核)

相同点

都能够控制硬件(本质:操作寄存器)

不同点

用C语言给对应的地址里面写值

按照一定的框架格式往地址里面写值

单独编译单独执行

依赖内核编译、执行

同时只能执行一份代码

同时执行多份代码

只需要一个main函数

依赖内核的框架来操作硬件

STM32启动流程详解(超全,startup_stm32xx.s分析)_stm32启动过程详解-CSDN博客文章浏览阅读3.8k次,点赞32次,收藏84次。启动模式只决定程序烧录的位置,加载完程序之后会有一个重映射(映射到0x00000000地址位置);真正产生复位信号的时候,CPU还是从开始位置执行。值得注意的是STM32上电复位以后,代码区都是从0x00000000开始的,三种启动模式只是将各自存储空间的地址映射到0x00000000中。_stm32启动过程详解https://blog.csdn.net/m0_56694518/article/details/135032170?spm=1001.2014.3001.5501

驱动里面操作LED灯的寄存器 

驱动模块是依赖内核框架执行代码

ARM裸机直接操作的是物理内存,直接拿到寄存器地址写值。

驱动是基于内核,操作的是虚拟内存,使用之前先映射实际物理内存。

Linux系统组成

硬件层:led 鼠标 键盘 lcd 触摸屏 摄像头 u盘 emmc 猫 路由器 dm9000

0-3G的用户空间是每个进程单独拥有0-3G的空间

系统调用(软中断swi)   应用层通过系统调用与底层交互,swi将应用层切换到内核层。

驱动代码就在内核空间(在3-4G内核空间, 共用空间)

注:1G的物理内存映射成0~4G的虚拟内存,每个进程都可以访问内核,0~3G是每个进程单独拥有的,3G~4G是所有的共有的。代码运行在物理内存上,向虚拟内存上面写值,其实是写在物理内存上面的

宏内核和微内核(了解)

宏内核:集中管理的架构,负责多种系统资源的调度和管理;

将进程、文件、网络、内存、设备等功能集成到一个内核中,具备直接操作硬件的能力。

优点:执行效率高,操作系统资源可以直接在内核中实现,减少了进程间通信带来的性能损失,提高了系统的执行速度。

缺点:内核的代码量非常大,不易拓展,且单个模块的崩溃可能会影响整个系统的运行。

eg:ubuntu、Android

微内核:更侧重于模块化和移植性,通过传递请求的方式实现不同模块之间的交互

将最基本的操作系统功能放到内核中,其他服务和程序在微内核之上构建,并在用户态下运行。(设计分界线不同)

优点:系统灵活性和可扩展性好,系统可靠性高

缺点:代码运行效率低->通过API接口让整个系统运行起来

eg:Window 、鸿蒙

驱动移植

步骤:

需要有对应的驱动代码(.c)

修改对应目录的Makefile - drivers-》char)-》obj-$(CONFIG_LED) +=led.o

修改对应目录里的Kconfig(tristate " ...... " )

make menuconfig-》配置自己的驱动为M(模块的)

make modules(在最顶层目录)

把编译产生的.ko结尾的驱动文件,放到nfs(/opt/6818/rootfs/rootfs)目录下使用

安装insmod led.ko

卸载rmmod led

静态编译:生成的执行文件不依赖于外部库文件,可以直接运行,且程序运行效率较高。

动态编译:可执行文件和库分开写,生成的可执行程序需要依赖于外部的库文件。

内部编译:在内核源码树中编译

外部编译:在内核源码树外编译

驱动模块

驱动的框架

入口(安装):资源申请

出口(卸载):资源释放

许可证:GPL(开源的---》Linux开源-----》GPL许可证)

Linux内核许可规则

Linux内核许可规则 — The Linux Kernel documentation

驱动程序编写

#include <linux/init.h>
#include <linux/module.h>//申请资源
//static - 限定作用域,延长生命周期
//存储类型 数据类型 指定存放内存区域 函数名(形参)
static int __init hello_init(void)
{
    return 0;
}//释放资源
static void __exit hello_exit(void)
{
}module_init(hello_init);    //入口:申请资源   本质-回调一个自己写的函数
module_exit(hello_exit);    //出口:释放资源
MODULE_LICENSE("GPL");      //许可证:公共许可协议(开源协议)

ctags的安装和使用

方法1

1.ctags

ctags工具是将指定目录以及子目录添加索引文件,可以实现快速搜索文件内容(宏定义、取别名以及结构体)

2.ctags创建索引文件

安装ctags:

sudo apt-get install ctags

在/usr/include目录下执行命令:

sudo ctags -R

执行完毕之后,会生成一个tags的索引文件

3、默认只能在/usr/include使用,所以需要设置为全局

打开家目录下的.vimrc文件,然后添加一句话:

set tags+=/usr/include/tags

5.3 ctags工具的使用

追代码:

vim -t 结构体名/宏定义名/取别名

vi -t 结构体名/宏定义名/取别名

如果要查看所有定义的位置:在底行模式下输入

tselect 结构体名/宏定义名/取别名

继续追指定的内容:

将光标放在这个内容的任意位置,然后点击快捷键ctrl ]

返回上一次的文件:

ctrl t

例如:追一下sockaddr_in结构体,查看结构体成员

继续查看这个结构体中成员的类型

查看完毕后返回到最开始的结构体

方法2

把ctags_set文件夹拷贝到Ubuntu里

cd ctags_set

sudo chmod 774 ctags_set.sh

sudo ./ctags_set.sh

验证:在~目录下

vi -t sockaddr_in

生成tags 文件 :在相应目录下 ctags -R

在代码中追变量: ctrl + ]

返回代码中 : ctrl + t

mv tags /home/hq/kernel/kernel-3.4.39

可以不执行:

==================================

在内核源码目录下 执行

make tags

========================

cd ~

sudo vim .vimrc

在.vimrc 最后添加

set set tags+=内核源码绝对路径/tags

例如set tags+=/home/hq/kernel/kernel-3.4.39/tags

驱动Makefile编写

KERNELDIR = /home/hq/kernel/kernel-3.4.39	#开发板路径
#KERNELDIR = /lib/modules/$(shell uname -r)/build	#PC机PWD = $(shell pwd)    #驱动文件的路径all:
	make -C $(KERNELDIR) M=$(PWD) modules
	#基于内核框架将驱动代码编译生成驱动模块
	#需要在内核的顶层目录下执行 make modules
	#-C:指定到哪个路径下执行这个命令
	#M:赋值,要将哪个路径下的驱动文件编译生成驱动模块
    #注:进入内核目录下执行make modules这条命令,如果不指定 M=$(PWD) 会把内核目录下的.c文件编译生成.ko.PHONY:clean
clean:
	make -C $(KERNELDIR) M=$(PWD) cleanobj-m += hello.o

Source Insight工具

软件安装

激活码:SI3US-719473-71478

使用(配置工程)

配置信息:*.c;*.h;*.S;*.lds;*defconfig;*Makefile;*.mak;*.dts;*.dtsi

软件使用

ctrl+/ 可以搜索变量及函数

按住ctrl左击鼠标可以追变量或者函数

打印函数

在Linux中可以使用

grep "printk" * -nR

搜索函数,搜到以后,在里面任意找到一个,看函数原形

	printk (打印级别 "内容");printk(KERN_ERR "Fail%d",a);printk(KERN_ERR "%s:%s:%d\n",__FILE__,__func__,__LINE__);//(驱动在哪一个文件,哪一个函数,哪一行)

内核打印级别

vi -t KERN_ERR(查看内核打印级别)//也可直接在SI中按住ctrl左击跳转进行查看

0 ------------------ 7

最高的 最低的

终端打印级别

#define console_loglevel (console_printk[0])    //终端的级别
#define default_message_loglevel (console_printk[1])//消息的默认级别
#define minimum_console_loglevel (console_printk[2])//终端的最大级别
#define default_console_loglevel (console_printk[3])//终端的最小级别

查看虚拟机终端级别

cat /proc/sys/kernel/printk

只有当消息的级别大于终端级别,消息才会被显示

打印函数代码

#include <linux/init.h>
#include <linux/module.h>
#include <linux/printk.h>static int __init hello_init(void)
{
    printk("hello world\n");
    printk(KERN_CRIT "%s %s %d\n",__FILE__,__func__,__LINE__);
    printk(KERN_INFO "%s %s %d\n",__FILE__,__func__,__LINE__);
    return 0;
}static void __exit hello_exit(void)
{
    printk("bai bai le nin lei\n");
    printk(KERN_CRIT "%s %s %d\n",__FILE__,__func__,__LINE__);
    printk(KERN_INFO "%s %s %d\n",__FILE__,__func__,__LINE__);
}module_init(hello_init);    //入口:申请资源
module_exit(hello_exit);    //出口:释放资源
MODULE_LICENSE("GPL");      //许可证:公共许可协议(开源协议)

但对与咱们的这个Ubuntu被开发者修改过,所有消息不会主动回显

命令使用

sudo insmod hello.ko 安装驱动模块

sudo rmmod hello 卸载驱动模块

lsmod 查看模块

dmesg 查看消息

sudo dmesg -C 直接清空消息不回显

sudo dmesg -c 回显后清空

修改系统的默认级别

su root

echo 4 3 1 7 > /proc/sys/kernel/printk

虚拟机的默认情况:

修改开发板的默认级别

查看开发板的默认级别

cat /proc/sys/kernel/printk

如果想修改开发板对应的打印级别

vi etc/init.d/rcS

echo 5 5 1 7 > /proc/sys/kernel/printk

//当系统重新启动,rcS中的命令会全部重新执行一遍

rootfs/etc/init.d/rcS里面添加上以后再起板子,板子的级别就为如下:

etc/init.d/rcS:一些启动虚拟机需要启动的东西都可以放在这个文件中,启动系统时同时启动。

echo 5 5 1 7 > /proc/sys/kernel/printk

放到板子跟文件系统对应这个文件中。

安装驱动和卸载驱动时,消息会打印。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

hackme靶机通关攻略

1、登录靶机&#xff0c;查询是否有注入点 2、判断闭合方式 输入OSINT and 11 # 输入OSINT and 12 # 得出闭合方式为单引号 2、查询数据库名 输入-1 union select database(),2,3 # 3、查询数据库中的表 输入-1 union select group_concat(table_name),2,3 from informa…

还在用谷歌翻译?这4款翻译工具也许更高效!

随着国内很多翻译工具的不断发展&#xff0c;谷歌翻译相对来说不是一款十分有优势的翻译工具。并且使用的时候还会受到网络的限制&#xff0c;如过大家有翻译方面的需求的话&#xff0c;不妨试试这几款翻译工具。不论是从翻译的语言种类&#xff0c;翻译质量还是翻译速度来看&a…

金蝶云星空协同平台业务对象下同时存在未加载未引入对象的原因分析和处理方式

文章目录 问题截图原因分析&#xff0c;解决方式 问题截图 原因分析&#xff0c;解决方式 未加载是 别的账套提交的数据&#xff0c;本账套不存在&#xff0c;点击加载则回、会同步到当前数据中心 未引入&#xff0c;则是在A账套删除后提交到应用&#xff0c;在B账套则显示未…

我的推荐:腾讯云罗云《从零构建向量数据库》

在2024年8月&#xff0c;好几本和数据库相关的图书相继出版&#xff0c;我以为&#xff0c;这恰恰是数据库领域蓬勃向上的一种表现。 数据库需要更多的人关注&#xff0c;哪怕是谈论&#xff0c;所以我的《数据库简史》是一种尝试&#xff0c;希望以一种科普的风格&#xff0c;…

陪诊志愿服务正在开展,喜鹊医疗打造国内首家陪诊聚合平台

2024年8月&#xff0c;为了培养一支专业、合格的陪诊志愿服务队伍&#xff0c;为志愿者提供就业帮扶&#xff0c;也满足社会日益增长的健康需求。由喜鹊医疗捐赠专项资金&#xff0c;中国民族卫生协会联合中国志愿基金会共同开展“健康中国行&#xff0c;陪诊惠民工程——陪诊志…

暴力破解和撞库攻击有什么区别,怎么防御暴力破解和撞库攻击

在网络世界中&#xff0c;我们的账户安全时刻面临着各种威胁。其中&#xff0c;暴力破解和撞库攻击就是常见的两种危险手段。今天&#xff0c;就让我们深入了解这两种攻击方式的含义&#xff0c;并学习如何有效地进行防护。 暴力破解的含义 暴力破解&#xff0c;就如同一个不…

FPGA开发:EDA × HDL × IP核

EDA技术 EDA指Electronic Design Automation&#xff0c;翻译为&#xff1a;电子设计自动化&#xff0c;最早发源于美国的影像技术&#xff0c;主要应用于集成电路设计、FPGA应用、IC设计制造、PCB设计上面。 而EDA技术就是指以计算机为工具&#xff0c;设计者在EDA软件平台上…

s3fs的使用

s3fs是一个将s3服务器上的桶映射为本地目录的程序。 项目源码位于&#xff1a; https://github.com/s3fs-fuse/s3fs-fuse 这是一个比较长期的项目了&#xff0c;现在在大数据领域S3协议基本上已经成为最通用的协议。 各大云平台&#xff0c;什么阿里云&#xff0c;某为云&am…

哪款清理猫咪浮毛效果好?希喂、霍尼韦尔、美的宠物空气净化器PK

最近在宠物领域&#xff0c;宠物空气净化器的讨论热度很高&#xff0c;不少铲屎官们都有购买的意向。身为三猫孩子的家长&#xff0c;养宠以来市面上所有的猫毛清理工具我都用过&#xff0c;这种新兴产品肯定也不会错过。我结合自身情况和预算&#xff0c;对市面上的品牌进行筛…

没关系,会一手Git版本控制就行(全)

Git版本控制 文章目录 Git版本控制1. 版本控制1.1 概述1.2 版本控制优点1.3 本地版本控制系统&#xff08;离线版&#xff09;1.4 集中化的版本控制系统&#xff08;联网版&#xff09;1.5 分布式版本控制系统&#xff08;离线联网版&#xff09; 2. Git概述2.1 Git基本工作流程…

python-第三方库-[yarl、yaml]

python-第三方库-[yarl、yaml] 一: yarl1> yarl 介绍2> yarl.URL 介绍1. yarl.URL 的语法格式2. yarl.URL demo3. yarl.URL.build()4. yarl.URL().with_*()5. yarl.URL().update_query()6> url / &%组合 二&#xff1a;yaml1> yaml 介绍2> yaml 基本规则1. …

Spring入门之AOP(包含实例代码)

目录 什么是spring AOPAOP的优势AOP的底层原理AOP的相关术语AOP的应用切入点表达式格式注意问题 通知类型 代码示例1. 导入Maven项目依赖2. 准备一个实体类&#xff08;先定义接口再实现&#xff09;3. 定义切面类4. 准备配置文件5. 准备测试类6. 测试结果6.1 方法正常运行6.2 …

同三维TM6-6 有线6级联会议麦克风详情介绍

同三维TM6-6 有线6级联会议麦克风 信息通讯类智能阵列麦克风 有线传输&#xff0c;强抗干扰、可级联、长续航、低延时 6个麦克风级联&#xff0c;通过3.5音频线级联, 可以同时使用3.5mm LINE IN/OUT、USB有线连接PC端&#xff0c;每条音频线是3米&#xff0c;可应用在视频会…

阶跃星辰推出Step-1X:让你的想象力插上翅膀

阶跃星辰 在人工智能快速发展的今天&#xff0c;AI绘画技术正以惊人的速度不断突破创新。就在不久前&#xff0c;阶跃星辰在2024世界人工智能大会上发布的Step-1X图像生成大模型。让我们一起走进Step-1X的世界&#xff0c;看看它如何为我们的想象力插上翅膀。 Step-1X Step-1X …

vue3中ref绑定的节点顺序错乱

问题复现 眨眼睛这个是修正过了的&#xff0c;小友的应该是ref直接绑定navigationTextList对吧&#xff0c; 按正常想法肯定是既然这个数组会动态更新&#xff0c;我只需要index不就能确定是哪个节点啦&#xff0c;倘若只是静态数据应该不会有什么问题&#xff0c; ⚠️但如果出…

湖南省工业废水高氯酸盐排放新标准解析与技术应对策略

随着工业化进程的加快&#xff0c;环境污染问题变得尤为突出。特别是在某些特定行业产生的污染物&#xff0c;如高氯酸盐&#xff0c;因其对环境和人体健康的潜在危害&#xff0c;越来越受到关注。为了解决这一问题&#xff0c;湖南省生态环境厅与省市场监督管理局联合制定了《…

网络层 IV(ARP、DHCP、ICMP)【★★★★★★】

&#xff08;★★&#xff09;代表非常重要的知识点&#xff0c;&#xff08;★&#xff09;代表重要的知识点。 一、地址解析协议&#xff08;ARP&#xff09;&#xff08;★★&#xff09; 在局域网中&#xff0c;由于硬件地址已固化在网卡上的 ROM 中&#xff0c;因此常常将…

PPT图表制作不再难!这款在线PPT软件让办公更简单!

ppt图表怎么制作&#xff1f; 在当下注重视觉呈现的数字化时代&#xff0c;有效的信息传递和数据可视化变得越来越重要。不管是商业演示、学术报告还是项目汇报&#xff0c;一份精心制作的PPT演示文稿&#xff0c;往往能够起到事半功倍的效果。其中&#xff0c;图表作为PPT中不…

C++ ─── List的模拟实现

一&#xff0c; List的模拟实现 List 是一个双向循环链表,由于List的节点不连续&#xff0c;不能用节点指针直接作为迭代器&#xff0c;因此我们要对结点指针封装&#xff0c;来实现迭代器的作用。 迭代器有两种实现方式&#xff0c;具体应根据容器底层数据结构实现&#xff1…

Linux 进程概念 进程状态 fock函数讲解

PID和PPID 我如果想获取自己的PID呢&#xff1f; pid_t getpid(void);头文件:#include<sys/types.h> #include<unistd.h> 返回调用这个函数的进程ID(自己的PID) PID一般会变化 如何获取PPID? pid_t getppid(void);(父ID)头文件:#include<sys/types.h>…