嵌入式实践教程--Android HAL自定义HAL代码教程
HIDL接口定义创建hidl目录在aosp中的hardware/interfaces目录下创建自己的hal目录mkdir -p hardware/interfaces/qmiller/1.0/default创建hal文件在我们刚才创建的hardware/interfaces/qmiller/1.0/目录下新建IQmiller.hal文件,传入string name,返回string类型的resul
HIDL接口定义
创建hidl目录
在aosp中的hardware/interfaces目录下创建自己的hal目录
mkdir -p hardware/interfaces/qmiller/1.0/default
创建hal文件
在我们刚才创建的hardware/interfaces/qmiller/1.0/目录下新建IQmiller.hal文件,传入string name,返回string类型的result。
package android.hardware.qmiller@1.0;
interface IQmiller {
helloWorld(string name) generates (string result);
};
生产HAL文件
使用hidl-gen工具来处理IQmiller.hal文件,这里可以写成一个shell脚本。
PACKAGE=android.hardware.qmiller@1.0
LOC=hardware/interfaces/qmiller/1.0/default/
make hidl-gen -j4
hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
此时的文件树:
hardware/interfaces/qmiller/1.0/
├── default
│ ├── Android.bp
│ ├── Qmiller.cpp
│ └── Qmiller.h
└── IQmiller.hal
然后使用脚本来更新Makefile,自动生成Android,mk, Android.bp
./hardware/interfaces/update-makefiles.sh
此时的文件树:
hardware/interfaces/qmiller/1.0/
├── Android.bp
├── default
│ ├── Android.bp
│ ├── Qmiller.cpp
│ └── Qmiller.h
└── IQmiller.hal
新建两个空文件:
touch hardware/interfaces/qmiller/1.0/default/android.hardware.qmiller@1.0-service.rc
touch hardware/interfaces/qmiller/1.0/default/service.cpp
实现HAL的implementation库
自动生成的Qmiller.h文件,这里介绍的是绑定式HAL,而不是直通式。
#pragma once
#include <android/hardware/qmiller/1.0/IQmiller.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
namespace android::hardware::qmiller::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 Qmiller : public V1_0::IQmiller {
// Methods from ::android::hardware::qmiller::V1_0::IQmiller 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" IQmiller* HIDL_FETCH_IQmiller(const char* name);
} // namespace android::hardware::qmiller::implementation
自动生成的Qmiller.cpp
#include "Qmiller.h"
namespace android::hardware::qmiller::implementation {
// Methods from ::android::hardware::qmiller::V1_0::IQmiller follow.
Return<void> Qmiller::helloWorld(const hidl_string& name, helloWorld_cb _hidl_cb) {
// TODO implement
return Void();
}
// Methods from ::android::hidl::base::V1_0::IBase follow.
//IQmiller* HIDL_FETCH_IQmiller(const char* /* name */) {
//return new Qmiller();
//}
//
} // namespace android::hardware::qmiller::implementation
修改Android.bp文件,将-impl改成-service,将cc_library_shared改成cc_library,在-service后面加上vendor名称。
cc_library {
name: "android.hardware.qmiller@1.0-service-lzm",
relative_install_path: "hw",
vendor:true,
// FIXME: this should be 'vendor: true' for modules that will eventually be
// on AOSP.
proprietary: true,
srcs: [
"Qmiller.cpp",
],
shared_libs: [
"libhidlbase",
"libutils",
"android.hardware.qmiller@1.0",
],
}
实现service.cpp
#define LOG_TAG "android.hardware.qmiller@1.0-service-lzm"
#include <hidl/HidlLazyUtils.h>
#include <hidl/HidlSupport.h>
#include <hidl/HidlTransportSupport.h>
#include "Qmiller.h"
using ::android::OK;
using ::android::sp;
using ::android::hardware::configureRpcThreadpool;
using ::android::hardware::joinRpcThreadpool;
using ::android::hardware::LazyServiceRegistrar;
using ::android::hardware::qmiller::V1_0::IQmiller;
using ::android::hardware::qmiller::V1_0::implementation::Qmiller;
int main(int argc, char* []) {
sp<IQmiller> qmiller = new Qmiller;
configureRpcThreadpool(1, true);
auto registrar = LazyServiceRegistrar::getInstance();
if (registrar.registerService(qmiller) != OK) {
ALOGE("Could not register service.");
return 1;
}
joinRpcThreadpool();
ALOGE("Service exited!");
return 1;
}
修改
Android.bpcc_library {
name: "android.hardware.qmiller@1.0-service-lzm",
relative_install_path: "hw",
vendor:true,
// FIXME: this should be 'vendor: true' for modules that will eventually be
// on AOSP.
proprietary: true,
srcs: [
"Qmiller.cpp",
],
shared_libs: [
"libhidlbase",
"libutils",
"android.hardware.qmiller@1.0",
],
}
cc_binary{
name: "android.hardware.qmiller@1.0-service",
defaults: ["hidl_defaults"],
relative_install_path: "hw",
proprietary: true,
srcs: ["service.cpp"],
init_rc: ["android.hardware.qmiller@1.0-service.rc"],
shared_libs: [
"libhidlbase",
"libhidltransport",
"libutils",
"liblog",
"libhardware",
"android.hardware.qmiller@1.0",
"android.hardware.qmiller@1.0-service-lzm",
],
}
实现Qmiller.cpp文件
#include "Qmiller.h"
namespace android::hardware::qmiller::implementation {
Return<void> Qmiller::helloWorld(const hidl_string& name, helloWorld_cb _hidl_cb) {
char buf[100];
::memset(buf, 0x00, 100);
::snprintf(buf, 100, "Hello World, %s", name.c_str());
hidl_string result(buf);
_hidl_cb(result);
return Void();
}
} // namespace android::hardware::qmiller::implementation
编译hal
mmm hardware/interfaces/qmiller/1.0/default/
最终会生成一个android.hardware.qmiller@1.0-service-lzm.so, 生成在/vendor/lib64/hw/下。service.rc
service.cpp会被编译成bin文件,我们需要在系统启动的时候将我们编写的hal服务加进系统。android.hardware.qmiller@1.0-service.rc文件内容如下:
service qmiller_hal_service /vendor/bin/hw/android.hardware.qmiller@1.0-service
class hal
user system
group system
为了让服务器被客户端访问到,还需要在device/xxx/xxx/manifest.xml(不同厂商路径不同)添加如下:
<hal format="hidl">
<name>android.hardware.qmiller</name>
<transport>hwbinder</transport>
<impl level="generic"></impl>
<version>1.0<version>
<interface>
<name>IQmiller</name>
<instance>default</instance>
</interface>
</hal>
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐

所有评论(0)