当前位置: 首页 > news >正文

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

http://www.jsqmd.com/news/253636/

相关文章:

  • 收藏级指南:Agentic RAG 彻底升级传统RAG,打造能干活的AI数字同事
  • 基于51单片机的出租车计价器
  • QML基本元素
  • 交直流可编程电源(技术资料) 直流电源是直流输出0-30V 5A TL494 线路; 交流电压...
  • DevSecOps时代测试工具的进化论:从功能验证到全链路质量保障
  • 收藏级!大厂后端面试全流程复盘+大模型从入门到实战学习礼包
  • 【Java毕设全套源码+文档】基于springboot的公务员考试管理系统设计与实现(丰富项目+远程调试+讲解+定制)
  • 基于Arduino的物流分拣控制系统设计
  • 【Java毕设全套源码+文档】基于springboot的新闻发布会管理系统设计与实现(丰富项目+远程调试+讲解+定制)
  • 本土DevOps领军者Gitee:如何重塑中国企业研发效能新范式
  • 收藏!AI焦虑别慌,程序员为啥要学大模型?零基础系统入门指南
  • listmap数据变驼峰
  • 【Java毕设源码分享】基于springboot+vue的水果在线销售系统的设计与实现(程序+文档+代码讲解+一条龙定制)
  • 量产HLW8032串口通讯芯片的三相电参数采集系统项目资料 1主芯片采用STM32F407
  • Java后端开发学习路线,零基础入门到精通,收藏这篇就够了
  • Maven 4 终于快来了,新特性很香!
  • AntDesign Table sorter 为什么点击第三次取消了,还是有参数发出?可设置sortDirections解决
  • 如何应对AI生成重复内容:精选十大工具评测及有效解决策略
  • 【Java毕设源码分享】基于springboot+vue的二手书交易商城系统的设计与实现(程序+文档+代码讲解+一条龙定制)
  • AI驱动的11款论文写作工具,提供LaTeX格式智能排版与内容优化功能。
  • AI驱动的11项论文写作工具,支持LaTeX格式排版与智能内容优化
  • 2026电子行业投资策略:具身智能赋能全产业链,本土硬科技从星火到燎原
  • 拒稿退散!宏智树 AI 解锁期刊论文录用密码
  • 芯片级机密计算,天翼云CSV3筑牢数据“可用不可见”防线
  • 绿的谐波纳米减速器量产,苏州中新具身智能产业园开工,亚马逊升级物流机器人,波士顿动力Atlas迭代​
  • 查重 + AIGC 双险通关!宏智树 AI:给论文注入人工原创灵魂
  • 【计算化学与人工智能驱动的 MOFs 性能预测与筛选技术】
  • 四足机器人场景应用发展蓝皮书(2025)
  • 三菱PLC与变频器通信程序——基于结构化文体语言版的PID控制及多功能监控
  • 全球抗量子迁移战略白皮书(2025)