Android学习15 -- LED点灯(Ver1) 一定会写的。。。//2024061 简介之前留言了一定会写所以还是抽时间把这个弄了。因为这次用的高通的板子IO输出是1.8V无法驱动一个真实的LED所以用的迷你示波器看波形。然后这次用的版本是userdebug所以自启动selinux这些也都没有弄算是简化版的简化版。2 DriverDTS/* user-led bring-up patch (temporary; see neo-aliso-sg2-idp.user-led.patch.dtsi) */ /* ---- 2) Custom user LED platform device on GPIO 19 ---- */ tlmm { user_led_default: user-led-default { mux { pins gpio19; function gpio; }; config { pins gpio19; drive-strength 2; bias-disable; output-low; }; }; }; soc { user_led: user-led { compatible vendor,user-led; label user_led; led-gpios tlmm 19 0; /* GPIO 19, active high */ pinctrl-names default; pinctrl-0 user_led_default; status okay; }; };代码// SPDX-License-Identifier: GPL-2.0-only /* * user_led_driver.c - Custom platform driver to control a user LED via GPIO * * Exposes a sysfs brightness attribute under its platform device: * echo 1 .../user-led/brightness (turn LED on) * echo 0 .../user-led/brightness (turn LED off) * * Device tree node expected (see user-led.dtsi): * user_led { * compatible vendor,user-led; * led-gpios tlmm 19 0; // GPIO 19 (placeholder, per user) * label user_led; * }; * * Build: KLEAF ddk_module (see BUILD.bazel) */ #include linux/module.h #include linux/platform_device.h #include linux/of.h #include linux/gpio/consumer.h #include linux/sysfs.h #include linux/device.h #include linux/err.h #include linux/mutex.h #include linux/slab.h #define DRIVER_NAME user-led #define DRIVER_DESC User LED GPIO platform driver struct user_led_dev { struct device *dev; struct gpio_desc *led_gpio; struct mutex lock; int brightness; }; /* -------------------- sysfs attribute -------------------- */ static ssize_t brightness_show(struct device *dev, struct device_attribute *attr, char *buf) { struct user_led_dev *led dev_get_drvdata(dev); return sysfs_emit(buf, %d\n, led-brightness); } static ssize_t brightness_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct user_led_dev *led dev_get_drvdata(dev); unsigned long value; int ret; ret kstrtoul(buf, 0, value); if (ret) return ret; if (value 1) return -EINVAL; mutex_lock(led-lock); gpiod_set_value_cansleep(led-led_gpio, value); led-brightness value; mutex_unlock(led-lock); return count; } static DEVICE_ATTR_RW(brightness); static struct attribute *user_led_attrs[] { dev_attr_brightness.attr, NULL, }; static struct attribute_group user_led_group { .attrs user_led_attrs, }; /* -------------------- platform driver -------------------- */ static int user_led_probe(struct platform_device *pdev) { struct device *dev pdev-dev; struct user_led_dev *led; int ret; led devm_kzalloc(dev, sizeof(*led), GFP_KERNEL); if (!led) return -ENOMEM; led-dev dev; mutex_init(led-lock); dev_set_drvdata(dev, led); /* * GPIO number comes from DTS led-gpios (currently tlmm 19 0). * The flags (0 active high, GPIO_ACTIVE_LOW active low) are taken * from DTS too, so the driver works for either polarity. */ led-led_gpio devm_gpiod_get(dev, led, GPIOD_OUT_LOW); if (IS_ERR(led-led_gpio)) { ret PTR_ERR(led-led_gpio); dev_err(dev, failed to get led-gpios: %d\n, ret); return ret; } gpiod_set_consumer_name(led-led_gpio, user-led); led-brightness 0; /* Create the sysfs brightness attribute under the platform device. */ ret devm_device_add_group(dev, user_led_group); if (ret) { dev_err(dev, failed to create sysfs group: %d\n, ret); return ret; } dev_info(dev, user LED driver probed, GPIO active-%s\n, gpiod_is_active_low(led-led_gpio) ? low : high); return 0; } static int user_led_remove(struct platform_device *pdev) { struct user_led_dev *led dev_get_drvdata(pdev-dev); if (led-led_gpio) gpiod_set_value_cansleep(led-led_gpio, 0); return 0; } static const struct of_device_id user_led_of_match[] { { .compatible vendor,user-led }, { } }; MODULE_DEVICE_TABLE(of, user_led_of_match); static struct platform_driver user_led_driver { .probe user_led_probe, .remove user_led_remove, .driver { .name DRIVER_NAME, .of_match_table user_led_of_match, }, }; module_platform_driver(user_led_driver); MODULE_LICENSE(GPL); MODULE_AUTHOR(Your Name); MODULE_DESCRIPTION(DRIVER_DESC);此时可以先在命令行下面观察执行结果3 App核心就是控制那个节点。package com.example.userled import android.os.Bundle import android.widget.Button import android.widget.TextView import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.File /** * Control App for the user LED. * * Writes 1/0 to the driver sysfs brightness node via root (su): * /sys/devices/.../user-led/brightness * * NOTE: The exact sysfs path depends on the platform device naming. * On Qualcomm platforms the node usually appears under /sys/devices/platform/ * or /sys/bus/platform/devices/. A robust way is to find it by reading the * label file, or use the fixed path if known. We locate it dynamically: * find /sys/devices -name brightness -path *user-led* */ class MainActivity : AppCompatActivity() { private val ledBrightnessPath /sys/devices/platform/soc/soc:user-led/brightness private lateinit var statusText: TextView private lateinit var btnOn: Button private lateinit var btnOff: Button private lateinit var btnFind: Button private val scope CoroutineScope(Dispatchers.Main) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) statusText findViewById(R.id.statusText) btnOn findViewById(R.id.btnOn) btnOff findViewById(R.id.btnOff) btnFind findViewById(R.id.btnFind) btnOn.setOnClickListener { setLed(1) } btnOff.setOnClickListener { setLed(0) } btnFind.setOnClickListener { findLedPath() } } override fun onDestroy() { super.onDestroy() RootHelper.release() } private fun setLed(value: Int) { scope.launch { val result withContext(Dispatchers.IO) { writeLed(value) } val (ok, message) result if (ok) { statusText.text LED ${if (value 1) ON else OFF} $ledBrightnessPath } else { statusText.text Failed: $message toast(message) } } } private fun findLedPath() { scope.launch { val path withContext(Dispatchers.IO) { locateLedBrightness() } if (path ! null) { statusText.text Found: $path toast(Found: $path) } else { statusText.text Not found (driver not loaded / not probed) toast(LED sysfs node not found) } } } /** Locates the brightness node for the user-led device. */ private fun locateLedBrightness(): String? { val node File(ledBrightnessPath) return ledBrightnessPath.takeIf { node.exists() } } private fun writeLed(value: Int): PairBoolean, String { val node File(ledBrightnessPath) if (!node.exists()) return false to LED driver node not found if (!node.canWrite()) return false to LED node is not writable return try { node.writeText(value.toString()) true to ledBrightnessPath } catch (e: Exception) { false to Write failed: ${e.message ?: e.javaClass.simpleName} } } private fun toast(msg: String) { Toast.makeText(this, msg, Toast.LENGTH_SHORT).show() } }UI

相关新闻

最新新闻

C语言/数据结构算法题解:环形数组最大连续子段和——单调队列+前缀和O(n)解法

C语言/数据结构算法题解:环形数组最大连续子段和——单调队列+前缀和O(n)解法

问题描述小明在玩一个环形数字游戏,游戏规则是:给定一个环形整数数组(即首尾相连的数组),每个元素代表一个位置上的“贡献值”。小明可以自由选择一段连续的位置(由于是环形,选择可以跨越数组首…

2026/8/15 15:32:57
剪映专业版教程:制作特效与转场质感大片

剪映专业版教程:制作特效与转场质感大片

前言 今天教大家一个特效与转场质感大片的制作方法。这种效果通过歌词同步卡拉OK、多段视频拼接、多种转场和特效叠加,营造出电影级的视觉质感。 效果预览:歌词以双色卡拉OK方式同步显示,四段美女视频依次切换,多种模糊转场过渡…

2026/8/15 15:32:57
为什么你的Illusion游戏Mod总在打架?用KKManager把它们管起来

为什么你的Illusion游戏Mod总在打架?用KKManager把它们管起来

为什么你的Illusion游戏Mod总在打架?用KKManager把它们管起来 【免费下载链接】KKManager Mod, plugin and card manager for games by Illusion that use BepInEx 项目地址: https://gitcode.com/gh_mirrors/kk/KKManager 如果你玩过Illusion系(…

2026/8/15 15:32:57
让 AI 生成 SQL 前,先限制表、字段和扫描范围

让 AI 生成 SQL 前,先限制表、字段和扫描范围

让 AI 生成 SQL 前,先限制表、字段和扫描范围 演示里,模型一句话生成查询并画图很顺滑;接入真实数据后,权限、成本和指标口径才是难点。模型适合产出候选计划,不应直接拿到任意数据库执行权。 查询先经过结构化计划 将…

2026/8/15 15:32:57
Web前端安全:XSS与CSRF防护及最佳实践

Web前端安全:XSS与CSRF防护及最佳实践

1. Web前端安全概述前端安全是Web开发中不可忽视的重要环节。随着Web应用功能日益复杂,前端面临的安全威胁也呈现出多样化趋势。从早期的XSS攻击到如今的CSRF、点击劫持等,攻击手段不断演变升级。作为与用户直接交互的界面层,前端一旦存在安全…

2026/8/15 15:32:57
DDrawCompat 终极指南:让 DirectX 1-7 老游戏在现代 Windows 上满血复活

DDrawCompat 终极指南:让 DirectX 1-7 老游戏在现代 Windows 上满血复活

DDrawCompat 终极指南:让 DirectX 1-7 老游戏在现代 Windows 上满血复活 【免费下载链接】DDrawCompat DirectDraw and Direct3D 1-7 compatibility, performance and visual enhancements for Windows Vista, 7, 8, 10 and 11 项目地址: https://gitcode.com/gh_…

2026/8/15 15:27:56