8.3 Android灯光系统_编写HAL_lights.c
注意在led-classes.c中定义的led_class_attrs[]所建立的文件的属性应该改为0666,否则应用程序无权操作它
同时ledtrig-time.c里面对应新建的那几个delay_on/delay_off也要改为0666,这样才能写它
Java: frameworks/base/services/core/java/com/android/server/lights/LightsService.java
JNI: frameworks/base/services/core/jni/com_android_server_lights_LightsService.cpp
Hal: lights.c //参考google上搜索到的lights.c,我们的开发上只有HAL的so库,在vendor/friendly-arm/tiny4412/proprietary/lights_tiny4412.so
默认配色:frameworks/base/core/res/res/values/config.xml
电池灯:frameworks/base/services/core/java/com/android/server/BatteryService.java
通知灯:frameworks/base/services/core/java/com/android/server/notification/NotificationManagerService.java
怎么写LIGHTS HAL
a. 实现一个名为HMI的hw_module_t结构体
b. 实现一个open函数, 它会根据name返回一个light_device_t结构体
c. 实现多个light_device_t结构体,每一个对应一个DEVICE
light_device_t结构体里第1个成员是hw_device_t结构体, 紧接着一个set_light函数
设置LED状态:
struct light_state_t {
/**
* The color of the LED in ARGB.
*
* Do your best here.
* - If your light can only do red or green, if they ask for blue,
* you should do green.
* - If you can only do a brightness ramp, then use this formula:
* unsigned char brightness = ((77*((color>>16)&0x00ff))
* + (150*((color>>8)&0x00ff)) + (29*(color&0x00ff))) >> 8;
* - If you can only do on or off, 0 is off, anything else is on.
*
* The high byte should be ignored. Callers will set it to 0xff (which
* would correspond to 255 alpha).
*/
unsigned int color; // 把灯设为什么颜色, 或 把LCD的亮度设为什么
/**
* See the LIGHT_FLASH_* constants
*/
int flashMode; // 是否闪烁, LIGHT_FLASH_NONE表示不闪
int flashOnMS; // 亮的时间
int flashOffMS;// 灭的时间
/**
* Policy used by the framework to manage the light's brightness.
* Currently the values are BRIGHTNESS_MODE_USER and BRIGHTNESS_MODE_SENSOR.
*/
int brightnessMode; // 表示LCD的背光亮度模式
};
lights.c文件
注意在led-classes.c中定义的led_class_attrs[]所建立的文件的属性应该改为0666,否则应用程序无权操作它
#define LOG_TAG “lights”
#define LOG_NDEBUG 0 //加上这句就可以用ALOGV来打印了,否则打印信息被忽略
#include <hardware/led_hal.h>
#include <hardware/hardware.h>
......还有很多头文件.........
//HAL里面操作led等就是往这些文件里面写值来完成的
char const*const RED_LED_FILE = "sys/class/leds/led1/brightness";
char const*const GREEN_LED_FILE = "sys/class/leds/led2/brightness";
char const*const BLUE_LED_FILE = "sys/class/leds/led3/brightness";
char const*const RED_LED_FILE_TRIGGER = "sys/class/leds/led1/trigger";
char const*const GREEN_LED_FILE_TRIGGER = "sys/class/leds/led2/trigger";
char const*const BLUE_LED_FILE_TRIGGER = "sys/class/leds/led3/trigger";
char const*const RED_LED_FILE_DELAYON = "sys/class/leds/led1/delay_on";
char const*const GREEN_LED_FILE_DELAYON = "sys/class/leds/led2/delay_on";
char const*const BLUE_LED_FILE_DELAYON = "sys/class/leds/led3/delay_on";
char const*const RED_LED_FILE_DELAYOFF = "sys/class/leds/led1/delay_off";
char const*const GREEN_LED_FILE_DELAYOFF = "sys/class/leds/led2/delay_off";
char const*const BLUE_LED_FILE_DELAYOFF = "sys/class/leds/led3/delay_off";
char const*const LCD_BACKLIGHT_FILE = "/dev/backlight-1wire";//反汇编厂家提供的HAL层SO,lights_tiny4412.so,可以看到对背光灯的操作是该文件,在内核中搜索“backlight-1wire”,发现其是对应drivers/input/touchscreen/tiny4412_1wire_host.c中注册的设备,其是一个miscdevice,提供了file_operation结构体
static pthread_one_t g_init = PTHREAD_ONCE_INIT;
static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;
//通知灯和电池灯公用一个硬件
static struct light_state_t g_notification;
static struct light_state_t g_battery;
static int write_int(const char *path,int value){
int fd;
static int already_warned = 0;
fd = open(path,O_RDWR);
if(fd<0)
{
if(already_warned == 0)
{
already_warned = 1;
}
return -errno;
}
char buffer[20];
int bytes = snprintf(buffer,sizeof(buffer),"%s\n",value);
int written = write(fd,buffer,bytes);
close(fd);
return written == -1?-errno:0;
}
static int write_string(const char *path,const char *value){
int fd;
static int already_warned = 0;
fd = open(path,O_RDWR);
if(fd<0)
{
if(already_warned == 0)
{
already_warned = 1;
}
return -errno;
}
char buffer[20];
int bytes = snprintf(buffer,sizeof(buffer),"%s\n",value);
int written = write(fd,buffer,bytes);
close(fd);
return written == -1?-errno:0;
}
static int is_lit(struct light_state_t const * state){
return state->color & 0x00ffffff;
}
static int rgb_to_brightness(struct light_state_t const * state){
int color = state->color & 0x00ffffff;
return ((77*((color>>16)&0x00ff))+(150*((color>>8)&0x00ff))+(29*(color&0x00ff)))>>
}
static int set_light_backlight(struct light_device_t *dev,,struct light_state_t *state){
int brightness = rgb_to_brightness(state);
pthread_mutex_lock(&g_lock);
//brightness在这里的范围是0-255,但是设备文件能接受的是0-127
write_int(LCD_BACKLIGHT_FILR,brightness/2);
pthread_mutex_unlock(&g_lock);
return 0;
}
static void set_shared_light_locked(struct light_device_t *dev,struct light_state_t *state){
int r,g,b;
int delayOn,delayOff;
r = (state->color>>16)&0xff;
g = (state->color>>8)&0xff;
b = (state->color)&0xff;
delayOn = state->flashOnMS;
delayOff = state->flashOffMS;
if(state->flashMode != LIGHT_FLASH_NONE){
write_string(RED_LED_FILE_TRIGGER,"trigger");
write_string(GREEN_LED_FILE_TRIGGER,"trigger");
write_string(BLUE_LED_FILE_TRIGGER,"trigger");
write_int(RED_LED_FILR_DELAYON,delayOn);
write_int(GREEN_LED_FILR_DELAYON,delayOn);
write_int(BLUE_LED_FILR_DELAYON,delayOn);
write_int(RED_LED_FILR_DELAYOFF,delayOff);
write_int(GREEN_LED_FILR_DELAYOFF,delayOff);
write_int(BLUE_LED_FILR_DELAYOFF,delayOff);
}else{
write_string(RED_LED_FILE_TRIGGER,"none");
write_string(GREEN_LED_FILE_TRIGGER,"none");
write_string(BLUE_LED_FILE_TRIGGER,"none");
}
write_int(RED_LED_FILE,r);
write_int(GREEN_LED_FILE,g);
write_int(BLUE_LED_FILE,b)
}
static void handle_shared_battery_locked(struct light_device_t *dev){
if(is_lit(&g_notification)){//优先设置通知灯
set_shared_light_locked(dev,&g_notification);
}else{
set_shared_light_locked(dev,&g_battery);
}
}
static int set_light_battery((struct light_device_t *dev,struct light_state_t *state){
pthread_mutex_lock(&g_lock);
g_battery = *state;
handle_shared_battery_locked(dev);
pthread_mutex_unlock(&g_lock);
return 0;
}
static int set_light_notifications((struct light_device_t *dev,struct light_state_t *state){
pthread_mutex_lock(&g_lock);
g_notification = *state;
handle_shared_battery_locked(dev);
pthread_mutex_unlock(&g_lock);
return 0;
}
void init_globals(){
pthread_mutex_init(&g_lock,NULL);
}
static int close_lights(struct light_device_t* dev){
}
static int open_lights(const struct hw_module_t *module,const char *name,struct hw_device_t **device)
{
int (*set_light)(struct light_device_t* dev,struct light_state_t const *state);
if(0 == strcmp(LIGHT_ID_BACKLIGHT,name))
set_light = set_light_backlight;
}else if(0 == strcmp(LIGHT_ID_BATTERY,name))
set_light = set_light_battery;
}else if(0 == strcmp(LIGHT_ID_NOTIFICATIONS,name))
set_light = set_light_notifications;
}else{
return -EINVAL;
}
pthread_once(&g_init,init_globals);
struct light_device_t *dev = malloc(sizeof(struct light_device_t),GPKERNEL);
memset(dev,0,sizeof(*dev));
dev->common.tag = HARDWARE_DEVICE_TAG;
dev->common.version = 0;
dev->common.module = (struct hw_module_t *)module;
dev->common.close = (int (*)(struct hw_device_t *))close_lights;
dev->set_light = set_light;
*device = (struct hw_device_t*)dev;
return 0;
*device = &led_dev //led_dev 的第一个成员就是hw_device_t ,他们地址一样
}
static struct hw_module_methods_t lights_module_methods {
.open = open_lights,
};
struct hw_module_t HAL_MODULE_INFO_SYM = {
.tag = HARDWARE_MODULE_TAG,
.version_major = 1,
.version_minor = 0,
.id = LIGHTS_HARDWARE_MODULE_ID,
.name ="Snoy_lights_module",
.methods = lights_module_methods ;
}
在lights.c下添加Android.mk
Android.mk内容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := lights.tiny4412;
LOCAL_MODULE_RELATIVE_PATH :=hw //指定了so存在的目录在/system/lib/hw下
LOCAL_C_INCLUDES := hardware/libhardware //头文件
LOCAL__SRC_FILES := lights.c //源文件
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_MODULE_TAGS := eng
include $(BUILD_SHARED_LIBRARY)
上传HAL:lights.c
hardware/libhardware/modules/lights/lights.c
hardware/libhardware/modules/lights/Android.mk
修改:
vi vendor friendly-arm/tiny4412/device-tiny4412.mk
注释掉device-tiny4412.mk里面的(应该是去掉厂家提供的HAL)
ifeq ($(BOARD_USES_PWMLIGHTS),false)
#PRODUCT_COPY_FILES +=\
# $(VENDOR_PATH)/proprietary/lights.tiny4412.so:system/lib/hw/lights.tiny4412.so
endif
编译:
.setenv//先设置环境变量
lunch//执行后选择23 full_tiny4412_eng 这里的eng对应的Android.mk里面设置的eng
mmm hardware/libhardware/modules/lights -B //强制编译C库
make snod
./gen-img.sh
对比下厂家提供HAL和我们自己生成的HAL,会发现不一样,同时该命令也能确保我们提供的lights.c已经编进system.img
diff vendor/friendly-arm/tiny4412/proprietary/lights.tiny4412.so out/target/product/tiny4412/system/lib/hw/lights.tiny4412.so
更新system.img 和上一节中得到的zImage
8.3 Android灯光系统_编写HAL_lights.c的更多相关文章
- Android灯光系统_编写HAL_lights.c【转】
本文转载自:https://blog.csdn.net/qq_33443989/article/details/77074411 1>. 编写灯光系统的HAL层 之 HAL_light.c1&l ...
- 8.1 Android灯光系统_总体框架
1.框架 APP(java语言实现) ------------------------------- JNI(c++语言实现) 向上提供Java执行c函数的接口 向下访问HAL ------ ...
- 8.6 Android灯光系统_源码分析_背光灯
Change system screen brightness, using android.provider.Settings.System.SCREEN_BRIGHTNESSandroid-er. ...
- 8.5 Android灯光系统_源码分析_通知灯
参考文章(应用程序举例)how to use the LED with Android phonehttp://androidblogger.blogspot.jp/2009/09/tutorial- ...
- 8.4 Android灯光系统_源码分析_电池灯
电池灯的Java代码在batteryservice.java中 电池的状态电量等信息由驱动获得,但驱动不会主动做这些事情,因此肯定有个App调用驱动程序读取电池信息,称这个App为A应用. 还有个Ap ...
- Android系统--灯光系统驱动编写
Android系统开发--Android灯光系统tiny4412_led_class驱动编写 框架分析 led_classdev_4412结构体 创建led_classdev_4412结构体 分配结构 ...
- Android灯光系统--通知灯深入分析【转】
本文转自:https://www.cnblogs.com/lkq1220/p/6406261.html Android灯光系统--通知灯深入分析 通知的类别 声音 振动 闪灯 APP如何发出通知灯请求 ...
- Android灯光系统--通知灯深入分析
Android灯光系统--通知灯深入分析 通知的类别 声音 振动 闪灯 APP如何发出通知灯请求 getSystemService(获得通知服务) 构造notification 类别 其他参数(颜色, ...
- Android灯光系统--深入理解背光灯
Android灯光系统--深入理解背光灯 一.怎么控制背光灯(简述) APP将亮度值写入数据库 线程检测数据库的值是否发生变化 这种机制成为"内容观察者"--contentObse ...
随机推荐
- html5中的容器标签和文本标签
html5中的容器标签和文本标签 html中的容器级标签和文本级标签,css中的块级元素和行内元素是我们常常拿来比较的四个名词(行内块级暂时先不考虑). 容器标签 容器级的标签可以简单的理解为能嵌套其 ...
- vue --- 全局守卫
vue2.0 实现导航守卫(路由守卫) 路由跳转前做一些验证,比如登录验证,是网站中的普遍需求. 对此,vue-route 提供的 beforeRouteUpdate 可以方便地实现导航守卫(navi ...
- 71.lambda表达式的递归
#include <iostream> #include <functional> using namespace std; void main() { //&调用外部 ...
- 搭建Spark源码研读和代码调试的开发环境
转载自https://github.com/linbojin/spark-notes/blob/master/ide-setup.md 搭建Spark源码研读和代码调试的开发环境 工欲善其事,必先利其 ...
- 源码安装 ipython
https://blog.csdn.net/huobanjishijian/article/details/51470898
- android图像处理系列之五--给图片添加边框(中)
前面一篇讲到给图片加边框的方式,只能给图片加一些有规则的边框,如果想加一些比较精美的效果,就有点麻烦了.下面就给出解决这个问题的思路. 思路是:一些比较精美的花边图片我们是很难用代码控制,就目前本人水 ...
- 最小生成树(MST,minimum spanning tree)
生成树:由图生成的树,由图转化为树,进一步可用对树的相关操作来对图进行操作.最小指的是权值最小: 生成树是边的集合,如下图所示的最小生成树:MST={{a,b},{a,f},{f,c}} 本文主要探讨 ...
- 39.mutex 的lock_guard与unique_lock
#include <iostream> #include <thread> #include <mutex> using namespace std; #defin ...
- C#解析HTML源码
刚做了一个小任务,需要抓取其他网站的部分数据,这里就顺便介绍使用Winista.Text.HtmlParser这个类库如何解析HTML并抓取部分数据 1.获取指定网站的页面源码 string url ...
- element-UI 表单校验失效处理
1.el-form-item 的 prop属性绑定的要是字符串: eg: :prop="'answer[' + 0 + ']' " //而不是 :prop=&qu ...