赞
踩
1.HIDL 介绍
HIDL(HAL interface definition language),HAL 接口定义语言是用于指定 HAL 层和其用户之间的
接口的一种接口描述语言(IDL)。HIDL 允许指定类型和方法调用。从更广泛的意义上来说,HIDL
是用于在独立编程的代码库之间通信的系统。
https://source.android.com/devices/architecture/hidl
2.实现自己的一个HIDL
本文以LED为例在aosp上添加HIDL,以熟悉整个过程。
在hardware/interfaces/目录下创建led文件夹和基版本1.0,这个版本号分为两部分,major.minor。
major版本不变得话,只能添加api,不能修改。
创建ILed.hal和types.hal
hardware/interfaces/led/1.0/ILed.hal
- package android.hardware.led@1.0;
-
- interface ILed
- {
- //get led status
- get() generates (LedStatus result);
-
-
- //set led status
- set(LedStatus val) generates(int32_t ret);
-
- getBrightnessRange() generates(bool ret,BrightnessRange range);
-
- setBrightnessValue(vec<int32_t> range) generates(bool ret);
-
- on() ;
-
- off() ;
-
- };
然后我们需要的一些变量以及结构体的定义放到
hardware/interfaces/led/1.0/types.hal
- package android.hardware.led@1.0;
-
-
- enum LedStatus : uint32_t {
- LED_ON,
- LED_OFF,
- LED_BAD_VALUE,
- };
-
-
- struct BrightnessRange {
- uint32_t min;
-
- uint32_t max;
- };
当我们创建完以上的文件以后就需要下一步的自动代码生成了:
添加完后,执行hardware/interfaces/update-makefiles.sh 会自动生成编译编译脚本,然后在
hardware/interfaces/led/1.0/ 路径下执行mm,会生成所需要得hidl库,接下来我们需要实现hidl
interface,供client调用。
3.实现Hidl Interface
首先实现ILed interface的子类ledImpl 得头文件和对应得cpp。
hardware/interfaces/led/1.0/default/ledImpl.h
- #ifndef ANDROID_HARDWARE_LED_V1_0_LED_H
- #define ANDROID_HARDWARE_LED_V1_0_LED_H
- #include <android/hardware/led/1.0/ILed.h>
-
- #include <hidl/Status.h>
-
- #include <hidl/MQDescriptor.h>
-
-
-
-
- namespace android {
- namespace hardware {
- namespace led {
- namespace V1_0 {
- namespace implementation {
-
- using ::android::hardware::led::V1_0::LedStatus;
- using ::android::hardware::led::V1_0::BrightnessRange;
- using ::android::hardware::led::V1_0::ILed;
- using ::android::hardware::hidl_array;
- using ::android::hardware::hidl_string;
- using ::android::hardware::hidl_vec;
- using ::android::hardware::Return;
- using ::android::hardware::Void;
- using ::android::sp;
-
-
- struct ledImpl : public ILed {
- public:
- ledImpl();
- Return<LedStatus> get() override ;
- Return<int32_t> set(LedStatus val) override;
- Return<void> on() override;
- Return<void> off() override;
- Return<void> getBrightnessRange(getBrightnessRange_cb _hidl_cb) override;
- Return<bool> setBrightnessValue(const hidl_vec<int32_t>& range) override;
- private:
- LedStatus state;
- };
-
- extern "C" ILed* HIDL_FETCH_ILed(const char* name);
- } // namespace implementation
- } // namespace V1_0
- } // namespace led
- } // namespace hardware
- } // namespace android
-
- #endif //ANDROID_HARDWARE_LED_V1_0_LED_H
hardware/interfaces/led/1.0/default/ledImpl.cpp
- #define LOG_TAG "LedService"
-
- #include <log/log.h>
- #include "ledImpl.h"
-
- namespace android {
- namespace hardware {
- namespace led {
- namespace V1_0 {
- namespace implementation {
-
- ledImpl::ledImpl() {
- state = LedStatus::LED_BAD_VALUE;
- ALOGE("ledImpl Init status:%d", state);
- }
-
- Return<void> ledImpl::on() {
- state = LedStatus::LED_ON;
- ALOGE("ledImpl on status:%d", state);
- return Void();
- }
-
- Return<void> ledImpl::off() {
- state = LedStatus::LED_OFF;
- ALOGE("ledImpl off status:%d", state);
- return Void();
- }
-
- Return<LedStatus> ledImpl::get() {
- return state;
- }
- Return<int32_t> ledImpl::set(LedStatus val) {
- if(val == LedStatus::LED_OFF || val == LedStatus::LED_ON)
- state = val;
- else
- return -1;
- return 0;
- }
-
- Return<void> ledImpl::getBrightnessRange(getBrightnessRange_cb _hidl_cb)
- {
- ALOGE("ledImpl getBrightnessRange ");
- BrightnessRange range;
- range.max = 100;
- range.min = 1;
- _hidl_cb(true,range);
- return Void();
-
- }
-
- Return<bool> ledImpl::setBrightnessValue(const hidl_vec<int32_t>& range)
- {
- ALOGE("ledImpl getBrightnessValue ");
- auto iter = range.begin();
- ALOGE("ledImpl getBrightnessValue range.begin: %d",*iter);
- iter = range.end();
- ALOGE("ledImpl getBrightnessValue range.end: %d",*iter);
- ALOGE("ledImpl getBrightnessValue range.size: %zu",range.size());
- return true;
- }
-
- ILed* HIDL_FETCH_ILed(const char * /*name*/) {
- ALOGE("ledImpl HIDL_FETCH_ILed ");
- return new ledImpl();
- }
-
- } // namespace implementation
- } // namespace V1_0
- } // namespace led
- } // namespace hardware
- } // namespace android
hardware/interfaces/led/1.0/default/Android.bp
- cc_library_shared {
- name: "android.hardware.led@1.0-impl",
- defaults: ["hidl_defaults"],
- srcs: ["ledImpl.cpp"],
- shared_libs: [
- "libhidlbase",
- "libhidltransport",
- "libhardware",
- "liblog",
- "libutils",
- "android.hardware.led@1.0",
- ],
- }
-
- cc_binary {
- name: "android.hardware.led@1.0-service",
- init_rc: ["android.hardware.led@1.0-service.rc"],
- srcs: ["service.cpp",
- "ledImpl.cpp"],
-
- shared_libs: [
- "liblog",
- "libhardware",
- "libhidlbase",
- "libhidltransport",
- "libutils",
- "android.hardware.led@1.0",
- ],
-
- }
4.编写hdil service
接下来,使用相应功能填写存根并设置守护进程。可以使用passthrough方式和binder方式,示
例:hardware/interfaces/led/1.0/default/service.cpp
-
- #define LOG_TAG "android.hardware.led@1.0-service"
-
- #include <android/hardware/led/1.0/ILed.h>
- #include <hidl/LegacySupport.h>
- #include "ledImpl.h"
- using android::hardware::led::V1_0::ILed;
- using android::hardware::led::V1_0::implementation::ledImpl;
- using android::hardware::defaultPassthroughServiceImplementation;
- using android::hardware::configureRpcThreadpool;
- using android::hardware::joinRpcThreadpool;
- using android::sp;
-
-
- int main() {
- #if 0
- // Passthrough dlopen so方式
- return defaultPassthroughServiceImplementation<Iled>();
- #else
- // Binder 方式
- sp<ILed> service = new ledImpl();
- configureRpcThreadpool(1, true /*callerWillJoin*/);
- if(android::OK != service->registerAsService())
- return 1;
- joinRpcThreadpool();
- #endif
- }
5.配置manifest.xml
add the code to the manifest.xm 以至于hwservicemanager 查找到指定的hidl service
About HIDL configures
device/<vendorxxx>/<devicexxx>/manifest.xml
- <hal format="hidl">
- <name>android.hardware.led</name>
- <transport>hwbinder</transport> //hwbinder 或者passthrough (直通模式)
- <version>1.0</version>
- <interface>
- <name>ILed</name>
- <instance>default</instance>
- </interface>
- </hal>
5.hidl client端调用
实现C++ 调用hidl service的例子:首先将 HAL 库添加到 makefile 中
- Make:LOCAL_SHARED_LIBRARIES += android.hardware.led@1.0
- Soong:shared_libs: [ …, android.hardware.led@1.0 ]
接下来,添加 HAL 头文件:
- #include <android/hardware/led/1.0/ILed.h>
- …
- // in code:
- sp<ILed> client = ILed::getService();
- client->on();
下面是我的Demo clinet
- #define LOG_TAG "LED_CLINET"
- #include <android/hardware/led/1.0/ILed.h>
- #include <log/log.h>
-
- using android::hardware::led::V1_0::ILed;
- using android::hardware::led::V1_0::LedStatus;
- using android::hardware::led::V1_0::BrightnessRange;
- using android::hardware::hidl_vec;
- using android::sp;
-
-
- int main(){
- // BrightnessRange range;
- sp<ILed> service = ILed::getService();
- if( service == nullptr ){
- ALOGE("Can't find ILed service...");
- return -1;
- }
- ALOGE("ILed ON");
- service->on();
-
- ALOGE("ILed OFF");
- service->off();
-
- ALOGE("ILed set");
- service->set(LedStatus::LED_ON);
-
- ALOGE("ILed get");
- LedStatus ret = service->get();
- ALOGE("ILed get: %d",ret);
-
- service->getBrightnessRange([](bool ret1,BrightnessRange range){
- ALOGE("ILed getBrightnessRange ret: %d",ret1);
- ALOGE("ILed getBrightnessRange Max: %d",range.max);
- ALOGE("ILed getBrightnessRange Min: %d",range.min);
- });
- int32_t array[] = {5, 6, 7};
- hidl_vec<int32_t> hv1 = std::vector<int32_t>(array, array + 3);
- bool ret2 = service->setBrightnessValue(hv1);
- ALOGE("ILed getBrightnessValue bool: %d",ret2);
- return 0;
- }
参考:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。