美文网首页
android P hal开发demo

android P hal开发demo

作者: 周鹤_006d | 来源:发表于2020-04-09 15:08 被阅读0次

    1.编译(基于ubuntu16.04)

    1.1先安装repo工具(参考https://mirrors.tuna.tsinghua.edu.cn/help/git-repo/)

    1.2代码下载

    到内网10.19.118.212的/home/neusoft/android_source/zhangshuang文件夹下(用户名:neusoft,密码:root)用smb把aosp_9_back.tar.gz拷贝到任意目录,然后解压

    或者

    $ repo init -u https://android.googlesource.com/platform/manifest -b android-9.0.0_r39 --depth=1

    $ repo sync

    1.3编译

    $ source build/envsetup.sh

    // 因为我们要实验car的版本

    lunch命令的效果

    $ lunch 10

    $ make -j8

    编译成功的效果

    1.4启动模拟器

    编译成功之后,输入命令emulator可以启动模拟器(模拟器更多指令参数参照emulator -help)

    模拟器

    2.HAL服务端开发

    2.1.编写hal文件

    在AOSP代码的目录 hardware/interfaces/中新建test/1.0/,在此目录中新建 ITest.hal,内容:

    package android.hardware.test@1.0;

    interface ITest{

    helloWorld(string name) generates (string result);

    };

    2.2.使用hidl-gen生成对应的c++文件

    2.2.1编译hidl-gen工具

    make hidl-gen

    2.2.2设置临时变量

    PACKAGE=android.hardware.test@1.0

    LOC=hardware/interfaces/test/1.0/default

    2.2.3生成c++文件

    (在aosp根目录下执行,source完之后执行croot可以回到aosp根目录)

    hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE

    生成的目录

    2.2.4生成Android.bp文件

    hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE

    生成之后的目录

    2.2.5生成1.0目录下的Android.bp

    执行./hardware/interfaces/update-makefiles.sh

    生成之后的目录

    2.3实现c++文件

    2.3.1Test.h文件实现passthrough模式

    #ifndef ANDROID_HARDWARE_TEST_V1_0_TEST_H

    #define ANDROID_HARDWARE_TEST_V1_0_TEST_H

    #include <android/hardware/test/1.0/ITest.h>

    #include <hidl/MQDescriptor.h>

    #include <hidl/Status.h>

    namespace android {

    namespace hardware {

    namespace test {

    namespace V1_0 {

    namespace implementation {

    using ::android::hardware::hidl_array;

    using ::android::hardware::hidl_memory;

    using ::android::hardware::hidl_string;

    using ::android::hardware::hidl_vec;

    using ::android::hardware::Return;

    using ::android::hardware::Void;

    using ::android::sp;

    struct Test : public ITest {

        // Methods from ::android::hardware::test::V1_0::ITest follow.

        Return<void> helloWorld(const hidl_string& name, helloWorld_cb _hidl_cb) override;

        // Methods from ::android::hidl::base::V1_0::IBase follow.

    };

    // FIXME: most likely delete, this is only for passthrough implementations

    extern "C" ITest* HIDL_FETCH_ITest(const char* name);

    }  // namespace implementation

    }  // namespace V1_0

    }  // namespace test

    }  // namespace hardware

    }  // namespace android

    #endif  // ANDROID_HARDWARE_TEST_V1_0_TEST_H

    2.3.2Test.cpp实现

    #include "Test.h"

    namespace android {

    namespace hardware {

    namespace test {

    namespace V1_0 {

    namespace implementation {

    // Methods from ::android::hardware::test::V1_0::ITest follow.

    Return<void> Test::helloWorld(const hidl_string& name, helloWorld_cb _hidl_cb) {

        // TODO implement

        // 做了简单实现 start @{

        printf("Test helloWorld");

        char buf[100];

        memset(buf, 0, 100);

        snprintf(buf, 100, "Hello World, %s", name.c_str());

        hidl_string result(buf);

        _hidl_cb(result);

        // 做了简单实现 end @}

        return Void();

    }

    // Methods from ::android::hidl::base::V1_0::IBase follow.

    ITest* HIDL_FETCH_ITest(const char* /* name */) {

        return new Test();

    }

    }  // namespace implementation

    }  // namespace V1_0

    }  // namespace test

    }  // namespace hardware

    }  // namespace android

    2.4添加启动service

    在hardware/interfaces/gunder/1.0/default目录下新建android.hardware.test@1.0-service.rc 启动脚本

    service test_hal_service /vendor/bin/hw/android.hardware.test@1.0-service

        class hal

        user system

        group system

    添加之后的目录

    2.5新建service.cpp,采用直通式

    #define LOG_TAG "android.hardware.test@1.0-service"

    #include <android/hardware/test/1.0/ITest.h>

    #include <hidl/LegacySupport.h>

    using android::hardware::test::V1_0::ITest;

    using android::hardware::defaultPassthroughServiceImplementation;;

    //passthrough mode

    int main() {

      return defaultPassthroughServiceImplementation<ITest>();

    //passthrough mode

    }

    添加之后的目录

    2.6修改hardware/interfaces/test/1.0/default目录下的Android.bp

    cc_library_shared {

        name: "android.hardware.test@1.0-impl",

        relative_install_path: "hw",

        proprietary: true,

        srcs: [

            "Test.cpp",

        ],

        shared_libs: [

            "libhidlbase",

            "libhidltransport",

            "libutils",

            "android.hardware.test@1.0",

        ],

    }

    cc_binary {

        name: "android.hardware.test@1.0-service",

        defaults: ["hidl_defaults"],

        proprietary: true,

        relative_install_path: "hw",

        srcs: ["service.cpp"],

        init_rc: ["android.hardware.test@1.0-service.rc"],

        shared_libs: [

            "libhidlbase",

            "libhidltransport",

            "libutils",

            "liblog",

            "android.hardware.test@1.0",

        ],

    }

    2.7调用update-makefiles.sh更新一下

    更新之后的目录

    2.8.编译

    mmm ./hardware/interfaces/test/1.0

    编译结果


    3.VNDK相关(https://chendongqi.me/2019/09/01/hidl-binderizing-passthrough/)

    build/make/target/product/vndk/28.txt增加一行

    新增的内容

    build/make/target/product/vndk/current.txt增加一行

    新增的内容

    4.device部分

    为了保证新增的hidl是可以被客户端访问到的,由于此次要使用emulator验证,并且lunch的是aosp_car_x86_64-eng所以在device找到下面目录aosp\device\generic\car\common\manifest.xml添加如下内容:

    <hal format="hidl"><name>android.hardware.test</name><transport>hwbinder</transport><version>1.0</version><interface>        <name>ITest</name>        <instance>default</instance></interface></hal>

    5.完整编译

    在aosp根目录执行make编译出相应的镜像

    6.启动服务

    6.1启动模拟器

    // -writable-system让模拟器可写,-selinux disabled跳过selinux检查
    emulator -writable-system -selinux disabled

    执行如下命令

    // 获取root权限

    adb root 

    // 获取模拟器写权限

    adb remount

    // 进入模拟器控制台

    adb shell

    // 启动hal服务

    vendor/bin/hw/android.hardware.test@1.0-service &

    服务启动成功

    6.2查看服务是否启动成功

    ps -A |grep "test"

    7.客户端测试程序

    7.1.c++客户端

    7.1.1内容编写

    在packages/apps目录下新建testApp/native文件夹,创建Android.mk,内容如下:

    LOCAL_PATH := $(call my-dir)

    include $(CLEAR_VARS)

    LOCAL_PROPRIETARY_MODULE := true

    LOCAL_MODULE := test

    LOCAL_SRC_FILES := \

    client.cpp \

    LOCAL_SHARED_LIBRARIES := \

    liblog \

    libhidlbase \

    libutils \

    android.hardware.test@1.0 \

    include $(BUILD_EXECUTABLE)

    创建client.cpp内容如下:

    # include <android/hardware/test/1.0/ITest.h>

    # include <hidl/Status.h>

    # include <hidl/LegacySupport.h>

    # include <utils/misc.h>

    # include <hidl/HidlSupport.h>

    # include <stdio.h>

    using android::hardware::test::V1_0::ITest;

    using android::sp;

    using android::hardware::hidl_string;

    int main()

    {

        fprintf(stderr,"%s\n" , "start");

        android::sp<ITest> service = ITest::getService();

        printf("%s\n", "service");

        if(service == nullptr) {

            printf("Failed to get service\n");

            return -1;

        }

        service->helloWorld("test", [&](hidl_string result) {

                    printf("%s\n", result.c_str());

            });

        printf("%s\n", "end");

        return 0;

    }

    编写的文件

    7.1.2.编译客户端

    mmm packages/apps/testApp/native/,编译成功之后

    在编译输出路径中有test可执行文件

    7.1.3.把可执行文件push到模拟器中

    adb push out/target/product/generic_x86/vendor/bin/test /vendor/bin/

    push到模拟器中

    7.1.4.在模拟器控制台中验证是否成功

    客户端运行成功

    8.在App中调用hal服务

    在编译hal服务端的时候,自动编译出来的java端支持的客户端,编译的结果在(可以通过反编译来查看里面的具体内容)

    hal客户端

    打包之后再模拟器的路径

    模拟器中的hal客户端支持

    所以我们的app只需要引入包即可调用hal的客户端

    8.1编写HAL客户端

    在packages/apps/testApp中新建如下目录(完整程序在git@github.com:nicholaszhou/HalClientTest.git)

    编译客户端程序

    mmm packages/apps/testApp

    编译成功标识

    编译成功之后,在会生成客户端的apk程序

    hal客户端程序

    把apk安装到模拟器中

    adb install -r out/target/product/generic_x86/system/app/TestApp/TestApp.apk

    apk安装成功

    点击运行程序

    调用成功

    相关文章

      网友评论

          本文标题:android P hal开发demo

          本文链接:https://www.haomeiwen.com/subject/uvfcmhtx.html