背景
近几年是互联网高速发展的几年,孕育出了如谷歌、阿里巴巴等许多超级互联网公司,随着互联网的发展已经触到了天花板,一个比互联网更大的市场即将打开,那就是物联网(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");