首页文章android应用如何调用驱动 android 驱动开发入门android手机驱动「android应用如何调用驱动 android 驱动开发入门」

android应用如何调用驱动 android 驱动开发入门android手机驱动「android应用如何调用驱动 android 驱动开发入门」

时间2025-01-16 22:15:16发布yu分类文章浏览134
导读:1 前言2 驱动开发认识2.1 驱动2.1.1 设备驱动程序的主要功能2.1.2 驱动程序的主要类型2.1.3 设备文件2.1.4 sys文件系统:...



  • 1 前言
  • 2 驱动开发认识
  • 2.1 驱动
  • 2.1.1 设备驱动程序的主要功能
  • 2.1.2 驱动程序的主要类型
  • 2.1.3 设备文件
  • 2.1.4 sys文件系统:
  • 3 基础编程
  • 3.1 内核模块
  • 3.1.1 设备驱动的编译和加载方式
  • 3.1.2 一个模块入时的主要工作
  • 3.2 内核编程
  • 3.2.1 内核模块编程模板
  • 3.3 字符驱动程序模板
  • 4 总结


已经有段时间没好好地写博客了,最近在研究安卓底层,所以想写写我对安卓底层的认识和总结。本篇是安卓底层学习总结系列的第一篇,驱动开发基础。

安卓系统,想必我也不用作太多介绍,这里我要提及的是安卓系统和嵌入式系统十分接近,所编写的驱动程序实际上大多也可以认为是嵌入式驱动程序。并且安卓的内核是Linux,所以写安卓驱动程序实际上和写Linux内核模块差不多,我门这篇主要认识PC中的Linux驱动。

所谓驱动,就是内核与外部设备的媒介,下面介绍有关驱动需要知道的知识。

2.1.1 设备驱动程序的主要功能

  • 对设备初始化和释放
  • 内核与硬件的数据交互
  • 应用程序和硬件的数据交互
  • 硬件的错误检测

2.1.2 驱动程序的主要类型

  • 字符设备
    – 使用自己制定的数据大小,通常以字节为单位输入输出
  • 块设备
    – 以块为单位输入输出
    – 对块设备读写时,利用系统内存作缓冲区,当用户进程对设备请求能满足用户的要求就返回请求的数据
  • 网络设备

2.1.3 设备文件

在shell中查看这个目录

可以看到所有的设备文件节点,通常为以下格式

  • 文件类型
    – 上面格式的第一个字符c代表了这个设备文件的文件类型为字符设备,b就是块设备,网络设备没有设备文件
  • 主设备号
    – 设备类型和主设备号唯一确定设备文件的驱动程序和界面。在上述格式中10, 235的10就是代表了主设备号。
  • 次设备号
    – 说明目标设备是同类设备的第几个,在上述格式中10, 235的235就是代表了次设备号。
    例:
    crw------- 1 root root 10, 59 3月 29 08:12 cpu_dma_latency
    crw------- 1 root root 10, 203 3月 29 08:12 cuse
    上面两个字符设备同属于一种设备,但不是一个设备。

2.1.4 sys文件系统:

统一管理查看内核功能参数和设备模型

驱动程序通常是以内核模块的方式编写,并且插入到系统内核进行执行,所以我们得先了解什么是内核模块。

Linux是一个单体内核系统,分成5个子系统,整个内核在一个地址空间。Linux提供了模块机制,来为其增加设备;只需编译模块,再插入内核就可以完成设备增加。而内核模块就是可以在系统运行期间动态安装和拆卸的内核功能单元。

3.1.1 设备驱动的编译和加载方式

  • 直接编译进内核,随同Linux启动时加载。
  • 编译成可加载删除模块,inod加载,rmmod删除

3.1.2 一个模块入时的主要工作

  1. 打开要安装的模块(·ko文件),读进用户空间。
  2. 链接其他函数到内核。即把外部函数的地址填入访问指令和数据结构中
  3. 在内核创建module数据结构,申请系统空间
  4. 将完成链接的模块映像装入内核空间,并在内核登记模块相关的数据结构(里面有相关操作的函数指针)

要编写一个内核模块就要先了解一下基本函数。
首先,内核与用户之间数据是不互通的,要互相使用数据得经过系统调用,系统调用中有着一些基本函数,用来完成基本任务。
比如:

这些函数在用户态是无法使用的,也就是说,在外部写的.c程序库中是不包含这两个函数的。所以编写内核程序是与编写普通c程序是有所区别的。

3.2.1 内核模块编程模板

下面贴出一个简单的helloworld内核程序,我们在具体程序中进行解释。

接下来编写Makefile文件,具体请自行查看资料

下面,我们对其进行测试,在shell中输入以下命令

即可查看信息,其中:
用于插入内核模块。
用于打印内核日志信息。
可以清空日志信息。
用 查看模块信息。
用 卸载模块。

最后我的内核日志打印信息为:


[ 9806.210068] HELLO WORLD!!! [10004.819841] perf: interrupt took too long (3137 > 3130), lowering kernel.perf_event_max_sample_rate to 63750 [10097.027480] bye bye!!


至此我们完成了一个简单的内核模块编程模板。

3.3 字符驱动程序模板

上面我们已经简单介绍了内核模块编写,下面我们来正式写一个有基本输入输出和基本测试程序的字符驱动程序模板。

下面是测试程序

Makefile文件

下面进行测试

注: 用来创建设备文件,指定设备文件主设备号为55,在制定前最好用 查看是否主设备号重复.
执行完命令就可以用查看设备是否加载成功了。
接下来我们运行测试程序,以下是输出内容


<<<<<>>>> test write: can't open devive test read: read size:8 readbuf[0]:0 readbuf[1]:0 readbuf[2]:0 readbuf[3]:0 readbuf[4]:9d readbuf[5]:55 readbuf[6]:0 readbuf[7]:0 test ioctl: ioctl test 0 ioctl test 1 arg:fffffff0, fffffff1, fffffff2, fffffff3


用查看内核日志



[11955.133491] hello character devices!! [11960.960142] open [11960.960148] read :8 [11960.960205] close


最后,卸载驱动程序

至此,我们完成了一个有输入输出功能的字符设备驱动程序模板。

总的来说,编写驱动程序并不难,但驱动程序主要与硬件相关,编写具体的驱动会需要特定硬件的芯片手册,所以以上只是Linux的驱动程序基础,编写驱动程序还需要进一步学习,比如学习系统的启动、设备树、硬件引脚等概念,学完后希望能在安卓开发板子上动手实践,下篇文章,我将对系统启动流程进行总结介绍。

浙江版权声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕,E-mail:xinmeigg88@163.com

展开全文READ MORE
驱动调用
逃离塔克夫离线版逃离塔科夫手机版「逃离塔克夫离线版」 手机高清镜子(Mirror)手机镜子「手机高清镜子(Mirror)」