树莓派4B android 系统添加led灯 Hal 层

本文内容需要用到我上一篇文章做的驱动,可以先看文章https://blog.csdn.net/ange_li/article/details/136759249

一、Hal 层的实现

1.Hal 层的实现一般放在 vendor 目录下,我们在 vendor 目录下创建如下的目录

aosp/vendor/arpi/hardware/interfaces/rbg_led_control_hidl/1.0

接着在aosp/vendor/arpi/hardware/interfaces/rbg_led_control_hidl/1.0 目录下创建Hal文件ILedControl.hal

//定义包名,最后跟一个版本号
package arpi.hardware.rbg_led_control_hidl@1.0;
//定义 hidl 服务对外提供的接口
interface ILedControl {//开灯openLed(uint32_t red,uint32_t blue,uint32_t green) generates (uint32_t result);//读 hello 驱动closeLed() generates (uint32_t result);
};

2. hal 文件生成 C++ 源文件

接着我们使用 hidl-gen 命令将我们写的 hal 文件转换为 C++ 文件:

source build/envsetup.sh
lunch rpi4-eng
PACKAGE=arpi.hardware.rbg_led_control_hidl@1.0
LOC=vendor/arpi/hardware/interfaces/rbg_led_control_hidl/1.0/default
hidl-gen -o $LOC -Lc++-impl -rarpi.hardware:vendor/arpi/hardware/interfaces $PACKAGE

接着就会生成一些 C++ 代码:生成下图中的LedControl.h  LedControl.cpp

接着修改 LedControl.cpp

// FIXME: your file license if you have one#include "LedControl.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>namespace arpi::hardware::rbg_led_control_hidl::implementation {// Methods from ::arpi::hardware::rbg_led_control_hidl::V1_0::ILedControl follow.
Return<uint32_t> LedControl::openLed(uint32_t red, uint32_t blue, uint32_t green) {int fd = open("/dev/led_drv", O_RDWR);if (fd == -1){printf("can not open file /dev/led_drv\n");return  uint32_t { 0 };}char r[]="red";char b[]="blue";char g[]="green";char cmd[14]="";if(red==1){strcat(cmd, r);}if(blue==1){strcat(cmd, b);}if(green==1){strcat(cmd, g);}::write(fd, cmd, strlen(cmd) +1);close(fd);return uint32_t {1};
}Return<uint32_t> LedControl::closeLed() {int fd = open("/dev/led_drv", O_RDWR);if (fd == -1){printf("can not open file /dev/led_drv\n");return  uint32_t { 0 };}char cmd[14]="";::write(fd, cmd, strlen(cmd) +1);close(fd);return uint32_t {1};
}// Methods from ::android::hidl::base::V1_0::IBase follow.//ILedControl* HIDL_FETCH_ILedControl(const char* /* name */) {//return new LedControl();
//}
//
}  // namespace arpi::hardware::rbg_led_control_hidl::implementation

这里主要是对我们的协议进行实现,实现了对上一节实现的设备文件 /dev/led_drv 的读写。至此我们的 hidl 服务就定义好了

3. 服务端实现

接着我们需要写一个 Server 端来向 HwServiceManager 注册我们的服务。在vendor/arpi/hardware/interfaces/rbg_led_control_hidl/1.0/default 目录下添加 service.cpp(参考上图)

#include <hidl/HidlTransportSupport.h>
#include <utils/Looper.h>
#include <utils/StrongPointer.h>
#include <log/log.h>
#include "LedControl.h"using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
using arpi::hardware::rbg_led_control_hidl::V1_0::ILedControl;
using arpi::hardware::rbg_led_control_hidl::implementation::LedControl;int main() {ALOGD("hello-hidl is starting...");configureRpcThreadpool(4, true /* callerWillJoin */);android::sp<ILedControl> service = new LedControl();android::status_t ret = service->registerAsService();if (ret != android::NO_ERROR) {}joinRpcThreadpool();return 0;//Passthrough模式//return defaultPassthroughServiceImplementation<IHello>(4);
}

我们的服务端需要在开机时启动,vendor/arpi/hardware/interfaces/rbg_led_control_hidl/1.0/default 目录下创建arpi.hardware.rbg_led_control_hidl@1.0-service.rc 文件

service vendor_rbg_led_control_hidl_service /vendor/bin/hw/arpi.hardware.rbg_led_control_hidl@1.0-serviceclass haluser systemgroup system

接着我们需要添加 VINTF 对象,对于注册到 hwservicemanager 的服务都需要添加一个 VINTF 对象。对于编码来说 VINTF 对象就是一个 xml 文件,vendor/arpi/hardware/interfaces/rbg_led_control_hidl/1.0/default 目录下创建arpi.hardware.rbg_led_control_hidl@1.0-service.xml

<manifest version="1.0" type="device"><hal format="hidl"><name>arpi.hardware.rbg_led_control_hidl</name><transport>hwbinder</transport><version>1.0</version><interface><name>ILedControl</name><instance>default</instance></interface></hal>
</manifest>

4 生成 Android.bp

hidl-gen -o $LOC -Landroidbp-impl -rarpi.hardware:vendor/arpi/hardware/interfaces $PACKAGE

该命令会在vendor/arpi/hardware/interfaces/rbg_led_control_hidl/1.0/default 目录下创建Android.bp

简单修改该文件:

// FIXME: your file license if you have onecc_library_shared {// FIXME: this should only be -impl for a passthrough hal.// In most cases, to convert this to a binderized implementation, you should:// - change '-impl' to '-service' here and make it a cc_binary instead of a//   cc_library_shared.// - add a *.rc file for this module.// - delete HIDL_FETCH_I* functions.// - call configureRpcThreadpool and registerAsService on the instance.// You may also want to append '-impl/-service' with a specific identifier like// '-vendor' or '-<hardware identifier>' etc to distinguish it.name: "arpi.hardware.rbg_led_control_hidl@1.0-impl",relative_install_path: "hw",// FIXME: this should be 'vendor: true' for modules that will eventually be// on AOSP.proprietary: true,srcs: ["LedControl.cpp",],shared_libs: ["libhidlbase","libhidltransport","libutils","arpi.hardware.rbg_led_control_hidl@1.0","liblog",],
}cc_binary {name: "arpi.hardware.rbg_led_control_hidl@1.0-service",init_rc: ["arpi.hardware.rbg_led_control_hidl@1.0-service.rc"],vintf_fragments: ["arpi.hardware.rbg_led_control_hidl@1.0-service.xml"],defaults: ["hidl_defaults"],relative_install_path: "hw",vendor: true,srcs: ["service.cpp", "LedControl.cpp"],shared_libs: ["arpi.hardware.rbg_led_control_hidl@1.0","libhardware","libhidlbase","libhidltransport","libutils","liblog",],
}

生成的库里面有一个依赖 arpi.hardware.rbg_led_control_hidl@1.0,接着我们来生成这个库对应的 Android.bp:

在vendor/arpi/hardware/interfaces/下创建update-makefiles.sh 

#!/bin/bashsource $ANDROID_BUILD_TOP/system/tools/hidl/update-makefiles-helper.shdo_makefiles_update \"arpi.hardware:vendor/arpi/hardware/interfaces"

接着执行:

./vendor/arpi/hardware/interfaces/update-makefiles.sh

结果生成文件aosp/vendor/arpi/hardware/interfaces/rbg_led_control_hidl/Android.bp 

// This file is autogenerated by hidl-gen -Landroidbp.hidl_interface {name: "arpi.hardware.rbg_led_control_hidl@1.0",root: "arpi.hardware",system_ext_specific: true,srcs: ["ILedControl.hal",],interfaces: ["android.hidl.base@1.0",],gen_java: true,
}

这个过程会生成一些so 库。

随后在aosp/vendor/arpi/hardware/interfaces下创建Android.bp (告诉编译系统包名与路径的映射关系)

hidl_package_root {name: "arpi.hardware",path: "vendor/arpi/hardware/interfaces",
}

接着创建aosp/vendor/arpi/hardware/interfaces/current.txt

ecf0cea3adff3da5319d360d2e86c3a4b336aa64e798f1fc4eb3dc2abbd6905f arpi.hardware.rbg_led_control_hidl@1.0::ILedControl

再执行一遍 update-makefiles.sh,这个时候就会发现提示 hash 值不正确了,同时会给出正确的 hash 值,我们把正确的 hash 值替换到 current.txt 即可。

5 test客户端编写

vendor/arpi/hardware/interfaces/rbg_led_control_hidl/1.0/default 目录下创建test文件夹

Android.bp

cc_binary {name: "rbg_led_control_hidl_test",srcs: ["rbg_led_control_hidl_test.cpp"],vendor: true,shared_libs: ["liblog","arpi.hardware.rbg_led_control_hidl@1.0","libhidlbase","libhidltransport","libhwbinder","libutils",],
}
#include <arpi/hardware/rbg_led_control_hidl/1.0/ILedControl.h>
#include <hidl/LegacySupport.h>#define LOG_TAG "rbg_led_control_hidl"
#include <log/log.h>using android::sp;
using arpi::hardware::rbg_led_control_hidl::V1_0::ILedControl;
using android::hardware::Return;
using android::hardware::hidl_string;int main(){android::sp<ILedControl> hw_device = ILedControl::getService();if (hw_device == nullptr) {ALOGD("failed to get rbg_led_control_hidl");return -1;}ALOGD("success to rbg_led_control_hidl....");hw_device->openLed(1,0,0);return 0;
} 

上面测试代码可以点亮led 红灯

6 selinux 配置

在aosp/device/arpi/rpi4/sepolicy 目录下

device.te 中添加如下内容:

type led_drv_t, dev_type;

hwservice.te:

type rbg_led_control_hidl_hwservice, hwservice_manager_type;

rbg_led_control_hidl.te:

# type rbg_led_control_hidl, domain;type rbg_led_control_hidl, domain;
type rbg_led_control_hidl_exec, exec_type, vendor_file_type, file_type;init_daemon_domain(rbg_led_control_hidl);
add_hwservice(rbg_led_control_hidl, rbg_led_control_hidl_hwservice)
hwbinder_use(rbg_led_control_hidl)allow rbg_led_control_hidl hidl_base_hwservice:hwservice_manager { add };
allow rbg_led_control_hidl led_drv_t:chr_file { open read write };
binder_call(rbg_led_control_hidl,hwservicemanager)
get_prop(rbg_led_control_hidl,hwservicemanager_prop)

hwservice_contexts:

arpi.hardware.rbg_led_control_hidl::ILedControl      u:object_r:rbg_led_control_hidl_hwservice:s0

rbg_led_control_hidl_test.te:

type  rbg_led_control_hidl_test, domain;
type  rbg_led_control_hidl_test_exec, exec_type, vendor_file_type, file_type;domain_auto_trans(shell, rbg_led_control_hidl_test_exec, rbg_led_control_hidl_test);get_prop(rbg_led_control_hidl_test, hwservicemanager_prop);
allow rbg_led_control_hidl_test rbg_led_control_hidl_hwservice:hwservice_manager find;
hwbinder_use(rbg_led_control_hidl_test);

file_contexts:

/dev/led_drv                    u:object_r:led_drv_t:s0
/vendor/bin/hw/arpi\.hardware\.rbg_led_control_hidl@1\.0-service    u:object_r:rbg_led_control_hidl_exec:s0

7 编译执行

接着在aosp/device/arpi/rpi4/rpi4.mk 加入程序

PRODUCT_PACKAGES += \arpi.hardware.rbg_led_control_hidl@1.0-service \rbg_led_control_hidl_test \arpi.hardware.rbg_led_control_hidl@1.0-impl \
 source build/envsetup.shlunch rpi4-engmake ramdisk systemimage vendorimage

最后测试(点亮led):

rbg_led_control_hidl_test &

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/486619.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于Matlab的变压器仿真模型建模方法(9):三相变压器组的建模仿真(续)

1.引言 前一节介绍了基于混合磁链的考虑主磁路饱和情况的三相变压器组的Simulink仿真模型,并应用它对Y,yn接法三相变压器组的瞬态过程进行了仿真计算。这一节建立一个新的基于等效电路的Simulink三相变压器组的仿真模型,并应用它对Y,d11接法的三相变压器组的瞬态过程进行仿…

【Atcoder】【ABC383】A- Humidifier 1加湿器 题解

前言 不知道大家有没有关注过AtCoder 这是小日子那边的一个网站&#xff0c;每周都会有比赛 比起CF等等&#xff0c;最大的优点就是延迟低&#xff0c;题目质量也不错 计划以后每周更新题解了 正文 题目传送门A - Humidifier 1 题目大意 有一个加湿器&#xff0c;给定 …

LeetCode 热题 100_反转链表(23_206_简单_C++)(单链表_递归)

LeetCode 热题 100_反转链表&#xff08;23_206&#xff09; 题目描述&#xff1a;输入输出样例&#xff1a;题解&#xff1a;解题思路&#xff1a;思路一&#xff08;迭代&#xff09;&#xff1a;思路二&#xff08;简化方法一(迭代)代码&#xff09;&#xff1a;思路三&…

49 基于单片机的湿度和光照监测

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于AT89C52单片机&#xff0c;采用DHT11温湿度传感器检测土壤湿度&#xff0c;光敏电阻连接ADC0832数模转换器作为光敏传感器&#xff0c;然后通过LCD1602显示湿度和光照值&#xff0c;如果湿度低…

【C语言】程序设计--算法

文章目录 1. 判断两个数的大小并交换2. 计算三角形面积3. 根据x的值计算y4. 字符大小写转换5. 百钱百鸡问题6. 计算公式y的值7. 输出所有的水仙花数8. 计算n的阶乘9. 下三角数据10. 斐波那契数列11. 学生成绩统计12. 数组的平均值1. 判断两个数的大小并交换 介绍: 从键盘输入…

嵌入式Linux,字符串的处理,以及相关函数详解

C 语言库函数中已经给我们提供了丰富的字符串处理相关函数&#xff0c;基本常见的字符串处理需求都可 以直接使用这些库函数来实现。 1. 字符串输入/输出 在程序当中&#xff0c;经常需要在程序运行过程中打印出一些信息&#xff0c;譬如调试信息、报错信息、中间产生的变量的…

400G智算网络助力知名自动驾驶企业算力训练提效

根据Gartner的最新趋势预测&#xff0c;自动驾驶技术正迅速发展&#xff0c;预计在未来几年内将带来显著的商业效益&#xff0c;特别是在决策智能和边缘人工智能领域。目前&#xff0c;一家领军企业正积极拥抱基于大模型的数字化转型之路&#xff0c;作为自动驾驶领域的佼佼者&…

【iOS】OC高级编程 iOS多线程与内存管理阅读笔记——自动引用计数(三)

目录 ARC规则 概要 所有权修饰符 __strong修饰符 __weak修饰符 __unsafe_unretained修饰符 ___autoreleasing修饰符 ARC规则 概要 “引用计数式内存管理”的本质部分在ARC中并没有改变&#xff0c;ARC只是自动地帮助我们处理“引用计数”的相关部分。 在编译单位上可以…

数学活动是什么过程?

有专家说&#xff1a;数学活动是建构的操作过程&#xff0c;建构的过程必须是探索、发现和创造的过程。 什么是建构&#xff0c;建构就是构建&#xff0c;就是建立。明明有让人一看就明白的词&#xff0c;人非得弄得云遮雾绕。 也难怪&#xff0c;现在什么都流行上云。 上云…

windows11安装Linux子系统配置大数据hadoop

zai 1、安装linux子系统 1、启用适用于 Linux 的 Windows 子系统 搜索框里面输入<开发>即可跳转&#xff0c;打开开发人员模式 命令行里面输入systeminfo确定是否电脑已经支持虚拟化&#xff0c;是则可以继续安装: 2、然后先启用“适用于 Linux 的 Windows 子系统”可选…

RPC设计--从reactor设计 (IOthread)

主从reactor架构 一般的一个网络IO库都是主从reactor模式&#xff0c;即主线程中有一个MainReactor&#xff0c;其负责监听ListenFd&#xff0c;当接受到新的用户连接时&#xff0c;返回的clientfd并不会加入的MainReacotr&#xff0c;而是在子线程&#xff08;这里称为IO线程&…

微信创建小程序码 - 数量不受限制

获取小程序码&#xff1a;小程序码为圆图&#xff0c;且不受数量限制。 目录 文档 接口地址 请求方式 功能描述 注意事项 获取 scene 值 请求参数 返回参数 对接 请求方法 获取小程序码 调用获取小程序码 总结 文档 接口地址 https://api.weixin.qq.com/wxa/get…

【机器学习】基于SVM、逻辑回归和CNN的手写数字识别:性能对比与应用分析

基于SVM、逻辑回归和CNN的手写数字识别&#xff1a;性能对比与应用分析 1 基于SVM对手写数字识别2 基于逻辑回归对手写数字进行识别3 基于CNN对手写数字进行识别总结对比分析 1 基于SVM对手写数字识别 在使用SVM方法对手写数字进行识别的时候&#xff0c;我采用了一对多&#…

群控系统服务端开发模式-应用开发-邮件工厂电信189发送开发

一、电信189邮件工厂开发 1、添加框架对应的SDK composer require phpmailer/phpmailer 2、添加电信189邮件工厂 在根目录下extend文件夹下Mail文件夹下channel文件夹下&#xff0c;创建电信189邮件发送工厂并命名为DianxinMailSender。记住&#xff0c;一定要在电信189邮件发…

部署loki,grafana 以及springcloud用法举例

文章目录 场景docker 部署grafanadocker-compose部署loki维护配置文件 local-config.yaml维护docker-compose.yml配置启动 grafana 添加loki数据源springcloud用法举例查看loki的explore,查看日志 场景 小公司缺少运维岗位&#xff0c;需要研发自己部署日志系统&#xff0c;elk…

非常简单实用的前后端分离项目-仓库管理系统(Springboot+Vue)part 4

三十三、出入库管理 Header.vue导一下,RecordController加一个 //将入库数据和原有数据相加吧//新增PostMapping("/save")public Result save(RequestBody Record record) {return recordService.save(record) ? Result.success() : Result.fail();} GoodsManage.v…

Leetcode—1133. 最大唯一数【简单】Plus

2024每日刷题&#xff08;205&#xff09; Leetcode—1133. 最大唯一数 C 实现代码 class Solution { public:int largestUniqueNumber(vector<int>& nums) {constexpr int MAX 1000;vector<int> count(MAX 1, 0);for(int num: nums) {count[num];}for(int…

如何通过自学成长为一名后端开发工程师?

大家好&#xff0c;我是袁庭新。最近&#xff0c;有星友向我提出了一个很好的问题&#xff1a;如何通过自学成为一名后端开发工程师&#xff1f; 为了解答这个疑问&#xff0c;我特意制作了一个视频来详细分享我的看法和建议。 戳链接&#xff1a;如何通过自学成长为一名后端开…

GCC/G++ Centos离线安装

方式一&#xff08;推荐&#xff09; 官方地址&#xff1a;https://gcc.gnu.org/releases.html 镜像站点1&#xff1a;http://mirrors.aliyun.com/centos/7/os/x86_64/Packages/ 镜像站点2&#xff1a;https://vault.centos.org/7.5.1804/os/x86_64/Packages/ gcc &#xff1a…

工业—使用Flink处理Kafka中的数据_ChangeRecord2

使用 Flink 消费 Kafka 中 ChangeRecord 主题的数据,每隔 1 分钟输出最近 3 分钟的预警次数最多的 设备,将结果存入Redis 中, key 值为