Android底层软硬件结合开发

Android底层软硬件结合开发概述

Android底层软硬件结合开发概述

Android是 个开源的智能移动平台 一个开源的智能移动平台, 任何 个厂商拿 一个厂商拿到 Android Source 都可以基于自己的硬件架构设计

移动设备。

硬件多样化

厂商自己的利益

软硬件结合开发的弊端?

失去了Android应用的跨平台特性

由于不同厂商研发能力参差不齐,应用程序的稳定性及性能有所不同

分类

NDK开发:

从应用角度来开发软硬结合代码

适用于单个应用程序的底层结合需求

HAL硬件抽象层开发:

从整个系统框架需求角度来开发本地程序

适用于共享功能软硬结合代码

HAL 概念

HAL( Hardware Abstract Layer)硬件抽象层是Google开发的Android系统里上层应用对底层硬件操作屏蔽的一个软件层次,说白了,就是上层的应用不用关心底层硬件具体是如何工作的,只要向上提供一个统一的接口即可,这种设计思想广泛的存在于当前的软件架构设计里。

image-20200706134655889

image-20200706134701523

image-20200706134709193

image-20200706134718998

image-20200706134646845

HAL存在的原因

1、 并不是所有的硬件设备都有标准的 linux kernel 的接口。

2、 Kernel driver涉及到GPL的版权。某些设备制造商并不愿意公开硬件驱动,所以才通过HAL方式绕过GPL。

3、 针对某些硬件, Android有一些特殊的需求。

HAL简介及现状分析

现有HAL架构由 Patrick Brady (Google) 在2008G l oogle I/O演讲中提出, 从上面架构图我们知道,HAL 的目的是为了把 Android framework 与Linux kernel 完整「隔开」。让 Android 不至过度依赖 Linux kernel, 有点「kernel independent」的意思。

AL简介及现状分析

HAL 主要的实现储存于以下目录

libhardware_legacy/ ‐ 旧的架构、 采取链接库模块的观念进行

libhardware/ ‐ 新架构、调整为 HAL stub 的观念

旧的HAL 架构(libhardware_legacy)

libhardware_legacy 作法,是传统的「module」方式,也就是将 *.so 文件当做「shared library」来使用,在runtime(JNI 部份) 以 direct functioncall 使用 HAL module。通过直接调用函数的方式,来操作驱动程序。

当然,应用程序也可以不需要通过 JNI 的方式进行, 直接加载 .so 库(dlopen)的做法调用.so 里的符号(symbol)也是 一种方式。

总而言之是没有经过封装,上层可以直接操作硬件。

image-20200706134945797

image-20200706135452501

新的HAL 架构(libhardware)

现在的 libhardware 架构,就有「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层结构框架,通过几个接口访问硬件从而统一了调用方式。

image-20200706135547846

image-20200706135611185

HAL_legacy和HAL的对比

  • HAL_legacy:旧式的HAL是一个模块,采用共享库形式,在编译时会调用到。 由于采用 function call 形式调用,因此可被多个进程使用,但会被 mapping 到多个进程空间中, 同时需要考虑代码能否安全重入的问题(thread safe)。
  • HAL: 新式的HAL采用 HAL moduleHAL stub 结合形式,HAL stub不是一个share library,编译时上层只拥有访问HAL stub的函数指针, 并不需要HAL stub。 上层通过HAL module提供的统一接口获取并操作HAL stub,so文件只会被mapping到一个进程, 也不存在重复mapping和重入问题。

HAL_legacy和HAL的对比

Module

角色是被调用 , 在Android架构里面仅作为程序库(library)用途

Stub

Stub又称为代理人(proxy) , 扮演操作供应者的概念(operations provider)

HAL_legacy和HAL的对比

HAL stub的框架比较简单: 三个结构体、 两个常量、 一个函数

它的定义在:

 hardware/libhardware/include/hardware/hardware.h
 hardware/libhardware/hardware.c  

HAL Stub架构分析

 /*
 每个一个HAL Stub都通过 hw_module_t 来描述, 我们称之为一个Stub对象。你可以去“ 继承 ”这个 hw_module_t,然后扩展自己的属性,这个HAL Stub对象必须定义为一个固定的名字:HMI( Hardware Module Information ) ,每一个Stub对象里都封装了一个函数open,通过这个函数来打开这个硬件Stub设备,返回这个硬件对应的Operation interface。
 */
 struct hw_module_t;
 /*
 HAL Stub对象的open描述结构体, 它里面只有一个元素: open函数指针
 */
 struct hw_module_methods_t;
 ​
 /*
 由结构体hw_module_t可知,它的open函数返回一个硬件对应的Operation interface, 这个硬件的operation interface的描述由hw_device_t 结构体来描述
 */
 struct hw_device_t;
 // 这个就是HAL Stub对象固定的名字
 #define HAL_MODULE_INFO_SYM HMI
 // 这个是以字符串的名字
 #define HAL_MODULE_INFO_SYM_AS_STR "HMI"
 //这个函数是通过硬件名来获得硬件HAL Stub对象
 int hw_get_module(const char *id, const struct hw_module_t **module);
 //注册一个Stub对象
 const struct led_modulet_HAL_MODULE_INFO_SYM = {
     common: {
     tag: HARDWARE_MODULE_TAG,
     version_major: 1,
     version_minor: 0,
     id: LED_HARDWARE_MODULE_ID,
     name: "led HAL Stub",
     author: "farsight",
     methods: &led_module_methods,
     },
     // 扩展属性放在这儿
 }

image-20200706135929366

image-20200706135949036

Android里的Jni调用机制

JVM 很好的解决java的可移植性问题,使得java软件可以在不同的硬件平台下运行,但是JVM不是万能的,毕竟它只是一个模拟环境,对于一些外围的硬件就很难模拟, JVM只是模拟了一部分的寄存器, 栈结构, JVM储存器,这些都是软件运行的基础硬件结构。

对于像android手机这样的平台, 有很多的外围设备在软件层是需要操作的,如wifi,蓝牙,触摸屏,重力感应,键盘等,如果直接通过java语言操作是很难实现的, JVM无法模拟这些硬件。

JNI( Java Native Interface ), 中文为JAVA本地调用。 从Java1.1开始,Java Native Interface( JNI )标准成为java平台的一部分,它允许Java代码 和 其他语言写的代码进行交互。 JNI一开始是为了本地已编译语言, 尤其是 C 和 C++ 而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。使用 java 与本地已编译的代码交互,通常会丧失平台可移植性。

但是, 有些些情况下这样做是可以接受的, 甚至是必须的,比如, 使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能。 JNI标准至少保证本地代码能工作在任何Java虚拟机实现下。

image-20200706140038704

Jni在 Java和C、 C++等语言之间建立了一个桥梁作用,因此, JNI首先要做的,就是统一两者间的数据类型。

所有其它引用类型,在JNI中都被定义为 jobject 类型,在C中都定义为 void*。

Java Language TypeJNI Type
booleanjboolean
bytejbyte
charjchar
shortjshort
intjint
longjlong
floatjfloat
doublejdouble

Java中可以直接调用底层语言的函数或方法, Jni规定了Java调用底层语言的方法签名规范。

类型签名Java 类型类型签名Java 类型
Zboolean[[]
Bbyte[Iint[]
Cchar[Ffloat[]
Sshort[Bbyte[]
Iint[Cchar[]
Jlong[Sshort[]
Ffloat[Ddouble[]
Ddouble[Jlong[]
Lfully-qualified-class(全限定的类)[Zboolean[]

Android里的Jni调用机制

  • 函数签名通常是以下结构: 返回值 fun(参数1,参数2,参数3) ;
  • 其对应的Jni方法签名格式为: (参数1参数2参数3)返回值
  • 注意:

函数名,在Jni中没有体现出来

参数列表相挨着, 中间没有逗号, 没有空格

返回值出现在()后面

如果参数是引用类型, 那么参数应该为: L类型;

HAL Led调用流程

/LedDemo/Led Service(java)/Led Service(Native)/Led HAL Stub1:创建服务对象<<create>>2:通过JNI初始化本地服务()3: 查找并得到HAL操作接口()4:返回device操作接口5:操作service提供的API()6: 通过JNI调用本地服务操作接口()7: 调用保存的devicer操作接口()8: 返回HAL操作结果9: 返回本地服务操作结果10: 返回框架服务操作结果/LedDemo/Led Service(java)/Led Service(Native)/Led HAL Stub
/Led APP/Led Service(java)/Led Service(Native)/Led HAL Stub1:new LedService()2:system.loadLibrary()3: JNI_OnLoad()注册java方法与本地函数的映射关系4: _init()5: hw_get_module()6: Return module_t object7: callback module_t open interface()8: Return device_t operations9: LedService.set_on/set_off()10: _set_on, _set_off()11: devict_t->set_on/set_off()/Led APP/Led Service(java)/Led Service(Native)/Led HAL Stub
  • 13
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Android底层开发指的是在Android操作系统中对底层系统组件进行开发和调试的过程。底层开发需要对操作系统的内部机制、底层接口和系统调用有深入的了解。 在Android底层开发中,需要掌握Linux内核、C/C++编程语言以及JNI(Java Native Interface)等技术。开发者需要了解Linux内核的机制和原理,以便能够理解和分析Android系统在底层运行时的行为和逻辑。 在底层开发中,还需要通过C/C++编程语言来编写底层库和驱动程序,与硬件进行交互和通信。这些底层库和驱动程序负责实现Android系统各个组件的底层功能,如图形显示、音频处理、网络通信等。 另外,JNI技术用于在Java层和底层库之间进行交互。通过JNI,可以调用底层库的函数和方法,实现Java层与底层的数据传递和功能调用。 底层开发中经常会涉及到调试和性能优化的工作。开发者需要使用调试工具来分析和追踪底层代码的执行过程,以及解决底层开发中遇到的问题和bug。性能优化方面,可以通过调整底层代码和参数来提高系统的性能和响应能力。 总之,Android底层开发是一项需要对操作系统原理和底层技术有深入了解的工作。通过学习和实践,开发者可以掌握底层开发技术,为Android系统的功能和性能做出贡献。 ### 回答2: Android底层开发是指在Android操作系统中直接与硬件进行交互的开发工作。在Android底层开发中,开发者需要熟悉Linux内核、硬件驱动程序以及底层库等关键技术。 Android操作系统基于Linux内核,因此熟悉Linux内核是进行Android底层开发的基础。开发者需要了解Linux内核的基本原理和结构,以便理解Android系统底层的运行机制。 硬件驱动程序是Android底层开发的重要组成部分,它们负责将硬件设备与Android系统进行连接和通信。开发者需要掌握硬件驱动的编写和调试技巧,以确保硬件设备在Android系统中能够正常工作。 底层库是Android底层开发的另一个关键技术。Android提供了一系列的底层库,用于实现底层功能,比如图形处理、网络通信、多媒体播放等。开发者需要熟悉这些库的使用方法和原理,以便在底层开发中进行功能的实现和调试。 Android底层开发通常涉及到一些高级的编程语言,比如C/C++。开发者需要熟练掌握这些编程语言,以便能够编写出高效和稳定的底层代码。 总之,Android底层开发是一项复杂而庞大的工作,需要开发者具备扎实的技术基础和深厚的理论知识。只有掌握了底层开发所需的关键技术,开发者才能够在Android系统中开发出高效、稳定和功能丰富的应用程序。 ### 回答3: Android底层开发是指在Android操作系统上进行系统级别的功能开发Android底层开发主要包括四个方面的内容:内核开发、HAL(硬件抽象层)开发、驱动程序开发底层开发。 首先,内核开发是指对Android系统内核进行修改和优化,以满足特定需求,并提供更好的性能和稳定性。内核开发需要对操作系统的核心组件进行深入研究和理解,包括进程管理、内存管理、文件系统等。 其次,HAL开发通过编写硬件抽象层的代码,将硬件和操作系统进行连接。这样做的目的是为了让Android系统能够支持不同品牌和型号的硬件设备,如传感器、摄像头、显示屏等。HAL开发需要理解硬件设备的工作原理和规范,并编写对应的接口和驱动程序。 驱动程序开发是为了让Android系统能够正确地识别和使用硬件设备。驱动程序是一种特殊的软件,用于与硬件设备进行通信和控制。驱动程序开发需要具备底层编程语言的知识,如C或C++,以及硬件设备的技术规范和接口协议。 最后,底层开发是指编写和优化Android系统底层的库文件,以提供一些基础的功能和服务,如网络通信、图形显示、音频处理等。底层开发需要对操作系统的功能和架构有深入了解,并具备编程技巧和算法优化的能力。 总之,Android底层开发需要深入理解操作系统和硬件设备的工作原理,具备底层编程语言的知识和技能,以及良好的系统分析和优化能力。通过进行Android底层开发开发者能够深入了解Android系统的运行原理,提升系统性能,并实现定制化和优化的功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Make程序设计

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值