Android HAL硬件抽象层与硬件系统架构

背景

    近几年是互联网高速发展的几年,孕育出了如谷歌、阿里巴巴等许多超级互联网公司,随着互联网的发展已经触到了天花板,一个比互联网更大的市场即将打开,那就是物联网(Internet of Things)。IOT就是将现实世界中的物体连到互联网上,使得物与物、人与物可以很方便的互相沟通,将是下一个规模更大网络发展机遇的风口,是一个高科技公司抢占技术高地和风口,谷歌近日发布了第一代物联网平台操作系统Android Things。华为也推出了IOT操作系统LiteOS。

    说到IOT,我们最多的是理解成智能硬件,万物互联;确实,IOT系统的每个节点都是不同的智能硬件,都是不同的网络智能终端设备。咱们丰巢快递智能柜也在某种程度上说也属于IOT设备。所以开发基于Android系统的丰巢智能柜,高铁寄存柜;我们有必要去搞懂Android的硬件系统和HAL层,正好我以前有过Android系统开发和HAL驱动开发的经验,和大家分享讨论下硬件相关知识。

整体架构

在这里插入图片描述

    如图,Android系统的整个架构由五层结构组成:

  • 应用层(Applications):这一层主要用于手机应用的安装,如系统自带联系人、短信等程序,或是第三方应用程序;
  • 应用框架层(Application framework):这一层主要提供构建应用程序时可能用到的各种API,Android自带的一些核心应用就是使用这些API完成的,开发者也可通过使用API来构建自己的应用程序;
  • 系统运行库层(Libraries And Runtimes):这一层通过一些C/C++库(so库)来为Android系统提供了主要的特性支持。如SQLite库提供了数据库支持,OpenGL ES库提供了3D绘图支持,Webkit库提供了浏览器内核支持等;
  • 硬件抽象层(hardware abstraction layer):安卓驱动硬件的方式与Linux不尽相同。传统Linux的驱动完全存活于内核空间。硬件抽象层(HAL, Hardware Abstraction Layer),把一部分驱动功能放到HAL层中。安卓为什么费尽麻烦增加一个HAL呢?为了保护源代码。Linux内核采用了GPL协议,所以硬件生产商想要支持Linux系统,必须遵照GPL协议公开硬件驱动的源代码。但这些源代码中包含有许多硬件的设计信息,牵涉到硬件生产商的核心利益。而增加了HAL层之后,硬件厂商就不需要开放所有的驱动代码了。
  • Linux内核层(Linux Kernel):Android系统基于Linux2.6内核,这一层为Android设备各种硬件提供了底层驱动,如显示驱动、音频驱动、照相机驱动、蓝牙驱动、Wi-Fi驱动、电源管理等;

    Android HAL层不是Android一直都存在的,是从android4.0.3开始才加入的。Android的HAL是为了保护一些硬件提供商的知识产权而提出的,是为了避开linux的GPL束缚。思路是把控制硬件的动作都放到了Android HAL中,而linux driver仅仅完成一些简单的数据交互作用,甚至把硬件寄存器空间直接映射到user space。而Android是基于Aparch的license,因此硬件厂商可以只提供二进制代码,所以说Android只是一个开放的平台,并不是一个开源的平台。也许也正是因为Android不遵从GPL,所以Greg Kroah-Hartman才在2.6.33内核将Andorid驱动从linux中删除。GPL和硬件厂商目前还是有着无法弥合的裂痕。Android想要把这个问题处理好也是不容易的。

总结下来,Android HAL存在的原因主要有:

1. 并不是所有的硬件设备都有标准的linux kernel的接口;
2. KERNEL DRIVER涉及到GPL的版权。某些设备制造商并不原因公开硬件驱动,所以才去用HAL方 式绕过GPL;
3. 针对某些硬件,Android有一些特殊的需求

硬件系统架构介绍

    目前存在两种HAL架构,位于libhardware_legacy目录下的“旧硬件架构架构”和位于libhardware目录下的“新HAL架构”。两种框架如下图所示。

    老的硬件架构libhardware_legacy 是将 *.so 文件当作shared library来使用,在runtime(JNI 部份)以 direct function call 使用 HAL module。通过直接函数调用的方式,来操作驱动程序。当然,应用程序也可以不需要通过 JNI 的方式进行,直接加载 .so (dlopen)的做法调用.so 里的符号(symbol)也是一种方式。总而言之是没有经过封装,上层可以直接操作硬件。

    现在的 libhardware HAL架构,就有stub的味道了。HAL stub 是一种代理人(proxy)的概念,stub 虽然仍是以 *.so库的形式存在,但HAL已经将 *.so 库隐藏起来了。Stub 向 HAL提供操作函数(operations),而 runtime 则是向 HAL 取得特定模块(stub)的 operations,再 callback 这些操作函数。这种以 indirect function call 的架构,让HAL stub 变成是一种包含关系,即 HAL 里包含了许许多多的 stub(代理人)。Runtime 只要说明类型,即 module ID,就可以取得操作函数。对于目前的HAL,可以认为Android定义了HAL层结构框架,通过几个接口访问硬件从而统一了调用方式。

硬件架构源码分析

    下面我们从普通的振动器硬件的控制vibrate使用开始,从振动器服务的获取getSystemService方法,然后到硬件服务的调用,然后通过HAL硬件抽象层打开硬件驱动节点文件读写等操作,然后到Linux内核态驱动程序,以及处理器芯片引脚的控制与芯片时序驱动,一步一步讲解Android的新的硬件系统架构HAL架构是怎么进行硬件设备调度和控制的…
         [外链图片转存失败]

APP层

Android应用层对振动器的调用形式一般是,通过获取到Vibrator实例后,通过实例方法vibrate来控制震动器的振动操作

Vibrator mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
mVibrator.vibrate(500);

通过源码跟踪,通常调getSystemService调的是ContextImpl里面的getSystemService方法

framework层

位置:frameworks\base\core\java\android\app\ContextImpl.java

@Override
public Object getSystemService(String name) {
    ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
    return fetcher == null ? null : fetcher.getService(this);
}

可以看出是从SYSTEM_SERVICE_MAP集合里面通过那么作为key进行取出ServiceFetcher,然后getService获取到服务的实例。那SYSTEM_SERVICE_MAP集合里面存的服务实例是从哪里来呢?

private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
            new HashMap<String, ServiceFetcher>();

private static void registerService(String serviceName, ServiceFetcher fetcher) {
        if (!(fetcher instanceof StaticServiceFetcher)) {
            fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
        }
        SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
}

private static void registerService(String serviceName, ServiceFetcher fetcher) {
        if (!(fetcher instanceof StaticServiceFetcher)) {
            fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
        }
        SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
    }

static {
		...
        registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
                public Object createService(ContextImpl ctx) {
                    return new SystemVibrator(ctx);
                }});
		...

实际上SYSTEM_SERVICE_MAP里面添加的服务Fetcher是通过类静态块进行registerService注册进去的。接下来我们看看SystemVibrator类的实现

位置:frameworks\base\core\java\android\os\SystemVibrator.java


public class SystemVibrator extends Vibrator {
    private static final String TAG = "Vibrator";

    private final IVibratorService mService;
    private final Binder mToken = new Binder();

    public SystemVibrator() {
        mService = IVibratorService.Stub.asInterface(
                ServiceManager.getService("vibrator"));
    }

    public SystemVibrator(Context context) {
        super(context);
        mService = IVibratorService.Stub.asInterface(
                ServiceManager.getService("vibrator"));
    }

    @Override
    public boolean hasVibrator() {
          ...
          return mService.hasVibrator();

    }

    /**
     * @hide
     */
    @Override
    public void vibrate(int uid, String opPkg, long milliseconds, AudioAttributes attributes) {
        ...
        mService.vibrate(uid, opPkg, milliseconds, usageForAttributes(attributes), mToken);

    }

   ...

    @Override
    public void cancel() {
        ...
        mService.cancelVibrate(mToken);
    }
}

SystemVibrator类相当于一个代理类,主要是通过Binder通信拿到IVibratorService,然后去远程调用对应的方法
,我们看到远程的Service IBinder是怎么获取过来的,看看ServiceManager.getService(“vibrator”)查找ServiceManager的getService方法的具体实现

位置:frameworks\base\core\java\android\os\ServiceManager.java

public final class ServiceManager {
    private static final String TAG = "ServiceManager";

    private static IServiceManager sServiceManager;
    private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>();

    private static IServiceManager getIServiceManager() {
        if (sServiceManager != null) {
            return sServiceManager;
        }

        // Find the service manager
        sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
        return sServiceManager;
    }

    ....
    public static IBinder getService(String name) {
        try {
            IBinder service = sCache.get(name);
            if (service != null) {
                return service;
            } else {
                return getIServiceManager().getService(name);
            }
        } catch (RemoteException e) {
            Log.e(TAG, "error in getService", e);
        }
        return null;
    }


    public static void addService(String name, IBinder service) {
        try {
            getIServiceManager().addService(name, service, false);
        } catch (RemoteException e) {
            Log.e(TAG, "error in addService", e);
        }
    }

    ....

}

ServiceManager.getService(“vibrator”)获取到的IBinder是从sCache HashMap里面获取到的,我们查查是怎么添加进去的。

位置:frameworks\base\services\java\com\android\server\SystemServer.java

public static void main(String[] args) {

        new SystemServer().run();
}


//run
private void run() {
	  ...
    //开始启动服务
	  startBootstrapServices();
    //开启核心服务
    startCoreServices();
    //开启另外一些服务
    startOtherServices();
	  ...
}
//startOtherServices
private void startOtherServices() {

	  ...
	  Slog.i(TAG, "Vibrator Service");
    vibrator = new VibratorService(context);
    ServiceManager.addService("vibrator", vibrator);
}

系统在初始化时候,SystemServer.main()方法,然后调用run调用了startOtherServices()这时候可以看出其实是在SystemServer注册了VibratorService服务,然后加入了ServiceManager里面去管理.想知道Android系统启动流程,可以看看我的另外一篇博客:https://blog.csdn.net/zgkxzx/article/details/88623498

位置:frameworks\base\services\core\java\com\android\server\VibratorService.java

public class VibratorService extends IVibratorService.Stub
        implements InputManager.InputDeviceListener {

	native static boolean vibratorExists();
    native static void vibratorOn(long milliseconds);
    native static void vibratorOff();

		...
	@Override // Binder call
  public void vibrate(int uid, String opPkg, long milliseconds, int usageHint,
            IBinder token) {
        ...
        startVibrationLocked(vib);

    }
	 //
	 private void startVibrationLocked(final Vibration vib) {
            ...
            //开启VibrateThread线程
            mThread = new VibrateThread(vib);
            mThread.start();
        }
  }

	private class VibrateThread extends Thread {
		public void run() {
			...
			VibratorService.this.doVibratorOn(duration, uid, usageHint);
		}
	}
	private void doVibratorOn(long millis, int uid, int usageHint) {
			...
      //调用JNI Native本地方法
        vibratorOn(millis);

      }
    }
  }

VibratorService服务通过创建了VibrateThread线程,然后去调用Native本地端的振动器的接口vibratorOn方法

HAL层

位置:frameworks\base\services\core\jni\com_android_server_VibratorService.cpp

#include <hardware_legacy/vibrator.h>

#include <stdio.h>

namespace android
{

static hw_module_t *gVibraModule = NULL;
static vibrator_device_t *gVibraDevice = NULL;

static void vibratorInit(JNIEnv /* env */, jobject /* clazz */)
{
    ...
    int err = hw_get_module(VIBRATOR_HARDWARE_MODULE_ID, (hw_module_t const**)&gVibraModule);

}



static void vibratorOn(JNIEnv* /* env */, jobject /* clazz */, jlong timeout_ms)
{
     ...
    int err = gVibraDevice->vibrator_on(gVibraDevice, timeout_ms);

}

static void vibratorOff(JNIEnv* /* env */, jobject /* clazz */)
{
    ...
    int err = gVibraDevice->vibrator_off(gVibraDevice);
}

static const JNINativeMethod method_table[] = {
    { "vibratorExists", "()Z", (void*)vibratorExists },
    { "vibratorInit", "()V", (void*)vibratorInit },
    { "vibratorOn", "(J)V", (void*)vibratorOn },
    { "vibratorOff", "()V", (void*)vibratorOff }
};

int register_android_server_VibratorService(JNIEnv *env)
{
    return jniRegisterNativeMethods(env, "com/android/server/VibratorService",
            method_table, NELEM(method_table));
}

};

com_android_server_VibratorService.cpp 这个典型的HAL抽象层,通过hw_get_module获取到hw_module_t硬件模块描述结构体对象,然后对改对象进行vibratorOn或vibratorOff调用控制。

位置:hardware/libhardware/modules/vibrator/vibrator.c

#include <hardware/vibrator.h>
#include <hardware/hardware.h>


static const char THE_DEVICE[] = "/sys/class/timed_output/vibrator/enable";


static int sendit(unsigned int timeout_ms)
{
    int to_write, written, ret, fd;

    ...
    //获取到驱动设备节点的文件描述符
    fd = TEMP_FAILURE_RETRY(open(THE_DEVICE, O_RDWR));

    //对设备文件进行写操作
    written = TEMP_FAILURE_RETRY(write(fd, value, to_write));

    //关闭文件
    close(fd);

    return ret;
}

static int vibra_on(vibrator_device_t* vibradev __unused, unsigned int timeout_ms)
{
    return sendit(timeout_ms);
}

static int vibra_off(vibrator_device_t* vibradev __unused)
{
    return sendit(0);
}

static int vibra_close(hw_device_t *device)
{
    free(device);
    return 0;
}

static int vibra_open(const hw_module_t* module, const char* id __unused,
                      hw_device_t** device __unused) {


    vibradev->common.tag = HARDWARE_DEVICE_TAG;
    vibradev->common.module = (hw_module_t *) module;
    vibradev->common.version = HARDWARE_DEVICE_API_VERSION(1,0);
    vibradev->common.close = vibra_close;

    vibradev->vibrator_on = vibra_on;
    vibradev->vibrator_off = vibra_off;

    *device = (hw_device_t *) vibradev;

    return 0;
}


static struct hw_module_methods_t vibrator_module_methods = {
    .open = vibra_open,
};

struct hw_module_t HAL_MODULE_INFO_SYM = {
    .tag = HARDWARE_MODULE_TAG,
    .module_api_version = VIBRATOR_API_VERSION,
    .hal_api_version = HARDWARE_HAL_API_VERSION,
    .id = VIBRATOR_HARDWARE_MODULE_ID,
    .name = "Default vibrator HAL",
    .author = "The Android Open Source Project",
    .methods = &vibrator_module_methods,
};

这里是com_android_server_VibratorService.cpp文件的头文件,主要是HAL的接口描述映射关系,以及Linux用户层的驱动文件打开与控制,vibra_on与vibra_off实际上最终能调用的是sendit函数,通过open方法打开驱动节点/sys/class/timed_output/vibrator/enable进行写操作,来实现振动器Vibrator硬件设备的控制。

Linux驱动层

位置:drivers/misc/misc_sysfs.c

#include <linux/kernel.h>
...
#include <mach/gpio.h>

 // vibrator 对应的GPIO
 #define  VIBRATOR_POWER_PORT (EXYNOS4_GPD(1))

 static unsigned char vibrator_status = 0;


 static void vibrate_init(void)
 {
     int ret;

     ret = gpio_request(VIBRATOR_POWER_PORT, "GPX1");
     if(ret)
        printk("open  vibrator device fail\n");
      //VIBRATOR_POWER_PORT引脚加入上拉配置
     s3c_gpio_setpull(VIBRATOR_POWER_PORT, S3C_GPIO_PULL_UP);
     //VIBRATOR_POWER_PORT引脚输出低电平
     gpio_direction_output(VIBRATOR_POWER_PORT, vibrator_status);
 }


 //读函数
 static ssize_t show_vibrator_onoff (struct device *dev, struct device_attribute *attr, char *buf)
 {
     return    vibrator_status;
 }
 //写函数
 static ssize_t set_vibrator_onoff (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
      unsigned int    vibrator_status;

     if(!(sscanf(buf, "%u\n", &vibrator_status)))     
        return    -EINVAL;
     if(!vibrator_status )    
     {
         vibrator_status = 0;
         //VIBRATOR_POWER_PORT引脚输出低电平
         gpio_direction_output(VIBRATOR_POWER_PORT, GPIO_LOW);
     } else  {
         vibrator_status = 1;
          //VIBRATOR_POWER_PORT引脚输出高电平
         gpio_direction_output(VIBRATOR_POWER_PORT, GPIO_HIGH);
     }

     return count;
 }

 static    ssize_t show_vibrator_onoff    (struct device *dev, struct device_attribute *attr, char *buf);
 static     ssize_t set_vibrator_onoff    (struct device *dev, struct device_attribute *attr, const char *buf, size_t count);

 static DEVICE_ATTR(vibrator_onoff, S_IRWXUGO, show_vibrator_onoff, set_vibrator_onoff);

 static struct attribute *control_sysfs_entries[] = {
     &dev_attr_vibrator_onoff.attr,
     NULL
 };

 static struct attribute_group control_sysfs_attr_group = {
     .name   = NULL,
     .attrs  = control_sysfs_entries,
 };
//探测函数,驱动框架第一个初始化的函数
 static int control_sysfs_probe(struct platform_device *pdev)    
 {
     printk("vibrator probe");
     vibrate_init();
     return    sysfs_create_group(&pdev->dev.kobj, &control_sysfs_attr_group);
 }

 staticint control_sysfs_remove(struct platform_device *pdev)    
 {
     sysfs_remove_group(&pdev->dev.kobj, &control_sysfs_attr_group);
     return    0;
 }


 static struct platform_driver control_sysfs_driver = {
     .driver = {
         .name = "misc_ctl",
         .owner = THIS_MODULE,
     },
     .probe         = control_sysfs_probe,
     .remove     = control_sysfs_remove,
 };
 // 将vibrator注册到platform总线
 static int __init control_sysfs_init(void)
 {    
     return platform_driver_register(&control_sysfs_driver);
 }

 static void __exit control_sysfs_exit(void)
 {
    platform_driver_unregister(&control_sysfs_driver);
 }

 module_init(control_sysfs_init);
 module_exit(control_sysfs_exit);

 MODULE_DESCRIPTION("misc control driver for zgkxzx");
 MODULE_AUTHOR("other");
 MODULE_LICENSE("GPL");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值