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

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

android应用如何访问C库 - 落魄影子 - 博客频道 - CSDN.NET  http://blog.csdn.net/ab198604/article/details/51249303

Android硬件访问服务框架代码编写 - 落魄影子 - 博客频道 - CSDN.NET  http://blog.csdn.net/ab198604/article/details/51397586

 



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

 

 

JNI 向上提供本地函数, 向下加载HAL文件并调用HAL的函数

HAL 负责访问驱动程序执行硬件操作

dlopen

externalchromium_org hird_partyhwcplussrchardware.c   (参考代码)

hw_get_module("led")

1. 模块名==>文件名

hw_get_module_by_class("led", NULL)

name = "led"

property_get xxx是某个属性

hw_module_exists 判断是否存在led.xxx.so





它用来判断"name"."subname".so文件是否存在

查找的目录:

a. HAL_LIBRARY_PATH 环境变量

b. /vendor/lib/hw

c. /system/lib/hw

 

 

 

 /vendor/lib/hw 这个目录下没有文件,tiny4412所以只能去/system/lib/hw这个目录下找

 

 

 

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)



编译:

$ mmm frameworks/base/services

$ mmm hardware/libhardware/modules/led

$ make snod

$ ./gen-img.sh

 

最终生成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

选出自己感兴趣的信息:

 

和上一个章节相比,主要修改了

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 
#include #include #include 
#include 
#include 
#include 
#include 
#include 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结构体 *//* 参考 hardwarelibhardwaremodulesvibratorvibrator.c*/#include 
#include #include #include 
#include 
#include 
#include #include #include 
#include 
#include 
#include 
#include 
#include 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;elsereturn -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 
#include 
#include #include __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

 

转载于:https://www.cnblogs.com/zhulinhaibao/p/6995461.html

更多相关:

  • 关于点云的分割算是我想做的机械臂抓取中十分重要的俄一部分,所以首先学习如果使用点云库处理我用kinect获取的点云的数据,本例程也是我自己慢慢修改程序并结合官方API 的解说实现的,其中有很多细节如果直接更改源程序,可能会因为数据类型,或者头文件等各种原因编译不过,会导致我们比较难得找出其中的错误,首先我们看一下我自己设定的一个场景,...

  • /* 使用正态分布变换进行配准的实验 。其中room_scan1.pcd room_scan2.pcd这些点云包含同一房间360不同视角的扫描数据 */ #include #include #include #include

  • #include #include #include #include ...

  • #include #include #include #include #include #include...

  • #include #include #include #include int main (int argc,...