linux驱动(一):linux驱动框架
编写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驱动框架相关推荐
- 【嵌入式Linux】嵌入式Linux驱动开发基础知识之按键驱动框架
文章目录 前言 1.APP怎么读取按键值 1.1.查询方式 1.2.休眠-唤醒方式 1.3.poll方式 1.3.异步通知方式 1.5. 驱动程序提供能力,不提供策略 2.按键驱动程序框架--查询方式 ...
- imx6 通过移植XRM117x(SPI转串口)对Linux中的SPI驱动框架进行分析
最近分析了一下Linux 中的SPI驱动框架,将自己的理解总结一下,不足之处还请斧正! 1.SPI通信基础知识 SPI(Serial Peripheral Interface)是一种串行(一次发送1b ...
- Linux驱动——mmc概念与框架(一)
Linux驱动--mmc概念与框架(一) 备注: 1. Kernel版本:5.4 2. 使用工具:Source Insight 4.0 3. 参考博客: Linux MMC framewo ...
- linux用户空间flash驱动,全面掌握Linux驱动框架——字符设备驱动、I2C驱动、总线设备驱动、NAND FLASH驱动...
原标题:全面掌握Linux驱动框架--字符设备驱动.I2C驱动.总线设备驱动.NAND FLASH驱动 字符设备驱动 哈~ 这几天都在发图,通过这种方式,我们希望能帮大家梳理学过的知识,全局的掌握Li ...
- Linux之字符设备驱动框架
目录 一.驱动介绍 1.内核模块 2.日志级别 3.模块符号的导出 4.内核模块参数 二.字符设备驱动(一) 1.模块加载 2.注册字符设备驱动 3.内存映射 三.字符设备驱动(二) 1.模块加载 2 ...
- Linux下的FrameBuffer驱动框架
一.RGB LCD经典显示器件介绍: 1.LCD屏幕的重要属性参数: ① 分辨率:也就是屏幕上的像素点的个数: ② 像素格式:即单个像素点RGB三种颜色的表达方式,包括RGB888.ARGB8888和 ...
- Linux 音频驱动(一) ASoC音频框架简介
目录 1. ALSA简介 2. ASoC音频驱动构成 3. PCM数据流 4. 数据结构简介 5. ASoC音频驱动注册流程 1. ALSA简介 Native ALSA Application:tin ...
- linux 编译字符设备驱动错误,linux字符设备驱动框架及编写流程
流程: init { } exit { } 申请设备号 (动态注册/静态注册) 创建一个字符设备 cdev_alloc 初始化字符设备 cdev_init 设备号和字符设备关联 cdev_add 销毁 ...
- Linux主机驱动与外设驱动分离思想
- by 宋宝华(Barry Song) 1主机.外设驱动分离的意义 在Linux设备驱动框架的设计中,除了有分层设计实现以外,还有分隔的思想.举一个简单的例子,假设我们要通过SPI总线访问某外设,在 ...
- 【驱动】linux下I2C驱动架构全面分析
I2C 概述 I2C是philips提出的外设总线. I2C只有两条线,一条串行数据线:SDA,一条是时钟线SCL ,使用SCL,SDA这两根信号线就实现了设备之间的数据交互,它方便了工程师的布线. ...
最新文章
- Sublime Text 3 (含:配置 C# 编译环境)
- webpack.config.js配置遇到Error: Cannot find module '@babel/core'问题
- visual studio 2019安装配置可编写c/c++语言的IDE环境
- sql三个表join_「数据蒋堂」第 31 期:JOIN 简化 – 维度对齐
- 有趣的JS 一行代码 偷取所有图片
- python将csv转字典_python – 将CSV数据转换为字典中的列表
- python-函数之命名空间作用域
- [ NOI 2005 ] 聪聪与可可
- jdbc连接数据库步骤oracle,jdbc连接oracle数据库的步骤
- vs2019键盘钩子_Windows消息钩子
- 如何用echarts创建市区地图
- 朱加强计算机网络技术,深入对比三种标准拓扑结构
- 退出qemu_qemu虚拟机的关机方式
- 内网KDC服务器开放在哪个端口,针对kerbores的攻击有哪些?
- win10的系统mysql服务器地址,win10系统上的mysql服务器地址
- 官网下载git缓慢问题
- 一个比较完整的登陆和注册后台
- 分解质因数Java实现
- Java Hutool 汉字转拼音码
- html <table> 表格 表头固定 内容滚动 代码拿去就能用