news 2026/4/15 20:38:53

AIDL Hal 开发笔记4----驱动开发

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AIDL Hal 开发笔记4----驱动开发

目录

  • 一、编写Linux 内核驱动
    • 1.1 编写驱动
    • 1.2 将模块编译进内核
  • 二、Native 程序测试驱动程序
  • 三、权限配置

驱动开发

一、编写Linux 内核驱动

1.1 编写驱动

Linux 驱动实际就是一个 Linux 内核模块。

首先,我们需要理解什么是内核模块?简单来说,内核模块是一段 “固定格式” 的代码,像一个“插件”一样,linux 内核可以动态的加载并执行这段代码,也可以把这段代码编译进内核,在内核启动的时候来执行这段代码。

下面我们写一个简单的 linux 驱动:在内核的drivers/char目录中添加 hello_driver.c

#include<linux/module.h>#include<linux/fs.h>#include<linux/errno.h>#include<linux/miscdevice.h>#include<linux/kernel.h>#include<linux/major.h>#include<linux/mutex.h>#include<linux/proc_fs.h>#include<linux/seq_file.h>#include<linux/stat.h>#include<linux/init.h>#include<linux/device.h>#include<linux/tty.h>#include<linux/kmod.h>#include<linux/gfp.h>/* 1. 确定主设备号 */staticintmajor=0;staticcharkernel_buf[1024];staticstructclass*hello_class;#defineMIN(a,b)(a<b?a:b)/* 3. 实现对应的open/read/write等函数,填入file_operations结构体 */staticssize_thello_drv_read(structfile*file,char__user*buf,size_tsize,loff_t*offset){interr;printk("%s %s line %d\n",__FILE__,__FUNCTION__,__LINE__);err=copy_to_user(buf,kernel_buf,MIN(1024,size));returnMIN(1024,size);}staticssize_thello_drv_write(structfile*file,constchar__user*buf,size_tsize,loff_t*offset){interr;printk("%s %s line %d\n",__FILE__,__FUNCTION__,__LINE__);err=copy_from_user(kernel_buf,buf,MIN(1024,size));returnMIN(1024,size);}staticinthello_drv_open(structinode*node,structfile*file){printk("%s %s line %d\n",__FILE__,__FUNCTION__,__LINE__);return0;}staticinthello_drv_close(structinode*node,structfile*file){printk("%s %s line %d\n",__FILE__,__FUNCTION__,__LINE__);return0;}/* 2. 定义自己的file_operations结构体 */staticstructfile_operationshello_drv={.owner=THIS_MODULE,.open=hello_drv_open,.read=hello_drv_read,.write=hello_drv_write,.release=hello_drv_close,};/* 4. 把file_operations结构体告诉内核:注册驱动程序 *//* 5. 谁来注册驱动程序啊?得有一个入口函数:安装驱动程序时,就会去调用这个入口函数 */staticint__inithello_init(void){interr;printk("%s %s line %d\n",__FILE__,__FUNCTION__,__LINE__);major=register_chrdev(0,"hello",&hello_drv);/* /dev/hello *///提供设备信息,自动创建设备节点。// /dev/hellohello_class=class_create(THIS_MODULE,"hello_class");err=PTR_ERR(hello_class);if(IS_ERR(hello_class)){printk("%s %s line %d\n",__FILE__,__FUNCTION__,__LINE__);unregister_chrdev(major,"hello");return-1;}device_create(hello_class,NULL,MKDEV(major,0),NULL,"hello");/* /dev/hello *///到这里我们就可以通过 /dev/hello 文件来访问我们的驱动程序了。return0;}/* 6. 有入口函数就应该有出口函数:卸载驱动程序时,就会去调用这个出口函数 */staticvoid__exithello_exit(void){printk("%s %s line %d\n",__FILE__,__FUNCTION__,__LINE__);device_destroy(hello_class,MKDEV(major,0));class_destroy(hello_class);unregister_chrdev(major,"hello");}/* 7. 其他完善:提供设备信息,自动创建设备节点 */module_init(hello_init);module_exit(hello_exit);MODULE_LICENSE("GPL");

1.2 将模块编译进内核

接下来我们修改 /drivers/char/Kconfig 文件,使得我们的 hello_driver 模块,能出现在内核的编译选项中。

在 /drivers/char 中的 Kconfig 文件中添加:

config HELLO_DRIVER_MODULE bool"hello driver module support"defaulty

然后在 /drivers/char 下的 Makefile 文件中添加:

obj-$(CONFIG_HELLO_DRIVER_MODULE)+=hello_driver.o

当在 make menuconfig 编译菜单中选中了 hello module support,CONFIG_HELLO_MODULE的值是 y,没有选中值是 m(我们定义的默认值是 y):

  • obj-y += hello_driver.o 的意思是将 hello_driver.o 编译进内核
  • obj-m += hello_driver.o 的意思是文件 hello_driver.o 作为"模块"进行编译,不会编译到内核,但是会生成一个独立的 “hello_driver.ko” 文件,可以使用insmod命令将模块加载到内核中

最后配置内核:

kernel/linux-5.4$ make menuconfig

进入 Device Drivers 选项:

进入 Character devices


这里就可以看见我们刚才添加的选项,默认是选上的。

然后执行编译:

source build/envsetup.sh lunch xxx make

烧录后抓取 kernel日志

#dmesg用于显示开机信息adb shell dmesg|grep hello

二、Native 程序测试驱动程序

在 frameworks/base/native/ 目录下创建如下的目录结构:

hello_drv_test/├── Android.mk └── hello_drv_test.c

其中 hello_drv_test.c 的内容如下:

#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<unistd.h>#include<stdio.h>#include<string.h>/* * ./hello_drv_test -w abc * ./hello_drv_test -r */intmain(intargc,char**argv){intfd;charbuf[1024];intlen;/* 1. 判断参数 */if(argc<2){printf("Usage: %s -w <string>\n",argv[0]);printf(" %s -r\n",argv[0]);return-1;}/* 2. 打开文件 */fd=open("/dev/hello",O_RDWR);if(fd==-1){printf("can not open file /dev/hello\n");return-1;}/* 3. 写文件或读文件 */if((0==strcmp(argv[1],"-w"))&&(argc==3)){len=strlen(argv[2])+1;len=len<1024?len:1024;write(fd,argv[2],len);}else{len=read(fd,buf,1024);buf[1023]='\0';printf("APP read : %s\n",buf);}close(fd);return0;}

测试程序的内容很简单,就是根据命令行参数读写 /dev/hello文件。

接着编写 Android.mk 文件:

LOCAL_PATH:=$(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE_TAGS:=optional LOCAL_SRC_FILES:=\ hello_drv_test.c LOCAL_MODULE:=hello_drv_test include $(BUILD_EXECUTABLE)

编译程序并push到机器:

# 编译 cd frameworks/base/native/hello_drv_test mm cd-adb push out/target/product/ceres-b7/system/bin/hello_drv_testsystem/bin/hello_drv_test system/bin adb shell # 执行程序 cd system/bin./hello_drv_test-w"hello"./hello_drv_test-r

执行程序的结果如下所示:


三、权限配置

要把驱动集成到系统中,还需要添加一些权限相关的配置:

system/core/rootdir/ueventd.rc中添加:

/dev/hello0666root root

system/sepolicy/device.te中添加:

typehello_dev_t,dev_type;

system/sepolicy/file_contexts中添加

/dev/hello u:object_r:hello_dev_t:s0

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/15 3:39:38

导师推荐!MBA开题报告TOP8 AI论文写作软件测评

导师推荐&#xff01;MBA开题报告TOP8 AI论文写作软件测评 2026年MBA开题报告写作工具测评&#xff1a;精准选择&#xff0c;提升效率 随着AI技术的不断进步&#xff0c;越来越多的MBA学生开始借助智能写作工具来提高论文写作效率。然而&#xff0c;面对市场上琳琅满目的AI论文…

作者头像 李华
网站建设 2026/4/11 15:53:26

CAD协作更高效!浩辰CAD看图王电脑版能看视频批注了

CAD图纸遇到问题&#xff0c;沟通起来不方便&#xff0c;视频批注功能就能完美解决这一问题&#xff0c;哪里有问题拍视频记录下来&#xff0c;批注在相应的位置&#xff0c;既清楚又明白&#xff0c;沟通省时省力。 浩辰CAD看图王&#xff08;手机版&#xff09;目前已新增视…

作者头像 李华
网站建设 2026/4/9 3:36:04

Docker Swarm ES集群基本维护

文章目录 一、运维视角:集群状态与监控(1-5) 例1:查看 ES 集群健康状态(核心运维) 例2:查看集群所有节点信息 例3:查看集群基本信息(版本、名称) 例4:查看集群所有索引列表 例5:查看节点 JVM 内存使用情况 二、开发+运维:索引基础操作(6-9) 例6:创建自定义索引…

作者头像 李华
网站建设 2026/4/6 22:44:59

关于单元测试编写原则的一些思考

目的 单元测试编写的目的&#xff0c;是面向计算机特性的&#xff0c;基于函数的in-out&#xff0c;所以单元测试的好帮手就是断言&#xff0c;通过不断的构造输出并对结果进行断言&#xff0c;我们就可以针对一个对象以及它的函数&#xff0c;构建出充足的用例去包裹它&#…

作者头像 李华
网站建设 2026/4/7 2:07:28

前端项目打包部署完整流程

1. 环境准备确认项目为 Vue.js 前端项目已安装 Node.js (> 14.0.0) 和 npm (> 6.0.0)项目依赖已安装 (node_modules)2. 选择打包环境根据部署环境选择对应的打包命令:测试环境: npm run build:test生产环境: npm run build:prod3. 执行打包# 进入项目目录 cd web-master-…

作者头像 李华