第1课第4.4节_Android硬件访问服务编写HAL代码

天下之事常成于困约,而败于奢靡。这篇文章主要讲述第1课第4.4节_Android硬件访问服务编写HAL代码相关的知识,希望能为你提供帮助。

4 编写HAL代码
源码下载方法
第一次:
git clone https://github.com/weidongshan/SYS_0001_LEDDemo.git
更新:
git pull origin
取出指定版本:
git checkout v1// 有JNI没有HAL
git checkout v2// 有JNI,HAL
git checkout v3// add MODULE TAG, DEVICE TAG

第1课第4.4节_Android硬件访问服务编写HAL代码

文章图片

第1课第4.4节_Android硬件访问服务编写HAL代码

文章图片

 
 
JNI 向上提供本地函数, 向下加载HAL文件并调用HAL的函数
HAL 负责访问驱动程序执行硬件操作
dlopen
external\\chromium_org\\third_party\\hwcplus\\src\\hardware.c   (参考代码)
hw_get_module("led")
1. 模块名==> 文件名
hw_get_module_by_class("led", NULL)
name = "led"
property_getxxx是某个属性
hw_module_exists 判断是否存在led.xxx.so



它用来判断"name"."subname".so文件是否存在
查找的目录:
a. HAL_LIBRARY_PATH 环境变量
第1课第4.4节_Android硬件访问服务编写HAL代码

文章图片

b. /vendor/lib/hw
c. /system/lib/hw
第1课第4.4节_Android硬件访问服务编写HAL代码

文章图片

 
 
第1课第4.4节_Android硬件访问服务编写HAL代码

文章图片

 
  /vendor/lib/hw 这个目录下没有文件,tiny4412所以只能去/system/lib/hw这个目录下找
第1课第4.4节_Android硬件访问服务编写HAL代码

文章图片

 
 
第1课第4.4节_Android硬件访问服务编写HAL代码

文章图片

 
2. 加载
load
dlopen(filename)
dlsym("HMI") 从SO文件中获得名为HMI的hw_module_t结构体
strcmp(id, hmi-> id) 判断名字是否一致(hmi-> id, "led")

 
V2:
(3) JNI: 重新上传
frameworks/base/services/core/jni/com_android_server_LedService.cpp
(4) HAL: led_hal.h
led_hal.c
把新文件上传到服务器, 所在目录:
hardware/libhardware/include/hardware/led_hal.h
 
hardware/libhardware/modules 在这个目录下创建一个目录led,放入led_hal.c和自己写一个Android.mk
hardware/libhardware/modules/led/led_hal.c
hardware/libhardware/modules/led/Android.mk
Android.mk内容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := led.default
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_C_INCLUDES := hardware/libhardware
LOCAL_SRC_FILES := led_hal.c
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_MODULE_TAGS := eng
include $(BUILD_SHARED_LIBRARY)

编译:
第1课第4.4节_Android硬件访问服务编写HAL代码

文章图片

$ mmm frameworks/base/services
$ mmm hardware/libhardware/modules/led
$ make snod
$ ./gen-img.sh
 
第1课第4.4节_Android硬件访问服务编写HAL代码

文章图片

最终生成system.img文件

打印信息简介:
a. 有三类打印信息: app, system, radio
程序里使用 ALOGx, SLOGx, RLOGx来打印
b. x表示6种打印级别,有:
V     Verbose
D     Debug
I     Info
W   Warn
E     Error
F     Fatal
比如:
#define LOG_TAG "LedHal"
ALOGI("led_open : %d", fd);
c. 打印出来的格式为:
I/LedHal( 1987): led_open : 65
(级别) LOG_TAG进程号打印信息
d. 使用 logcat 命令查看
logcat LedHal:I *:S
选出自己感兴趣的信息:
第1课第4.4节_Android硬件访问服务编写HAL代码

文章图片

 
和上一个章节相比,主要修改了
com_android_server_LedService.cpp
添加了led_hal.h     led_hal.c   Android.mk
 
  com_android_server_LedService.cpp
#define LOG_TAG "LedService"#include "jni.h" #include "JNIHelp.h" #include "android_runtime/AndroidRuntime.h"#include < utils/misc.h> #include < utils/Log.h> #include < stdio.h> #include < stdlib.h> #include < sys/types.h> #include < sys/stat.h> #include < fcntl.h> #include < sys/ioctl.h> #include < hardware/led_hal.h> namespace android {static led_device_t* led_device; jint ledOpen(JNIEnv *env, jobject cls) { jint err; hw_module_t* module; hw_device_t* device; ALOGI("native ledOpen ..."); /* 1. hw_get_module */ err = hw_get_module("led", (hw_module_t const**)& module); if (err == 0) { /* 2. get device : module-> methods-> open */ err = module-> methods-> open(module, NULL, & device); if (err == 0) { /* 3. call led_open */ led_device = (led_device_t *)device; return led_device-> led_open(led_device); } else { return -1; } }return -1; }void ledClose(JNIEnv *env, jobject cls) { //ALOGI("native ledClose ..."); //close(fd); }jint ledCtrl(JNIEnv *env, jobject cls, jint which, jint status) { ALOGI("native ledCtrl %d, %d", which, status); return led_device-> led_ctrl(led_device, which, status); }static const JNINativeMethod methods[] = { {"native_ledOpen", "()I", (void *)ledOpen}, {"native_ledClose", "()V", (void *)ledClose}, {"native_ledCtrl", "(II)I", (void *)ledCtrl}, }; int register_android_server_LedService(JNIEnv *env) { return jniRegisterNativeMethods(env, "com/android/server/LedService", methods, NELEM(methods)); }}

 
led_hal.c
#define LOG_TAG "LedHal"/* 1. 实现一个名为HMI的hw_module_t结构体 *//* 2. 实现一个open函数, 它返回led_device_t结构体 *//* 3. 实现led_device_t结构体 *//* 参考 hardware\\libhardware\\modules\\vibrator\\vibrator.c */#include < hardware/vibrator.h> #include < hardware/hardware.h> #include < cutils/log.h> #include < stdio.h> #include < unistd.h> #include < fcntl.h> #include < errno.h> #include < hardware/led_hal.h> #include < stdlib.h> #include < sys/types.h> #include < sys/stat.h> #include < fcntl.h> #include < sys/ioctl.h> #include < utils/Log.h> static int fd; /** Close this device */ static int led_close(struct hw_device_t* device) { close(fd); return 0; }static int led_open(struct led_device_t* dev) { fd = open("/dev/leds", O_RDWR); ALOGI("led_open : %d", fd); if (fd > = 0) return 0; else return -1; }static int led_ctrl(struct led_device_t* dev, int which, int status) { int ret = ioctl(fd, status, which); ALOGI("led_ctrl : %d, %d, %d", which, status, ret); return ret; }static struct led_device_t led_dev = { .common = { .tag= HARDWARE_DEVICE_TAG, .close = led_close, }, .led_open= led_open, .led_ctrl= led_ctrl, }; static int led_device_open(const struct hw_module_t* module, const char* id, struct hw_device_t** device) { *device = & led_dev; return 0; }static struct hw_module_methods_t led_module_methods = { .open = led_device_open, }; struct hw_module_t HAL_MODULE_INFO_SYM = { .tag = HARDWARE_MODULE_TAG, .id = "led", .methods = & led_module_methods, };

 
led_hal.h
#ifndef ANDROID_LED_INTERFACE_H #define ANDROID_LED_INTERFACE_H#include < stdint.h> #include < sys/cdefs.h> #include < sys/types.h> #include < hardware/hardware.h> __BEGIN_DECLSstruct led_device_t { struct hw_device_t common; int (*led_open)(struct led_device_t* dev); int (*led_ctrl)(struct led_device_t* dev, int which, int status); }; __END_DECLS#endif// ANDROID_LED_INTERFACE_H

【第1课第4.4节_Android硬件访问服务编写HAL代码】 



























































    推荐阅读