(一)Linux代码的重用

重用=静态重用(将要重用的代码放到其他的文件的头文件中声明)+动态重用(使用另外一个Linux驱动中的资源,例如函数、变量、宏等)

1、编译是由多个文件组成的Linux驱动(静态重用)

对于复杂的Linux驱动,需要使用多个源代码文件存放不同的功能代码,这样做有利于代码分类和管理,那么就不得不编译多个源代码文件,最终生成.ko文件或编译进Linux内核

下面,就介绍将3个.c文件分别编译为3个.o文件,并将这3个.o文件链接(link)成一个.ko文件——静态重用

假设C语言源代码文件有main.c、fun.c、product.c、product.h,其中main.c是Linux驱动的主程序,在fun.c和product.c、product.h中定义和实现了在main.c中使用的函数,在main.c中通过extern关键字使用fun.c中的函数,通过包含product.h文件使用product.c文件中的函数

最关键一步就是编写Makefile文件

#Makefile

obj-m := multi_file_driver(文件所在目录).o

multi_file_driver-y := main.o fun.o product.o

总之,c或c++ 语言中编译多个源代码文件时,如果a.c使用了b.c文件中的函数,需要在a.c文件中使用extern预先定义b.c中的函数,extern的作用是告诉编译器该函数的函数名、参数个数、参数类型、返回值类型,等到将a.o和b.o链接成可执行文件或程序库时,编译器再到b.o中寻找函数的具体实现。除此之外,还可以使用b.h文件定义b.c中的函数,然后在a.c中包含b.h文件。

2、Linux驱动模块的依赖(动态重用)

在一个驱动模块里使用另一个驱动模块里的被导出的符号(常量、变量、函数等)

下面,示例由两个Linux驱动组成(symbol_producer和symbol_consumer),其中symbol_producer(symbol_producer.c文件)驱动的两个函数(add和sub)和symbo_const常量以及result变量被导出,而在symbol_consumer(symbol_concumer.c文件)驱动中则使用了这4个被导出的符号。

symbol_producer.c 文件部分代码如下://导出add函数

                    EXPORT_SYMBOL(add);

                   //导出result变量

                    EXPRORT_SYMBOL(result);

                   //导出sub函数,使用EXPROT_SYMBOL_GPL导出的符号

                    EXPORT_SYMBOL_GPL(sub);

                   //导出symbol_const常量

                    EXPORT_SYMBOL_GPL(symbol_const);

symbol_consumer.c文件中部分代码如下:extern const char* symbol_const;//定义被导出的常量

                    extern int result;//定义被导出的变量

                    extern int add(int x1,int x2);//定义被导出的add函数

                    extern int sub(int x1,int x2);//定义被导出的sub函数

由于有两个Linux驱动,因此需要在Makefile文件中指定两个Linux模块,代码如下:

#Makefile

obj-m := symbol_consumer.o

obj-m +=symbol_producer.o

注意:在安装symbol_consumer之前,需要先安装symbol_producer;卸载时顺序正好相反。

(二)强行卸载Linux驱动

情况1:初始化函数崩溃

由于Linux驱动模块的初始化函数进行了某些操作而崩溃,从而导致初始化函数无法正常返回,这种情况变现是当前Linux驱动模块没用被任何其他的Linux驱动模块使用,但却显示已经被应用了一次

这种情况关键是引用计数器的值和引用者不一致。只需要将当前的Linux驱动模块的引用计数器清零即可,修改计数器可以使用下面两个函数

//是module指向的Linux驱动模块的引用计数器加1,成功返回1,失败返回0

static inline int try_module_get(struct module *module);

//是module指向的Linux驱动模块的引用计数器减1

extern void module_put(struct module *module);

情况2:卸载函数被阻塞

在使用rmmod命令卸载Linux驱动时,系统会调用卸载函数,只有卸载函数成功返回时,Linux驱动才会被卸载,如果卸载函数被阻塞,rmmod命令也会被阻塞,也就是说永远不会执行到卸载Linux驱动模块的代码,这种情况的表现是一执行rmmod命令就会停在那不动了,永远也不会返回到系统的操作提示符

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

总之,两者情况都要解决一个不可回避的问题,就是要获取表示要卸载的Linux驱动模块的module结构体指针。

转载于:https://www.cnblogs.com/AJ--/p/5651674.html

Android深度探索HAL与驱动开发—第8章相关推荐

  1. Android深度探索--HAL与驱动开发----第五章读书笔记

    第五章主要学习了搭建S3C6410开发板的测试环境.首先要了解到S3C6410是一款低功耗.高性价比的RISC处理器它是基于ARMI1内核,广泛应用于移动电话和通用处理等领域. 开发板从技术上说与我们 ...

  2. Android深度探索--HAL与驱动开发----第三章读书笔记

    Git--源代码管理软件,Git功能十分复杂,我们需要完成的功能有:创建版本库,提交源代码,创建分支,向远程服务器提交源代码,从远程服务器获取源代码等.而本章的学习内容就是掌握如何使用Git从源代码托 ...

  3. Android深度探索--HAL与驱动开发----第一章读书笔记

    1.1   Android拥有非常完善的系统构架可以分为四层: 第一层:Linux内核.主要包括驱动程序以及管理内存.进程.电源等资源的程序 第二层:C/C++代码库.主要包括Linux的.so文件以 ...

  4. android深度探索 HAL及驱动开发 第八章

    第八章 读书笔记 本章主要讲蜂鸣器的驱动,蜂鸣器是S3cC6410开发板上带的一个硬件设备,本节将介绍蜂鸣器的实现原理,并实现一个完整的蜂鸣器驱动.本节讲介绍把linux驱动分成多个文件的方式.这些文 ...

  5. Android深度探索--HAL与驱动开发----第十章读书笔记

    一.打印内核调试信息:printk Printk函数用法与printf函数类似,只不过printk函数运行在内核空间,printf函数运行在用户空间,printk函数在printk.c文件中实现. P ...

  6. 《Android深度探究HAL与驱动开发》学习笔记----第五章

    第五章 搭建S3C6410开发板的测试环境 开发板是开发和学习嵌入式技术的主要硬件设备. 主要学习了搭建S3C6410开发板的测试环境.首先要了解到S3C6410是一款低功耗.高性价比的RISC处理器 ...

  7. Android深度探索(卷1)HAL与驱动开发 第四章 源代码的下载和编译 读书笔记

    Android深度探索(卷1)HAL与驱动开发 第四章 源代码的下载和编译 读书笔记     本章学习了使用git下载两套源代码并搭建两个开发环境.分别为Android源代码和Linux内核源代码.A ...

  8. Android深度探索(卷1)HAL与驱动开发第六章总结

    操作系统是通过各种驱动程序赖家与硬件设备的,它为用户屏蔽了各种各样的设备,驱动硬件是操作系统最基本的功能,并且提供统一的操作方式.设备驱动程序是操作系统最基本的组成部分之一,在Linux内核源程序中也 ...

  9. Android深度探索(卷1)HAL与驱动开发第五章总结

    开发板是开发和学习嵌入式技术的主要硬件设备,开发板的型号和种类很多,目前流行的是基于S3C6410 ARM11架构的开发板,S3C6410是由三星公司推出的一款低功耗,高性价比的RISC处理器,它基于 ...

最新文章

  1. Using NUnit with Visual Studio 2005 Express Editions
  2. 浅谈Spring的AOP实现-代理机制
  3. 红帽:将开源进行到底!
  4. java 编程规范 check list
  5. PHPwamp开发环境搭建详解
  6. 一名待业小生亲身调研揭秘10家大数据培训机构“内幕”
  7. 高斯混合模型(GMM),c++实现
  8. 如何将amr文件转成mp3格式?
  9. topojson转换与应用
  10. bellman_ford算法 由边数限制的最短路
  11. YTU OJ 2458: 换啤酒
  12. 梯度下降算法_Adam-一种随机优化算法
  13. MOOS例程HelloWorld-详细注释
  14. 安装Nvidia驱动run文件
  15. 极光推送收费标准_《天涯明月刀OL腾讯旗下 北极光工作室的 厄运魔咒:“做什么凉什么”》...
  16. 谈谈proxy的安全问题
  17. 2-SAT(随意写点)
  18. 普罗米修斯-docker安装
  19. 纯css固定tbody高度,超出滚动效果
  20. CNAS 检验机构认可规范文件清单

热门文章

  1. 求数组中的最小值以及最小值的序列号
  2. 第二次团队作业-需求分析
  3. 基于CentOS 搭建 Seafile 专属网盘
  4. spring注解注入属性
  5. opencv3.2.0 Cmake 3.8.0 + tdm-gcc-5.1.0-3 编译问题 highgui _Win32_IE
  6. Mac OS X 10.8.X编译Android4.2.X源码不生成emulator的问题
  7. 2011年复活节慕尼黑及其周边游之四-新天鹅堡
  8. hdu4539 郑厂长系列故事——排兵布阵 + POJ1158 炮兵阵地
  9. hdu1074 状态压缩dp+记录方案
  10. 【Groovy】Groovy 动态语言特性 ( Groovy 中函数实参自动类型推断 | 函数动态参数注意事项 )