当前位置:   article > 正文

Android 之 Binder机制HIDL接口_android hidl接口添加

android hidl接口添加

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

  1. package android.hardware.led@1.0;
  2. interface ILed
  3. {
  4. //get led status
  5. get() generates (LedStatus result);
  6. //set led status
  7. set(LedStatus val) generates(int32_t ret);
  8. getBrightnessRange() generates(bool ret,BrightnessRange range);
  9. setBrightnessValue(vec<int32_t> range) generates(bool ret);
  10. on() ;
  11. off() ;
  12. };

然后我们需要的一些变量以及结构体的定义放到

hardware/interfaces/led/1.0/types.hal

  1. package android.hardware.led@1.0;
  2. enum LedStatus : uint32_t {
  3. LED_ON,
  4. LED_OFF,
  5. LED_BAD_VALUE,
  6. };
  7. struct BrightnessRange {
  8. uint32_t min;
  9. uint32_t max;
  10. };

当我们创建完以上的文件以后就需要下一步的自动代码生成了:

添加完后,执行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

  1. #ifndef ANDROID_HARDWARE_LED_V1_0_LED_H
  2. #define ANDROID_HARDWARE_LED_V1_0_LED_H
  3. #include <android/hardware/led/1.0/ILed.h>
  4. #include <hidl/Status.h>
  5. #include <hidl/MQDescriptor.h>
  6. namespace android {
  7. namespace hardware {
  8. namespace led {
  9. namespace V1_0 {
  10. namespace implementation {
  11. using ::android::hardware::led::V1_0::LedStatus;
  12. using ::android::hardware::led::V1_0::BrightnessRange;
  13. using ::android::hardware::led::V1_0::ILed;
  14. using ::android::hardware::hidl_array;
  15. using ::android::hardware::hidl_string;
  16. using ::android::hardware::hidl_vec;
  17. using ::android::hardware::Return;
  18. using ::android::hardware::Void;
  19. using ::android::sp;
  20. struct ledImpl : public ILed {
  21. public:
  22. ledImpl();
  23. Return<LedStatus> get() override ;
  24. Return<int32_t> set(LedStatus val) override;
  25. Return<void> on() override;
  26. Return<void> off() override;
  27. Return<void> getBrightnessRange(getBrightnessRange_cb _hidl_cb) override;
  28. Return<bool> setBrightnessValue(const hidl_vec<int32_t>& range) override;
  29. private:
  30. LedStatus state;
  31. };
  32. extern "C" ILed* HIDL_FETCH_ILed(const char* name);
  33. } // namespace implementation
  34. } // namespace V1_0
  35. } // namespace led
  36. } // namespace hardware
  37. } // namespace android
  38. #endif //ANDROID_HARDWARE_LED_V1_0_LED_H

hardware/interfaces/led/1.0/default/ledImpl.cpp

  1. #define LOG_TAG "LedService"
  2. #include <log/log.h>
  3. #include "ledImpl.h"
  4. namespace android {
  5. namespace hardware {
  6. namespace led {
  7. namespace V1_0 {
  8. namespace implementation {
  9. ledImpl::ledImpl() {
  10. state = LedStatus::LED_BAD_VALUE;
  11. ALOGE("ledImpl Init status:%d", state);
  12. }
  13. Return<void> ledImpl::on() {
  14. state = LedStatus::LED_ON;
  15. ALOGE("ledImpl on status:%d", state);
  16. return Void();
  17. }
  18. Return<void> ledImpl::off() {
  19. state = LedStatus::LED_OFF;
  20. ALOGE("ledImpl off status:%d", state);
  21. return Void();
  22. }
  23. Return<LedStatus> ledImpl::get() {
  24. return state;
  25. }
  26. Return<int32_t> ledImpl::set(LedStatus val) {
  27. if(val == LedStatus::LED_OFF || val == LedStatus::LED_ON)
  28. state = val;
  29. else
  30. return -1;
  31. return 0;
  32. }
  33. Return<void> ledImpl::getBrightnessRange(getBrightnessRange_cb _hidl_cb)
  34. {
  35. ALOGE("ledImpl getBrightnessRange ");
  36. BrightnessRange range;
  37. range.max = 100;
  38. range.min = 1;
  39. _hidl_cb(true,range);
  40. return Void();
  41. }
  42. Return<bool> ledImpl::setBrightnessValue(const hidl_vec<int32_t>& range)
  43. {
  44. ALOGE("ledImpl getBrightnessValue ");
  45. auto iter = range.begin();
  46. ALOGE("ledImpl getBrightnessValue range.begin: %d",*iter);
  47. iter = range.end();
  48. ALOGE("ledImpl getBrightnessValue range.end: %d",*iter);
  49. ALOGE("ledImpl getBrightnessValue range.size: %zu",range.size());
  50. return true;
  51. }
  52. ILed* HIDL_FETCH_ILed(const char * /*name*/) {
  53. ALOGE("ledImpl HIDL_FETCH_ILed ");
  54. return new ledImpl();
  55. }
  56. } // namespace implementation
  57. } // namespace V1_0
  58. } // namespace led
  59. } // namespace hardware
  60. } // namespace android

hardware/interfaces/led/1.0/default/Android.bp

  1. cc_library_shared {
  2. name: "android.hardware.led@1.0-impl",
  3. defaults: ["hidl_defaults"],
  4. srcs: ["ledImpl.cpp"],
  5. shared_libs: [
  6. "libhidlbase",
  7. "libhidltransport",
  8. "libhardware",
  9. "liblog",
  10. "libutils",
  11. "android.hardware.led@1.0",
  12. ],
  13. }
  14. cc_binary {
  15. name: "android.hardware.led@1.0-service",
  16. init_rc: ["android.hardware.led@1.0-service.rc"],
  17. srcs: ["service.cpp",
  18. "ledImpl.cpp"],
  19. shared_libs: [
  20. "liblog",
  21. "libhardware",
  22. "libhidlbase",
  23. "libhidltransport",
  24. "libutils",
  25. "android.hardware.led@1.0",
  26. ],
  27. }

4.编写hdil service

接下来,使用相应功能填写存根并设置守护进程。可以使用passthrough方式和binder方式,示

例:hardware/interfaces/led/1.0/default/service.cpp

  1. #define LOG_TAG "android.hardware.led@1.0-service"
  2. #include <android/hardware/led/1.0/ILed.h>
  3. #include <hidl/LegacySupport.h>
  4. #include "ledImpl.h"
  5. using android::hardware::led::V1_0::ILed;
  6. using android::hardware::led::V1_0::implementation::ledImpl;
  7. using android::hardware::defaultPassthroughServiceImplementation;
  8. using android::hardware::configureRpcThreadpool;
  9. using android::hardware::joinRpcThreadpool;
  10. using android::sp;
  11. int main() {
  12. #if 0
  13. // Passthrough dlopen so方式
  14. return defaultPassthroughServiceImplementation<Iled>();
  15. #else
  16. // Binder 方式
  17. sp<ILed> service = new ledImpl();
  18. configureRpcThreadpool(1, true /*callerWillJoin*/);
  19. if(android::OK != service->registerAsService())
  20. return 1;
  21. joinRpcThreadpool();
  22. #endif
  23. }

5.配置manifest.xml

add the code to the manifest.xm 以至于hwservicemanager 查找到指定的hidl service

   About HIDL configures

   device/<vendorxxx>/<devicexxx>/manifest.xml

  1. <hal format="hidl">
  2. <name>android.hardware.led</name>
  3. <transport>hwbinder</transport> //hwbinder 或者passthrough (直通模式)
  4. <version>1.0</version>
  5. <interface>
  6. <name>ILed</name>
  7. <instance>default</instance>
  8. </interface>
  9. </hal>

5.hidl client端调用

实现C++ 调用hidl service的例子:首先将 HAL 库添加到 makefile 中

  1. Make:LOCAL_SHARED_LIBRARIES += android.hardware.led@1.0
  2. Soong:shared_libs: [ …, android.hardware.led@1.0 ]

接下来,添加 HAL 头文件:

  1. #include <android/hardware/led/1.0/ILed.h>
  2. // in code:
  3. sp<ILed> client = ILed::getService();
  4. client->on();

下面是我的Demo clinet

  1. #define LOG_TAG "LED_CLINET"
  2. #include <android/hardware/led/1.0/ILed.h>
  3. #include <log/log.h>
  4. using android::hardware::led::V1_0::ILed;
  5. using android::hardware::led::V1_0::LedStatus;
  6. using android::hardware::led::V1_0::BrightnessRange;
  7. using android::hardware::hidl_vec;
  8. using android::sp;
  9. int main(){
  10. // BrightnessRange range;
  11. sp<ILed> service = ILed::getService();
  12. if( service == nullptr ){
  13. ALOGE("Can't find ILed service...");
  14. return -1;
  15. }
  16. ALOGE("ILed ON");
  17. service->on();
  18. ALOGE("ILed OFF");
  19. service->off();
  20. ALOGE("ILed set");
  21. service->set(LedStatus::LED_ON);
  22. ALOGE("ILed get");
  23. LedStatus ret = service->get();
  24. ALOGE("ILed get: %d",ret);
  25. service->getBrightnessRange([](bool ret1,BrightnessRange range){
  26. ALOGE("ILed getBrightnessRange ret: %d",ret1);
  27. ALOGE("ILed getBrightnessRange Max: %d",range.max);
  28. ALOGE("ILed getBrightnessRange Min: %d",range.min);
  29. });
  30. int32_t array[] = {5, 6, 7};
  31. hidl_vec<int32_t> hv1 = std::vector<int32_t>(array, array + 3);
  32. bool ret2 = service->setBrightnessValue(hv1);
  33. ALOGE("ILed getBrightnessValue bool: %d",ret2);
  34. return 0;
  35. }

参考:

在Android 8.0之后版本上添加Hidl Service_anlory的博客-CSDN博客

Android HIDL 介绍学习_Super Jang的博客-CSDN博客_安卓hidl
 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/255867
推荐阅读
相关标签
  

闽ICP备14008679号