基于Amlogic 安卓9.0, 驱动简说(五):基于GPIO、LED子系统的LED驱动

news2024/11/15 20:11:53

一、篇头

  • 本章介绍LED子系统的使用。
  • 使用LED子系统,可以轻松实现对LED,例如常见的闪烁和亮度控制功能。
  • 简单起见,本章先使用GPIO实现,在不模拟PWM的情况下,只能实现点亮和灭灯的效果,重点是介绍GPIO、LED子系统的使用。

本文基于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平台驱动,驱动与设备的分离
第5篇:基于Amlogic 安卓9.0, 驱动简说(五):基于GPIO、LED子系统的LED驱动

三、准备工作

3.1 原理图:挑选测试用GPIO脚

(1) 红色LED: GPIOZ_6
(2) 绿色LED: GPIOZ_2
(3) 黄色LED: GPIOZ_1
(4) GND接地
在这里插入图片描述


3.2 LED模块

• 如下4个PIN脚,分别连接至开发板的4个引脚
在这里插入图片描述

四、源码解析

4.1 DTS设备树

	aml_led_class{
		status = "okay";
		compatible = "szhou,aml_led_class";
		/*
		* 	(1) amlled-gpios 是使用新版GPIO子系统API的固定写法,必须以 -gpios 结尾
		* 	(2)&gpio” : 引用的GPIO控制器的名称
		* 	(3) “GPIOZ_X ” :是一个宏定义,可转换成具体的gpio index
		* 	(4) 最后的GPIO_ACTIVE_HIGH,代表此PIN脚物理上是高电平有效
		*/
		amlled-gpios =  <&gpio GPIOZ_6 GPIO_ACTIVE_HIGH>,  //red_led
						<&gpio GPIOZ_2 GPIO_ACTIVE_HIGH>,  //green_led
						<&gpio GPIOZ_1 GPIO_ACTIVE_HIGH>;  //yellow_led
	};

4.2 驱动源码

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/leds.h>
#include <linux/gpio/consumer.h>

static char *name_red = "red";
static char *name_green = "green";
static char *name_yellow = "yellow";

//私有结构体
struct led_dev
{
	struct gpio_desc *desc;
	struct led_classdev cdev;
};


/* 
* (1)对 /sys/class/leds/red/brightness 等LED属性进行控制时,会回调此函数 
*/
static void led_control(struct led_classdev *led_cdev, enum led_brightness brightness)
{
	struct led_dev *led = container_of(led_cdev, struct led_dev, cdev);
	pr_info(" led_control  led(0x%p)->desc=0x%p \n", led, led->desc);	

	if (brightness != LED_OFF) { 
		gpiod_set_value(led->desc , 1);
		pr_info(" gpiod_set_value(led->desc , 1) \n");		
	}else{
		gpiod_set_value(led->desc , 0);
		pr_info(" gpiod_set_value(led->desc , 0) \n");		
	}
}

/*
* (1)在检测到DT中.compatible = "szhou,aml_led_class"的节点后,会自动调用此函数,实现初始化
*/
static int __init ledclass_plat_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	int i, count, ret;

	pr_info( "ledclass_plat_probe enter\n");

	/* 获取amlled-gpios里面gpio的数量  */
	count = gpiod_count(dev, "amlled");
	if (count ==  -ENOENT)
		return -ENOENT;

	dev_info(dev, "gpiod_count = %d \n", count);

	/* 填充每个gpio-led对象,并注册到LED子系统 */
	for(i=0; i<count; i++){
	
		struct led_dev *led_device; 	
		led_device = devm_kzalloc(dev, sizeof(*led_device), GFP_KERNEL);
		if (!led_device)
			return -ENOMEM;

		/* 初始化gpio对象,屏初始化为GPIOD_OUT_LOW,即设为输出脚、低电平 */
		led_device->desc = gpiod_get_index(dev, "amlled", i, GPIOD_OUT_LOW);
		switch(i){
			case 0:
				led_device->cdev.name = name_red;
			    break;
			case 1:
				led_device->cdev.name = name_green;
			    break;
			case 2:
				led_device->cdev.name = name_yellow;
			    break;	
			default:
				pr_info( "zs, i=%d, default \n", i);				
		}

		/* 初始化亮度值,以及LED的控制函数 */
		led_device->cdev.brightness = LED_OFF;
		led_device->cdev.brightness_set = led_control;
		
		/* 注册到LED子系统 */
		ret = devm_led_classdev_register(dev, &led_device->cdev);
		if (ret) {
			dev_err(dev, "failed to register the led %s\n", led_device->cdev.name);
			return ret;
		}	
	}

	dev_info(dev, "ledclass_plat_probe exit\n");
	return 0;
}

static int __exit ledclass_plat_remove(struct platform_device *pdev)
{
	dev_info(&pdev->dev, "leds_remove enter\n");
	dev_info(&pdev->dev, "leds_remove exit\n");
	return 0;
}


/*
* 设备树的匹配属性 .compatible ,需完全相同才会匹配
*/
static const struct of_device_id my_of_ids[] = {
	{ .compatible = "szhou,aml_led_class"},
	{},
};

MODULE_DEVICE_TABLE(of, my_of_ids);


/*
* led_platform_driver 结构体
*/
static struct platform_driver led_platform_driver = {
	.probe = ledclass_plat_probe,
	.remove = ledclass_plat_remove,
	.driver = {
		.name = "aml_class_leds",
		.of_match_table = my_of_ids,
		.owner = THIS_MODULE,
	}
};


/*
* 注册 led_platform_driver 结构体到Platform子系统
*/
static int aml_GpioLedClass_plat_init(void)
{
	int ret_val;
	pr_info("aml_GpioLedClass_plat_init enter\n");

	ret_val = platform_driver_register(&led_platform_driver);
	if (ret_val !=0){
		pr_err("platform value returned %d\n", ret_val);
		return ret_val;
	}

	pr_info("aml_GpioLedClass_plat_init exit\n");
	return 0;
}

/*
* 从Platform子系统注销 led_platform_driver 结构体
*/
static void aml_GpioLedClass_plat_exit(void)
{
	pr_info("aml_GpioLedClass_plat_exit enter\n");
	platform_driver_unregister(&led_platform_driver);
	pr_info("aml_GpioLedClass_plat_exit exit\n");
}

module_init(aml_GpioLedClass_plat_init);
module_exit(aml_GpioLedClass_plat_exit);

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

五、测试

(1)因为LED子系统自动为我们创建了用户接口,所以通过命令行就可以测试对LED的控制。
(2)编译、部署方法,参考之前的系列文章,不再赘述

5.1 加载KO

执行打印:

:/data # insmod  aml_gpio_led_class_platform.ko 

[ 1005.070654@1]- aml_GpioLedClass_plat_init enter
[ 1005.071134@1]- ledclass_plat_probe enter
[ 1005.071178@1]- aml_class_leds aml_led_class: gpiod_count = 3 
[ 1005.071218@1]-  ledclass_plat_probe  led(0xe97f7b10)->desc=0xed96b860 
[ 1005.071626@1]- zs, platform_probe  devm_led_classdev_register [0], cdev->name=red 
[ 1005.071667@1]-  ledclass_plat_probe  led(0xe97f7f10)->desc=0xed96b820 
[ 1005.071975@1]- zs, platform_probe  devm_led_classdev_register [1], cdev->name=green 
[ 1005.072017@1]-  ledclass_plat_probe  led(0xe97f7c10)->desc=0xed96b810 
[ 1005.072265@1]- zs, platform_probe  devm_led_classdev_register [2], cdev->name=yellow 
[ 1005.072274@1]- aml_class_leds aml_led_class: ledclass_plat_probe exit
[ 1005.075349@1]- aml_GpioLedClass_plat_init exit

图示如下:
在这里插入图片描述

5.2 查看设备

如下可见到在probe里面命名的3个LED灯,分别是red、green、yellow

执行打印:

x301:/ # cd /sys/class/leds/
x301:/sys/class/leds # ls -al
total 0
drwxr-xr-x   2 root root 0 2023-01-05 01:16 .
drwxr-xr-x 131 root root 0 2023-01-05 01:16 ..
lrwxrwxrwx   1 root root 0 2023-01-05 01:38 green -> ../../devices/platform/aml_led_class/leds/green
lrwxrwxrwx   1 root root 0 2023-01-05 01:38 pwm_e1 -> ../../devices/platform/pwmleds/leds/pwm_e1
lrwxrwxrwx   1 root root 0 2023-01-05 01:38 red -> ../../devices/platform/aml_led_class/leds/red
lrwxrwxrwx   1 root root 0 2023-01-05 01:38 yellow -> ../../devices/platform/aml_led_class/leds/yellow
x301:/sys/class/leds #

图示如下:
在这里插入图片描述

5.3 LED控制

1)查看LED灯的属性,例如red
x301:/sys/class/leds # cd red/
x301:/sys/class/leds/red # ls -al
total 0
drwxr-xr-x 3 root root    0 2023-01-05 01:33 .
drwxr-xr-x 5 root root    0 2023-01-05 01:33 ..
-rw-r--r-- 1 root root 4096 2023-01-05 01:41 brightness
lrwxrwxrwx 1 root root    0 2023-01-05 01:41 device -> ../../../aml_led_class
-r--r--r-- 1 root root 4096 2023-01-05 01:41 max_brightness
drwxr-xr-x 2 root root    0 2023-01-05 01:41 power
lrwxrwxrwx 1 root root    0 2023-01-05 01:41 subsystem -> ../../../../../class/leds
-rw-r--r-- 1 root root 4096 2023-01-05 01:41 trigger
-rw-r--r-- 1 root root 4096 2023-01-05 01:41 uevent

(2)可见red默认为0,灯灭,符合设定
x301:/sys/class/leds/red # cat brightness
03)点亮红灯
x301:/sys/class/leds/red # echo 1 > brightness
x301:/sys/class/leds/red # cd ..4)点亮绿灯
127|x301:/sys/class/leds # echo 1 > green/brightness

(5)点亮黄灯
x301:/sys/class/leds # echo 1 > yellow/brightness
x301:/sys/class/leds #

命令图示如下:
在这里插入图片描述

5.4 点灯效果

在这里插入图片描述


六、源码下载

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

七、篇尾

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/141266.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

腾讯前端一面常考vue面试题汇总

vue2.x详细 1. 分析 首先找到vue的构造函数 源码位置&#xff1a;src\core\instance\index.js function Vue (options) {if (process.env.NODE_ENV ! production &&!(this instanceof Vue)) {warn(Vue is a constructor and should be called with the new keyword…

【Linux】Linux进程的理解 --- 进程描述符、状态、优先级、切换…

如果不改变自己&#xff0c;就别把跨年搞的和分水岭一样&#xff0c;记住你今年是什么吊样&#xff0c;明年就还会是什么吊样&#xff01;&#xff01;&#xff01; 文章目录一、冯诺依曼体系结构&#xff08;硬件&#xff09;二、操作系统&#xff08;软件&#xff09;1.操作…

HCIP第六天

文章目录一&#xff0c;实验要求二&#xff0c;搭建拓扑图三&#xff0c;配置IP地址和环回地址四&#xff0c;宣告OSPF五&#xff0c;抓取流量六&#xff0c;测试一&#xff0c;实验要求 所有到达目标的路径最优,互有备份二&#xff0c;搭建拓扑图 三&#xff0c;配置IP地址和环…

photoshop绘制网格线的几种办法和重复绘制处理加工

第一种 绘制一个十字 ,然后保存为图案,然后添加图层样式 图案叠加 重复 第二种 显示网格线 编辑-首选项-参考线网格线设置 默认是25, 25*5125毫米 image.png新建125x125毫米会发现非常对称 image.png画笔直接按shift自动锁定网格线进行绘制这样非常标准也很快,比图案还要灵活一…

60. 实战 Kaggle 比赛:图像分类 (CIFAR-10)【在colab上运行】

之前几节中&#xff0c;我们一直在使用深度学习框架的高级API直接获取张量格式的图像数据集。 但是在实践中&#xff0c;图像数据集通常以图像文件的形式出现。 本节将从原始图像文件开始&#xff0c;然后逐步组织、读取并将它们转换为张量格式。 我们之前对CIFAR-10数据集做了…

论文投稿指南——中文核心期刊推荐(生物科学)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…

vue开发环境配置Visual Studio Code配置和安装教程查询

方便前端vue开发&#xff0c;使用vs code插件安装详细教程&#xff0c;关于vs code在网络上查询相关的教程&#xff0c;插件安装如下图所示&#xff0c;大家发现常用的&#xff0c;好用的插件可以留言分享&#xff0c;或与我联系。 1 安装Vue语法高亮显示插件&#xff1a;vetur…

63.目标检测数据集

目标检测领域没有像MNIST和Fashion-MNIST那样的小数据集。 为了快速测试目标检测模型&#xff0c;我们收集并标记了一个小型数据集。 首先&#xff0c;我们拍摄了一组香蕉的照片&#xff0c;并生成了1000张不同角度和大小的香蕉图像。 然后&#xff0c;我们在一些背景图片的随机…

MSF弱点扫描

● 根据信息收集结果搜索漏洞利用模块 ● 结合外部漏洞扫描系统对大IP地址段进行批量扫描 ● 误判率、漏判率 VNC密码破解 use auxiliary/scanner/vnc/vnc_login● VNC无密码访问 use auxiliary/scanner/vnc/vnc_none_authRDP远程桌面漏洞 use auxiliary/scanner/rdp/ms12_…

【系统设计】直播架构分析

直播架构 1. 组成 三部分组成&#xff0c; 分别是 客户端&#xff08;主播端 观众端&#xff09; 、应用服务器集群 、 CDN 技术 2. 模块间交互方式 主播端 &#xff1a; 直播客户端开启直播间 —— 获取 CDN 推流地址 ——通过 CDN 协议推流到 CDN 服务器上 观众端&#x…

软考信息安全工程师看什么教材?

教材在官网上都有给出具体的版本。 如何复习备考&#xff1f; 首先准备考教材&#xff0c;视频&#xff0c;资料等内容。&#xff08;可分享&#xff09; 了解考情&#xff1a; 通过历年真题分析历年考试相关知识内容的考查频度及分值占比&#xff0c;梳理出核心考点内容。第二…

【CANN训练营第三季】Pytorch模型迁移

文章目录第4题第5题首先安装pytorch 参考&#xff1a;https://gitee.com/ascend/pytorch 安到测试这一步&#xff0c;报错&#xff0c;没办法继续了。 RuntimeError: Unsupported soc version: Ascend310 https://gitee.com/ascend/pytorch/issues/I68UDG?fromproject-issue …

微软的AD登录

微软的AD登录最早在1999年出现&#xff0c;&#xff0c;&#xff0c;也就是我们知道的SSO&#xff0c;&#xff0c;具体原理不做过多展开。见官网 AD 官网 安装依赖 "azure/msal-browser": "^2.15.0","azure/msal-react": "^1.0.1",…

XXE - XML外部实体注入攻击

XXE漏洞是什么&#xff1f; xxe&#xff08;xml External Entity attack&#xff09;&#xff0c;在可以解析XML语言的地方&#xff0c;攻击者提交恶意的XML代码并被执行后&#xff0c;获取服务器中本应被保护的数据。对于XXE漏洞最为关键的部分是DTD文档类型&#xff0c;DTD …

全球 5G RAN 市场呈现强劲增长

根据Future Market Insights的一份新报告&#xff0c;全球对5G RAN的需求预计将在2022年和2032年以28.7%的健康CAGR增长&#xff0c;到2032年达到342亿美元的净值。 5G RAN市场蜂窝设备利用无线电波进行通信。这些设备将用户的语音和移动数据转换成数字化信号&#xff0c;以无…

Vue--》vue3中的计算属性与监视的使用讲解

computed函数与Vue2.x中的computed配置功能一致&#xff0c;只不过在Vue3.x中我们需要按需导入该函数。因为Vue3.x是向下兼容Vue2语法的&#xff0c;所以我们可以写成既有 setup 又有 Vue2中的computed函数&#xff0c;如下代码示例&#xff1a;<template><h1>个人…

IIC(I2C)协议详解

1.简介IIC,即IC&#xff0c;全称 Inter-Integrated Circuit&#xff0c;字面上的意思是集成电路之间&#xff0c;它其实是IC Bus简称&#xff0c;所以中文应该叫 集成电路总线 &#xff0c;它是一种串行通信总线&#xff0c;使用多主从架构&#xff0c;由飞利浦公司在1980年代为…

魔兽世界服务端源码各个重要文件详细情况说明——魔兽世界开服

魔兽服务端开服源文件各文件翻译很多文件在服务器中我们知道是跟什么有关&#xff0c;但就是不知道其作用是什么。就算我们知道在这些地方中的文件都是有着不小的作用。但是由于不知道各个文件代表的是什么意思所以在面对这些文件的时候都会有无从下手的感觉&#xff0c;所以今…

云渲染市场安全吗?

云渲染虽然在3D制作行业已经日益普及&#xff0c;但仍有人持观望态度&#xff1a;云渲染市场安全吗&#xff1f;使用云渲染是否能够保证我的数据安全、财产安全等问题&#xff0c;今天小编就来跟大家探讨一下这个问题。首先&#xff0c;在解答云渲染市场是否安全这个问题之前&a…

MobarX远程登录虚拟机

环境&#xff1a;宿主机WIN10&#xff0c;virtualBox安装的ubuntu16&#xff1b; 前提条件&#xff1a;宿主机和ubuntu能够互相ping通&#xff1b; 步骤&#xff1a; 第一步&#xff1a;添加网卡类型为“仅主机的网络”&#xff08;MobarX登录Ubuntu需要的网卡&#xff09; …