2016-10-08 12:20:48 u013738338 阅读数 1091
  • Android底层技术:HAL驱动开发

    本课程提供开发者学习Android底层的HAL(硬件抽象层)的开发方法和技术。HAL所在的位置是介于Android系统服务与Linux内核之间,HAL Driver是以library形式出现,给HAL Stub调用,供Android System架构者调用。而HAL Stub则是google设计出来的,保护硬件厂商的硬件驱动。

    18253 人正在学习 去看看 高煥堂

深度探索 HAL与驱动开发

1.1 Android系统架构
Android的系统架构分为4层。
第1层:Linux内核
主要包括Linux的驱动程序以及内存管理、进程管理、电源管理等程序。Android使用Linux2.6作为其内核,不同Android版本的驱动可能并不通用。
主要讲开发第1层的驱动程序,以及再不同Linux版本、硬件平台移植驱动程序。

    第2层:C/C++代码库
        主要包括使用C/C++编写的代码库(Linux下的.so文件)。

    第3层:Android SDK API
        Java API层,用Java编写的各种Library。参考《Android开发权威指南》

    第4层:应用程序
        相当于Android的UI,所有的Android应用程序都属于这一层,主要依靠第3层中的Android SDK API来完成各种功能。

1.2 Android系统移植的主要工作
Android移植可分为两部分:应用移植和系统移植。
本书的Android移植是指Android操作系统的移植,包括Linux驱动、HAL程序库的移植。
Android系统移植是指让Android操作系统在某个特定硬件平台上运行,使操作系统在某个特定硬件平台上运行的一个首要条件就是该操作系统支持硬件平台的CPU架构。要想Android在不同硬件平台上正常运行,只支持CPU架构还不行,必须要让Android可以识别平台上的各种硬件。这些工作主要由Linux内核完成,主角就是Linux驱动。因此系统移植除了移植CPU架构,最重要的就是移植Linux驱动。
HAL(Hardware Abstraction Layer),硬件抽象层,位于第2层,即普通的Linux程序库(.so文件),Android SDK通过HAL直接访问Linux驱动。Android并不像其他的Linux系统一样由应用程序直接访问驱动,而是中间通过HAL隔了一层。

Android移植的主要工作:
    一、移植Linux驱动
    二、移植HAL

Android和Linux内核版本说明:
Android移植在很大程度上是Linux内核的移植。Linux内核移植主要就是移植驱动程序。不同Linux版本的驱动程序不能通用。Android版本和Linux版本不同,无论哪个Android版本,其Linux内核版本都是Linux2.6或Linux3.0(或更高),只是小版本号不同。所以就算同一个Android版本,Linux内核也可能不同。移植Linux驱动时,主要应考虑Linux内核的版本,就算Android版本不同,只要Linux内核版本相同,Linux驱动就可以相互替换,有时需要考虑HAL是否与Linux驱动兼容。

1.3 查看Linux内核版本
Linux内核主要维护3个版本:Linux2.4、Linux2.6(使用最广泛)、Linux3.x。
可以在Android系统中的“设备”—->“关于手机”中查看当前Android系统采用的Linux内核版本。

查看Linux系统的内核版本,两种方法:
1、Linux终端执行
       #uname -a
2、Linux终端执行
       #cat /proc/version

注意:
/proc不是普通文件系统,是内核的映像,该目录中的文件是存放在系统内存中的。

1.5 如何学习Linux驱动开发
学习Linux驱动开发条件:
Linux操作系统,用来开发和测试Linux驱动:如ubuntu Linux10.04以上版本。
GNU C,是对标准C的扩展,是Linux/UNIX下最常用的C语言编译环境。
需要一些与驱动相关的硬件知识。
基于ARM11的开发板,如S3C6410
练习实践

1.6 Linux设备驱动
如果应用程序直接访问硬件,就会造成与硬件耦合度过高的情况。
驱动是直接和硬件交互的一类程序,负责对硬件进行抽象。

计算机系统的硬件主要由CPU、存储器和外设组成。驱动针对的对象是存储器和外设(包括CPU内部集成的存储器和外设),而不是针对CPU核。
Linux将存储器和外设分为3大类:
字符设备(Character devices)
块设备(Block devices)
网络设备(Network devices)

字符设备指那些必须以串行顺序依次进行访问的设备,如:触摸屏、磁带驱动器、鼠标、键盘等。不经过系统的快速缓冲。
块设备可以用任意顺序进行访问,以块为单位进行操作,如:硬盘、软驱等。经过系统的快速缓冲。
字符设备和块设备都是用文件系统(Linux通过文件系统访问驱动)的操作接口open、close、read、write等函数进行访问。

1.7 见识驱动:LED

任何的Linux驱动都有一个装载函数(装载驱动时调用,通过module_init()宏指定)和一个卸载函数(卸载驱动时调用,通过module_exit()宏指定)。

1.8 小结
Linux驱动只和Linux内核有关,与用户使用的Linux系统无关。只要使用了同样的Linux内核,驱动就可以通用。只有组成内核版本号的五部分完全相同,才能说明两个Linux系统内核相同。
学习Android驱动开发,实际上就是学习Linux驱动开发。Android增加了一个HAL,是Android特有的。HAL不是必需的,最好使用HAL程序库。

第2章 搭建Android开发环境

搭建Android底层开发环境:
Android应用程序开发环境
Android NDK开发环境
交叉编译环境

2.1 Android底层开发需要哪些工具

开发、测试和调试Linux驱动、HAL程序库需要的工具:
JDK6或以上版本
Eclipse3.4或以上版本
ADT(用于开发Android应用程序)
CDT(用于开发Android NDK程序)
Android SDK
Android NDK
交叉编译环境
Linux内核源代码
Android源代码
minicom:用于调试开发板的串口工具

2.2 安装JDK

JDK下载地址:
http://www.oracle.com/technetwork/java/javase/downloads/index.html

mkdir -p developer/jdk8/

tar -xvf …

vim /etc/profile

末行添加:
export PATH=.:/developer/jdk/jdk8/bin:$PATH

source /etc/profile

echo $PATH

2.3 搭建Android应用程序开发环境

2.3.1 安装Android SDK
下载SDK:
http://developer.android.com/sdk/index.html

8729e6f2f1fa58f04df9f8d1caac2f5be9dfc549

725bb360f0f7d04eaccff5a2d57abdd49061326d

3 Git使用入门

3.1 安装Git
ubuntu 10系统中安装Git:
#sudo apt-get install git
#sudo apt-get install git-doc git-svn git-email git-gui gitk
ubuntu 低版本系统中安装Git:
#sudo apt-get install git-core
#sudo apt-get install git-doc git-svn git-email git-gui gitk
Redhat、Fedora、CentO S系统中安装Git:
#yum install git
#yum install git-doc git-svn git-email git-gui gitk

如果Linux系统没有为root用户设置密码,用sudo passwd root命令设置root密码。

3.2 查看Git文档
Linux下使用man命令查看帮助,如:
#man git-checkout
安装git-doc后会安装git的文本格式和HTML格式的文档,所有文档都存在/usr/share/doc/git-doc/目录下。
以文本形式查看指定的文档,使用如下命令:
#git help
#git help git-checkout
#git help -w git-checkout 查看HTML格式的文档。

3.3 源代码的提交与获取

3.3.1 创建版本库:git init
Git的版本库分为本地版本库和远程版本库。
访问本地版本库不需要任何的权限,不需要联网。要修改Git源代码托管服务器中的源代码,必须使用git clone命令在本地建立一个与远程版本库一样的本地版本库,必须要联网。
建立开源项目步骤:
在本地创建一个空的版本库,建立一个开源项目的工作目录(/home/demo/helloworld-git/):
#mkdir -p /home/demo/helloworld-git
#cd /home/demo/helloworld-git
#git init
#ls -al 可以看到.git文件夹
空的版本库创建成功, /home/demo/helloworld-git/目录下有一个隐藏的.git目录,即本地版本库。.git目录下有一些子目录和文件。
3.3.2 将文件提交到本地版本库(.git/目录)
在/home/demo/helloworld-git/目录下创建helloworld.c文件:
#cd /home/demo/helloworld-git
#echo “Hello world!” > helloworld.c
将helloworld.c文件添加到本地版本库的索引中,并提交到版本库:
#git add helloworld.c
#git commit -m ‘helloworld-master’
其中,-m命令行参数是本次提交的备注,必修指定该信息。
#git log 显示日志信息
如果提交到本地版本库中的文件被误删或者误改,可以恢复到最近一次提交的状态:
#git checkout helloworld.c

3.3.3 创建本地分支:git branch
在创建本地分支之前可以先了解下当前版本库包含哪些本地分支:
#git branch
#git branch -a
建立一个新的分支:
#git branch new-branch

查看分支时,分支前的星号(*)表示当前工作目录在哪个分支下。

将修改后的文件提交到工作目录当前所在的本地分支:
    #git commit
删除刚建立的分支(在分支中所做的一切修改都被删除):
    #git branch -D new-branch

3.3.4 切换本地分支:git checkout
将当前本地分支切换到new-branch上:
#git checkout new-branch
将修改的helloworld.c文件提交到new-branch分支:
#echo ‘New world!’ > helloworld.c
#git add helloworld.c
#git commit -m helloworld-new-branch

3.3.5 在GitHub上创建开源项目
使用GitHub来托管创建的文件helloworld.c:
先在https://github.com/signup/free页面注册一个免费用户,“Create an account”按钮会成功创建一个用户。
进入GitHub首页,单击页面右下角的“New repository”按钮创建一个新的项目。项目名必须在GitHub上没有使用过。

3.3.6 上传源代码到GitHub:git push
GitHub上传代码时需要SSH校验,需要在~/.ssh/目录下生成两个纯文本文件,一个密钥文件(id_rsa)和一个公钥文件(id_rsa.pub):
#ssh-keygen -t rsa -C “chiyuan.ma@myemail.com”
将~/.ssh/id_rsa.pub文件中的所有内容复制到剪切板,在GitHub的账户设置页面左侧选择“SSH Public Keys”项,单击“Add another public key”链接,将剪贴板的内容粘贴到Key输入框中。在Title输入框中输入任意标题,单击“Add key”按钮添加一个public key。

设置完public key后,检测公钥、密钥以及设置是否正确:
    #ssh -T git@github.com        不要修改git@github.com
有一些Linux系统(如Ubuntu Linux),就算成功完成上面的操作也无法通过测试,需要向代理身份验证添加RSA身份:
    #ssh-add

上传文件之前需要设置上传者的名字和email:
    #git config --global user.name "Chiyuan.Ma"
    #git config --global user.email "chiyuan.ma@myemail.com"

上传工作目录中的文件:
设置helloworld工程在GitHub上的URI:
    #git remote add origin git@github.com:androidguy/helloworld.git
        origin是远程代码库名,可以任意起名。
将本地版本库中的文件上传到GitHub:
    #git push -u origin master
查看所有的分支(本地分支和远程分支):
    #git branch -a

3.3.7 从GitHub下载源代码:git clone
下载整个工程:
#git clone git@github.com:androidguy/helloworld.git
下载好的helloworld目录中也包含一个.git本地版本库目录。
只获取某一分支的最新内容:
#git pull origin master

第二篇 Android底层开发入门

第6章 第一个Linux驱动程序:统计单词个数

6.1 Linux驱动到底是什么

Linux系统将每一个驱动都映射成一个文件。这些文件称为设备文件或驱动文件,都保存在/dev/目录。Linux驱动的事件,也就是回调(callback)函数。编写Linux驱动最重要的一步就是编写回调函数,否则与设备文件交互的数据将无法得到处理。
应用软件、设备文件、驱动程序、硬件之间的关系:

6.2 编写Linux驱动程序的步骤

第1步:建立Linux驱动骨架(装载和卸载Linux驱动)
Linux内核在使用驱动时首先需要装载驱动,装载过程中需要进行一些初始化工作,如:建立设备文件、分配内存地址空间等。当Linux系统退出时需要卸载Linux驱动,卸载过程中需要释放由Linux驱动占用的资源,如:删除设备、释放内存地址空间等。Linux驱动程序用module_init()和module_exit()宏分别处理函数的装载和卸载。即包含module_init()和module_exit()宏的C程序文件作为Linux驱动的骨架。

第2步:注册和注销设备文件
Linux驱动需要有一个设备文件,建立设备文件在处理Linux初始化工作的函数中完成,用misc_register()函数创建设备文件。删除设备文件在处理Linuz退出工作的函数中完成,用misc_deregister()函数移除设备文件。

第3步:指定与驱动相关的信息
驱动程序是自描述的,可以通过modinfo命令获取驱动程序的信息。这些信息通过MODULE_AUTHOR、MODULE_LICENSE、MODULE_ALIAS、MODULE_DESCRIPTION等宏指定驱动相关信息。

第4步:指定回调函数
Linux驱动有一个操作集,包含read、write等回调函数,一个驱动程序不一定要指定操作集中的所有回调函数。

第5步:编写业务逻辑
Linux驱动的核心部分。业务逻辑与驱动的功能相关,可能由多个函数、多个文件、多个Linux驱动模块组成。

第6步:编写Makefile文件
定义Linux驱动代码的编译规则。

第7步:编译Linux驱动程序
Linux驱动程序可以直接编译进内核(obj-y:),也可以作为模块单独编译(obj-m:)成*.ko文件。obj-y和obj-m都需要使用“:=”赋值。

第8步:安装和卸载Linux驱动
如果将Linux驱动编译进内核,驱动程序会自动装载。如果Linux驱动程序以模块单独存在,需要使用insmod或modprobe命令装载,使用rmmod或modprobe -d命令卸载。

如果Linux驱动编译进内核,目标文件*.o会被连接进build-in.o文件,该文件是连接同一类程序的.o文件生成的中间目标文件,可以在/kernel/drivers/char/目录找到,该目标文件包含了所有可连接进Linux内核的字符驱动。
如果Linux驱动依赖其他程序,需要修改Makefile文件:
    obj-m := word_count.o
    word_count-y := process.o data.o
其中依赖文件使用module-y或module-objs指定,module表示模块名。

Linux系统将内存分为了用户空间和内核空间,两个空间的程序不能直接访问。printf()函数运行在用户空间,printk()函数运行在内核空间。Linux驱动程序不能直接访问printf()函数。
如果用户空间的程序要访问内核空间,需要做一个可以访问内核空间的驱动程序,然后用户空间的程序通过设备文件可以与驱动程序进行交互。
/kernel/include/目录的各个子目录中包含了大量的C语言头文件,这些头文件中定义的函数、宏等就是运行在用户空间的程序的替代函数。
用户空间            内核空间
malloc()                kmalloc()
atoi()                    simple_strtol()
itoa()                    snprintf()

编译驱动程序:
    #make -C /kernel/ M=/driver_code       
由于编译Linux驱动需要使用Linux内核的头文件,在Ubuntu Linux上编译驱动程序,需要使用-C命令行参数指定Linux内核头文件目录(*/kernel/),如果以模块方式编译Linux驱动程序,需要使用M指定驱动程序所在的目录。

安装Linux驱动:
    #insmod **.ko
查看**是否成功安装:
    #lsmod | grep **
卸载Linux驱动:
    #rmmod **
查看由Linux驱动输出的日志信息:
    #dmesg | grep ** | tail -n 2
dmesg命令实际是从/var/log/messages(低版本ubuntu)或/var/log/syslog(高版本ubuntu)文件中读取的日志信息,    

6.3.3 指定与驱动相关的信息
模块作者:MODULE_AUTHOR宏指定
模块描述:MODULE_DESCRIPTION宏指定
模块别名:MODULE_ALIAS宏指定
开源协议:MODULE_LICENSE宏指定,如:GPL协议

查看**.ko的信息:
    #modinfo **.ko
vermagic表示当前Lunux驱动模块在哪个Linux内核版本下编译。

6.3.4 注册和注销设备文件

设备文件一般在初始化Linux驱动时用misc_register()函数建立,在卸载Linux驱动时用misc_deregister()函数删除,创建好的设备文件位于/dev/目录下。
extern int misc_register(struct miscdevice *misc);
extern int misc_deregister(struct miscdevice *misc);
设备文件还需要一个结构体(miscdevice)来描述与其相关的信息,其中一个重要成员变量file_operations fops,用于描述设备文件可触发事件的函数指针。

需要注意:
设备文件由主设备号和次设备号描述。而使用misc_register函数只能设置次设备号,主设备号统一设为10,主设备号为10的设备是Linux系统中拥有共同特性的简单子辐设备,称为misc设备。次设备号需要指定,或者动态生成(需要指定MISC_DYNAMIC_MINOR常量)。
使用register_chrdev_region和alloc_chrdev_region函数同时指定主设备号和次设备号的方式注册和注销设备文件。
miscdevice.name 设备文件的名称,设备注册成功后,可以在/dev/目录下查到。
file_operations.owner 如果为module结构体,表示file_operations可以被应用在由module指定的驱动模块中;如果为THIS_MODULE,表示file_operations只应用于当前驱动模块。
设备文件注册成功,misc_register()函数返回非0整数,失败返回0.

2019-05-15 17:29:48 u014644594 阅读数 77
  • Android底层技术:HAL驱动开发

    本课程提供开发者学习Android底层的HAL(硬件抽象层)的开发方法和技术。HAL所在的位置是介于Android系统服务与Linux内核之间,HAL Driver是以library形式出现,给HAL Stub调用,供Android System架构者调用。而HAL Stub则是google设计出来的,保护硬件厂商的硬件驱动。

    18253 人正在学习 去看看 高煥堂

    

链接到

《 Android深度探索(卷1):HAL与驱动开发》分为4篇,分别从搭建开发环境,Linux驱动和Android HAL的基础知识,开发Linux驱动的高级技术和分析典型的Linux驱动源代码4个方面介绍Android和Linux的底层开发。本书使用的试验环境是Ubuntu Linux12.04 LTS、Android模拟器和S3C6410开发板。在第1篇详细介绍了如何搭建和使用这3个试验环境。第2篇通过3个Linux驱动的完整案例(统计单词个数驱动、LED驱动和蜂鸣器驱动)从不同角度来讨论如何开发一个完整的Linux驱动。并且通过完整的案例介绍了如何编写Android HAL,以及如何与Linux驱动交互。第3篇则介绍了开发Linux驱动所需要的高级技术,这些技术包括并发控制、阻塞和非阻塞I/O、异步编程、Linux中断和底半部、时间管理、内存管理和I/O访问。最后一部分分析了一些典型Linux驱动的源代码(RTC驱动、LCD驱动、音频驱动、块设备驱动、网络设备驱动和USB驱动)。
  《Android深度探索(卷1):HAL与驱动开发》注重理论和实践相结合。在介绍了大量的基础知识的同时,为每一个知识点提供了完整的案例,使读者可以通过实际的代码更好地理解Linux驱动和Android底层技术。
 

2017-05-02 13:54:00 weixin_34402090 阅读数 38
  • Android底层技术:HAL驱动开发

    本课程提供开发者学习Android底层的HAL(硬件抽象层)的开发方法和技术。HAL所在的位置是介于Android系统服务与Linux内核之间,HAL Driver是以library形式出现,给HAL Stub调用,供Android System架构者调用。而HAL Stub则是google设计出来的,保护硬件厂商的硬件驱动。

    18253 人正在学习 去看看 高煥堂

本节书摘来自异步社区《Android深度探索(卷1):HAL与驱动开发》一书中的目录,作者李宁,更多章节内容可以访问云栖社区“异步社区”公众号查看


52efdc362511d107ef3d6d1026767c0a474fc8b1

目 录

第一篇 Android驱动开发前的准备
第1章 Android系统移植与 驱动开发概述
1.1 Android系统架构
1.2 Android系统移植的主要工作
1.3 查看Linux内核版本
1.4 Linux内核版本号的定义规则
1.5 如何学习Linux驱动开发
1.6 Linux设备驱动
1.7 见识一下什么叫Linux驱动:LED
1.8 小 结
第2章 搭建Android开发环境
第3章 Git使用入门
第4章 源代码的下载和编译
第5章 搭建S3C6410开发板的测试环境
第二篇 Android底层开发入门
第6章 第一个Linux驱动程序: 统计单词个数
6.1 Linux驱动到底是个什么东西
6.2 编写Linux驱动程序的步骤
6.3 第一个Linux驱动:统计单词个数
6.4 使用多种方式测试Linux驱动
6.5 使用Eclipse开发和测试Linux驱动程序
6.6 小 结
第7章 LED将为我闪烁:控制发光二级管
第8章 让开发板发出声音:蜂鸣器驱动
第9章 硬件抽象层:HAL
第10章 嵌入式Linux的调试技术
第三篇 Linux驱动开发高级技术
第11章 Linux驱动程序中的并发控制
第12章 LINUX驱动程序中的阻塞和非阻塞I/O
第13章 LINUX驱动程序中的异步编程
第14章 Linux中断和底半部
第15章 时间管理
第16章 内存管理与I/O访问
第四篇 LINUX设备驱动与ANDROID底层开发
第17章 RTC驱动
第18章 LCD驱动
第19章 音频驱动
第20章 Linux块设备驱动
第21章 网络设备驱动
第22章 USB驱动

2013-01-24 23:17:06 nokiaguy 阅读数 6729
  • Android底层技术:HAL驱动开发

    本课程提供开发者学习Android底层的HAL(硬件抽象层)的开发方法和技术。HAL所在的位置是介于Android系统服务与Linux内核之间,HAL Driver是以library形式出现,给HAL Stub调用,供Android System架构者调用。而HAL Stub则是google设计出来的,保护硬件厂商的硬件驱动。

    18253 人正在学习 去看看 高煥堂
        《 Android深度探索(卷1):HAL与驱动开发》分为4篇,分别从搭建开发环境,Linux驱动和Android HAL的基础知识,开发Linux驱动的高级技术和分析典型的Linux驱动源代码4个方面介绍Android和Linux的底层开发。本书使用的试验环境是Ubuntu Linux12.04 LTS、Android模拟器和S3C6410开发板。在第1篇详细介绍了如何搭建和使用这3个试验环境。第2篇通过3个Linux驱动的完整案例(统计单词个数驱动、LED驱动和蜂鸣器驱动)从不同角度来讨论如何开发一个完整的Linux驱动。并且通过完整的案例介绍了如何编写Android HAL,以及如何与Linux驱动交互。第3篇则介绍了开发Linux驱动所需要的高级技术,这些技术包括并发控制、阻塞和非阻塞I/O、异步编程、Linux中断和底半部、时间管理、内存管理和I/O访问。最后一部分分析了一些典型Linux驱动的源代码(RTC驱动、LCD驱动、音频驱动、块设备驱动、网络设备驱动和USB驱动)。

  《Android深度探索(卷1):HAL与驱动开发》注重理论和实践相结合。在介绍了大量的基础知识的同时,为每一个知识点提供了完整的案例,使读者可以通过实际的代码更好地理解Linux驱动和Android底层技术。

     个人微博

http://weibo.com/androidguy

  为了使读者更好地实践本书提供的实例代码,在随书光盘中除了提供源代码文件外,还提供了一个VMWare Ubuntu Linux12.04 LTS的虚拟环境(如过在win8下使用vmware,请参阅《Windows8与VMWare不兼容的解决方案》。如将虚拟机文件复制到PC上无法启动Ubuntu Linux12.04,请看这篇文章《Vmware虚拟机的复制后无法使用的问题和解决 》,读者可以在Windows、Linux和Mac OS X上,通过VMWare打开该虚拟机文件来学习和测试本书的例子(虚拟环境中也带了一套本书提供的例子代码)。

  《Android深度探索(卷1):HAL与驱动开发》适合底层开发的程序员和编程爱好者使用,也适合作为相关培训学校的Android底层开发培训教材。


目录


第一篇 Android驱动开发前的准备
第1章 Android系统移植与驱动开发概述
1.1 Android系统架构
1.2 Android系统移植的主要工作
1.3 查看Linux内核版本
1.4 Linux内核版本号的定义规则
1.5 如何学习Linux驱动开发
1.6 Linux设备驱动
1.6.1 设备驱动的发展和作用
1.6.2 设备的分类及特点
1.7 见识一下什么叫Linux驱动:LED
1.8 小结

第2章 搭建Android开发环境
2.1 Android底层开发需要哪些工具
2.2 安装JDK
2.3 搭建Android应用程序开发环境
2.3.1 安装Android SDK
2.3.2 安装Eclipse
2.3.3 安装ADT
2.3.4 配置ADT
2.3.5 建立AVD
2.4 安装Android NDK开发环境
2.4.1 下载Android NDK
2.4.2 安装CDT
2.4.3 命令行方式编译Android NDK程序
2.4.4 导入Android NDK的例子
2.4.5 配置Android NDK的集成开发环境
2.5 安装交叉编译环境
2.6 小结

第3章 Git使用入门
3.1 安装Git
3.2 查看Git文档
3.3 源代码的提交与获取
3.3.1 创建版本库:git init
3.3.2 将文件提交到本地版本库:git commit
3.3.3 创建本地分支:git branch
3.3.4 切换本地分支:git checkout
3.3.5 在GitHub上创建开源项目
3.3.6 上传源代码到GitHub:git push
3.3.7 从GitHub下载源代码:git clone
3.4 小结

第4章 源代码的下载和编译
4.1 下载、编译和测试Android源代码
4.1.1 配置Android源代码下载环境
4.1.2 Android源代码目录结构解析
4.1.3 下载Android源代码中的一部分
4.1.4 编译Android 源代码
4.1.5 out目录结构分析
4.1.6 将自己的APK作为Android内置程序发布
4.1.7 用模拟器测试system.img文件
4.2 下载和编译Linux内核源代码
4.2.1 下载Linux内核源代码
4.2.2 Linux内核源代码的目录结构
4.2.3 安装Android内核的编译环境
4.2.4 配置和编译Linux内核
4.3 小结

第5章 搭建S3C6410开发板的测试环境
5.1 S3C6410开发板简介
5.2 安装串口调试工具:minicom
5.3 烧写Android系统
5.4 配置有线网络
5.5 小结

第二篇 Android底层开发入门
第6章 第一个Linux驱动程序:统计单词个数
6.1 Linux驱动到底是个什么东西
6.2 编写Linux驱动程序的步骤
6.3 第一个Linux驱动:统计单词个数
6.3.1 编写Linux驱动程序前的准备工作
6.3.2 编写Linux驱动程序的骨架(初始化和退出驱动)
6.3.3 指定与驱动相关的信息
6.3.4 注册和注销设备文件
6.3.5 指定回调函数
6.3.6 实现统计单词数的算法
6.3.7 编译、安装、卸载Linux驱动程序
6.4 使用多种方式测试Linux驱动
6.4.1 使用Ubuntu Linux测试Linux驱动
6.4.2 在Android模拟器上通过原生(Native)C程序测试Linux驱动
6.4.3 使用Android NDK测试Linux驱动
6.4.4 使用Java代码直接操作设备文件来测试Linux驱动
6.4.5 使用S3C6410开发板测试Linux驱动
6.4.6 将驱动编译进Linux内核进行测试
6.5 使用Eclipse开发和测试Linux驱动程序
6.5.1 在Eclipse中开发Linux驱动程序
6.5.2 在Eclipse中测试Linux驱动
6.6 小结

第7章 LED将为我闪烁:控制发光二级管
7.1 LED驱动的实现原理
7.2 编写LED驱动
7.2.1 体验LED驱动的奇妙
7.2.2 创建LED驱动的设备文件
7.2.3 卸载LED驱动的设备文件
7.2.4 设置寄存器与初始化LED驱动
7.2.5 控制LED
7.2.6 LED驱动的模块参数
7.2.7 LED驱动的完整代码
7.3 测试LED驱动
7.3.1 编写测试I/O控制命令的通用程序
7.3.2 使用NDK测试LED驱动
7.3.3 使用Java测试LED驱动
7.4 LED驱动的移植
7.5 小结

第8章 让开发板发出声音:蜂鸣器驱动
8.1 Linux驱动的代码重用
8.1.1 编译是由多个文件组成的Linux驱动
8.1.2 Linux驱动模块的依赖(导出符号)
8.2 强行卸载Linux驱动
8.3 蜂鸣器(PWM)驱动
8.3.1 蜂鸣器驱动的原理
8.3.2 实现蜂鸣器驱动
8.3.3 测试蜂鸣器驱动
8.4 小结

第9章 硬件抽象层:HAL
9.1 为什么要在Android中加入HAL
9.2 Android HAL架构
9.3 为LED驱动增加HAL
9.3.1 编写一款支持HAL的Linux驱动程序的步骤
9.3.2 颠覆Linux驱动的设计理念:精简LED驱动
9.3.3 测试读写寄存器操作
9.3.4 编写调用LED驱动的HAL模块
9.3.5 编写调用HAL模块的Service
9.3.6 HAL模块的存放路径和命名规则
9.3.7 编写调用Service的Java库
9.3.8 测试LED驱动
9.4 小结

第10章 嵌入式Linux的调试技术
10.1 打印内核调试信息:printk
10.2 防止printk函数降低Linux 驱动性能
10.3 通过虚拟文件系统(/proc)进行数据交互
10.4 调试工具
10.4.1 用gdb调试用户空间程序
10.4.2 用gdbserver远程调试用户空间程序
10.4.3 用kgdb远程调试内核程序
10.5 小结

第三篇 Linux驱动开发高级技术
第11章 Linux驱动程序中的并发控制
11.1 并发和竞态
11.2 原子操作
11.2.1 整型原子操作
11.2.2 64位整型原子操作
11.2.3 位原子操作
11.2.4 用原子操作阻止设备文件被多个进程打开
11.3 自旋锁(Spin Lock)
11.3.1 自旋锁的使用方法
11.3.2 使用自旋锁保护临界区
11.3.3 读写自旋锁
11.3.4 使用读写自旋锁保护临界区
11.3.5 顺序锁(seqlock)
11.3.6 使用顺序锁写入正在读取的共享资源
11.4 读-复制-更新(RCU)机制
11.4.1 RCU的原理
11.4.2 RCU API
11.4.3 RCU的应用
11.5 信号量(Semaphore)
11.5.1 信号量的使用
11.5.2 信号量用于同步
11.5.3 读写信号量
11.5.4 使用读写信号量保护临界区
11.6 互斥体(Mutex)
11.7 完成量(Completion)
11.8 小结

第12章 Linux驱动程序中的阻塞和非阻塞I/O
12.1 等待队列
12.1.1 等待队列原理
12.1.2 等待队列的API
12.1.3 等待队列的使用方法
12.1.4 支持休眠和唤醒的Linux驱动
12.2 轮询操作
12.2.1 用户空间的select函数
12.2.2 内核空间的poll函数
12.2.3 以非阻塞的方式访问Linux驱动
12.3 小结

第13章 Linux驱动程序中的异步编程
13.1 信号与异步通知
13.1.1 Linux信号
13.1.2 接收Linux信号
13.1.3 发送信号
13.2 异步I/O(AIO)
13.2.1 异步操作的API
13.2.2 异步读写本地文件
13.2.3 Linux驱动中的异步函数(aio_read和aio_write)
13.2.4 接收信号时异步读取数据
13.2.5 AIO中的回调函数
13.3 小结

第14章 Linux中断和底半部
14.1 什么是中断
14.2 中断处理程序
14.3 Linux 中断处理的核心:顶半部和底半部
14.4 获取Linux 系统的中断统计信息
14.5 Linux 中断编程
14.5.1 注册中断处理程序
14.5.2 注销中断处理程序
14.5.3 编写中断处理函数
14.5.4 共享中断处理程序
14.5.5 禁止和激活中断
14.5.6 禁止和激活中断线
14.5.7 获取中断系统的状态
14.5.8 与中断编程相关的函数和宏
14.6 实例:S3C6410实时钟中断
14.7 中断中下文
14.8 中断的实现原理
14.9 底半部
14.9.1 为什么要使用底半部
14.9.2 实现底半部的机制
14.9.3 软中断
14.9.4 Tasklet
14.9.5 实例:Tasklet演示
14.9.6 软中断处理线程(ksoftirqd)
14.9.7 工作队列(work queue)
14.9.8 与工作队列相关的API
14.9.9 实例:工作队列演示
14.10 小结

第15章 时间管理
15.1 Linux内核中的时间概念
15.1.1 时钟频率
15.1.2 提高时钟频率的优点和缺点
15.2 节拍总数(jiffies)
15.2.1 访问jiffies
15.2.2 jiffies、时间和时钟频率之间的转换
15.2.3 jiffies的回绕
15.2.4 用户空间和时钟频率
15.3 实时时钟和定时器
15.4 时钟中断处理程序的实现
15.5 读写本地时间
15.6 内核定时器
15.6.1 如何使用内核定时器
15.6.2 实例:秒表定时器
15.7 内核延迟
15.7.1 忙等待
15.7.2 短延迟
15.7.3 休眠延迟(schedule_timeout)
15.8 小结

第16章 内存管理与I/O访问
16.1 内存管理模式
16.1.1 内存的基本单位:页(Page)
16.1.2 页的逻辑划分:区(zone)
16.1.3 获取页
16.1.4 释放页
16.2 分配连续的内存空间(Kmalloc)
16.2.1 gfp_mask标志
16.2.2 释放内存(kfree)
16.3 分配不连续的内存空间(vmalloc)
16.4 全局缓存(slab)
16.4.1 Slab层的实现原理
16.4.2 Slab分配器
16.4.3 示例:从Slab高速缓存中分配和释放对象
16.5 Linux内存池
16.5.1 内存池的实现原理
16.5.2 示例:从内存池获取对象
16.6 虚拟地址与物理地址之间的转换
16.7 设备I/O端口与I/O内存
16.7.1 读写I/O端口
16.7.2 读写I/O内存
16.7.3 将I/O端口映射为I/O内存
16.7.4 申请和释放设备I/O端口和I/O内存
16.7.5 使用设备I/O端口和I/O内存的一般步骤
16.8 内核空间与用户空间共享数据
16.8.1 内存映射与VMA
16.8.2 示例:用户程序读取内核空间数据
16.9 I/O内存静态映射
16.10 小结

第四篇 Linux设备驱动与Android底层开发
第17章 RTC驱动
17.1 实时时钟(RTC)结构与移植内容
17.1.1 RTC系统的结构
17.1.2 RTC驱动主要的移植工作
17.2 RTC系统中的Android部分
17.2.1 警报管理:AlarmManager
17.2.2 警报服务:AlarmManagerService
17.2.3 直接与Alarm驱动交互的JNI代码
17.3 Alarm驱动的分析与移植
17.3.1 Alarm驱动简介
17.3.2 Alarm驱动中的关键数据结构
17.3.3 Alarm驱动的应用层接口(alarm_dev.c)代码分析
17.3.4 Alarm驱动的通用文件(alarm.c)代码分析
17.4 RTC驱动的分析与移植
17.4.1 实时时钟(RTC)的特性
17.4.2 RTC的结构
17.4.3 RTC芯片的寄存器
17.4.4 RTC驱动的用户空间接口
17.4.5 RTC系统组件之间的调用关系
17.4.6 设备文件(/dev/rtc0)的I/O命令
17.4.7 sysfs虚拟文件处理函数
17.4.8 proc虚拟文件处理函数
17.5 小结

第18章 LCD驱动
18.1 LCD简介
18.1.1 液晶的工作原理
18.1.2 LCD的种类
18.1.3 LCD的技术参数
18.1.4 LCD时序图
18.2 LCD驱动结构分析和移植要点
18.3 帧缓冲(FrameBuffer)驱动设计与实现
18.3.1 FrameBuffer设备
18.3.2 示例:通过dd命令与FrameBuffer设备文件交互
18.3.3 示例:编写访问FrameBuffer设备文件的程序
18.3.4 FrameBuffer驱动的架构
18.3.5 FrameBuffer驱动主要的数据结构
18.3.6 如何在Linux内核中查找指定的内容
18.3.7 FrameBuffer驱动设备事件的处理(fbmem.c)
18.3.8 FrameBuffer驱动源代码分析与移植
18.4 FrameBuffer驱动的HAL层分析
18.4.1 Gralloc库
18.4.2 初始化HAL Gralloc的核心结构体
18.4.3 获取Gralloc HAL模块
18.4.4 与FrameBuffer设备文件交互
18.5 调用Gralloc HAL库
18.6 小结

第19章 音频驱动
19.1 音频驱动基础
19.1.1 数字音频简介
19.1.2 ALSA架构简介
19.1.3 ALSA设备文件
19.1.4 数字采样与数字录音
19.1.5 混音器
19.1.6 音频驱动的目录结构
19.1.7 音频设备硬件接口
19.1.8 ALSA架构支持的声卡芯片
19.2 AC97芯片的寄存器
19.2.1 控制寄存器
19.2.2 状态寄存器
19.2.3 编解码器命令寄存器
19.2.4 编解码器状态寄存器
19.2.5 PCM输出/输入通道FIFO数据寄存器
19.2.6 MIC输入通道FIFO地址寄存器
19.2.7 PCM输出/输入通道FIFO数据寄存器
19.2.8 MIC输入通道FIFO数据寄存器
19.3 创建声卡
19.3.1 声卡的顶层数据结构
19.3.2 创建声卡的步骤
19.3.3 示例:基于ARM的AC97音频驱动
19.4 音频逻辑设备
19.4.1 创建PCM设备
19.4.2 创建录音和播放设备文件节点
19.4.3 创建Control设备数据结构
19.4.4 创建Control设备
19.4.5 注册与打开音频字符设备
19.5 嵌入式设备中的ALSA(ASoC)
19.5.1 什么是ASoC
19.5.2 ASoC的硬件架构
19.5.3 ASoC的软件架构
19.5.4 如何确定S3C开发板使用了哪个音频驱动
19.5.5 ASoC架构中的Machine
19.5.6 ASoC架构中的Codec
19.5.7 ASoC架构中的Platform
19.6 音频驱动的HAL分析
19.6.1 实现HAL Library
19.6.2 调用HAL Library
19.7 小结

第20章 Linux块设备驱动
20.1 块设备简介
20.2 块设备的体系架构
20.3 块设备的数据结构与相关操作
20.3.1 磁盘设备(gendisk结构体)
20.3.2 block_device_operations结构体
20.3.3 I/O请求(request结构体)
20.3.4 请求队列(request_queue结构体)
20.3.5 块I/O(bio结构体)
20.4 块设备的加载和卸载
20.5 块设备的打开和释放
20.6 块设备的ioctl函数
20.7 块设备驱动的I/O请求处理
20.7.1 依赖请求队列
20.7.2 不依赖请求队列
20.8 实例1:依赖请求队列的RamDisk
20.9 在嵌入式设备上测试块设备驱动
20.9.1 编译、配置和安装Busybox
20.9.2 测试块设备驱动
20.10 实例2:不依赖请求队列的RamDisk
20.11 扇区与磁盘碎片整理
20.12 小结

第21章 网络设备驱动
21.1 Linux网络设备驱动的结构
21.1.1 网络协议接口层
21.1.2 网络设备接口层
21.1.3 设备驱动功能层
21.1.4 网络设备与媒介层
21.2 网络设备驱动设计与实现
21.2.1 网络设备的注册与注销
21.2.2 网络设备的初始化
21.2.3 网络设备的打开与释放
21.2.4 发送数据
21.2.5 接收数据
21.2.6 网络连接状态
21.3 示例:DM9000网卡设备驱动
21.3.1 如何确定S3C6410开发板使用的网络设备
21.3.2 DM9000网卡硬件描述
21.3.3 网络设备驱动的定义与安装
21.3.4 初始化DM9000网卡设备驱动
21.3.5 移出网络设备
21.3.6 打开和停止DM9000网卡
21.3.7 发送数据
21.3.8 接收数据
21.3.9 设置广播地址
21.4 小结

第22章 USB驱动
22.1 USB设备简介
22.2 USB驱动与USB核心之间的交互
22.2.1 端点(Endpoint)
22.2.2 接口(Interfaces)
22.2.3 配置(Config)
22.3 USB设备的核心数据结构
22.3.1 USB设备:usb_device结构体
22.3.2 USB驱动:usb_driver结构体
22.3.3 识别USB设备:usb_device_id结构体
22.3.4 USB端点:usb_host_endpoint结构体
22.3.5 USB接口:usb_interface结构体
22.3.6 USB配置:usb_host_config结构体
22.4 描述符数据结构
22.4.1 设备描述符
22.4.2 配置描述符
22.4.3 接口描述符
22.4.4 端点描述符
22.4.5 字符串描述符
22.4.6 查看描述符信息
22.5 USB和sysfs
22.6 URB(USB请求块)
22.6.1 URB结构体
22.6.2 URB的处理流程
22.6.3 简单的批量与控制URB
22.7 USB驱动程序的结构
22.8 鼠标驱动分析
22.9 小结


2016-04-26 22:08:00 weixin_34281477 阅读数 30
  • Android底层技术:HAL驱动开发

    本课程提供开发者学习Android底层的HAL(硬件抽象层)的开发方法和技术。HAL所在的位置是介于Android系统服务与Linux内核之间,HAL Driver是以library形式出现,给HAL Stub调用,供Android System架构者调用。而HAL Stub则是google设计出来的,保护硬件厂商的硬件驱动。

    18253 人正在学习 去看看 高煥堂

  第一章Android系统移植与驱动开发概述主要讲了Android系统架构,Android系统移植的主要工作,查看Linux内核版本,Linux内核版本号的定义规则,如何学习Linux驱动开发,Linux设备驱动以及Linux驱动的典型例子:LED

  首先Android是一个非常优秀的嵌入式操作系统,经过了几年的快速发展,已经形成了Linux内核,c/c++代码库,Android SDK API,应用程序四层系统架构。然后介绍了一下Android系统移植的主要工作,主要分为应用移植和系统移植两部分。当然,移植的工作说多不多,说少也不少,如果要移植的Android系统提=提供了系统源代码,那就好办多了,直接根据移植的目标平台修改驱动代码就可以了。并且知道了Linux2.6是目前使用最广泛的版本,Android就使用了该版本。

  那么,怎样学习Linux驱动开发呢,由于Linux的内核版本更新较快,每一次内核的变化就意味着Linux驱动的变化,所以学习Linux驱动开发需要一个真正的操作系统来搭建Linux驱动的开发环境,并且在该系统下测试Linux驱动。还有GUN C 也是学习Linux驱动的一个必须掌握的技术。

  了解了上面这些,我认识到学习Linux驱动编程一定要了解Linux驱动只与Linux内核有关,与用户使用的Linux系统无关。唯一可以判断Linux内核是否相同的方法就是Linux内核版本号。

 

 

 

 

  第二章搭建Android开发环境主要介绍了如何搭建Android底层开发的环境,主要包括Android应用程序开发环境,Android NDK开发环境和交叉编译环境的搭建。Android底层开发需要很多工具,例如Android SDK,Android NDK等等,搭建Android应用程序开发环境都是在Linux下编写和测试的。由于Android NDK不能作为Android应用程序来运行,因此,使用Android NDK开发程序之前必须先安装Android SDK

  然后是安装交叉编译环境,X86架构的CPU采用的是复杂指令集计算机,而ARM架构的CPU使用的是精简指令集计算机。通常交叉编译器和相关工具包含了很多可执行文件以及大量的共享库及头文件等资源,这些资源的合集称为交叉编译环境。

Android开发环境的配置主要是在Ubuntu Linux环境下进行的。在配置好的交叉编译环境下,可以编写一个简单的C程序来测试一下这个交叉编译环境

//first.c

#include<stdio.h>

Int main()

{

Printf(“first arm program\n”);

Return 0;

}

输入#arm-none-linux-qnueabi-gcc -static -o first first.c编译first.c文件

输入#adb push first /data/localfirst文件上传到任意的Android设备的/data/lacal目录中

使用adb shell命令进入Android设备的控制台,并进入/data/lacal目录,执行#./first就会输出“first arm program”信息。First程序在X86架构上运行的Ubuntu Linux中是无法运行的。

 

 

 

第三章Git使用入门

  一开始并不知道Git是什么东西,阅读了本章前面的介绍,大概明白了Git是一款免费、开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。Git是一个开源的分布式版本控制系统,用以有效、高速的处理从很小到非常大的项目版本管理。Git Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

  Git的功能特性主要有以下几点:从一般开发者的角度来看,git有以下功能:1:从服务器上克隆数据库到单机上。2:在自己的机器上创建分支,修改代码。3:在单机上自己创建的分支上提交代码。4:在单机上合并分支。5:新建一个分支,把服务器上最新版的代码fetch下来,然后跟自己的主分支合并。6:生成补丁,把补丁发送给主开发者。7:看主开发者的反馈,如果主开发者发现两个一般开发者之间有冲突,就会要求他们先解决冲突,然后再由其中一个人提交。如果主开发者可以自己解决,或者没有冲突,就通过。8:一般开发者之间解决冲突的方法,开发者之间可以使用pull 命令解决冲突,解决完冲突之后再向主开发者提交补丁。

  首先是要安装Git,可以使用#apt-get intstall git等这些命令来直接安装,然后是查看Git文档,接下来是源代码的提交与获取,就是要创建版本库:Git init并将文件提交到本地版本库:Git commit,创建本地分支:Git branch,切换本地分支:Git checkout以及在GitHub上创建开源项目等等。

  我觉得编者说的一句话很有道理,学习新技术的最好方法不是阅读技术书籍,也不是在网上查看别人写的文章,而是直接阅读自己感兴趣的代码。我今后要努力朝这方面去努力了。

 

 

 

第四章源代码的下载和编译

  这一章的Android源代码包含了很多东西,如嵌在Android系统中的应用程序的源代码和Android SDK带的各种工具的源代码等等,当然,在了解这些源代码之前,我们首先应该做的就是配置Android源代码的下载环境,配置完成以后就是对Android源代码目录结构的解析,经过长时间的等待,多达4gAndroid源代码终于下载完成。其实,如果我们只需要一部分源代码的时候,只要了解了Android源代码的目录结构,就可以下载任何我们想要的部分。

  接下来呢,就是编译我们的Android源代码,由于Android源代码中的每一个工程目录都会有Android.mk文件,所以在编译整个Android源代码时会递归调用每一个工程目录中的Android.mk文件来编译当前的工程。第一步要初始化编译环境,第二步使用lunch命令来设置编译目标,第三步编译Android源代码。

  其实Android移植主要就是linux内核的移植,linux内核移植主要是linux驱动的移植。所以为了开发和驱动,就是搭建了两套开发环境:Android应用程序开发环境和linux内核开发环境。

转载于:https://www.cnblogs.com/warrios/p/5436894.html

没有更多推荐了,返回首页