Android系统传感器软件模块的设计与分析.doc_第1页
Android系统传感器软件模块的设计与分析.doc_第2页
Android系统传感器软件模块的设计与分析.doc_第3页
Android系统传感器软件模块的设计与分析.doc_第4页
Android系统传感器软件模块的设计与分析.doc_第5页
已阅读5页,还剩57页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

基于Android系统传感器软件模块的设计与分析第一章 绪论1.1 课题研究时代背景以及研究意义随着目前人们对手机依赖程度的不断增加,国内外无论何种品牌的手机均在技术上较传统有了质的飞跃。在现代化背景下,手机性能提升成都不断加大,相关功能也层出不穷,传统手机的基础型功能已经远远无法满足于人们使用手机的需求。在生活水平以及生活质量不断提升条件下,人们对手机的期待程度逐步提升,现如今已经希望手机能够像电脑一样实现多功能,例如收发邮件、处理文档、播放视频、玩游戏、上网等,且功能性的要求也处于不断提升过程之中。例如文档处理方面,需要手机能够读取多种不同类型的文档形式,包含word、PowerPoint、pdf等格式;播放视频同样需要满足多种格式需求,且视频的清晰程度要求也在上升之中;玩游戏需要实现大型游戏,也就是对手机内存的要求不断提升;上网则是对速度的要求,需要手机能够接收到3G、4G网络,实现高速上网。于是乎,智能手机的智能程度不断提升,不同品牌的手机厂商为了实现竞争力的提升以及市场特异性的优势,在操作系统方面开始了独自研发,让广大用户能够通过操作系统实现游戏、功能型软件等应用程序的自主开发。操作系统属于第三方程序的一种,目前智能手机产品主要存在中国台湾宏达(HTC)、韩国三星、美国摩托罗拉、加拿大RIM(黑莓)、美国苹果、诺基亚等,在操作系统方面主要有三星Bada、BlackBerryOS、Symbian、Windows Phone、iPhone OS、Android等。本文研究内容主要为Google的Android系统,这是一种建立在Linux平台开源的手机操作系统,也是全球第一个真正实现开源为移动终端研发的操作系统。它利用了自身免费、开源的特点,让Android系统在短短几年内便迅速的占领了消费者市场,成为了行业巨头。Android系统从技术层面能够被分为多个层面,也就是Linux驱动层、硬件抽象层、框架层、应用层,在传感器模块方面,其同样涉及到了这四个层次的方方面面。在应用层中,编写语言以Java为主,通常情况下属于第三方自主开发,也存在少部分为Google提供给用户的应用软件或是游戏,框架层为Google自主研发产品,在代码体系上处于完整状态,有完善的接口为用户提供操作体验,同时为第三方应用程序的研发提供支持与帮助。硬件抽象层能够提供硬件驱动模块,其状态为封闭源码形式,能够有效分格驱动层与框架层,让Android框架层在研发过程中可以实现完全不受驱动程序干扰。对于驱动层而言,其能够按照硬件设计针对传感器实时寄存器以及初始化的读写,促进传感器工作的正常化。本文基于这一背景,以实现传感器模块的开发为目标,研究了其在驱动层以及硬件抽象层的工作原理,旨在为开发者更便捷的解决传感器相关知识。1.2 国内外研究背景分析Android是Google公司的成员之一,早在2007年年底便已经推出(2007-11-05)。该系统属于建立在Linux内核基础之上的智能型操作系统,并且只能够适用于手机智能,在次年9月,HTC(宏达)与Google联手推出了一款T-Mobile G1,这是Android智能系统的第一款手机,能够支持WCDMA网络,同时还可以搜索到WIFI并自动连接无线网络,通过无线网实现上网功能。依赖着Google的开源特性以及技术支持,Android在短时间内便迅速占领了消费者市场,并一跃处于行业内的领先地位。目前,Android系统在全球的主要竞争对手为RIM的Blackberry OS以及苹果公司的iOS。据调查显示,在2011年的首个季度,Android在全球市场份额方面已经超过了原有行业巨头塞班系统,并且超过程度随着消费者市场的倾向化越来越明显,逐步成为了全球第一。在2012年2月,数据调查显示该系统占到了全球手机智能操作系统的52%以上,其中在我国市场占有率更是达到了68%以上。在智能型手机逐步普及背景下,该系统的游戏、软件等应用程序也在不断完善与发展,相信这个比例也处于不断增多过程之中。作为智能型手机的重要组成部分,传感器功能的目的在于让手机功能更为丰富多彩,让手机用户的体验感不断提升。在Android智能系统中,其对传感器的支持较为多元化,例如接近传感器、温度传感器、压力传感器、光线传感器、陀螺仪、方向传感器、磁力域传感器、加速度传感器等,这些传感器的应用让手机功能实现了丰富多元化的用户体验,从而进一步刺激消费者购买欲。通常而言,智能型手机在传感器方面均会支持接近传感器、光线传感器、方向传感器、磁力域传感器、加速度传感器,但也有一些在研发上投入较多的智能系统能够支持手机陀螺仪。对于Android智能系统而言,其传感器模块涉及到了系统本身的不同层次。传感器设备的运作需要建立在字符控制、设计基础之上,因此在驱动方面经常呈现出普通字符驱动状态;在硬件抽象层方面也会按照原有驱动来设计硬件抽象层。在硬件抽象层中,设计者必须将各种传感器整合成为一体,让其能够在同一环境中正常运作。1.3 主要研究内容本文主要对磁力传感器、加速传感器等,并借助MSM7227芯片为平台,对喘口气模块的构建进行分析,并分析其特征,主要分析内容为:1、国外Android发展现状及其系统构架进行研究和分析;2、ndroid下传下传感器中的硬件抽象层结构进行分析和总结,并编写其传感器的硬件抽象层代码;3、深入研究Android传感器的工作原理,并编写其驱动程序;4、通过模拟和还原设计,Android传感器模块,并通过MSM7227芯片版来实现其传感功能;在现有的传感器硬件的构架当中,其抽象层需要协调多个传感器,因此,抽象层设计的好坏直接关系到整个模块能否正常的运转,这就使得在实现传感器模块过程中,首先要解决抽象层问题,另外对代码的调试也不容忽视。1.4 本论文的结构安排 本研究主要内容,主要划分为七个章节的内容,各个章节的内容主要包括一下几个方面:第一个章节,论述。主要对本研究课题的背景、意义进行介绍,对国内外Android智能手机的研究状况进行了深入分析,探讨了本研究课题的主要内容、目的。第二个章节,介绍相关的技术。对开发过程中所需要使用的关键技术与理论知识进行介绍,主要包括Android编译统、Linux内核概念、Android平台框架等多个方面的介绍。第三个章节,对Android传感器模块进行深入的分析,探究Android传感器模块的设计。通过分析Android传感器模块,将其划分为Linux驱动层、HAL、传感器应用层,传感器模块的功能主要是可以实现Linux驱动层、硬件抽象层,然后对Linux驱动层、硬件抽象层的工作流程进行深入分析。第四个章节,实现Android传感器模块的主要方法。利用Android提供的接口函数,以此来实现传感器模块硬件抽象层,采用input子系统与字符设备实现驱动层传感器的设备控制以及信息数据传输。第五个章节,结束语。对本研究课题中的重点内容进行一个总结,分析Android产品的发展前景。第二章 传感器底层软件的总体设计2.1 Android系统的基本结构HomeContactsPhoneBrowserActivityManagerPackageManagerTelephonyManagerResourceManagerLocationManagerWindowManagerXMPPServiceContentProviderViewSystemNotificationManagerSuface ManagerSGLSSLLibcOpenGL/ESFreeTypeWebKitSQLiteMedia FrameworkAndroid RuntimeCore LibrariseDalvik VMDisplayDriverFlash MemDriverBluetoothDriverCameraDriverBinder(IPC)DriverUSB DriverKeypadDriverWiFi DriverPowerManagemenAduioDrivers一般来说,Android 系统主要分为四层结构,如上图,即:应用程序层、应用程序框架层、系统运行层以及Linux 内核层。 2.1.1 应用程序层介绍Android 平台除了是操作系统外,还包含诸如SMS短信客户端程序、图片浏览器、网页浏览器以及电话拨号程序等等应用程序。此类应用程序都采用Java 语言进行编写的,此外,此类应用程序还能被其他程序进行替换,这就提升了手机操作系统的灵活性,区别于传统手机操作系统中,应用程序被固化在其系统内部。2.1.2 应用程序框架层介绍应用程序框架层是实现核心功能的层级,它不仅能够简化组件的重用,提升程序运行速度,还能使开发人员对程序的的快熟开发,框架层能够实现模块的个性化拓展,因此应用程序框架层是进行Android开发的重要基础。程序功能:(1)Activity Manager,即活动管理器。其主要功能是对Android系统中的各个应用程序的周期,同时还拥有导航回退功能。(2)Window Manager,即窗口管理器。其主要功能是对窗口下的各个应用程序进行管理。(3)Content Provider,即内容提供器。其主要功能是在开启应用程序后,促使不同的应用程序之间能够进行存取或分享相关数据,如:复制粘贴功能等。(4)View System,即通常的视图系统。其主要功能为,对相应的程序,构建其基本组件。(5)Notification Manager,即通告管理器。通告管理器主要功能为对应用程序进行提示信息,其通常的表现形式为,在状态栏进行显示信息。(6)Package Manager,包管理器。主要的功能,就是管理Android系统内部中的全部程序。(7)Telephony Manager,即电话管理器。顾名思义,就是对系统内的所有移动设备功能进行有效管理。(8)Resource Manager,即资源管理器。其主要功能为应用程序提供各种非代码资源,例如图片、本地化字符串(就是通俗的表情包)、或自定义图片字符等等。(9)Location Manager,即位置管理器。其主要是为应用程序提供位置服务。(10)XMPP Service,即XMPP服务。此版块主要提供Google Talk服务。2.1.3 系统运行库层介绍系统运行库层,主要包括Android运行时与系统库两个部分。系统库。整个应用系统赖以形成的支架即系统库。系统库是整个应用程序框架层与Linux 内核层连接的纽带。Surface Manager:其主要功能为,在运行多个应用程序时,能够对程序进行有效管理,并实现存取操作间的互动,并且也能实现2D绘图与3D绘图进行显示、合成。Media Framework:即多媒体库,它是一个基于C+的实现,能够播放和录制多种格式的音频、视频,其主要的编码格式有:MP3、MP4、MPEG4、H264、ARM及AAC格式。SQLite:即轻型的关系数据库引擎,它主要遵守ACID的关系型数据库管理系统,由于其占用资源非常低,所以许多产品都嵌入此种数据库。OpenGL|ES:即OpenGL for Embedded Systems,是OpenGL三维图形API的子集,能够对手机、游戏主设备、PDA等设备等进行嵌而设计的。FreeType:在系统运行库层中,其主要提向量字与点阵字的描绘和显示功能,它能够提供统一的接口来访问多种字体,其主要包括CID、OpenType、CFF 、Type1、Windows FON/FNT、X11 PCF、TrueType等。SGL:为底层的2D图形渲染引擎。SSL:即Secure Sockets Layer 安全套接层,其主要功能是实现网络通信提供数据完整性。Libc:Libc基于BSD的标准C系统数据库,ANSI为最基本的C语言,其主要功能为对embedded linux 的设备定制。2.1.4 Android运行时使用用Java语言,对Android程序在Android运行过程中,Android程序的Dalvik虚拟机与核心库进行深入分析。核心库,主要提供Java语言功能(API为主),如A、Android.os、Android.media等等。Dalvik 虚拟机Dalvik虚拟机是基于栈的传统虚拟机,而是基于寄存器的JAVA虚拟机,它能够实现内存资源的优化使用,同时还能够支持多个虚拟机。值得注意的是,Dalvik虚拟机与J2ME,Android程序在其虚拟机中执行非编码译后的字节码,它主要是将JAVA字解码通过转换工具DX转换成DEX格式的中间码。2.1.5 Linux内核层Android主要基于Linux2.6内核,其主要作用在于,确保系统服务安全,同时系统的内存管理、网络协议、多任务功能、进程管理器、驱动模型等都依赖于Linux内核。2.2 Linux的体系结构属性对于一项规模较大的且系统性较强的、相对而言较为复杂的体系结构而言,其审视系统能够从多角度出发,将复杂问题简单化。在理解方式方面,对体系结构的分析也能够通过建立目标来理解源代码,相对而言这种方式更便于理解。Linux 内核在体系中起到了重要作用,在不同层次方面,其内核能够被分为不同的子系统来完成整个系统的运作。这种Linux 内核在技术层面也能够被看作是一个整体状态,这是由于其自身结构、性能决定的。这种系统将基本型的服务划分到了内核系统之中。但与微内核不同的是,在体系结构方面,微内核还能够提供一些较为基础性的服务,比方说应用程序进程管理、内存管理、I/O管理以及通信管理等,这类具体化的服务通常是深入到微内核层面之中的。随着相关技术的不断发展与完善,Linux 内核在CPU以及内存使用层面明显得到了优化,使用效率较高且运行状态处于稳定形势。另外,对于Linux 内核而言,在复杂性提升条件下其可移植性仍旧处于较高水平。Linux 内核在编译之后能够运行在具有差异性结构体系的平台上以及大量处理器之上。例如其能够在具有MMU(内存管理单元)的处理器上运行,也能够在不提供MMU的处理器上运行,这是由于其内核中的uClinux 移植让其能够实现对非MMU的运行保障与支持。2.3 Linux主要子系统介绍系统调用接口:由于SCI层为内核提供了某些机制的执行,并使从用户控件到内核函数的相关调用变得更加便捷。因此,系统调用接口依赖于整个Linux内核的体系结构。SCI能够提供多路复用的函数调用及多路分解服务。Linux系统调用,能够包含常用系统调用所派生出的函数。进程管理:进程管理的功能在于对程序的执行。在内核中,此类进程被称之为线程,其主要代表单独的处理器虚拟化(如:数据、CPU寄存器等等)。但在Linux实现中,并没有对进程和线程进行区分。内核主要通过SCI提供的程序编程接口来创建新的进程(如exec、fork、或POSIX函数),停止进程(exit、kill),完成其相互间的通信和同步(如POSIX机制或signal)。此外,进程管理还能够使活动进程之间共享的CPU进行优化。由于进程管理能够实现更多线程同时竞争CPU,并且能够在固定时间内满足其操作需求,此类算法被称之为新型的调度算法,即0(1)调度程序。而且0(1)调度程序也能支持多个堆成处理器,并能够在./linux/kernel找到其进程管理的源代码。内存管理:由于计算机内的内存资源分配不合理容易导致其运行效率低下,要实现其高效并能够快速的分配,需对内存资源进行合理的释放或收回。为了有效的提升效率,若是通过VFS在文件系统与用户之间对交换层管理虚拟内存进行提供,那么内存主要是根据相关的内存页方式对其进行管理。Linux,主要包括虚拟映射使用的硬件机制、物理映射使用的硬件机制以及管理过程中可以使用的内存方式。4KB的缓冲器无法满足内存管理要求,Linux针对这个问题,提供了例如slab分配器对4KB缓冲区的抽象。它能够很好的跟踪内存页面,针对各个内存页面的满负荷或空页面情况进行动态的调整。此外通过将页面移出内存,并将页面转存入磁盘中,能够支持多个用1户同时使用内存,可防止内存被耗光的状况。页面被转存如硬盘上,其内存管理的源代码在./linux/mm中是可以找到的,整个过程我们称之为交换。虚拟文件系统:在启动系统的时候对虚拟文件系统进行建立,跟随系统的关闭而消失,由于虚拟文件系统能够提供一个通用的接口给文件系统,所以虚拟文件系统在Linux内核中具有十分重要的作用。虚拟文件系统在SCI内核中,能够在全部的文件系统中对交换层进行一个合理的提供。此外虚拟文件系统还能在用户与文件系统之间提供交换层。在VFS上是对函数的一个通用API抽象,主要的对象有close、open、write等。而在其下面是对文件系统的抽象,其主要是对上层函数的实现方式进行定义。它们是给定文件系统(超过 50 个)的插件。文件系统的源代码可以在 ./linux/fs 中找到。文件层中的缓冲区缓存,主要是提供与具体文件系统没有任何关系的通用函数集给文件系统。缓存曾主要是对数据进行预先读取,以便在需要时优化对设备的访问。缓冲区缓存中的设备驱动程序,将其作为硬件接口,这样能够在很大程度上方便对系统进行操作,以此进一步对硬件设备的工作状态进行控制。2.4 Linux内核的有用特性 基于Linux的特性,Linux常常用来测试新协议。而且Linux能够支持包括典型的TCP/IP协议等大量网络协议,同时也支持大于1GBE和10GBE的高速网络扩展。此外Linux还支持诸如SCTP的协议,Linux内核提供了许多比传输控制协议(TCP)更高级的特性,并逐步取代传输层协议。由于Linux还能支持对软件组件进行添加或删除,因此被称为动态内核。动态内核可以在特定设备需要该模块时,由用户自行插入。在Linux最新的版本中,其新功能是可以对其他操作系统进行操作,因而被称之为系统管理程序。另外,新版本中,对内核也进行了一些修改,它为用户提供了能够让其他操作系统在基于内核的虚拟机之上运行的新接口,因而被称为基于内核的虚拟机。值得注意的是,除了运行Linux的其他实力之外,还有例如Windows®和Microsoft®都可以进行虚拟化,前提是,底层处理器要支持对象的虚拟化的指令。2.5 Android开发环境的搭建本文所研究的传感器模块是在MSM7227为主芯片的设备上进行的,因此,要模拟相应的软硬件环境,首先准备一台X86的计算机,并为其安装Linux系统,确保能够进行Android源码的编译。本文以Ubuntu10.0.4为操作系统,同时在操作系统中配置好所需的软件环境。在Linux内核开发中,git能够使大型项目的管理开发变得简单,其主要是采用分布式的版本库方式进行管理。Git的安装可参考网址:/lib/view/open1324365018280.html。由于Android都使用git工具来进行管理,但是在Android中git库太多,使得管理不便,因而Google在此基础上开发出repo工具,使得Android内众多的git库管理变得更为快捷有效。Repo的下载方法参考网址:/link?url=lca2gpPRuJtwNr45iElrAnmzNsoyQMwBsYIBa456ywZezp7xyNmpxlI-rDzFrDeVB_-QzHDMnxT8UA90KK5I10SWMRFTJ2h92kHzeNhbuHK。安装好git与repo后,再下载包括初始化仓库源码和代码两部分。获取初始化代码后,其仓库使用repo init命令,生成如:repo init- ugit://platform/manifest.git。使用命令后会生成.repo目录,其目录为隐藏目录,这个隐藏目录里为工程管理信息,在repo init之后,就能够用repo sync 命令下载全部代码了。将Android的源码全部下载完毕后,即可开始编译,由于X86的电脑上没有交叉编译环境,因此在对Linux内核进行编译时,需建立交叉编译环境。此外,编译环境还需要辅助工具,例如arm-linux-gcc等,因此在编译之前,需要先将其所在的目录添加到搭建的编译环境的变量之中。其编译所需要的工具安装命令如下:sudo apt-get install makesudo apt-get install gccsudo apt-get install g+sudo apt-get install libc6-devsudo apt-get install patchsudo apt-get install texinfosudo apt-get install libncurses-devsudo apt-get install git-core gnupgsudo apt-get install flex bison gperf libsdl-dev libesdO-devsudo apt-get install libwxgtk2.6-dev build-essential zip curlsudo apt-get install ncurses-devsudo apt-get install valgrindsudo apt-get install python2.5sudo apt-get install sun-java5-jdk将所需工具安装完毕后,交叉编译环境便安装完成,随后即可进行Android源码编译。为了提高效率,精简内核,需要对芯片进行配置,将在目录下通过执行make kemelconfig来编译选项。2.6 Android编译系统介绍编译系统是整个Android开发的重点,由于Android系统较大,其各个编译环境都不同,因此,需要将驱动程序编入内核,将硬件抽象层编入系统之中。Android系统的全部代码主要分核心工程代码、扩展工程代码、包代码三部分。核心工程:是是整个Android编译系统的基础,其在根目录的各个文件夹中。扩展工程:扩展工程的功能在于能够使其他源项目拥有扩展功能,其在external文件夹当中。包:包主要为Android系统提供输入法、应用程序等服务,包所在位置为packages目录下。虽然能将代码划分为三大部分,实际上某些功能的界定较为模糊,Android系统源代码根目录结构如下表2.1所示。bionicC标准函式库 运行时支持:libc、libl、libm、动态 linkerbootloader机启动代码build编译和配置所需的脚本和工具cts兼容性测试框架dalvikdalvik 虚拟机development发应用程序所需的模板和工具device设备相关代码external扩展库frameworks应用程序框架层hardware与硬件相关的库和接口kernel内核ndkndk相关内容out编译后生成的目录,包含构建文件系统所需的文件packagesAndroid的各种应用程序prebuilt对Linux编译的二进制支持sdksdk环境中所需要的内容systeAndroid的基本系统vendor针对不同平台的内核编译脚本Android系统中,的源文件存在与build/core/目录下,其表现形式为文件后缀带mk,也被称为build system。Android build system主要由配置部分和目标构建部分组成,其所有的Makefile文件可分为以下四类:配置类:其主要用来对product及board进行配置,同时可依据系统中的host和target来选择相应的工具,同时可设定相应的编译选项。模块组组织类:主要用来定义如何处理模块中的Android.mk,并定义其采用何种方式生产目标模块。其模块生产的规则定义都位于config.mk里。单个模块编译类:在本地模块的模块文件中,有很多Android.mk。系统生成类:在文件build/core/Makefile中,随处都能看到img方式的文件。Android虚体部分的编译方法较为简单,在Android系统中,其源码根目录当中有Makefile文件,此文件即编译系统的入口,在其目录中直接运行make命令即可对整个Android系统进行编译。 通过Makefile文件中的代码(include build/core/main.mk)即可导入main.mk文件。其中,build/core/main.mk主要作用就是安排build system运行流程,文件main.mk是Makefile的实际主控。Main.mk利用include中存在的一系列种Makefile文件对Android编译系统进行合理的控制。最终Android系统所编译的所有结果存放于根目录下out目录中,其编译的结果一般为如下内容:1、一般编译的内容以主机工具和其所依赖的内容为主(存放地点为out/host)2、还包括对目标机程序的编译(存放地点为out/target)3、此外还有目标机映像文件(其所在位置为out/target/product/msm7227/),其中msm7227为产品名称编号,编译的映像文件一般有三个,以img为后最的文件即映像文件,分别为bootimg(根文件系统)、userdata.img(数据文件系统)、system.img(主文件系统)。其中userdata.img数据文件系统和system.img主文件系统在用户空间运行,而boot.img(根文件系统)则是由kernel和bootloader编译所成,并在内核空间中运行。其中usetdata.img和system.img的编译规则在Android.mk中都有定义,而且这两个系统都有多个模块编译打包后生成。值得注意的是,内核的编译与Android文件系统有所差异,内核的编译即kernelbuild(kbuild)被用语编译内核文件,其中内核编译是对Makefile的扩充,而且大多内核模块都使用内核编译的组织结构kbuild makefile。其build的过程一般分为如下三个阶段:配置阶段:在编译前,首先要确定编译平台及编译目标。编译阶段:在编译时,要建立相应的编译目标和相互关系图。Deploy阶段:对所涉及到的模块逐个安装。Kbuild同样也有三个阶段,如下图所示:SelectKernel versionLocateKernel sourcePatchKernel sourceConfigureKernelBuild KernelInstallKernel图2.4编译Kernel的典型步骤Konfig即对应的就是configurtion阶段,在编译制定目标时,首先要生成.config,其后kbuild会根据之前生成的config进行自动编译。因而,kbuild被称之为独立、全面的编译系统。Kbuild的模块主要有五个部分:顶层模块:主要负责对各个对象进行分类,同时采用相应的规则来生成目标;包含用户配置选项的.config具体平台相关的模块:arch/$(ARCH)/makefile;各类规则文件:scripts/makefile.* ;Kernel目录树下的具体模块:makefiles最简单的kbuild模块只包含一行::obj-y+=foo.o,其表示kbuild在这个目录中。另外,目标文件中名为foo.o的文件,是通过foo.c或foo.S文件编译而来。在kbuild模块编译中,其目标文件所在地点都存在与$(obj-y:)列表中,而且列表依赖于内核的配置。在文件列表中,需要进行整合形成一个built-in.o,再链接到kernel中来,最后使得每个目录下都有一个built-in.o。将linux内核编译并链接后,其生成的ELF映像文件为Vmlinux,其生成规则定义位于顶层目录下的模块当中,系统的所有内核文件都会被编译到内核当中,并形成压缩的内核,一般压缩格式为BIN,内核编译后镜像生成的过程如下图:S(TOPDIR)/vmlinux非压缩内核,ELF格式Arch/arm/boot/compressed/piggy.gz压缩内核,gzig格式Arch/arm/boot/image非压缩内核,BIN格式Arch/arm/boot/compressed/piggy.gz汇编源文件,只包含./piggy.gz的数据段Arch/arm/boot/compressed/head.S汇编源文件,包含对gzip压缩内核进行解压的代码Arch/arm/boot/compressed/vmlinux-lds压缩内核连接脚本Arch/arm/boot/compressed/vmlinux具备自解压功能的压缩内核ELF格式Arch/arm/boot/zimage具备自解压功能的压缩内核,BIN格式图2.5 内核镜像产生过程示意图2.7 本章小结在本章当中,主要对Android软件传感器模块开发即将要用到的理论及相关技术进行了介绍和分析,主要对Android平台框架、Linux内核、Android驱动、Linux驱动差异以及对环境的搭建及其Android的编译系统进行简要介绍,为后续的分析设计及其开发做好准备。第三章 Android传感器模块的分析与设计Android传感器模块的开发分两部分,即内核传感器驱动的开发和硬件抽象层的开发两种。将两者编入Linux内核和Android文件系统,最后通过工具下载到智能手机存储器中,这样传感模块就能够正常运转。目前,Android传感器能够设计到系统的各个层次,而且还能够支持多种传感器。3.1 传感器模块结构分析 当前Android系统能够支持多种传感器,在目前较为常见的行列中,有如下8种传感器。传感器名称及其接口名称如下表3.1所示。表3.1 传感器类型与本地接口传感器JAVA中的名称本地接口名称数值加速度传感器TYPE_ACCELEROMETERSENSOR_TYPE_ ACCELEROMETER1磁力传感器TYPE_MAGNETIC_FIELDSENSOR_TYPE_ MAGNETIC_FIELD2方向传感器TYPE_ORIENTATIONSENSOR_TYPE_ ORIENTATION3陀螺仪TYPE_GYROSCOPESENSOR_TYPE_ GYROSCOPE4光线传感器TYPE_LIGHTSENSOR_TYPE_ LIGHT5压力传感器TYPE_PRESSURESENSOR_TYPE_ PRESSURE6温度传感器TYPE_TEMPERATURESENSOR_TYPE_ TEMPERATURE7接近传感器TYPE_PROXIMITYSENSOR_TYPE_ PROXIMITY8 在Android的传感器层次划分自上而下为:应用层、框架层、JNI层、硬件抽象层和内核层。其中内核层是整个Android传感器的核心即各个传感器的驱动程序;而硬件抽象层主要提供各种接口,并将其定义在hardware/libhardware/include/hardware/目录下的sensors.h文件当中;而框架层主要包含实现传感器模块核心的管理类、传感器的描述性文件、传感器模块的事件类、传感器事件的监听者接口;而应用层主要包括与传感器相关的各个应用程序,其具体关系示意图如下图3.1所示。应用程序SensorManagerSensorlintenerSensorEventSensorSensorevnetListenerSensor JNIAndroid.hardware.sensormanagerSensor Hardware InterfaceSensors Harware Moudule传感器驱动传感器驱动图3.1 Android传感器体系结构图3.2 传感器驱动层的设计与分析在定义方面,传感器相关驱动程序并没有被定义为一个较为标准的状态,其属于非标准状态下的Linux驱动程序。对于Android传感器而言,在驱动程序的设定方面其主要目的在于通过硬件系统得到有效数据,从而利用接口将数据传输给硬件抽象层。在加速度传感器不同时,其特性也存在差异性,在通信方式方面同样不尽相同。本次研究中的传感器开发是建立在尚通MSM7227平台基础之上的,这一平台属于局通公司产品,是一款处于中低端层面、性价比相对较高的处理器解决模式。这类处理器能够实现接近传感器、光线传感器、磁力传感器、加速度传感器功能,方便用户体验。本次研究中在对Android传感器的距离中主要以博世(Bosch)公司的BM020三轴重力加速度传感器为例,这类加速度传感器既能够使用I2C总线协议,又能够使用SPI总线协议来实现通信功能,在使用方面更为便捷。本文中提到的BMA020驱动器采用的是I2C总线协议来实施通信功能。通常而言,加速度传感器内部共有PIN脚12个,每个脚的定义都存在特异性。具体定义及特性见下表3.2。Pin NONameTypeDescriptionConnect to(in I2C)Stand alone(without C)1ReservedDo not connectNCNC2VDDPowerAnalogue power supplyVDDVDD3GNDPowerGroundGNDGND4INTOutputInterruptINT/NCINT5CSBInputChip selectVDDIOVDD6SCKInputSerial clockSCKGND7SDOOutputSerial data outGNDGND8SDIInput/ OutputSerial data in/outSDAGND9VDDIOPowerDingital interface power supplyVDDIOGND10reservedDo not connectNCNC11reservedDo not connectNCNC12reservedDo not connectNCNC表3.2 BMA020 PIN脚定义其中SCK和SDI两个PIN脚连接的是系统的I2C控制器,通过这两个PIN脚,芯片向设备发送和接收BMA020的数据,INT这个PIN脚连接的是中断控制器。VDD和VDDIO这两个PIN脚连接的是主芯片的电源控制器,电压恒定为2.6V。传感器BMA020和主芯片的连接图如图3. 2所示。本次研究中研究的加速度传感器主要是利用了I2C来实现数据上的接收与发送,因此这项设备本身的驱动程序能够被当作是自身的驱动器来操作,在Linux驱动程序中,已经能够将I2C编写到了设备驱动范围内,并且体现为两种形式:一是GPIO的操作,二是Linux I2C驱动体系结构。在GPIO的操作中,在操作过程方面相对复杂,且在系统稳定性以及可移植性方面并不强,因此这种方式采纳人群较少,通常不会被使用。Linux I2C驱动体系结构在操作方面相对简单便捷,只需要在之前将相关设备在I2C上注册,并保障设备通信的通畅程度即可。本文传感器的初始化流程如图3.3所示。开始1读取设备ID是否成功注册工作队列注册Early suspend注册字符设备注册input子系统设备初始化分配内存空间是否成功是否成功是否成功是否成功是否成功是否成功1打印出错信息打印出错信息结束图3.3传感器初始化流程图作为传感器驱动程序的初始化状态,流程在传感器感应到驱动模块产生了加在操作时(加载至内核),其驱动程序能够按照原先设定的步骤来完成操作以及内存分配,将各类型的虚拟设备注册并且将设备寄存器初始化。传感器驱动设计包含的内容较多,例如休眠设计、数据传输、数据采集以及内存分配。本次研究中将内存分配设定为Linux slab分配器,在数据采集方面使用的是“工作队列”状态模式,对寄存器中存在的数据实时轮询采集。在数据传输方面,研究使用的是input子系统,用于实现对数据的发送与接收;在休眠设计方面使用的是Early suspend 机制。3.2.1内存分配操作系统能否有效的对资源进行管理,是其系统好坏的显著标志。因此,内存的管理主要以实现内存时间与内存开销的最小化为目标。本文所研究的内存分配器为Linux slab分配器。目前Linux slab分配器较传统分配器相比,具有许多高效的优点。首先,能够有效避免碎片问题,其在缓存当中,能够对小对象进行合理分配,并对此类对象生命周期进行评估及重新分配。其次,slab分配器能够避免对某一目标多次进行初始化。最后,slab分配器能运行不同的缓存对象占用相同的缓存行,可有效提升缓存利用率。slab结构的高层组织结构如图3.4所示。Kmem_cacheobjectSlabs_fullslabKmem_cacheKmem_cacheSlabs_emptySlabs_partialslabslabpagepagepageobjectobject图3.4slab分配器的主要结构Cache_hain位于最高层,它是slab的缓存链接列表,它的每个元素与kmen_cache都存在引用关系,其主要作用是对管理对象的大小进行定义。在每个元素下有若干个缓存,缓存下又包含slabs列表,这样就形成了一个较为连续的内存块。内存块状态主要存在四种,即:完全分配的(slabs_full)、部分分配的(slabs_partial)、空置及没有对象分配的(slabs_empty)。其中没有对象分配的(slabs_empty)列表中的slab是进行回收(reaping)的主要对象,这样就能重新分配给其他用户继续使用。对象的转移主要在slab中进行分配和释放、当slab被分配并且有对象释放后,完全分配时:slab就会从slabs_full转移到slabs_partial列表中;有对象释放时:slab会从slabs_partial列表再次转移到slabs_empty中去。下表3.3主要列举了主要程序接口函数及其功能。函数功能Kmem_cache_create创建新的缓存,一般在内核初始化或首次加载内核是启动。Kmem_cache_destroy对缓存进行销毁,一般在内核模块卸载时启动,缓存为空时才能调用此函数。Kmem_cache_alloc从一个命名的缓存中分配一个对象使用的函数。Kmem_cache_free将一个对象释放回slab,调用者提供缓存引用和要释放的对象。Kmem_cache_kfree用来对内存进行分配和释放,是内核中常用的管理函数。Kmem_cache_size返回这个缓存所管理的对象大小。Kmem_cache_name在创建缓存时定义。Kmem_cache_shrink通过释放其中的空闲slab进行收缩。表3.3主要API函数及其功能表 在用户控件一般采用malloc函数进行分配内存,用kmalloc或vmalloc来对内核空间进行有效开辟,再用get_free_pages_直接申请页,对其释放内存时,用可kfree,vfree或free_pages。但是kamlloc,vmalloc与get_free_pages_有所区别,kamlloc在内存分配中,主要用语对较小物理内存进行连续申请,且物理地址与虚拟地址是的分配是连续性的。Vmalloc则主要是针对较大对象的内存进行申请,其物理地址申请可以不连续,但虚拟地址仍是连续的,其申请地址在vmalloc_start与vmalloc_end之间。鉴于对性能的考虑,一般对较小的物理内存使用kamlloc,较大块内存才激活vmalloc。此外,get_free_page与kmalloc区别在于,申请内存一般都是在128K(一整页),在最终调用实现上都基本一致。本文所探讨的驱动程序中所用的分配内存函数为kmalloc、slab,由于这种分配机制并不独立,其主要依存于页分配器的基础来进行细粒度的进行内存供调。3.2.2数据采集传感器驱动程序,在信息数据采集方面,主要是利用中断方式与轮询方式完成。在轮询方式方面,系统处于不间断的在数据寄存器中读取数据并收集。这种方式并不会受到传感器状态的较大影响,但由于在现实操作中传感器是处于较为敏感状态的,因此其状态通常会处于不断变化形态。换言之,在这类型高密度数据读取下,要想避免机器出现死机情况,必须设置延时。中断方式则是利用了中断引脚,在传感器出现变化情况下将中断触发,之后通过对中断处理函数的调用来达到从数据寄存器中收集有效数据的目的。总而言之,无论是采用轮询方式还是中断方式均需要利用到工作队列,并且注意在工作队列中的延时设置。工作队列指的是一种机制,一种从内核2.5开始的机制。在这种机制中,相关工作能够执行延后命令,方面操作。从表面而言,其与tasklets类似,都能够通过内核代码完成对尚未发生的某个时间点的函数调用。但实际上,两者间的差异性并不小,其关键差异在于执行状态与能力方面,tasklets,在增值性上周期较短且更为快捷;而且,在原子态状态下,工作

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论