android11使用gpio口控制led状态灯

目录

一、简介

二、解决方法

A、底层驱动

B、上层调用

C、验证


一、简介

1、需求:这里是用2个gpio口来控制LED灯,开机时默认亮蓝灯,按开机键,休眠亮红灯,唤醒亮蓝灯。

原理图:

这里由于主板上电阻R635未贴,所以led_sleep不启用。

2、分析:

a.一开始是想将这2个gpio口的控制写在背光pwm驱动中,但是该设备是不接屏幕(mipi/edp/lvds)的,直接由cpu输出信号到hdmi屏,所以无法控制背光pwm。

同理,想写在和屏启动相关的驱动里面,也是无法控制的。例如由i2c控制的gm8775c。

b.所以想到在底层驱动写一个文件节点,由上层应用去控制。

二、解决方法

A、底层驱动

这里写了一个c文件,gpio_led.c

/** Driver for keys on GPIO lines capable of generating interrupts.** Copyright (C) 2015, Fuzhou Rockchip Electronics Co., Ltd* Copyright 2005 Phil Blundell** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License version 2 as* published by the Free Software Foundation.*/#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/slab.h>
#include <linux/wakelock.h>#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>struct vanzeak_gpio_drvdata {struct gpio_desc *power_gpio;struct gpio_desc *sleep_gpio;
};static const struct of_device_id vanzeak_gpio_match[] = {{ .compatible = "vanzeak,gpio", .data = NULL},{},
};
MODULE_DEVICE_TABLE(of, vanzeak_gpio_match);static ssize_t led_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
{struct vanzeak_gpio_drvdata *ddata = dev_get_drvdata(dev);int val = val = simple_strtol(buf, NULL, 8);if(val){gpiod_direction_output(ddata->power_gpio, 1);gpiod_direction_output(ddata->sleep_gpio, 0);}else{gpiod_direction_output(ddata->power_gpio, 0);gpiod_direction_output(ddata->sleep_gpio, 1);}return size;
}static ssize_t led_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
{return 0;
}static DEVICE_ATTR(led_enable, 0644, led_enable_show, led_enable_store);static struct attribute *led_enable_attrs[] = {&dev_attr_led_enable.attr,NULL,
};static struct attribute_group led_enable_attr_group = {.name   = "led_enable",.attrs  = led_enable_attrs,
};static int vanzeak_gpio_probe(struct platform_device *pdev)
{struct vanzeak_gpio_drvdata *ddata = NULL;struct device *dev = &pdev->dev;int ret;ddata = devm_kzalloc(dev, sizeof(struct vanzeak_gpio_drvdata),GFP_KERNEL);
//	if(ddata = NULL)
//		return -1;platform_set_drvdata(pdev, ddata);dev_set_drvdata(&pdev->dev, ddata);ddata->power_gpio = devm_gpiod_get_optional(dev, "enable", 0);if (IS_ERR(ddata->power_gpio)) {ret = PTR_ERR(ddata->power_gpio);dev_err(dev, "failed to request power GPIO: %d\n", ret);goto fail0;}ddata->sleep_gpio = devm_gpiod_get_optional(dev, "sleep", 0);if (IS_ERR(ddata->sleep_gpio)) {ret = PTR_ERR(ddata->sleep_gpio);dev_err(dev, "failed to request sleep GPIO: %d\n", ret);goto fail0;}gpiod_direction_output(ddata->power_gpio, 1);gpiod_direction_output(ddata->sleep_gpio, 0);ret = sysfs_create_group(&pdev->dev.kobj, &led_enable_attr_group);if (ret) {pr_err("failed to create attr group\n");}return 0;fail0:platform_set_drvdata(pdev, NULL);return -1;
}static int vanzeak_gpio_remove(struct platform_device *pdev)
{return 0;
}#ifdef CONFIG_PM
static int vanzeak_gpio_suspend(struct device *dev)
{struct vanzeak_gpio_drvdata *ddata = dev_get_drvdata(dev);printk("DICKE printk %s : %d\n", __func__, __LINE__);gpiod_direction_output(ddata->power_gpio, 0);return 0;
}static int vanzeak_gpio_resume(struct device *dev)
{struct vanzeak_gpio_drvdata *ddata = dev_get_drvdata(dev);printk("DICKE printk %s : %d\n", __func__, __LINE__);gpiod_direction_output(ddata->power_gpio, 1);return 0;
}static const struct dev_pm_ops vanzeak_gpio_pm_ops = {.suspend	= vanzeak_gpio_suspend,.resume		= vanzeak_gpio_resume,
};
#endifstatic struct platform_driver vanzeak_gpio_device_driver = {.probe		= vanzeak_gpio_probe,.remove		= vanzeak_gpio_remove,.driver		= {.name	= "vanzeak-gpio",.owner	= THIS_MODULE,.of_match_table = vanzeak_gpio_match,
#ifdef CONFIG_PM.pm	= &vanzeak_gpio_pm_ops,
#endif}
};static int __init vanzeak_gpio_driver_init(void)
{return platform_driver_register(&vanzeak_gpio_device_driver);
}static void __exit vanzeak_gpio_driver_exit(void)
{platform_driver_unregister(&vanzeak_gpio_device_driver);
}module_init(vanzeak_gpio_driver_init);
module_exit(vanzeak_gpio_driver_exit);
B、上层调用

由上层的休眠唤醒来控制LED的亮灭。

diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index af7d91cf7ba6..1bbc51a9ed91 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -119,6 +119,14 @@ import java.util.Arrays;import java.util.List;import java.util.Objects;+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.io.BufferedWriter;
+/*** The power manager service is responsible for coordinating power management* functions on the device.
@@ -1598,6 +1606,46 @@ public final class PowerManagerService extends SystemService}}+   private void closeLed(int i){
+        String path = "/sys/devices/platform/vanzeak-gpio/led_enable/led_enable";
+        String value;
+	if(i == 1)
+		value = "1";
+	else if(i == 0)
+		value = "0";
+	else{
+		Slog.e(TAG, "data error");
+		return;
+	}
+        //  Log.i(TAG,"setGpioValue, path = [" + path + "] value = [" + value + "]");
+        File file = new File(path); 
+        if (!file.exists()) {
+            Slog.i("dxb","initOpenGpio , file is not exist!!!!");
+            return;
+        }
+        FileOutputStream fileOutputStream = null;
+        BufferedWriter bufferedWriter = null;
+        try {
+            fileOutputStream = new FileOutputStream(file);
+            bufferedWriter = new BufferedWriter(new OutputStreamWriter(fileOutputStream, "utf-8")); 
+            bufferedWriter.write(value);
+            bufferedWriter.flush();
+            bufferedWriter.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+            Slog.i("dxb","input data error " + e.getMessage());
+        } finally {
+            if (bufferedWriter != null) {
+                try {
+                    bufferedWriter.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+    }
+private boolean userActivityNoUpdateLocked(long eventTime, int event, int flags, int uid) {if (DEBUG_SPEW) {Slog.d(TAG, "userActivityNoUpdateLocked: eventTime=" + eventTime
@@ -1690,6 +1738,8 @@ public final class PowerManagerService extends SystemServiceTrace.traceBegin(Trace.TRACE_TAG_POWER, "wakeUp");try {
+		Slog.i(TAG, "ctrol led to working mode");
+		closeLed(1);Slog.i(TAG, "Waking up from "+ PowerManagerInternal.wakefulnessToString(getWakefulnessLocked())+ " (uid=" + reasonUid
@@ -1748,6 +1798,8 @@ public final class PowerManagerService extends SystemServicetry {reason = Math.min(PowerManager.GO_TO_SLEEP_REASON_MAX,Math.max(reason, PowerManager.GO_TO_SLEEP_REASON_MIN));
+		Slog.i(TAG, "ctrol led to sleeping mode");
+		closeLed(0);Slog.i(TAG, "Going to sleep due to " + PowerManager.sleepReasonToString(reason)+ " (uid " + uid + ")...");
C、验证

按开机键,休眠亮红灯,唤醒亮蓝灯。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

el-input 设置类型为number时,输入中文后光标会上移,并且会出现上下箭头

光标上移 设置 el-input 的 typenumber后&#xff0c;只能输入数字&#xff0c;输入中文后会自动清空&#xff0c;但是会出现一个问题&#xff1a;【光标会上移&#xff0c;如下图】 解决方法&#xff1a;修改样式 注意&#xff1a;需要使用样式穿透 :deep( ) /*解决el-in…

el-table一格两行;概率;find

样式&#xff1a; 根据概率表头关键代码&#xff1a;rateRanges&#xff1b; scope.row.targetHitTable.find((target:any) > target.targetHitRate > range.min && target.targetHitRate < range.max)!.targetHitNum &#xff08;1&#xff09;!.是TypeScri…

CSS定位详解上

1. 相对定位 1.1 如何设置相对定位&#xff1f; 给元素设置 position:relative 即可实现相对定位。 可以使用 left 、 right 、 top 、 bottom 四个属性调整位置。 1.2 相对定位的参考点在哪里&#xff1f; 相对自己原来的位置 1.3 相对定位的特点&#xff1…

二、Java-封装playwright UI自动化(根据官网执行步骤,首先封装BrowserFactory枚举类及BrowserManager)

前言 查看playwright官网&#xff0c;api文档了解到&#xff0c;playwright的基本步骤&#xff1a; 1、实例化一个playwright 2、启动一个浏览器类型 3、打开一个页面 所以&#xff0c;在封装时需要有一个浏览器工厂类&#xff0c;定义不同的浏览器类型&#xff0c;在配置文…

【问题解决】Jenkins使用File的exists()方法判断文件存在,一直提示不存在的问题

小剧场 最近为了给项目组提供一个能给Java程序替换前端、后端的增量的流水线&#xff0c;继续写上了声明式流水线。 替换增量是根据JSON配置文件去增量目录里去取再替换到对应位置的&#xff0c;替换前需要判断增量文件是否存在。 判断文件是否存在&#xff1f;作为一个老Ja…

神策数据严正声明

近日&#xff0c;我们发现有不法分子冒充神策网络科技&#xff08;北京&#xff09;有限公司&#xff08;以下简称”神策数据”&#xff09;的名义&#xff0c;发布虚假的招聘广告、面试邀请&#xff0c;企图误导求职者并进行不法行为。对此&#xff0c;我司发布严正声明&#…

ICLR 2025|香港浸会大学可信机器学习和推理课题组专场

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入&#xff01; AITIME 01 ICLR 2025预讲会团队专场 AITIME 02 专场信息 01 Noisy Test-Time Adaptation in Vision-Language Models 讲者&#xff1a;曹晨涛&#xff0c;HKBU TMLR Group一年级博士生&#xff0c;目前关注基础…

MySQL增量更新数据:高效同步策略与PanguSync实战指南

Mysql增量更新数据软件下载https://pan.baidu.com/s/1WesHaKGO7uQMhPNE-BTDmg?pwdabcd#list/path%2F 在数据驱动的商业环境中&#xff0c;实时数据同步已成为企业数字化转型的关键。本文将深入探讨MySQL增量更新的核心技术&#xff0c;并详细解析如何通过PanguSync工具实现高…

无人机灯光原理与应用解析!

工作原理 LED光源&#xff1a;LED因其高效、长寿命、高亮度和轻便等优点&#xff0c;成为无人机灯光的主要光源。 电路控制&#xff1a;通过微控制器或飞行控制器调节电流&#xff0c;控制灯光的开关、亮度和颜色。 信号传输&#xff1a;灯光控制信号通过无线或有线方式从遥…

51c自动驾驶~合集52

我自己的原文哦~ https://blog.51cto.com/whaosoft/13383340 #世界模型如何推演未来的千万种可能 驾驶世界模型&#xff08;DWM&#xff09;&#xff0c;专注于预测驾驶过程中的场景演变&#xff0c;已经成为追求自动驾驶的一种有前景的范式。这些方法使自动驾驶系统能够更…

lamp平台介绍

一、lamp介绍 网站&#xff1a; 静态 动态 php语言 .php 作用&#xff1a;运行php语言编写动态网站应用 lamp Linux Apache MySQL PHP PHP是作为httpd的一个功能模块存在的 二、部署lamp平台 1、测试httpd是否可正常返回PHP的响应 2、测试PHP代码是否可正常连接数据…

ROM修改进阶教程------修改安卓机型SELinux宽容的几种方式方法 以及第三方系统中如何关闭SELinux宽容

SELinux是一种强制访问控制安全机制,用于增强Linux系统的安全性。在某些情况下,可能需要对 SELinux 进行宽容设置,以满足特定的应用需求。当SELinux处于宽容模式时,系统允许违反安全策略的行为发生,但不会阻止这些行为,通常会在日志中记录这些违规事件。这与强制模式不同…

如何在 Aptos 上铸造 NFT

今天文章的第一部分将演示如何在 Aptos 上铸造 NFT&#xff0c;并使用 Moralis 轻松获取所有交易详细信息。在这里&#xff0c;我们将指导您完成使用 Aptos CLI 铸造活动门票 NFT 基本代币的过程。您还将了解如何完成初始设置步骤。此外&#xff0c;您还将了解如何获取 Moralis…

Springboot 梳理

一、Springboot 特性 方便创建可独立运行的spring应用程序直接内嵌Tomcat等服务简化了项目的构建配置为spring及第三方库提供自动配置提供生产级特性无需生成代码或者进行xml配置 二、四大核心 自动配置起步依赖命令行界面Actuator - 生成级的特性 三、自动配置的实现原理 …

C语言学习笔记-初阶(30)深入理解指针2

1. 数组名的理解 在上一个章节我们在使用指针访问数组的内容时&#xff0c;有这样的代码&#xff1a; int arr[10] {1,2,3,4,5,6,7,8,9,10}; int *p &arr[0]; 这里我们使用 &arr[0] 的方式拿到了数组第⼀个元素的地址&#xff0c;但是其实数组名本来就是地址&…

【Kubernetes 指南】基础入门——Kubernetes 基本概念(三)

三、Node 1、Node 简介 - Node 是 Pod 真正运行的主机&#xff0c;可以是物理机&#xff0c;也可以是虚拟机。 - 为了管理 Pod&#xff0c;每个 Node 节点 上至少要运行 container runtime&#xff08; 比如 docker 或者 rkt &#xff09;、kubelet 和 kube-proxy 服务。 2、…

电源测试系统有哪些可以利用AI工具的科技??

AI技术的发展对电源模块测试系统的影响是深远的&#xff0c;不仅协助系统提升了测试效率和精度&#xff0c;还推动了测试方法的创新和智能化。那么在电源测试系统中哪些模块可以利用AI工具实现自动化测试? 1. 自动化测试与效率提升 智能测试流程优化 AI算法可以自动优化测试…

解决Spring Boot中LocalDateTime返回前端数据为数组结构的问题

在Spring Boot开发中&#xff0c;处理日期时间数据是一个常见的需求。Java 8 引入了新的日期时间API&#xff0c;如LocalDateTime&#xff0c;它提供了更强大的日期时间处理功能。然而&#xff0c;在将LocalDateTime对象序列化为JSON时&#xff0c;可能会遇到返回为数组结构的问…

Redis---缓存穿透,雪崩,击穿

文章目录 缓存穿透什么是缓存穿透&#xff1f;缓存穿透情况的处理流程是怎样的&#xff1f;缓存穿透的解决办法缓存无效 key布隆过滤器 缓存雪崩什么是缓存雪崩&#xff1f;缓存雪崩的解决办法 缓存击穿什么是缓存击穿&#xff1f;缓存击穿的解决办法 区别对比 在如今的开发中&…

IntelliJ IDEA 2024.3.4 版本无法正常加载maven项目

报错如下&#xff1a; Possible solutions: - Check that Maven settings.xml does not contain http repositories - Check that Maven pom files do not contain http repository http://192.168.22.76:9003/repository/thirdparty/ - Check that Maven pom files do not co…