android9.0 从driver到APP(2)--hardware
文章目錄
- hardware代碼:
- 測試代碼:
- 加入到編譯系統中
注:本文為個人學習記錄,可能存在個別或多處錯誤,歡迎指正和討論。
接:
android9.0 從driver到APP(1)–driver
hardware代碼:
sample.c
/** Copyright (C) 2019 Alex** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/ #include <errno.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <fcntl.h>#include <unistd.h>#define LOG_TAG "SampleHal" #include <utils/Log.h>#include <hardware/sample.h> #include <hardware/hardware.h>#ifdef __ANDROID__ #include <linux/sample.h> #endif#define DEVICE_NAME "/dev/sample" #define MODULE_NAME "Demo Sample HAL" #define MODULE_AUTHOR "Alex" // We only support clang and g++. #define UNUSED_ARGUMENT __attribute((unused))static int sample_init(sample_module_t *module UNUSED_ARGUMENT) {printf("%s[%d]: start \n", __func__,__LINE__);if(NULL == module){printf("module is NULL \n");return -1;}// open deviceif(module->fd <= 0){module->fd = open(DEVICE_NAME, O_RDWR);if(module->fd == -1){printf("%s[%d]: open device %s failed ! \n",__func__,__LINE__,DEVICE_NAME);return -1;}}else{printf("%s[%d]: device has been inited! \n",__func__,__LINE__);}printf("%s[%d]: success! \n", __func__,__LINE__);return 0; }static int sample_close(sample_module_t *module UNUSED_ARGUMENT) {printf("%s[%d]: start \n", __func__,__LINE__);if(NULL == module){printf("module is NULL \n");return -1;}// close deviceif(module->fd >0){close(module->fd); module->fd =0;}return 0; }static int sample_read(sample_module_t *module UNUSED_ARGUMENT,int *val) {int ret =0;printf("%s[%d]: start \n", __func__,__LINE__);if(NULL == module){printf("module is NULL \n");return -1;}if(module->fd <=0){printf("device not open !! \n");return -1;}ret = read(module->fd,val,sizeof(int));if(ret != sizeof(int)){printf("read data failed !! \n");return -1;}return 0; }static void sample_write(sample_module_t *module UNUSED_ARGUMENT, int val UNUSED_ARGUMENT) {int ret = 0;printf("%s[%d]: start \n", __func__,__LINE__);printf("write %d \n",val);if(NULL == module){printf("module is NULL \n");return;}if(module->fd <=0){printf("device not open !! \n");return ;}ret = write(module->fd, &val, sizeof(val)); if(ret != sizeof(val)){printf("sample write failed \n");} }static void sample_set_val(sample_module_t *module UNUSED_ARGUMENT, int val UNUSED_ARGUMENT) {printf("%s[%d]: start \n", __func__,__LINE__);if(NULL == module){printf("module is NULL \n");return ;}if(module->fd <=0){printf("device not open !! \n");return ;}if (ioctl(module->fd, SAMPLE_IOTEST_SETVAL, &val) == -1){printf("Get value failed! --SAMPLE_IOTEST_SETVAL \n");return;}printf("set_val %d \n",val); }static int sample_get_val(sample_module_t *module UNUSED_ARGUMENT,int *val) {printf("%s[%d]: start \n", __func__,__LINE__);if(NULL == module){printf("module is NULL \n");return -1;}if(module->fd <=0){printf("device not open !! \n");return -1;}if (ioctl(module->fd, SAMPLE_IOTEST_GETVAL, val) == -1){printf("Get value failed! --SAMPLE_IOTEST_GETVAL \n");return -1;}else{printf("get value = %d \n",*val);}return 0; }static struct hw_module_methods_t sample_module_methods = {.open = NULL, };sample_module_t HAL_MODULE_INFO_SYM = {.common = {.tag = HARDWARE_MODULE_TAG,.module_api_version = SAMPLE_MODULE_API_VERSION_1_0,.hal_api_version = HARDWARE_HAL_API_VERSION,.id = SAMPLE_HARDWARE_MODULE_ID,.name = MODULE_NAME,.author = MODULE_AUTHOR,.methods = &sample_module_methods,},.sampleInit = sample_init,.sampleClose = sample_close,.sampleRead = sample_read,.sampleWrite = sample_write, .sampleGetval = sample_get_val,.sampleSetval = sample_set_val, };sample.h
/** Copyright (C) 2019 Alex** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/#ifndef ANDROID_INCLUDE_HARDWARE_SAMPLE_H #define ANDROID_INCLUDE_HARDWARE_SAMPLE_H#include <stdbool.h> #include <sys/cdefs.h> #include <hardware/hardware.h>__BEGIN_DECLS#define SAMPLE_HARDWARE_MODULE_ID "sample"#define SAMPLE_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(1, 0)typedef struct sample_module {/*** Common methods of the module. This *must* be the first member of* sample_module as users of this structure may cast a hw_module_t to a* sample_module pointer in contexts where it's known that the hw_module_t* references a sample_module.*/struct hw_module_t common;int fd;/**No methods from this HAL will be called before init.*/int (*sampleInit)(struct sample_module *module);int (*sampleClose)(struct sample_module *module);int (*sampleRead)(struct sample_module *module,int *val);void (*sampleWrite)(struct sample_module *module,int val);int (*sampleGetval)(struct sample_module *module,int *val);void (*sampleSetval)(struct sample_module *module,int val);} sample_module_t;__END_DECLS#endif /* ANDROID_INCLUDE_HARDWARE_SAMPLE_H */頭文件的路徑在:
hardware/libhardware/include/hardware/Android.bp
// Copyright (C) 2019 Alex // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License.cc_library_shared {name: "sample.default",relative_install_path: "hw",vendor: true,srcs: ["sample.c"],shared_libs: ["libcutils","liblog",],header_libs: ["libhardware_headers","libutils_headers",],cflags: ["-Wall","-Werror",],}Hal層的庫文件是怎么被上層調用的?上層調用時的入口(相當于main)又是什么呢?它就是HAL_MODULE_INFO_SYM。
一種調試方式:以sample.default.so庫為例子 ,HIDL層會根據SAMPLE_HARDWARE_MODULE_ID去/system/lib/hw/下面尋找sample.default.so這個庫,sample.defualt.so的入口就是HAL_MODULE_INFO_SYM, 從此再去調用hal層里的open,init,write,read等接口,hal再通過這個接口去設備結點讀寫。
Hardware層中的一個模塊中,主要的三個結構:
struct hw_module_t
struct hw_module_methods_t
struct hw_device_t
由于Android8.0之后采用HIDL的設計,在HAL層中實現
sample_module就可以直接調用相關的函數。
hw_module_methods_t的open可以不設計。(理解有限,歡迎探討)
測試代碼:
/** Copyright (C) 2019 Alex** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/#include <inttypes.h> #include <string.h> #include <stdint.h> #include <stdio.h> #include <string.h> #include <sys/cdefs.h> #include <sys/types.h>#include <utils/Timers.h> #include <utils/Log.h>#include <hardware/sample.h>int main(int /* argc */, char** /* argv */) {int err;int val = 0;const hw_module_t* hw_module = nullptr;sample_module_t* sample_module = nullptr;err = hw_get_module(SAMPLE_HARDWARE_MODULE_ID, &hw_module);if (err) {printf("hw_get_module %s failed: %d", SAMPLE_HARDWARE_MODULE_ID, err);return -1;}if (!hw_module->methods || !hw_module->methods->open) {sample_module = reinterpret_cast<sample_module_t*>(const_cast<hw_module_t*>(hw_module));} else {err = hw_module->methods->open(hw_module, SAMPLE_HARDWARE_MODULE_ID,reinterpret_cast<hw_device_t**>(&sample_module));if (err) {printf("Passthrough failed to load legacy HAL.");return -1;}}err = sample_module->sampleInit(sample_module);if (err) {printf("sampleInit failed: %d", err);return -1;}sample_module->sampleWrite(sample_module,10);err = sample_module->sampleRead(sample_module, &val);if (err) {printf("sampleInit failed: %d", err);goto exit_main;}else{printf("Read val = %d \n",val);}sample_module->sampleSetval(sample_module,20);err = sample_module->sampleGetval(sample_module,&val);if (err) {printf("sampleInit failed: %d", err);goto exit_main;}else{printf("Getval = %d \n",val);}exit_main:err = sample_module->sampleClose(sample_module);if (err) {printf("sampleInit failed: %d", err);return -1;}return 0; }Android.bp
cc_binary {name: "test-sample",srcs: ["nusamples.cpp"],cflags: ["-Wall", "-Werror"],shared_libs: ["liblog","libcutils","libhardware",], }將 sample.default.so 復制到板端的 /vendor/lib64/hw/ 路徑
將test-sample 復制到板端的 /vendor/lib64/bin/ 路徑
運行打印log如下:
可以正確對內核進行訪問。
加入到編譯系統中
device.mk增加:
#Sample HAL PRODUCT_PACKAGES += sample.default總結
以上是生活随笔為你收集整理的android9.0 从driver到APP(2)--hardware的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java随机数种子_使用种子的Java随
- 下一篇: go下载指定版本的依赖包