#驱动开发

内核模块
字符设备驱动
中断、内核定时器

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

|-----|----------------|------------------|
| | 裸机开发 | 驱动开发(基于内核) |
| 相同点 | 都能够控制硬件(本质:操作寄存器) ||
| 不同点 | 用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) clean`
	
`obj-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

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

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

相关推荐
三菱-Liu6 分钟前
三菱变频器以模拟量电流进行频率设定(电流输入)
驱动开发·单片机·嵌入式硬件·硬件工程·制造
三菱-Liu6 小时前
三菱FX5U CPU 内置以太网功能
网络·驱动开发·硬件工程·制造·mr
让开,我要吃人了9 小时前
OpenHarmony鸿蒙( Beta5.0)摄像头实践开发详解
驱动开发·华为·移动开发·harmonyos·鸿蒙·鸿蒙系统·openharmony
OH五星上将1 天前
如何更换OpenHarmony SDK API 10
驱动开发·嵌入式硬件·sdk·harmonyos·openharmony·鸿蒙开发
OH五星上将3 天前
OpenHarmony(鸿蒙南向开发)——标准系统移植指南(二)Linux内核
linux·驱动开发·嵌入式硬件·移动开发·harmonyos·鸿蒙开发·鸿蒙内核
芊言芊语3 天前
蓝牙驱动开发详解
驱动开发
让开,我要吃人了3 天前
OpenHarmony鸿蒙( Beta5.0)RTSPServer实现播放视频详解
驱动开发·嵌入式硬件·华为·移动开发·harmonyos·鸿蒙·openharmony
OH五星上将3 天前
OpenHarmony(鸿蒙南向开发)——轻量和小型系统三方库移植指南(二)
驱动开发·移动开发·harmonyos·内存管理·openharmony·鸿蒙内核·鸿蒙移植
CS_素锦少年4 天前
Linux_kernel驱动开发11
linux·运维·驱动开发
让开,我要吃人了4 天前
HarmonyOS NEXT应用开发性能实践总结
驱动开发·华为·性能优化·移动开发·harmonyos·鸿蒙·鸿蒙系统