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

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.lryc.cn/news/547077.html

相关文章:

  • 基于Asp.net的高校一卡通管理系统
  • C++蓝桥杯基础篇(七)
  • 8.路由原理专题
  • jQuery UI 简介
  • Web服务器配置
  • LINUX网络基础 [一] - 初识网络,理解网络协议
  • 定制化开发的WooCommerce独立站商城更安全
  • Xcode 运行真机失败
  • 【FFmpeg之如何新增一个硬件解码器】
  • P3385 【模板】负环
  • 破解透明物体抓取难题,地瓜机器人CASIA 推出几何和语义融合的单目抓取方案|ICRA 2025
  • 深度学习编译器(整理某survey)
  • 【计算机网络入门】应用层
  • @PostConstruct注解的作用
  • HTML + CSS 题目
  • 通过多线程获取RV1126的AAC码流
  • sql sqlserver的进程资源查看,杀掉多余进程
  • 自然语言处理:朴素贝叶斯
  • Pytorch实现之LSRGAN,轻量化SRGAN超分辨率SAR
  • 学习记录-缺陷
  • 文件压缩与解压工具7-Zip的安装和使用(免费)
  • 如何实现对用户密码的加密
  • MySQL基础四(JDBC)
  • 审批流AntV框架蚂蚁数据可视化X6饼图(注释详尽)
  • 用Python之requests库调用大模型API实现多轮对话
  • 《异步江湖:XHR、Promise 与 Event Loop 的恩怨情仇》
  • 【极客时间】浏览器工作原理与实践-2 宏观视角下的浏览器 (6讲) - 2.5 渲染流程(上):HTML、CSS和JavaScript,是如何变成页面的?
  • 蓝桥杯第15届真题解析
  • 19c rac-expdp备份异常处理
  • 轻松部署 Stable Diffusion WebUI 并实现局域网共享访问:解决 Conda Python 版本不为 3.10.6 的难题