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

rk3588 Android 12 添加framework层服务,HAL库,从硬件驱动层到上层APP,实现led灯控

系列文章目录

rk3588 Android 12 添加framework层服务,HAL库,从硬件驱动层到上层APP,实现led灯控

文章目录

  • 系列文章目录
  • 一、 驱动适配:
    • 1.设备树
    • 2.设置文件权限
    • 3、开启CONFIG_LEDS_PWM
  • 二、HAL层
    • 1.引入库
    • 2.打包hal库
  • 三、JNI
  • 四、framework层服务添加
    • 1.framework层服务
    • 2.添加系统服务权限设置
  • 五、app调用
  • 总结

一、 驱动适配:

1.设备树

kernel-5.10/arch/arm64/boot/dts/rockchip/rk3588_evb1_*.dtsi

	leds_panel {compatible = "pwm-leds";status = "okay";leds-light {pwms = <&pwm6 0 15000 0>;default-brightness = <2>;max-brightness = <100>;};};&pwm6 {pinctrl-0 = <&pwm6m2_pins>;status = "okay";};

kernel-5.10/drivers/leds/leds-pwm.c

static int set_brightness_perms(struct device *dev, struct led_classdev *lcdev)
{struct kobject *kobj = &lcdev->dev->kobj;struct attribute *attr = NULL;struct kobj_type *ktype;int i;int err = -ENOENT;if (!kobj || !kobj->ktype) return err;ktype = kobj->ktype;if (ktype->default_attrs) {for (i = 0; ktype->default_attrs[i] != NULL; i++) {if (strcmp(ktype->default_attrs[i]->name, "brightness") == 0) {attr = ktype->default_attrs[i];break;}}}if (attr) {err = sysfs_chmod_file(kobj, attr, 0644);if (err) {dev_dbg(dev, "Failed to set brightness permissions: %d\n", err);}}return err;
}led_data->pwm = devm_fwnode_pwm_get(dev, fwnode, NULL);if (IS_ERR(led_data->pwm))return dev_err_probe(dev, PTR_ERR(led_data->pwm),"unable to request PWM for %s\n",led->name);if (!fwnode_property_read_u32(fwnode, "default-brightness", &default_brightness)) led_data->cdev.brightness = default_brightness;else led_data->cdev.brightness = 1;set_brightness_perms(dev, &led_data->cdev);

2.设置文件权限

--- a/device/rockchip/common/rootdir/init.rk30board.rc
+++ b/device/rockchip/common/rootdir/init.rk30board.rc
@@ -125,7 +125,10 @@ on boot# backlightchown system system /sys/class/backlight/rk28_bl/brightnesschown system system /sys/class/backlight/backlight/brightness
-    
+
+	#leds-panle
+	chown system system /sys/devices/platform/leds_panel/leds/leds-light/brightness
+	# for hdmi

3、开启CONFIG_LEDS_PWM

diff --git a/kernel-5.10/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/kernel-5.10/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
index b4f9bcc214a..944c4b5345c 100644
--- a/kernel-5.10/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+++ b/kernel-5.10/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
@@ -5005,7 +5005,7 @@ hdmi0: hdmi@fde80000 {reset-names = "ref", "hdp";power-domains = <&power RK3588_PD_VO1>;pinctrl-names = "default";
-		pinctrl-0 = <&hdmim0_tx0_cec &hdmim0_tx0_hpd &hdmim0_tx0_scl &hdmim0_tx0_sda>;
+		pinctrl-0 = <&hdmim0_tx0_hpd &hdmim0_tx0_scl &hdmim0_tx0_sda>;reg-io-width = <4>;rockchip,grf = <&sys_grf>;rockchip,vo1_grf = <&vo1_grf>;
diff --git a/kernel-5.10/arch/arm64/configs/rockchip_defconfig b/kernel-5.10/arch/arm64/configs/rockchip_defconfig
index 4e943597127..1e8cb97119a 100755
--- a/kernel-5.10/arch/arm64/configs/rockchip_defconfig
+++ b/kernel-5.10/arch/arm64/configs/rockchip_defconfig
@@ -1018,3 +1018,5 @@ CONFIG_BUG_ON_DATA_CORRUPTION=yCONFIG_ENABLE_DEFAULT_TRACERS=y# CONFIG_RUNTIME_TESTING_MENU is not setCONFIG_ROCKCHIP_LT9211=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_PWM=y

二、HAL层

1.引入库

hardware/libhardware/modules/light_panel/Android.bp

// Copyright (C) 2013 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.cc_library_shared {name: "light_panel.default",relative_install_path: "hw",proprietary: true,srcs: ["light_panel.c"],cflags: ["-Wall", "-Werror"],header_libs: ["libhardware_headers"],shared_libs: ["liblog"],
}

hardware/libhardware/modules/light_panel/light_panel.c

/** Copyright (C) 2014, 2017-2018 The  Linux Foundation. All rights reserved.* Not a contribution* Copyright (C) 2008 The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**      http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/// #define LOG_NDEBUG 0#include <errno.h>
#include <malloc.h>
#include <stdint.h>
#include <string.h>
#include <log/log.h>
#include <hardware/light_panel.h>
#include <hardware/hardware.h>
#include <cutils/properties.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>#include <sys/ioctl.h>
#include <sys/types.h>char const*const LIGHT_PANEL_BRIGHTNESS_CONTROL= "/sys/devices/platform/leds_panel/leds/leds-light/brightness";static int
write_int(char const* path, int value)
{int fd;static int already_warned = 0;ALOGD("leds write_int!!!\n");fd = open(path, O_WRONLY);ALOGD("open file%s\n",strerror(errno));if (fd >= 0) {char buffer[20];int bytes = snprintf(buffer, sizeof(buffer), "%d\n", value);ssize_t amt = write(fd, buffer, (size_t)bytes);close(fd);return amt == -1 ? -errno : 0;} else {if (already_warned == 0) {ALOGE("write_int failed to open %s\n", path);already_warned = 0;}return -errno;}
}/** Close the lights device */
static int
close_led(struct light_panel_device_t *dev)
{if (dev) {free(dev);}return 0;
}int set_light_brightness(struct light_panel_device_t* dev,int brightness)
{int err = 0;if(!dev) {return -1;}if(brightness > 255){err = write_int(LIGHT_PANEL_BRIGHTNESS_CONTROL, 255);}else if(brightness < 0){err = write_int(LIGHT_PANEL_BRIGHTNESS_CONTROL, 0);}else {err = write_int(LIGHT_PANEL_BRIGHTNESS_CONTROL, brightness);}return err;
}static int light_panel_device_open(const struct hw_module_t* module, const char* name,struct hw_device_t** device)
{ALOGD("Hello: light_panel_device_open name = %s",name);struct light_panel_device_t *dev = malloc(sizeof(struct light_panel_device_t));if(!dev)return -ENOMEM;memset(dev, 0, sizeof(*dev));//HAL must init propertydev->common.tag= HARDWARE_DEVICE_TAG;dev->common.version = 0;dev->common.module= (hw_module_t*)module;dev->common.close = (int (*)(struct hw_device_t*))close_led;; dev->set_light_brightness= set_light_brightness;// //*device = (struct hw_device_t*)dev;*device = &(dev->common);return 0;
}static struct hw_module_methods_t light_panel_module_methods = {.open = light_panel_device_open  
};/** The led Module*/
struct hw_module_t HAL_MODULE_INFO_SYM = {.tag = HARDWARE_MODULE_TAG,.version_major = 1,.version_minor = 0,.id = LIGHT_PANEL_HARDWARE_MODULE_ID,.name = "light_panel HAL module",.author = "vendor_light_panel, Inc.",.methods = &light_panel_module_methods,
};

2.打包hal库

/build/make/target/product/full_base.mk

 #   audio.a2dp.default is a system module. Generic system image includes#   audio.a2dp.default to support A2DP if board has the capability.PRODUCT_PACKAGES += \
-    audio.a2dp.default
+    audio.a2dp.default \
+	light_panel.default
diff --git a/hardware/libhardware/modules/Android.mk b/hardware/libhardware/modules/Android.mk
index 9d934c5f9ca..eeedc46678e 100644
--- a/hardware/libhardware/modules/Android.mk
+++ b/hardware/libhardware/modules/Android.mk
@@ -1,5 +1,6 @@hardware_modules := \camera \gralloc \
-    sensors
+    sensors \
+    light_panel

三、JNI

/frameworks/base/services/core/jni/com_android_server_LightPanelService.cpp

@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define LOG_TAG "com_android_server_LightPanelService"
+#include "utils/Log.h"
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <hardware/light_panel.h>
+#include <hardware/hardware.h>
+
+namespace android  {
+
+    static light_panel_device_t *sLightPanelDevice = NULL;
+
+    static jint set_light_brightness(JNIEnv* env, jobject clazz, jint brightness) {
+        int brightness_val = brightness;
+        ALOGD("Hello JNI: set brightness_val %d to device.", brightness_val);
+        if(!sLightPanelDevice) {
+            ALOGD("Hello JNI: device is not open.");
+            return -1;
+        }
+        sLightPanelDevice->set_light_brightness(sLightPanelDevice,brightness_val);
+        return 0;
+    }
+
+    static inline int light_panel_device_open(const hw_module_t* module, struct light_panel_device_t** device) {
+        return module->methods->open(module, LIGHT_PANEL_HARDWARE_MODULE_ID, (struct hw_device_t**)device);
+		//return module->common.methods->open(&(module->common), LIGHT_PANEL_HARDWARE_MODULE_ID,(struct hw_device_t**)&device));
+    }
+
+    static jint light_panel_init(JNIEnv* env,jobject clazz) {
+		light_panel_module_t* module;
+		ALOGE("Initializing LightPanel HAL...");
+		
+		int ret = hw_get_module(LIGHT_PANEL_HARDWARE_MODULE_ID, (const hw_module_t**)&module);
+		if (ret != 0) {
+			ALOGE("Failed to get HAL module (Error %d). Check device HAL implementation.", ret);
+			return -1;
+		}
+
+		ret = light_panel_device_open(&module->common, &sLightPanelDevice);
+		if (ret != 0) {
+			ALOGE("Failed to open device (Error %d). Verify HAL compatibility.", ret);
+			return -1;
+		}
+
+		ALOGE("LightPanel device initialized successfully.");
+        return 0;
+    }
+
+    static const JNINativeMethod method_table[] = {
+        {"init_native", "()I", (void*)light_panel_init},
+        { "set_light_brightness","(I)I",(void*)set_light_brightness},
+    };
+	
+    int register_android_server_LightPanelService(JNIEnv* env) {
+            return jniRegisterNativeMethods(env, "com/android/server/LightPanelService", method_table, NELEM(method_table));
+    }
+};
diff --git a/frameworks/base/services/core/jni/Android.bp b/frameworks/base/services/core/jni/Android.bp
index 57db80bbc7f..9525d8ef596 100644
--- a/frameworks/base/services/core/jni/Android.bp
+++ b/frameworks/base/services/core/jni/Android.bp
@@ -73,6 +73,7 @@ cc_library_static {"com_android_server_sensor_SensorService.cpp","com_android_server_rkdisplay_RkDisplayModes.cpp","com_android_server_audio_RkAudioSetting.cpp",
+		"com_android_server_LightPanelService.cpp","rkbox/rklog.cpp","com_android_server_RKBoxService.cpp","onload.cpp",
diff --git a/frameworks/base/services/core/jni/onload.cpp b/frameworks/base/services/core/jni/onload.cpp
index de3526cf361..a8f47a9cc94 100644
--- a/frameworks/base/services/core/jni/onload.cpp
+++ b/frameworks/base/services/core/jni/onload.cpp
@@ -66,6 +66,7 @@ int register_android_server_sensor_SensorService(JavaVM* vm, JNIEnv* env);int register_com_android_server_rkdisplay_RkDisplayModes(JNIEnv* env);int register_com_android_server_audio_RkAudioSetting(JNIEnv* env);int register_com_android_server_RKBoxManagementService(JNIEnv* env);
+int register_android_server_LightPanelService(JNIEnv* env);};using namespace android;
@@ -125,5 +126,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)register_com_android_server_rkdisplay_RkDisplayModes(env);register_com_android_server_audio_RkAudioSetting(env);register_com_android_server_RKBoxManagementService(env);
+    register_android_server_LightPanelService(env);return JNI_VERSION_1_4;}

四、framework层服务添加

1.framework层服务

diff --git a/frameworks/base/Android.bp b/frameworks/base/Android.bp
index a99cef87938..d69d338edcd 100644
--- a/frameworks/base/Android.bp
+++ b/frameworks/base/Android.bp
@@ -496,7 +496,8 @@ metalava_framework_docs_args = "--manifest $(location core/res/AndroidManifest.x"--api-lint-ignore-prefix android.icu. " +"--api-lint-ignore-prefix java. " +"--api-lint-ignore-prefix junit. " +
-    "--api-lint-ignore-prefix org. "
+    "--api-lint-ignore-prefix org. " +
+	"--api-lint-ignore-prefix android. "packages_to_document = ["android",
diff --git a/frameworks/base/core/api/current.txt b/frameworks/base/core/api/current.txt
index 84e8e5e69ce..8556dd63d8e 100644
--- a/frameworks/base/core/api/current.txt
+++ b/frameworks/base/core/api/current.txt
@@ -5378,6 +5378,26 @@ package android.app {field public static final int GAME_MODE_UNSUPPORTED = 0; // 0x0}+  public interface ILightPanelService extends android.os.IInterface {
+    method public void setLightPanelBrightness(int) throws android.os.RemoteException;
+    field public static final String DESCRIPTOR = "android.app.ILightPanelService";
+  }
+
+  public static class ILightPanelService.Default implements android.app.ILightPanelService {
+    ctor public ILightPanelService.Default();
+    method public android.os.IBinder asBinder();
+    method public void setLightPanelBrightness(int) throws android.os.RemoteException;
+  }
+
+  public abstract static class ILightPanelService.Stub extends android.os.Binder implements android.app.ILightPanelService {
+    ctor public ILightPanelService.Stub();
+    method public android.os.IBinder asBinder();
+    method public static android.app.ILightPanelService asInterface(android.os.IBinder);
+    method public static android.app.ILightPanelService getDefaultImpl();
+    method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
+    method public static boolean setDefaultImpl(android.app.ILightPanelService);
+  }
+public class Instrumentation {ctor public Instrumentation();method public android.os.TestLooperManager acquireLooperManager(android.os.Looper);
@@ -5533,6 +5553,12 @@ package android.app {field @Deprecated public android.content.pm.ResolveInfo resolveInfo;}+  public class LightPanelManager {
+    ctor public LightPanelManager(android.content.Context, android.app.ILightPanelService);
+    method public static android.app.LightPanelManager getInstance(android.content.Context);
+    method public void setLightPanelBrightness(int);
+  }
+@Deprecated public class ListActivity extends android.app.Activity {ctor @Deprecated public ListActivity();method @Deprecated public android.widget.ListAdapter getListAdapter();
@@ -10658,6 +10684,7 @@ package android.content {field public static final String KEYGUARD_SERVICE = "keyguard";field public static final String LAUNCHER_APPS_SERVICE = "launcherapps";field @UiContext public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";
+    field public static final String LIGHTPANEL_SERVICE = "lightpanel";field public static final String LOCATION_SERVICE = "location";field public static final String MEDIA_COMMUNICATION_SERVICE = "media_communication";field public static final String MEDIA_METRICS_SERVICE = "media_metrics";
diff --git a/frameworks/base/core/java/android/app/ILightPanelService.aidl b/frameworks/base/core/java/android/app/ILightPanelService.aidl
new file mode 100755
index 00000000000..54b494a73aa
--- /dev/null
+++ b/frameworks/base/core/java/android/app/ILightPanelService.aidl
@@ -0,0 +1,21 @@
+/**
+ * Copyright (c) 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. HelloService
+ */
+
+package android.app;
+
+interface ILightPanelService {
+   void setLightPanelBrightness(int brightness);
+}
diff --git a/frameworks/base/core/java/android/app/LightPanelManager.java b/frameworks/base/core/java/android/app/LightPanelManager.java
new file mode 100755
index 00000000000..bb0e6ff8300
--- /dev/null
+++ b/frameworks/base/core/java/android/app/LightPanelManager.java
@@ -0,0 +1,44 @@
+package android.app;
+
+import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
+import android.annotation.SystemService;
+import android.os.ServiceManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.app.ILightPanelService;
+import android.util.Log;
+
+
+@SystemService(Context.LIGHTPANEL_SERVICE)
+public class LightPanelManager {
+    private static final String TAG = "LightPanelManager";
+    private final ILightPanelService mService;
+
+    // 公开构造函数,供系统内部使用
+    public LightPanelManager(Context context, ILightPanelService service) {
+        mService = service;
+    }
+
+    // 提供静态获取方法,无需隐藏
+    public static LightPanelManager getInstance(Context context) {
+        ILightPanelService service = ILightPanelService.Stub.asInterface(
+            ServiceManager.getService(Context.LIGHTPANEL_SERVICE)
+        );
+        return new LightPanelManager(context, service);
+    }
+
+    // 公开亮度设置方法
+    public void setLightPanelBrightness(int brightness) {
+        try {
+            mService.setLightPanelBrightness(brightness);
+        } catch (RemoteException e) {
+            throw new RuntimeException("Failed to set brightness", e);
+        }
+    }
+}
+
diff --git a/frameworks/base/core/java/android/app/SystemServiceRegistry.java b/frameworks/base/core/java/android/app/SystemServiceRegistry.java
index 32ea41b2c75..deb8b0fa0c1 100644
--- a/frameworks/base/core/java/android/app/SystemServiceRegistry.java
+++ b/frameworks/base/core/java/android/app/SystemServiceRegistry.java
@@ -47,6 +47,8 @@ import android.app.usage.IUsageStatsManager;import android.app.usage.NetworkStatsManager;import android.app.usage.StorageStatsManager;import android.app.usage.UsageStatsManager;
+import android.app.ILightPanelService;
+import android.app.LightPanelManager;import android.apphibernation.AppHibernationManager;import android.appwidget.AppWidgetManager;import android.bluetooth.BluetoothManager;
@@ -1469,7 +1471,15 @@ public final class SystemServiceRegistry {public DisplayHashManager createService(ContextImpl ctx) {return new DisplayHashManager();}});
-
+        registerService(Context.LIGHTPANEL_SERVICE, LightPanelManager.class,
+                new CachedServiceFetcher<LightPanelManager>() {
+                @Override
+                public LightPanelManager createService(ContextImpl ctx) {
+                    IBinder b = ServiceManager.getService(Context.LIGHTPANEL_SERVICE);
+                    ILightPanelService service = ILightPanelService.Stub.asInterface(b);
+                    return new LightPanelManager(ctx, service);
+                }});
+				sInitializing = true;try {// Note: the following functions need to be @SystemApis, once they become mainline
diff --git a/frameworks/base/core/java/android/content/Context.java b/frameworks/base/core/java/android/content/Context.java
index 913c3b8a33c..02ae318e9e2 100644
--- a/frameworks/base/core/java/android/content/Context.java
+++ b/frameworks/base/core/java/android/content/Context.java
@@ -3728,6 +3728,7 @@ public abstract class Context {//@hide: SPEECH_RECOGNITION_SERVICE,UWB_SERVICE,MEDIA_METRICS_SERVICE,
+			LIGHTPANEL_SERVICE,})@Retention(RetentionPolicy.SOURCE)public @int
http://www.dtcms.com/a/291103.html

相关文章:

  • OpenAI开发的一款实验性大型语言模型(LLM),在2025年国际数学奥林匹克竞赛(IMO)中达到了金牌水平
  • 数智管理学(三十七)
  • liunx宝塔面板部署easyswoole项目
  • 常规笔记本和加固笔记本的区别
  • React 中使用immer修改state摆脱“不可变”
  • 打造自己的 Jar 文件分析工具:类名匹配 + 二进制搜索 + 日志输出全搞定
  • 从一开始的网络攻防(六):php反序列化
  • UART串口
  • 什么是内网穿透?本地内网无公网IP如何实现互联网上远程访问?
  • 每日一题7.21
  • 自动化商品监控:利用淘宝API开发实时价格库存采集接口
  • springdoc-openapi-ui的使用教程
  • 嵌入式开发学习———Linux环境下C语言学习(十二)
  • 【Tools】Ubuntu24.04安装详细教程
  • mobaxteam x11传输界面避坑
  • SAP 邮箱配置
  • C语言运算符优先级“潜规则”
  • 原型与原型链
  • 二维码扫描登录流程详解
  • 【Elasticsearch】settings
  • 解密分账系统:企业资金管理的智能中枢
  • Linux的相关指令
  • 京东商品评论如何获取?API接口实战指南
  • Kali MSF渗透Windows 11电脑
  • Linux_gdb调试器--进程概念
  • Linux初识网络
  • MySQL 核心知识点梳理(3)
  • buntu 22.04 上离线安装Docker 25.0.5(二)
  • 如何升级到macOS Tahoe:全面指南与实用步骤
  • LeetCode 每日一题 2025/7/14-2025/7/20