基于Amlogic 安卓9.0, 驱动简说:使用misc框架,让驱动更简单

Posted 阿迷创客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于Amlogic 安卓9.0, 驱动简说:使用misc框架,让驱动更简单相关的知识,希望对你有一定的参考价值。

文章目录

一、前文总结

  • 在第1篇文章《驱动简说(一):字符设备驱动,手动创建设备》中,我们了解了基础的字符设备驱动的写法,但也注意到了它的缺点:
    • 设备号需要自己去找,自己创建(容易冲突) ;
    • 需要自己创建和驱动匹配的设备文件(否则应用层无设备可用)。
  • 在第2篇文章《驱动简说(二):字符设备驱动,自动创建设备》中,我们通过alloc自动分配设备号,以及主动注册class、device对象,解决了第1篇的两个问题。
  • 但是…… 我们还有更简单的方法,达到第2篇的目的,但不需要写第2篇的那么多代码!

本文基于Amlogic T972 , android 9.0, 内核版本 4.9.113

二、系列文章

第1篇:基于Amlogic 安卓9.0, 驱动简说(一):字符设备驱动,手动创建设备
第2篇:基于Amlogic 安卓9.0, 驱动简说(二):字符设备驱动,自动创建设备
第3篇:基于Amlogic 安卓9.0, 驱动简说(三):使用misc框架,让驱动更简单
第4篇:基于Amlogic 安卓9.0, 驱动简说(四):Platform平台驱动,驱动与设备的分离


三、MISC框架驱动

misc 驱动框架,直译过来就是杂项设备驱动框架。使用此框架,misc框架将自动为你分配主次设备号,同时会为你在/dev目录下,以及/sys/class/misc目录下创建你的设备文件。

更重要的是,基于系统自动分配(其实只分配了一个次设备号,主设备号与所有misc共用),减少了设备号冲突,更减少了主设备号的资源浪费。同时也减少了类似class/device创建、注销的模块化代码!


四、解析:完整源码

4.1 helloworld_misc_amlogic_driver.c

  • 文件,参考位置:android9.0\\common\\drivers\\amlogic\\input\\helloworld_misc_amlogic_driver.c
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/miscdevice.h> /*misc 驱动框架头文件*/


/* 实现系统调用接口:open() */
static int aml_misc_open(struct inode *inode, struct file *file)

	pr_info("aml_misc_open() is called.\\n");
	return 0;



/* 实现系统调用接口:close() */
static int aml_misc_close(struct inode *inode, struct file *file)

	pr_info("aml_misc_close() is called.\\n");
	return 0;



/* 实现系统调用接口:ioctl() */
static long aml_misc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)

	pr_info("aml_misc_ioctl() is called. cmd = %d, arg = %ld\\n", cmd, arg);
	return 0;


static const struct file_operations aml_misc_fops = 
	.owner = THIS_MODULE,  /* 固定搭配 */
	.open = aml_misc_open, /* 提供open(), fopen()系统调用 */
	.release = aml_misc_close, /* 提供close(), fclose()系统调用 */
	.unlocked_ioctl = aml_misc_ioctl, /* 提供ioctl()系统调用 */
;

/* 声明 struct miscdevice 结构体变量,并赋值*/
static struct miscdevice aml_misc_device = 
		.minor = MISC_DYNAMIC_MINOR,  /* 优点:misc设备已由misc框架提供了主设备号,其余设备通过此设定,自动分配一个次设备号*/
		.name = "aml_misc_dev",  /* 将创建/dev/aml_misc_dev    以及 /sys/class/misc/aml_misc_dev */
		.fops = &aml_misc_fops, 
;


/*
* 模块初始化接口
* 对比之前两篇文章的例子,可见此版本,有如下几个优点
* (1)不需去申请设备号
* (2)不需去创建和注册 struct class
* (3)不需去创建和注册 struct device
* (4)省去了一大堆,申请、注册的异常判断语句
*/
static int __init aml_misc_init(void)

	int ret;
	pr_info("aml_misc_init\\n");

	/* 将miscdevice对象注册进内核 */
	ret = misc_register(&aml_misc_device);

	if (ret != 0) 
		pr_err("Failded: misc_register aml_misc_dev\\n");
		return ret;
	

	pr_info("init alloc aml_misc_dev's minor[%i]\\n",aml_misc_device.minor);
	return 0;


/*同初始化函数,退出时候,也不需执行Major/Minor的反注册 */
static void __exit aml_misc_exit(void)

	pr_info("aml_misc_exit\\n");

	/* 注销miscdevice对象 */
	misc_deregister(&aml_misc_device);



module_init(aml_misc_init);
module_exit(aml_misc_exit);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("szhou <66176468@qq.com>");
MODULE_DESCRIPTION("simple say[3]: misc device driver");

4.2 Makefile

  • android9.0\\common\\drivers\\amlogic\\input\\Makefile
  • 添加下面语句,并将helloworld_misc_amlogic_driver.c放在同一目录下
obj-m +=  helloworld_misc_amlogic_driver.o

五、编译执行

(1)编译及部署

参考系列文章,第1篇

(2)运行

  • 串口上执行
(1)加载驱动模块
:/data # insmod  helloworld_misc_amlogic_driver.ko                             
[ 3950.099788@3]- aml_misc_init
[ 3950.100480@0]- init alloc aml_misc_dev's minor[47]
:/data # 

(2)查看设备文件
:/data # ls -l /dev/aml_misc_dev                                               
crw------- 1 root root 10,  47 2022-12-29 11:12 /dev/aml_misc_dev
:/data # ls -l /sys/class/misc/aml_mis*
lrwxrwxrwx 1 root root 0 2022-12-29 11:13 /sys/class/misc/aml_misc_dev -> ../../devices/virtual/misc/aml_misc_dev
:/data # 

效果如下图:


六、应用层调用

因为设备节点文件的名称变成了/dev/aml_misc_dev, 所以不能直接使用第1篇的APP程序进行测试,稍微修改一下

  • 如下如有疑问,可参考第1篇,或留言

6.1 APP源码

  • 文件:android9.0\\development\\hello_aml\\hello_aml.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>

/*
* 使用argv[1]来传入,需要打开的设备文件的路径
* 用法: #./data/hello_aml  /dev/aml_misc_dev
*/
int main(int argc, char *argv[])


  int buf[4]=0;
  int fd=0;

  if(argc < 2)
    printf("Usage: hello_aml  /dev/aml_misc_dev\\n");
    return 0;
  

  //(1) 测试 open
  fd = open(argv[1], O_RDWR);
  if(fd == -1)
	printf("Failed: open %s \\n", argv[1]);
	return 0;
  

  //(2) 测试 ioctl
  ioctl(fd, 0x12, buf); 

  //(3) 测试 clsoe	
  close(fd);
  return 0;

6.2 命令及运行效果

Windows PowerShell
版权所有(C) Microsoft Corporation。保留所有权利。

安装最新的 PowerShell,了解新功能和改进!https://aka.ms/PSWindows1)部署
PS Z:\\T972\\android_x301\\source\\t962x3-t972-android9.0\\out\\target\\product\\x301\\system\\bin> adb root
adbd is already running as root
PS Z:\\T972\\android_x301\\source\\t962x3-t972-android9.0\\out\\target\\product\\x301\\system\\bin> adb push .\\hello_aml /data/
.\\hello_aml: 1 file pushed, 0 skipped. 0.8 MB/s (15988 bytes in 0.020s)2)修改权限
PS Z:\\T972\\android_x301\\source\\t962x3-t972-android9.0\\out\\target\\product\\x301\\system\\bin> adb shell chmod 777 /data/hello_aml

(3)查看设备文件
PS Z:\\T972\\android_x301\\source\\t962x3-t972-android9.0\\out\\target\\product\\x301\\system\\bin> adb shell
x301:/ # ls -l /dev/aml_mi*
crw------- 1 root root 10,  47 2022-12-29 11:31 /dev/aml_misc_dev

(4)执行APP
x301:/ # ./data/hello_aml /dev/aml_misc_dev

(5)查看打印
x301:/ # dmesg | tail
[ 5143.465058] aml_misc_open() is called.
[ 5143.465112] aml_misc_ioctl() is called. cmd = 18, arg = -1146418760
[ 5143.470051] aml_misc_close() is called.
x301:/ #

命令及效果图示:

七、源码下载

百看不如一试……

  • 地址:https://gitee.com/amizhou/amlogic_t972_android9_driver/tree/master/index_01_simpleSay_drivers/lesson_03
git clone git@gitee.com:amizhou/amlogic_t972_android9_driver.git

八、篇尾

保持持续学习, 欢迎私信交流。

以上是关于基于Amlogic 安卓9.0, 驱动简说:使用misc框架,让驱动更简单的主要内容,如果未能解决你的问题,请参考以下文章

基于Amlogic 安卓9.0, 驱动简说:使用misc框架,让驱动更简单

基于Amlogic 安卓9.0, 驱动简说:使用misc框架,让驱动更简单

基于Amlogic 安卓9.0, 驱动简说:字符设备驱动,手动创建设备

基于Amlogic 安卓9.0, 驱动简说:字符设备驱动,自动创建设备

基于Amlogic 安卓9.0, 驱动简说:字符设备驱动,自动创建设备

基于Amlogic 安卓9.0, 驱动简说:基于GPIOLED子系统的LED驱动