rk3568-Linux应用程序和驱动程序接口

字符设备特征:

APP 如何找到字符设备

当驱动加载后会产生一个设备文件,也会有一个唯一对应的innode结构体。当应用层调用open函数时,会进入内核发生一次软中断,从用户空间进入到内核空间。open会调用内核中的sys_open函数,该函数会根据open函数传入的文件名确定该文件是一个字符设备还是其他设备文件。如果是字符设备文件,则会通过字符设备的主设备号和次设备号在chrdevs结构体中找到对应的一项。该项中会有file_operation结构体,file_operation结构体中会有.open等函数。简单理解为,当APP调用open函数时会调用到驱动中对应的open函数。

字符设备驱动流程

1、确定主次设备号:静态指定或动态向内核申请。

2、实现 file_operations 方法:编写 open, read, write 等函数的具体代码。在这些函数中,你可能会:

从硬件寄存器读取数据(read)。

向硬件寄存器写入数据(write)。

配置硬件(ioctl)。

使用 copy_to_user() 和 copy_from_user() 在内核空间(驱动程序)和用户空间之间安全地传递数据。

3、注册字符设备

major=register_chrdev(主设备号,驱动名字,&file_operations)

4、创建设备文件:在 /dev 目录下使用 mknod 命令或通过驱动代码自动创建(使用 device_create)一个设备文件,并将其与你的设备号关联。

5、模块的加载和卸载:

在模块加载函数 (module_init) 中完成上述的申请设备号、注册 cdev 等操作。

在模块卸载函数 (module_exit) 中完成相反的清理工作:注销 cdev、释放设备号等

代码示例

驱动代码hello_driver

复制代码
#include <linux/module.h>

int hello_init(void)
{
    return 0;
    
}
void hello_exit(void)
{

}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");

Makefile

复制代码
ARCH=arm64
CROSS_COMPILE=/home/ps/rk3568_linux_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-
KERN_DIR=/home/ps/rk3568_linux_sdk/kernel

all:
	make -C $(KERN_DIR) M=$(PWD) modules

clean:
	make -C $(KERN_DIR) M=$(PWD) clean
	rm -rf modules.order Module.symvers

obj-m += hello_drv.o

make完成之后会生成驱动的.ko文件,将该文件传输到rk3568上执行

复制代码
insmod hello_drv.ko

发现并没有什么输出,是因为我们在驱动中没有执行任何输出信息,执行lsmod之后可以找到该驱动即为成功。

可以使用rmmod hello_drv移除已经加载的驱动

加入打印信息

复制代码
#include <linux/module.h>
int hello_init(void)
{
    printk("init");
    return 0;
}
void hello_exit(void)
{
    printk("exit");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");

加载之后并没有打印出任何信息:

printk函数会将打印信息放在一个内核的buf中,可以通过demsg函数查看

相关推荐
倒酒小生2 小时前
4月7日算法学习小结
linux·服务器·学习
木子欢儿2 小时前
KasmVNC 指南:高性能网页原生 Linux 远程桌面方案
linux·运维·服务器
luoqice3 小时前
嵌入式linux用nfs挂载ubuntu目录的配置步骤
linux
我科绝伦(Huanhuan Zhou)4 小时前
分享一个很实用的K8S巡检脚本
linux·docker·kubernetes
Net_Walke4 小时前
【Ubuntu】共享文件夹 /mnt/hgfs 下不显示问题解决
linux·运维·ubuntu
CHANG_THE_WORLD4 小时前
PDFIUM如何处理宽度数组
java·linux·服务器
孙同学_4 小时前
【Linux篇】应用层自定义协议与序列化
linux·服务器·网络
航Hang*4 小时前
第3章:Linux系统安全管理——第1节:Linux 防火墙部署(firewalld)
linux·服务器·网络·学习·系统安全·vmware
桦04 小时前
【Linux复习】:多线程
linux·运维