编写linux驱动先看一下驱动框架是什么样子的。

驱动编写和应用层编写有什么区别呢?

(一)首先 入口函数的问题。应用层编写我们的入口就是main函数,但在驱动编写时不是这样的,有两种情况,

1、缺省情况下

int __init init_module(void)  加载模块时的初始化函数,也就是驱动模块的入口函数

void __exit cleanup_module(void) 卸载模块时的函数,也就是卸载某个驱动时要执行的函数

2、

static int __init xxxx_init(void)  加载模块时的初始化函数,也就是驱动模块的入口函数

static void __exit xxxx_exit(void)  卸载模块时的函数,也就是卸载某个驱动时要执行的函数

上述两种情况相比,我们一般用第二种,因为第一种的名称是固定的,我们不能做更改,第二种我们可以改写xxxx为我们自己模块的名字。可以达到见文知义。

在用第二种模式时,我们要首先用固定格式声明一下:

module_init(xxxx_init);
module_exit(xxxx_exit);

来表明加载初始化函数和卸载函数。

(二)c语言的标准函数库不能使用

驱动属于内核的一部分,我们此时还无法使用类似像printf这样的c库,但是内核会提供自己的c库,在内核中我们用printk代替printf函数。

(三)添加LICENSE声明

linux是开源的系统,那就要我们遵守一定的规范,我们一般用GPL规范,所以在驱动编写时都要声明一下

MODULE_LICENSE(“GPL”);

基本的区别就是这些,我们来看一个简单的驱动框架

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>MODULE_LICENSE("GPL");static int __init demo_init(void)
{printk("%s,%d\n", __func__, __LINE__);printk("val:%d\n", obj.val);obj.func();return 0;
}static void __exit demo_exit(void)
{printk("%s,%d\n", __func__, __LINE__);
}module_init(demo_init);
module_exit(demo_exit);

完成驱动编写后,如何才能加载到内核呢?我们需要通过Makefile 生成.ko文件,一个简单的Makefile如下,这是在ubutnu下的Makefile,如果换为ARM平台下的linux需要更换源文件目录。具体解释可以看内核模块编译makefile入门。执行make即可生成模块.ko文件

$(warning KERNELRELEASE = $(KERNELRELEASE))ifeq ($(KERNELRELEASE),)#内核的源码路径, ?= 条件赋值, uname -r  得到内核的版本号
KERNELDIR ?= /lib/modules/$(shell uname -r)/build  # := 立即赋值, 得到当前的绝对路径
PWD := $(shell pwd)# -C 切换工作路径, make -c
modules:$(MAKE) -C $(KERNELDIR) M=$(PWD) modulesclean:rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions Module* modules*.PHONY: modules  cleanelse# 生成模块obj-m := used.o endif

下面我们来看几个驱动中常用的命令

1、加载驱动模块insmod

将生成驱动模块.ko文件加载,

insmod xxx.ko

加载后就会执行xxxx_init函数

2、卸载驱动模块rmmod

     对应的卸载驱动的命令

rmmod xxxx 注意不用带.ko

3、查看内核中的模块信息

     lsmod

4、查看模块的描述信息

     modinfo xxxx.ko

     我们可以在驱动程序添加一些辅助信息,例如作者 ,驱动描述等。

5、查看模块打印信息

     dmesg   

     printk是内核打印函数,默认模式下在中断下无法显示(当然,可以设置成打印到终端),用dmesg可以查看一下打印到内核的信息。

上述几个比较常用,有其他的我们可以以后再看。

我们把上述几个熟悉一下

insmod /rmmod/dmesg

加载模块后执行初始化函数,打印函数名和行号

卸载模块后执行卸载函数,打印函数名和行号

打印模块信息 modinfo


查看内核中模块信息lsmod


module为模块名称   size为模块打下  usedby 表明有几个其他文件使用

实际上lsmod是读取并分析“/proc/modules”文件,我们来看一下这个文件

内核已经加载的模块的信息也存在于/sys/module目录下,加载demo.ko后,内核中将包含/sys/moudle/demo目录,demo的目录树结构如下

除了使用insmod加载模块以外,还可以用modprobe命令来加载模块,并且使用modprobe加载模块时,会同时加载模块所依赖的其他模块。insmod必须按顺序一个一个加载模块。同样在卸载时,modprobe -r filename的方式会同时卸载该模块所依赖的模块。

模块之间的依赖关系放在/lib/modules/<kernel-version>/modules.dep文件中。实际上是在整体编译内核的时候由depmod工具生成的,该文件的格式很简单:有依赖的直接在“:”后面加上。

linux驱动(一):linux驱动框架相关推荐

  1. 【嵌入式Linux】嵌入式Linux驱动开发基础知识之按键驱动框架

    文章目录 前言 1.APP怎么读取按键值 1.1.查询方式 1.2.休眠-唤醒方式 1.3.poll方式 1.3.异步通知方式 1.5. 驱动程序提供能力,不提供策略 2.按键驱动程序框架--查询方式 ...

  2. imx6 通过移植XRM117x(SPI转串口)对Linux中的SPI驱动框架进行分析

    最近分析了一下Linux 中的SPI驱动框架,将自己的理解总结一下,不足之处还请斧正! 1.SPI通信基础知识 SPI(Serial Peripheral Interface)是一种串行(一次发送1b ...

  3. Linux驱动——mmc概念与框架(一)

    Linux驱动--mmc概念与框架(一) 备注:   1. Kernel版本:5.4   2. 使用工具:Source Insight 4.0   3. 参考博客: Linux MMC framewo ...

  4. linux用户空间flash驱动,全面掌握Linux驱动框架——字符设备驱动、I2C驱动、总线设备驱动、NAND FLASH驱动...

    原标题:全面掌握Linux驱动框架--字符设备驱动.I2C驱动.总线设备驱动.NAND FLASH驱动 字符设备驱动 哈~ 这几天都在发图,通过这种方式,我们希望能帮大家梳理学过的知识,全局的掌握Li ...

  5. Linux之字符设备驱动框架

    目录 一.驱动介绍 1.内核模块 2.日志级别 3.模块符号的导出 4.内核模块参数 二.字符设备驱动(一) 1.模块加载 2.注册字符设备驱动 3.内存映射 三.字符设备驱动(二) 1.模块加载 2 ...

  6. Linux下的FrameBuffer驱动框架

    一.RGB LCD经典显示器件介绍: 1.LCD屏幕的重要属性参数: ① 分辨率:也就是屏幕上的像素点的个数: ② 像素格式:即单个像素点RGB三种颜色的表达方式,包括RGB888.ARGB8888和 ...

  7. Linux 音频驱动(一) ASoC音频框架简介

    目录 1. ALSA简介 2. ASoC音频驱动构成 3. PCM数据流 4. 数据结构简介 5. ASoC音频驱动注册流程 1. ALSA简介 Native ALSA Application:tin ...

  8. linux 编译字符设备驱动错误,linux字符设备驱动框架及编写流程

    流程: init { } exit { } 申请设备号 (动态注册/静态注册) 创建一个字符设备 cdev_alloc 初始化字符设备 cdev_init 设备号和字符设备关联 cdev_add 销毁 ...

  9. Linux主机驱动与外设驱动分离思想

    - by 宋宝华(Barry Song) 1主机.外设驱动分离的意义 在Linux设备驱动框架的设计中,除了有分层设计实现以外,还有分隔的思想.举一个简单的例子,假设我们要通过SPI总线访问某外设,在 ...

  10. 【驱动】linux下I2C驱动架构全面分析

    I2C 概述 I2C是philips提出的外设总线. I2C只有两条线,一条串行数据线:SDA,一条是时钟线SCL ,使用SCL,SDA这两根信号线就实现了设备之间的数据交互,它方便了工程师的布线. ...

最新文章

  1. Sublime Text 3 (含:配置 C# 编译环境)
  2. webpack.config.js配置遇到Error: Cannot find module '@babel/core'问题
  3. visual studio 2019安装配置可编写c/c++语言的IDE环境
  4. sql三个表join_「数据蒋堂」第 31 期:JOIN 简化 – 维度对齐
  5. 有趣的JS 一行代码 偷取所有图片
  6. python将csv转字典_python – 将CSV数据转换为字典中的列表
  7. python-函数之命名空间作用域
  8. [ NOI 2005 ] 聪聪与可可
  9. jdbc连接数据库步骤oracle,jdbc连接oracle数据库的步骤
  10. vs2019键盘钩子_Windows消息钩子
  11. 如何用echarts创建市区地图
  12. 朱加强计算机网络技术,深入对比三种标准拓扑结构
  13. 退出qemu_qemu虚拟机的关机方式
  14. 内网KDC服务器开放在哪个端口,针对kerbores的攻击有哪些?
  15. win10的系统mysql服务器地址,win10系统上的mysql服务器地址
  16. 官网下载git缓慢问题
  17. 一个比较完整的登陆和注册后台
  18. 分解质因数Java实现
  19. Java Hutool 汉字转拼音码
  20. html <table> 表格 表头固定 内容滚动 代码拿去就能用

热门文章

  1. 一些很漂亮的字符图片
  2. openwrt软路由实现ipv6上网配置
  3. OpenCV开发笔记(五十四):红胖子8分钟带你深入了解Haar级联分类器进行人脸检测(图文并茂+浅显易懂+程序源码)
  4. 费曼技巧:一张白纸提高学习效率
  5. 第七讲项目3-编制三角函数表
  6. java实现:随机生成小写字母,并判断是元音还是辅音
  7. 浏览器端转盘抽奖策略实现
  8. Android 快应用
  9. 【OCR】中文街景数据集、场景文本定位识别新网络:End2End-PSL
  10. supermap mysql_超图supermap sdx数据库用sql实现空间查询