android 从底层到上层,新增LED设备--从上层到底层理解安卓架构之HAL篇

硬件抽象层介绍

+

硬件抽象层(Hardware Abstraction Layer,简称HAL)是介于android内核kernel和上层之间的抽象出来的一层结构,是对Linux驱动的一个封装,对上层提供统一接口,上层应用不必知道下层硬件具体怎么工作的,屏蔽了底层的实现细节。为什么有了 硬件抽象层有其存在的意义:

1)不是所有的硬件设备都有标准的Linux内核接口,通过HAL层封装了一套固定的向上接口,可以使得上层的开发逻辑更清晰简单。HAL框架是固定的,开发人员只需要按照框架开发即可,无需关注与上层的交互上,将精力放在HAL层本身的实现上即可。

2)从商业角度,硬件厂商可以把一些核心的算法、调试参数、实现逻辑等放在HAL层而不是kenel层,kenel层只是简单与硬件做数据交互。这样的好处是可以不用遵Linux的GPL开源协议,保护自身的商业机密。

1jsSZmGooUeUzWe8

Hal架构图

模块类型结构体hw_module_t,设备类型结构体hw_device_t,

两个结构体的详细内容可以参考源码路径:/hardware/libhardware/include/hardware/hardware.h。HAL层开发主要工作是建立好自定义的结构体,并实现hw_device_t的内部的几个关键函数。

头文件hardware/libhardware/include/hardware/testled_hal.h

#ifndef _LED_HAL_H_#define _LED_HAL_H_#include #define LED_HAL_MODULE_ID "testled_hal"struct testled_module_t {struct hw_module_t common;};struct testled_device_t {struct hw_device_t common;int (*open)(void);int (*control)(int on);};#endif

头文件内申明了led的两个关键结构体testled_module_t和testled_device_t,结构体的实现在c文件中。

2)c文件 hardware/libhardware/modules/testled/testled_hal.c

#include #include #include #include #include #include #include #include

//日志的标签

#define LOG_TAG "testled_hal"#include #define LEDCTRL_MAGIC 'k'#define LED1CTRL_ON_CMD _IO (LEDCTRL_MAGIC, 1)#define LED1CTRL_OFF_CMD _IO (LEDCTRL_MAGIC, 2)#define LED2CTRL_ON_CMD _IO (LEDCTRL_MAGIC, 3)#define LED2CTRL_OFF_CMD _IO (LEDCTRL_MAGIC, 4)static int fd;int testled_hal_dev_close(struct hw_device_t *device){if(device != NULL){struct testled_device_t *temp = (struct testled_device_t *)device;free(temp);}close(fd);return 0;}int testled_hal_open_dev(void){ALOGD("--%s--", __func__);fd = open("/dev/test-led", O_RDWR);if(fd < 0){ALOGE("open failed : %s", strerror(errno));return fd;}return 0;}int testled_hal_control_dev(int on){ALOGD("--%s--", __func__);int ret;switch(on){case 0:ret = ioctl(fd, LED1CTRL_ON_CMD,0);break;case 1:ret = ioctl(fd, LED1CTRL_OFF_CMD,0);break;case 2:ret = ioctl(fd, LED2CTRL_ON_CMD,0);break;case 3:ret = ioctl(fd, LED2CTRL_OFF_CMD,0);break;default:break;}if(ret < 0){ALOGE("control failed : %s", strerror(errno));return ret;}return 0;}int testled_hal_module_open(const struct hw_module_t *module, const char *id,struct hw_device_t **device){ALOGD("--%s--", __func__);struct testled_device_t *led_dev = NULL;led_dev = (struct testled_device_t *)malloc(sizeof(struct testled_device_t));if (led_dev == NULL){ALOGE("malloc failed");return -1;}ALOGD("malloc success");//初始化device对象led_dev->common.tag = HARDWARE_DEVICE_TAG;led_dev->common.version = 1;led_dev->common.module = module;led_dev->common.close = testled_hal_dev_close;led_dev->open = testled_hal_open_dev;led_dev->control = testled_hal_control_dev;

//将当前的led_dev传递给jni层

*device = (struct hw_device_t *)led_dev;return 0;}struct testled_device_t testled_hal_methods = {open : testled_hal_module_open,};struct testled_module_t HAL_MODULE_INFO_SYM = {common : {tag : HARDWARE_MODULE_TAG,version_major : 1,version_minor : 0,id : LED_HAL_MODULE_ID,name : "testled hal module",methods : &testled_hal_methods,},};

主要实现了hal结构体中的close,open,control函数,并将函数传给结led_dev构体。

led_dev->common.close = testled_hal_dev_close;led_dev->open = testled_hal_open_dev;led_dev->control = testled_hal_control_dev;

Android.mk hardware/libhardware/modules/testled/Android.mk

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := testled_hal.defaultLOCAL_MODULE_RELATIVE_PATH := hwLOCAL_SRC_FILES := testled_hal.cLOCAL_SHARED_LIBRARIES := liblog libcutilsLOCAL_MODULE_TAGS := optionalinclude $(BUILD_SHARED_LIBRARY)

将c文件编译成模块

hardware/libhardware/modules/Android.mk内加入testled

三、编译

模块编译

mmm hardware/libhardware/modules/ testled

在out/target/product/nanopc-t4/system/lib/hw/ 目录下生生成test_led_hal.default.so

全部编译后,test_led_hal.default.so在设备的/system/lib/hw路径下,android frameworks中的JNI调用led设备时,通过一系列转换就会调用到这个库内部的函数,从而调动掉底层的led驱动。

c052rwnrL+ZN3zjkCrvMlzdphwASosWMimrCrKbJZyalpDAdMO3ICcsWKa+rzOVAvmsBaeXx8XFs4gxyh+0PaUw9ylREeORIPdU

扫码关注我们

看更多嵌入式案例

nn5iD9dthHA58V5JCQl7IhqaAZZsGoz5DjOyRXrYpjALRPtIyFa811Gnm2T3zLsjfuM

喜欢本篇内容请给我们点个再看

84b4J4Dsrl87jQicUd+o9UT4Qz3C5GWsHm7VsG539j+sbSljbuypczOnYz3xlGYmEXJgFTzV1AasiouvFUlVi6OL1h5i31tTfHE

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值