
本文转载自:
首先别人的APP要能直接访问到你写的硬件或者不经过任何修改的APP能直接使用你的驱动,就需要使用系统自带的JNI,所以我们需要写出符合系统自带JNI文件的HAL文件和驱动程序,下面具体分析一个这个HAL和驱动程序需要实现什么。
灯光系统由以下四个文件组成
APP:电池灯APP,通知灯APP,背光灯APP
JNI :com_android_server_lights_LightsService.cpp
HAL:我们自己实现,实现一个lights.c
驱动:leds_nanopi3.c(JNI需要什么这里就给它提供什么,这里我们实现亮灭闪烁和亮度)
灯光系统的主要功能:
硬件上是属于同一个的有(包括颜色和闪烁):
电池灯:电池电量发生变化时颜色会发生变化
通知灯:有通知会闪烁,比如未接电话或短信
调节LCD亮度:
背光灯
驱动部分:
JNI:
com_android_server_lights_LightsService.cpp(不需要我们实现,但我们需要给它提供接口)
里面需要获得hw_module_t结构体,所以我们的HAL需要实现这个结构体
JNI里面的get_device会根据不同的名字调用module->methods->open返回不同的light_device_t结构体,这个结构体里面带有set_light,即不同灯的控制函数
*********************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 "notifications"
#define LIGHT_ID_ATTENTION "attention"
1
2
3
4
5
6
7
8
这里我们只实现LIGHT_ID_BACKLIGHT(背光)、LIGHT_ID_BATTERY(电池)、LIGHT_ID_NOTIFICATIONS(通知)
HAL:
把硬件LED再次划分为不同的逻辑灯
1. 实现hw_module_t结构体
2. 实现open函数,它会根据name返回不同的light_device_t结构体
3. 针对不同的灯(背光/电池/通知),实现对应的set_light函数
struct light_device_t {
struct hw_device_t common;
int (*set_light)(struct light_device_t* dev,
struct light_state_t const* state);
};
1
2
3
4
5
这里需实现三个set_light函数
set_light_battery (struct light_device_t *dev, struct light_state_t const* state)
set_light_notifications (struct light_device_t *dev, struct light_state_t const* state)
set_light_backlight (struct light_device_t *dev, struct light_state_t const *state)
1
2
3
通过这些函数里面操作驱动程序
驱动程序:
1. 对于RGB三个LED,实现亮灭闪烁三个功能
2. 对于背光灯,设置PWM
总结:
我们只需要实现一个HAL和一个驱动程序,HAL里面我们只需要实现hw_module_t结构体和一个open函数,open函数根据传进来的不同的name构造不同的light_device_t结构体,最后指向不同的set_light函数操作驱动程序,下一章具体实现这些代码。