1、android 系统-背光模块1,总论背光模块属于 HAL 层开发, HAL 层开发,用一句话来概括就是定义一个 hardware.h 中定义的名称为宏 HAL_MODULE_INFO_SYM 的 hw_module_t 结构体,然后实现结构体的相关内容2,驱动方面的准备简单的嵌入式 linux 驱动,编写 LCD 背光驱动,并提供接口给上层修改,我所用的是直接修改接口文件,接口如下:/sys/class/backlight/pwm-backlight/brightness 这个是亮度调节/sys/class/backlight/pwm-backlight/max_brightness 这个是
2、最大亮度,按照 android 系统的要求应该设置成 255控制亮度直接写 brightness 文件即可背光驱动主要是通过 PWM 来完成,这里不详细说明。3,需要包含的头文件/hardware/libhardware/include/hardware 目录下的 hardware.h 和 lights.h其中 hardware.h 中定义了通用硬件模块,lights.h 中定义了背光设备相关的内容4,android 已有的硬件模块在 /hardware/libhardware/modules 目录下,为了区分,我们开发的背光模块放置在如下的目录:vendor/ardent/merlin/li
3、ghts 目录下,编译成 lights.default.so 放置到/system/lib/hw 目录下,模块命名规则可以参考上一节的内容。5,修改 vendor/ardent/merlin 目录下 AndroidBoard.mk 文件,添加如下内容:include $(LOCAL_PATH)/lights/Mdroid.mk6,lights 目录新建 Mdroid.mk 文件,内容如下:LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hwLO
4、CAL_SRC_FILES:= lights.cLOCAL_SHARED_LIBRARIES := libutils libcutils libhardwareLOCAL_PRELINK_MODULE := falseLOCAL_MODULE := lights.defaultinclude $(BUILD_SHARED_LIBRARY)7,lights 目录下新建一个 lights.c 文件,如下:const struct hw_module_t HAL_MODULE_INFO_SYM = .tag = HARDWARE_MODULE_TAG,.version_major = 1,.vers
5、ion_minor = 0,.id = LIGHTS_HARDWARE_MODULE_ID,.name = “lights module“,.author = “allen“,.methods = NULL,;8,上面的内容可以直接编译通过,但是因为我将其 methods 部分指向了空指针,因此没有任何功能,下面来实现此部分hw_module_t 机构体的 methods 成员是一个指向 hw_module_methods_t 结构体的一个指针,hw_module_methods_t 结构体定义如下:typedef struct hw_module_methods_t int (*open)(
6、const struct hw_module_t* module, const char* id,struct hw_device_t* device); hw_module_methods_t;据此我们定义一个 hw_module_methods_t 类型的参数 lights_module_methods 如下:struct hw_module_methods_t lights_module_methods = .open = lights_device_open;然后将上面的 methods 由 NULL 改成 lights_module_methods9,接下来就是定义 lights_d
7、evice_open 函数了,此函数的参数和返回值由hw_module_methods_t 结构体的 open 成员决定,此函数定义如下:static int lights_device_open(const struct hw_module_t *module,const char *id, struct hw_device_t *device)从 lights_device_open 函数的参数来看,第一个参数和第二个参数是常量,第三个参数是 一个指向 hw_device_t 结构体的指针,因此可以断定实现此函数也就是要完成第三个参数的内容,详细的内容我们可以参考直接调用该函数的内容,在
8、frameworks/base/services/jni 目录下的com_android_server_LightsService.cpp 文件中,内容如下:static light_device_t* get_device(hw_module_t* module, char const* name)int err;hw_device_t* device;err = module-methods-open(module, name, if (err = 0) return (light_device_t*)device;/device 由 hw_device_t 指针强制转换成 light_d
9、evice_t指针 else return NULL;static jint init_native(JNIEnv *env, jobject clazz)int err;hw_module_t* module;Devices* devices;devices = (Devices*)malloc(sizeof(Devices);err = hw_get_module(LIGHTS_HARDWARE_MODULE_ID, (hw_module_t const*)if (err = 0) devices-lightsLIGHT_INDEX_BACKLIGHT= get_device(module
10、, LIGHT_ID_BACKLIGHT);devices-lightsLIGHT_INDEX_KEYBOARD= get_device(module, LIGHT_ID_KEYBOARD);devices-lightsLIGHT_INDEX_BUTTONS= get_device(module, LIGHT_ID_BUTTONS);devices-lightsLIGHT_INDEX_BATTERY= get_device(module, LIGHT_ID_BATTERY);devices-lightsLIGHT_INDEX_NOTIFICATIONS= get_device(module,
11、LIGHT_ID_NOTIFICATIONS);devices-lightsLIGHT_INDEX_ATTENTION= get_device(module, LIGHT_ID_ATTENTION);devices-lightsLIGHT_INDEX_BLUETOOTH= get_device(module, LIGHT_ID_BLUETOOTH);devices-lightsLIGHT_INDEX_WIFI= get_device(module, LIGHT_ID_WIFI); else memset(devices, 0, sizeof(Devices);return (jint)devi
12、ces;从上面的内容我们可以看出 lights_device_open 的第一个参数是 JNI 层用 hw_get_module 所获得,第二个参数根据设备的不同有很多种情况该参数的内容定义在 lights.h 中,全部情况如下:#define LIGHT_ID_BACKLIGHT “backlight“#define LIGHT_ID_KEYBOARD “keyboard“#define LIGHT_ID_BUTTONS “buttons“#define LIGHT_ID_BATTERY “battery“#define LIGHT_ID_NOTIFICATIONS “notificatio
13、ns“#define LIGHT_ID_ATTENTION “attention“#define LIGHT_ID_BLUETOOTH “bluetooth“#define LIGHT_ID_WIFI “wifi“lights 调节有背光,键盘,按键,电池,通知,提醒,蓝牙和 WIF第三个参数是一个指向一个 hw_device_t 的指针,但是com_android_server_LightsService.cpp 文件中的背光调节函数定义如下:static void setLight_native(JNIEnv *env, jobject clazz, int ptr,int light,
14、int colorARGB, int flashMode, int onMS, int offMS, int brightnessMode)Devices* devices = (Devices*)ptr;light_state_t state;if (light = LIGHT_COUNT | devices-lightslight = NULL) return ;memset(state.color = colorARGB;state.flashMode = flashMode;state.flashOnMS = onMS;state.flashOffMS = offMS;state.br
15、ightnessMode = brightnessMode;devices-lightslight-set_light(devices-lightslight, get_device 函数中将 hw_device_t 指针强制转换成 light_device_t 指针给调节背光用,而light_device_t 定义如下:struct light_device_t struct hw_device_t common;int (*set_light)(struct light_device_t* dev,struct light_state_t const* state);因此在实现 light
16、s_device_open 的第三个参数的时候,我们应该定义一个 light_device_t 类型结构体,然后将起 common 域的指针地址传递过去。这样虽然传递的是一个 hw_device_t 指针地址,但是 JNI 层可以将其强制转换成 light_device_t 指针地址用,否则 devices-lightslight-set_light 就会起不到作用了。实现如下:static int lights_device_open(const struct hw_module_t *module,const char *id, struct hw_device_t *device)str
17、uct light_device_t *dev = NULL;int resvalue = -1;dev = calloc(sizeof(struct light_device_t),1);dev-common.tag = HARDWARE_DEVICE_TAG;dev-common.version = 0;dev-common.module = (struct hw_module_t *)module;dev-common.close = lights_device_close;if(!strcmp(id, LIGHT_ID_BACKLIGHT)dev-set_light = lcd_set
18、_light;resvalue = 0;elsedev-set_light = other_set_light;resvalue = 0;*device = return resvalue;10,实现 lights_device_close,lcd_set_light 和 other_set_light,这个主要是调用驱动提供的接口直接控制硬件,举例如下:static int lights_device_close(struct hw_device_t* device)struct light_device_t *m_device = (struct light_device_t *)devi
19、ce;if(m_device)free(m_device);return 0;static int lcd_set_light(struct light_device_t* dev,struct light_state_t const* state)int fd = -1;int bytes = 0;int rlt = -1;unsigned char brightness = (77*(state-color16)fd = open(“/sys/class/backlight/pwm-backlight/brightness“, O_RDWR);if(fd0)char buffer20;me
20、mset(buffer, 0, 20);bytes = sprintf(buffer, “%d“, brightness);rlt = write(fd, buffer, bytes);if(rlt0)close(fd);return 0;close(fd);return -1;static int other_set_light(struct light_device_t* dev,struct light_state_t const* state)return 0;11,因为上面调节背光是通过写/sys/class/backlight/pwm-backlight/brightness 文件
21、来完成,因此一定要设置该文件的权限,在 init.xxx.rc 文件中添加如下的内容:# for control LCD backlightchown system system /sys/class/backlight/pwm-backlight/brightnesschmod 0666 /sys/class/backlight/pwm-backlight/brightness12,修改完成后经验证亮度调节可用,上面的例子只是实现了 lights 部分功能,如果需要完成所有的功能,请参考 hardware.h, lights.h 和 com_android_server_LightsService.cpp 文件中的内容。