安卓深度探索(卷一)第八章

代码矗用分为静态和动态两种。在上 节介绍的方式是代码的静态重用,这种方式是代码级的重用,也就是将需要重用的代码和使用这些代码的使用者放在 起进行编译,最终生成 个可执行文件或程序C. ko .so 等) 8-1 测试 mu ti fi iver 驱动在本节将介绍另外 种代码共享的方式:模块依赖,也称为导出符号。如果只能用一句话解释如何利用导出符号实现代码共卒,这句话就是“在 个驱动模块里使用另 个驱动模块里的被导出的符号(常章、变量、函数等〉”

由于 ymbol_ consumer 驱动使用了 symbo I_producer 驱动中导出的符号,因此,在安装

ψnbol_ consumer 之前, 需要先安装 symbol_producer ,否则会输出如 的错误信息。

insmod: eπor inserting ’symbol_consumer.ko‘: -1 Unknown symbol in module

depmod 令用于分析 inux 筷块之间的依赖性,这 功能在多个 Linux 模块之间拥有复杂的依赖关系方面非常有用。使用 depmod 分析 Linux模块的依赖关系 ,就可以使用modprobe 命令装载 Lin 皿模块。 mod probe 命令全根据 depmod 命令成的 Linux 模块依赖关系来装载 Linux 模块,并不需要像使用 ins mod 命令那样挨个装载 inux 模块。

如果在模拟器或开发板上采用动态装载.ko 文件的方式测试 Linux 驱动,就算无法正常卸载 Linux 驱动,只要重新启动模拟器或开发板,动态 Linux 模坏就会从 存中卸载。

情况1 初始化函数崩溃

由于 Linux 驱动模块的初始化函数(通诠module_ init 宏指定的函数〉进行了某些操作而崩溃,从而导致初始化函数无法正常返田二这种情况的表现是当前 nux 驱动模块没用被任何其他的linux 驱动模块使用,但却显示已经被引用 一了一次。

使用 rmmo d bad driver 命令细载bad drive 时会输出如下的信息,但却找不到使用 ad_ driverl 的其他linux 模块

情况 2卸载函数被阻塞

在使用 rmmod 命令卸载 Linux 驱动时,系统会调用卸载函数(跑过 modu le_ exit 宏指定的函数),只有卸载函数成功返回肘, Linux 动才会被翻载。如果卸载函数被阻塞(可能是死循环、并发等情况引起的阻塞), rmmod 命令也会被阻塞 也就是说永远不会执行到卸载 Linux 驱动模块的代码。

首先看第 种情况。这种情况的关键是引用计数器的值和引用者不 致。实际上引用者是不存在的,因此,只需要将当前的 inux 驱动模块的引用计数器清零即可。

第2种情况的问题根源就是卸载函数,因此,只要将原来的卸载函数替换成一个空的卸载函数即可。

不管是哪种情况,都需要解决 个不可回避的问题,就是要获取表示要卸载的 Linux 驱动模块modu le 结构体指针。因为 struct module 表示了 Linux 驱动的相关信息.

pwm驱动

蜂鸣器也称为 PWM (脉冲宽度调制〉,基本原理是通过脉冲来控制蜂鸣器的打开和停止。为了方便,本书将蜂吗然统称为 PWM PWM 连接到了 TOUT 1端口

PWM使用 端口 GPFCON 存器进行控制。该寄存器在 Lin 皿内核中对应的宏是S3C64XX PF CON ,该宏表示 GPFCON 寄存器寄存器的虚拟地址。 GPFCON 只用了最高两位( 3031 位〉来控制 PWM 。当最高两位为 时,打开 PWM 。为 时停止 PWM 。所以只需要通过 owrite3函数为 GPFCON 寄存器设置不同的值即可。

时间: 2024-11-04 09:53:01

安卓深度探索(卷一)第八章的相关文章

《Android深度探索卷一》第一章Android系统移植与驱动开发概述。

<Android深度探索>第一章讲的是Android系统移植与驱动开发概述.这一章节将对Android以及Linux驱动做一个总体的介绍. Android是一个非常优秀的的嵌入式操作系统.经过几年的发展和演进,Android已经形成了非常完善的系统架构.Android的系统架构分为四层,如下图 Android移植可分为两部分:应用移植和系统移植. Android系统移植是指让Android操作系统在某一个特定硬件平台上运行.使一个操作系统在特定硬件平台上运行的一个首要条件就是该操作系统支持硬件

安卓深度探索(卷一)第五章

S3C6410 是由三星公司推出的 款低功耗.高性价比的 SC ( reduced instruction set computer, 精简指令集计算机〉处理器,它基于 ARM11 内核. OK6410 开发板采用“核心板+底板”结构 安装串口调试工具:minicom 第一步:检测当前系统是否支持 SB 转串口 lsmod | grep usbserial 第二步:安装minicom sudo apt-get install minicom 第三步:配置minicom sudo minicom

安卓深度探索(卷一)第十章

printk 函数的原型如下: asmlinkage int printk(const char *fmt, ... ) 第1个参数表示格式字符串,后面是再变参数.也就是说,一旦 printk 函数至少要有两个参数[格式字符串),如果格式字符串中包含在占位符(%d. %s), 后面必须跟与占位符相等数量的参数,以便一一对应传入 printk 函数. KERN_DEBUG KREN_WARNING 是两个宏 它们的值分别为飞<7>和飞<4>.在 printk 数的第1个参数值(格式字

安卓深度探索(卷一)第九章

HAL ( Hardware Abstraction Layer ,硬件抽象层,是建立在 Linux 驱动之上的一套程序库,传统的 linux系统中 Linux 驱动一般有两种类型的代码:访问硬件寄存器的代码和业务逻辑代码HAL 并不是 Linux 内核的 部分,而是位于Android的系统运行库.也就是说在 Linux驱动中不应该保留任何不想公开的业务逻辑代码 这些代码都放在 HAI 层中,而只保留与寄存器交互的代码,访问寄存器只有 Linux 内核的相关函数能做到.如果这样安排 Linpx

安卓深度探索(卷一)第七章

led驱动的实现原理尽管 Linux 驱动直接与硬件打交道,但并不是 Linux 驱动直接向硬件中的内存写数据 而是与本机的 ν0 内存( νO Memory ,位于内核空间〉进行交互.所谓 1/0 内存是通过各种接口( PC I .USB .蓝牙.以太网口 等〉连接到主机( PC .手机〉的硬件〈网卡.声卡.摄像头等〉在主机内存中的映射. 编写LED驱动 第一步:使用 cdev_init 函数初始化cdev 第二步:指定设备号 直接在代码中指定(硬编码〉 动态分配 第三步:使用 cdev_ad

安卓深度探索(卷一)第六章

Linux系统将每一个驱动都映射成一个文件.这些文件称为设备文件或驱动文件,都保存在/dev目中.这种设计理念使得与Linux驱动进行交互就像与普通文件进行交互一样容易. 由于大多数Linux驱动都有与其对应的设备文件, 因此与Linux驱动交换数据就变成了与 设备文件交换数据.例如,向Linux打印机驱动发送一个打印命令,可以直接使用C语言函数open打开设备文件, 使肝 函数 oc tl 向该驱 的设备文件发送打印命令. 编写linux驱动的步骤 第一步:建 Linu 驱动骨架 装载和卸载

《Android深度探索卷一》读书笔记一

一.Android系统架构 Android系统架构分为4层: 第一层:Linux内核 Android是基于Linux内核的,因此,Android内核和标准Linux2.6的内核结构基本相同,细微差异在Android在Linux内核中增加的主要是一些Android专用驱动和Android使用的设备驱动,这些驱动程序在Android不同版本中可能并不通用. 第二层:C/C++代码库 是使用C/C++编写的代码库也就是Linux下的.so文件,还有Android运行时环境(AndroidRuntime

《Android深度探索卷一》读书笔记二

开发,测试和调用Linux驱动,HAL程序库需要的工具: JDK6或以上版本: Eclipse3.4或以上版本: ADT(用于开发Android应用程序): CDT(用于开发AndroidNDK程序): Android SDK: Android NDK: 交叉编译环境: Linux内核源代码: Android源代码: 用于调试开发板的串口工具:minicom; 一.安装JDK 下载JDK压缩包并解压到任意目录,在Linux终端输入“getdit /etc/profile”打开profile文件,

《Android深度探索卷一》读书笔记四

下载,编译和测试Android源代码 1.配置Android源代码下载环境 下载之前必须先在Linux终端执行一些命令配置环境. 创建存放脚本文件的目录“mkdir ~/bin””PATH=~/bin:$PATH”:下载repo脚本文件“curl 地址 > ~/bin/repo””chmod a+x ~/bin/repo”;创建存放Android源代码的目录“mkdir android_source”“cd android_source”;初始化“repo init -u 地址”: 2.开始下载