-- 针对内核开发去配置vscode
-- 解决头文件不报错
-- 头文件报错就去改环境变量
内核的驱动框架
目录
驱动的理论开发
1、系统的分层概念
-- 实际上系统分为两层
-
一层叫做系统层11 就是你们学习系统接触层面11 之前缩写的所有的程序 main 系统编程
都运行在系统层! -
一层叫做内核层
一般人根本不知道层:内核层!
一般人写的程序不可能运行到内核层!
除非他有内核源码
-- 所以说:之前你学习的系统层的框架 int main() { } 在驱动开发中,以上框架 不能运行在内核层
你想要把程序运行在内核层你就要学习一个新的框架!
内核层的框架!
2、内核层和系统层区别
-- 系统层: 一般程序员接触的运行程序的层面
搞上层: Java Python 网页 后台 Linux 系统开发
-- 内核层:
只有驱动开发人员最关注这个层面
驱动程序就是运行在这个层面
且这个层面有权限可以访问真实物理地址
也就是说在这个层面可以开发驱动
-- 3、内核层的代码的框架
#include “linux/kernel.h”
#include “linux/module.h”
//加载函数 必须用__init 修饰
static int __init myled_init()
{
return 0; //内核层有返回值 必须给返回值
//内核层如果不给返回值,则返回随机值
//可能会造成内核错误
//内核错误就直接造成整个系统崩溃!
}
//卸载函数
static void __exit myled_exit()
{
}
module_init(myled_init);//加载函数声明
module_exit(myled_exit);//卸载函数的声明
MODULE_LICENSE(“GPL”);//遵循开源协议
-- 4、内核层的代码是如何编译的
-- 写一个Makefile
--
obj-m += 1.o
#obj-m:代表模块 module (驱动) 目标-> test.o->test.c
KDIR:=/home/pp/RK3588S/kernel
#代表你的编译的所用的内核的位置
CROSS_COMPILE_FLAG=/home/xyd/mycode/RK3588S/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-
#这是你的交叉编译器路径
all:
make -C $(KDIR) M=$(PWD) modules ARCH=arm64 CROSS_COMPILE=$(CROSS_COMPILE_FLAG)
#调用内核层 Makefile 编译目标为 modules->模块 文件在当前路径
# 架构 ARCH=arm64
clean:
rm -f *.ko *.o *.mod.o *.mod.c *mod *.symvers *.markers *.order
-- 之后使用,注意更改文件路径,将路径改成你的路径
make
-- 注意makefile中写了一个警告当错误的标识,所以这里会报错没有参数的警告弄成错误,所以这里要加一个参数。
-- 生成驱动文件(*.ko)
-- 之后打开apd终端(上一节讲过),使用insmod命令加载驱动文件
-- 先连接开发板然后连接虚拟机
-- 连接成功后会生成一个手机
-- 我们需要将我们生成的驱动文件直接推送到adb终端
-- 先进入adb终端
adb shell
-- 之后使用push命令将文件推送adb终端
-- 之后就可以看到推送成功
-- 之后使用insmod命令加载驱动文件
加载指令: insmod xxx.ko 就会调用 内核驱动写的加载函数
-- 注意:可以看到这里没有显示,这是因为adb终端不显示内核层的信息。所以我们要去uart终端查看内核层的信息。
adb终端只显示系统层的打印,而uart终端显示系统层和内核层的打印。
系统曾就是说我们之前学的程序,内核层就是驱动程序!
例如#include “stdio.h” int main就是系统曾的
ADB 调试终端不显示内核任何输出信息
只有 UART 显示所有系统 + 内核层信息!
ADB 想要查看内核信息:
dmesg 查看系统日志!
-- 但是adb终端可以查看日志
dmesg
-- 注意前面有时间
内核输出有一个特点
内核的所有信息输出都有一个前缀的时间!
时间代表开发板开机时间!
--
-- 之后打开uart终端
-- 之后使用insmod命令加载驱动文件
-- 之后使用rmmod命令卸载驱动文件
卸载指令:
rmmod xxx.ko
就会调用内核驱动写的卸载函数
-- 之后使用dmesg命令查看内核日志
vscode 自动提醒功能怎么实现(通过配置头文件路径)
-- 1、先在一个文件夹下打开vscode,可以先建文件再打开,也可以先打开后创建新文件
code ./
-- 注意:打开之后我们可以看到同样生成了三个文件
-- 其中第一个文件里面就可以添加我们使用到的头文件路径
-- 2、之后按照我们的框架写代码
-- 可以看到vscode会报错,这是因为内核模块的代码框架本身就在vscode不适配,所以先不用管,我们只需要配一下头文件即可,我们配头文件的目的是vscode可以AI自动补全,方便我们写代码。
-- 3、来配置头文件
-- 那么头文件的路径在哪找呢?
-- 首先来到内核的路径下使用find命令搜索我们的头文件路径
find ./ -name kernel.h
-- 找到linux下的这个头文件,因为我们写的头文件是linux下的,所以路径不用再次包含linux,直接将linux省掉即可。
-- 但是可以看到这个头文件有很多都是linux下的头文件,我们这里优先找原声内核include下的,也就是画出来的
-- 4、之后添加到存放头文件的路径下
-- 因为这里给的是相对路径,而头文件的路径要给绝对路径
-- 于是要加上当前文件夹下的路径,注意将linux路径省了
-- 5、之后保存,我们再看什么报错
-- 可以看到又报了一个错,是找不到这个头文件
-- 于是我们再去搜这个头文件
find ./ -name linkage.h
-- 这里可以看出上述找不到的头文件实在asm下的,我们就找asm下的头文件
-- 因为架构是arm64,所以我们优先看arm64架构下的头文件
-- 注意记得写逗号和绝对路径
-- 之后保存之后我们再看有什么错误
-- 发现又是其他头文件找不到
-- 重复以上步骤
-- 之后保存之后我们再看有什么错误
-- 重复以上步骤
-- 之后保存之后我们再看有什么错误
-- 重复以上步骤
-- 保存,最终发现我们的程序还是报错,但是头文件不报错了,就不用再管了,因为我们配置文件主要就是配置他的头文件,方便我们写代码,所以头文件不报错我们就可以ai自动生成函数了