基本概念
- Linux kernel
- 由linus等维护Linux的人员开发的内核
- https://www.kernel.org/
- 例如:linux-5.10.7.tar.gz
- linux_sdk.tar.gz
- 由芯片原厂(例如:Rockchip)BSP开发人员基于
Linux kernel
开发,提供给Linux驱动开发人员。 - 泰山派rk3566的linux sdk:
tspi_linux_sdk_repo_20240131.tar.gz
是由立创开发人员写的(类似上面的BSP开发人员)
- 由芯片原厂(例如:Rockchip)BSP开发人员基于
- Linux driver
- Linux驱动开发:在有
Linux sdk
的基础上进行开发,根据项目需求,决定增、删、改、调
哪些外设,为应用开发人员提供驱动接口。 - 当前学习的内容
- Linux驱动开发:在有
准备工作
设备与环境
个人笔记本电脑:Windows 10;gitee;mingw64;北京迅为电子开发板rk3568资料;移动WiFi(192.168.0.3)
Ubuntu Linux 20.4:VSCode;make;aarch64-none-linux-gnu;gitee;USB直连移动WiFi(192.168.42.133)
Linux开发板:泰山派;gitee;移动WiFi(192.168.0.196)
Ubuntu Linux 20.4
编译官方提供的linux_sdk.tar.gz
(官方指:瑞芯微或嘉立创)- 个人存放路径
/jnheCode/tspkfb/kernel
- 个人存放路径
交叉编译器环境配置
1
sudo vi /etc/profile
1
2
3# 末尾添加
# export PATH=$PATH:/usr/local/你的交叉编译器/bin
export PATH=$PATH:/usr/local/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin
模板记住
驱动模板(全文默写)
1
2
3
4
5
6
7
8/* 头文件 */
/* 参数传入(可选) */
/* 符号导出(可选) */
/* 函数 */
/* 模块加载 */
/* 模块卸载 */
/* 开源协议(可选) */
/* 作者信息(可选) */1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24/* 头文件 */
/* 参数传入(可选) */
/* 符号导出(可选) */
/* 函数 */
static int helloworld_init(void)
{
printk("helloworld_init\r\n");
return 0;
}
static void helloworld_exit(void)
{
printk("helloworld_exit\r\n");
}
/* 模块加载 */
module_init(helloworld_init);
/* 模块卸载 */
module_exit(helloworld_exit);
/* 开源协议(可选) */
MODULE_LICENSE("GPL v2")
/* 作者信息(可选) */
MODULE_AUTHOR("jianghe")Makefile模板(全文默写)
1
2
3# 架构 交叉编译器
# 目标 内核路径等
# make和make clean1
2
3
4
5
6
7
8
9
10
11
12# 架构 交叉编译器
ARCH = arm64
CROSS_COMPILE = aarch64-none-linux-gnu-
# 目标 内核路径等
obj-m += helloworld.o
KDIR := /jnheCode/tspkfb/kernel
PWD ?= $(shell pwd)
# make和make clean
all:
make -C $(KDIR) M=$(PWD) modules
clean:
make -C $(KDIR) M=$(PWD) clean加载与导出
1
2
3insmod helloworld.ko
lsmod
rmmod helloworld.ko参数传入(记住思路)
1
2
3/* 定义数据类型 */
/* 参数传入函数(重点) */
/* 同:驱动模板 */布尔型 布尔反值 字符指针 char * 短整型 无符号短整型 整型 无符号整型 长整型 无符号长整型 bool inbool charp short ushort int uint long ulong 1
2
3
4
5
6
7
8
9
10/*- kernel/include/linux/moduleparam.h -*/
/*
* name:模块参数的名称
* type:模块参数的数据类型
* perm:模块参数的访问权限
*/
module_param(name, type, perm)
module_param_array(name, type, nump, perm)
module_param_string(name, string, len, perm)1
2
3
4
5
6
7
8
9
10/*- kernel//include/linux/stat.h -*/
1
2
3
4# insmod helloworld.ko 参数名=参数值
insmod parameter.ko number=100 name="topeet" para=0,1,2,3,4,5,6,7 str="itop"
lsmod
rmmod helloworld.ko符号导出(记住思路)
1
2
3
4
5
6
7
8
9//----------------------------
/*- kernel/include/linux/export.h -*/
/* 定义数据类型和函数 */
/* 导出数据类型和函数 */
/* 同:驱动模板 */
//----------------------------
/* 导入(extern)数据类型和函数 */
/* 同:驱动模板 */1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16//-----------------------
/* 定义数据类型和函数 */
int num = 10;
int add(int a, int b)
{
return (a+b);
}
/* 导出数据类型和函数 */
EXPORT_SYMBOL(num);
EXPORT_SYMBOL(add);
/* 同:驱动模板 */
//----------------------------
/* 导入(extern)数据类型和函数 */
extern int num;
extern int add(int a, int b);
/* 同:驱动模板 */1
2# 加载:先依赖后模块
# 卸载:先模块后依赖