android11使用gpio口控制led状态灯

server/2025/3/6 8:38:28/

目录

一、简介

二、解决方法

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.ppmy.cn/server/172825.html

相关文章

SQL注入的原理及详细运用

1、SQL注入的目的 <1>查询数据 <2>读写文件 <3>执行命令 2、SQL注入的原理 没有账号密码如何登录 <1>原因 当web应用向后台数据库传递SQL语句进行数据库操作时&#xff0c;如果对用户输入的参数没有经过严格的过滤处理&#xff0c;那么攻击者就…

使用ffmpeg读取mp4文件解码失败

最近做一功能&#xff0c;使用ffmpeg读取mp4文件&#xff0c;使用rockchip的芯片播放出来。ffmpeg读取的mp4文件喂给vdec&#xff0c;一直不显示。 把ffmpeg解码后的文件保存成h264,使用mpi_dec_test测试&#xff0c;显示如下: [rootrv1126:/userdata/tmp]# mpi_dec_test -i /…

Java Web 相关技术概念与知识点

Java Web 主要用于构建基于 Web 的应用程序&#xff0c;涵盖了从客户端请求到服务器端处理再到响应返回的全过程 掌握这些 Java Web 关键技术后&#xff0c;可以进一步学习 Spring MVC、Spring Boot 等现代框架来构建更复杂的 Web 应用&#xff01; &#x1f680; 1. HTTP 协议…

安卓开发相机功能

相机功能 安卓中的相机调用功能也经历了很多的方案升级&#xff0c;目前可选的官方方案是CameraX、Camera2、Camera&#xff08;废弃&#xff09;&#xff0c;还有一些第三方免费或者是付费的相机库。对于大多数开发者&#xff0c;建议使用 CameraX。 CameraX CameraX 是 An…

请解释 HTTP 中的状态码,常见的状态码有哪些?

一、HTTP状态码基础概念 HTTP状态码是服务器对客户端请求的三位数字响应标识&#xff0c;由RFC 7231等规范定义。 其核心作用是快速传递请求处理结果&#xff0c;帮助开发者定位问题。状态码按首字母分为五类&#xff1a; ​1xx&#xff1a;信息性响应&#xff08;如100 Con…

ArcGIS操作:08 计算shp面积并添加到属性表

1、打开属性表 注意&#xff1a;计算面积前&#xff0c;需要把shp的坐标系转化为投影坐标系&#xff08;地理坐标系用于定位、投影坐标系用于测量&#xff09; 2、创建字段 3、编辑字段名、类型 4、选择字段&#xff0c;计算几何 5、选择属性、坐标系、单位

理解Java泛型通配符:List<? extends T>与List<? super T>的深度解析

引言 在Java泛型系统中&#xff0c;通配符?是实现类型安全与灵活性的重要工具。其中List<? extends T>和List<? super T>的差异常令开发者困惑。本文将通过理论解析、代码示例和实践场景&#xff0c;揭示它们的核心区别及应用场景。 一、基础概念 1.1 上界通…

解锁数据抓取新高度:Python 分布式爬虫与逆向进阶实战课

在数据为王的当下&#xff0c;高效获取有价值的数据是众多开发者的核心诉求。《Python分布式爬虫与逆向进阶实战》课程&#xff0c;堪称数据抓取领域的宝藏指南。课程专注于前沿技术&#xff0c;深入剖析分布式爬虫原理&#xff0c;教你如何巧妙构建分布式爬虫架构&#xff0c;…