$2$驱动模块

news/2024/11/6 14:43:35/

 

目录

1.驱动模块(驱动程序的框架)

2.内核中的打印函数(编写第一个驱动程序)

Source Insight 使用:

打印函数编写

分析

3.驱动的多文件编译

4.模块传递参数

安装好驱动之后如何传参?

 多驱动之间调用(导出符号表)

具体过程

5.字符设备驱动

字符设备驱动的注册

总结归纳

具体过程


1.驱动模块(驱动程序的框架)

入口(安装):资源的申请

出口(卸载):资源的释放

许可证:GPL

#include <linux/init.h>
#include <linux/module.h>
//声明   //static 是为了防止别人的驱动和你重名 
static int __init hello_init(void)    //入口
{}
static void __exit hello_exit(void)   //出口
{}
//告诉内核驱动的入口
module_init(hello_init);
//告诉内核驱动的出口
module_exit(hello_exit);
MODULE_LICENSE("GPL");    //许可证

Makefile

KERNELDIR:= /lib/modules/$(shell uname -r)/build/  //ubuntu 内核目录
#KERNELDIR:= /home/linux/kernel/kernel-3.4.39/    //开发板内核目录
PWD:=$(shell pwd)
all: make -C $(KERNELDIR) M=$(PWD) modules
clean:make -C $(KERNELDIR) M=$(PWD) clean
obj-m:=hello.o 	

具体过程:

vi Makefile

 ls

 

 

 

 

 更改

 

 

 

 

 vi hello.c

make

 

 

 

 SI3US-361500-17409

2.内核中的打印函数(编写第一个驱动程序)

Source Insight 使用:

 

 

 

 

 

 

 

 

打印函数编写

分析

--------------------------------------打印级别--------------------------------------
#define KERN_EMERG	"<0>"	/* system is unusable			*/
#define KERN_ALERT	"<1>"	/* action must be taken immediately	*/
#define KERN_CRIT	"<2>"	/* critical conditions			*/
#define KERN_ERR	"<3>"	/* error conditions			*/
#define KERN_WARNING	"<4>"	/* warning conditions			*/
#define KERN_NOTICE	"<5>"	/* normal but significant condition	*/
#define KERN_INFO	"<6>"	/* informational			*/
#define KERN_DEBUG	"<7>"	/* debug-level messages			*/
y@y-virtual-machine:~/linux6818/demo$ cat /proc/sys/kernel/printk4              4	                 1	            7     终端的级别   消息的默认级别   终端的最大级别   终端的最小级别  
#define console_loglevel (console_printk[0])
#define default_message_loglevel (console_printk[1])
#define minimum_console_loglevel (console_printk[2])
#define default_console_loglevel (console_printk[3])
--------------------------------打印函数---------------------------------------------
printk(KERN_ERR "BFS-fs: %s(): " format, __func__, ## args)
功能:消息打印
参数:第一个参数:打印的级别第二个参数:打印的内容第三个参数:和printf一样,需要打印的参数

 ubuntu级别

#include <linux/init.h>
#include <linux/module.h>
#include <linux/printk.h>
static int __init hello_init(void)//入口
{printk(KERN_ERR "hello word\n");return 0;
}
static void __exit hello_exit(void)//出口
{printk(KERN_ERR "baibai\n");
}
module_init(hello_init);//告诉内核驱动的入口
module_exit(hello_exit);//告诉内核驱动的出口
MODULE_LICENSE("GPL");

 安装卸载无反应,因为ubuntu基于linux内核做的开发

PM:

 

dmesg (查看消息的回显) dmesg -c (查看回显并清空)dmesg -C (清空回显)

 

 

 可以不写KERN _ERR 以默认的级别显示

重点:

ctrl+Alt+F5 (进入虚拟控制台)ctrl+Alt+F7(退出虚拟控制台)-》有的退出是F2
sudo insmod  hello.ko(安装驱动)sudo rmmod  hello(卸载驱动)
 dmesg (查看消息的回显)  dmesg -c  (查看回显并清空)dmesg -C  (清空回显)
cat /prod/sys/kernel/printk 
(查看ubuntu终端显示级别 消息默认级别 消息最大级别  消息最小级别)
su root echo 4 3 1 7 > /proc/sys/kernel/printk
(修改ubuntu终端显示级别 消息默认级别 消息最大级别  消息最小级别)
echo 4 3 1 7 > /proc/sys/kernel/printk
(修改开发板)
= 赋值 需要等待其他文件全部执行完,才执行调用的 
:= 立即赋值
+= 附加赋值
?= 询问变量之前是否被赋值过 如果赋值过,本次赋值不成立,否则成立

3.驱动的多文件编译

hello.c  add.cMakefileobj-m:=demo.odemo-y+=hello.o add.o最终生成demo.ko文件	

 vi makefile

增添完后 make

然后make clean

4.模块传递参数

module_param(name, type, perm)    //驱动安装时候的安装路径,或者安装时配置的参数功能:接收命令行传递的参数参数:name: 变量的名字  type:变量的类型  perm:权限 0664 0775 
#include <linux/init.h>
#include <linux/module.h>
int a=10;
module_param(a,int,0664);                   
static int __init hello_init(void)
{printk("sum= %d\n",a);return 0;
}
static void __exit hello_exit(void)
{printk(KERN_ERR"bai");                
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");

 替换Linux6818/demo的hello.c文件 然后进行修改之前的双编译Makefile 即vi Makefile

 完事后 进行make

 

 

 完事后 卸载驱动 sudo rmmod hello

传递两个参数程序

int a=10;
module_param(a,int,0664);    
int b=10;
module_param(b,int,0664);    

问:安装时怎么区分a和b的作用,自己写的知道那如果移植其他厂商的呢比如LCD屏

使用modinfo hello.ko查看,且需要程序里使用如下函数进行配置

 无法看出哪个是什么功能 无法提示

MODULE_PARM_DESC(_parm, desc)
功能:对变量的功能进行描述
参数:@_parm:变量@desc :描述字段
int a=10;
module_param(a,int,0664);
MODULE_PARM_DESC(a,"light");
short b=123;
module_param(b,short,0664);
MODULE_PARM_DESC(b,"clour");
char c='c';module_param(c,byte,0664);MODULE_PARM_DESC(c,"light_c");char *d=null;module_param(d,charp,0664);MODULE_PARM_DESC(d,"clour");static int __init hello_init(void)
{ printk("sum= %d\n",a);printk("sum= %d\n",b);printk("sum= %c\n",c);printk("sum= %s\n",d);                                                                                                                                                                                 
return 0;
}
static void __exit hello_exit(void){printk(KERN_ERR"bai");
}module_init(hello_init);module_exit(hello_exit);MODULE_LICENSE("GPL");

vi hello.c

 

 

int a=10;

int b=0;

module_param(a, int, 0664) ;

module_param(b, int, 0664) ;

MODULE_PARM_dESC(a,"light");

MODULE_PARM_dESC(b,"color");

sudo insmod hello.ko a=20

make

modinfo hello.ko

sudo insomd hello.ko a=30 b=24

sudo dmesg -c

数组传参:

module_param_array(name,type,nump,perm)
功能:接收命令行传递的数组
参数:
name:数组名 type :数组类型  nump:参数的个数,变量的地址 perm 权限
int ww[10]={0}; 
int num;
module_param_array(ww,int,&num,0664)
static int __init hello_init(void)
{int i;for(i=0;i<num;i++){printk("ww[%d]=%d\n",i,ww[i]);}
}

sudo insmod hello.ko ww=1,2,3,4,5

具体过程:

 

 

 

 

int ww[10]={0}; 
int num;
module_param_array(ww,int,&num,0664)
static int __init hello_init(void)
{int i;for(i=0;i<num;i++){printk("ww[%d]=%d\n",i,ww[i]);}
}

make

sudo insmod hello.ko ww=1,2,3,4,5

安装好驱动之后如何传参?

1.lsmod查看驱动名字

2.找路径 /sys/module/驱动模块的名字/parameters

3.修改 -》su root -》echo 需要改为多少>需要修改的参数名

4.cat 需要修改的参数名(查看是否修改成功)

 多驱动之间调用(导出符号表)

假如有两个驱动模块,modul1和modu2 。这两个是可以调用的

cp  ../day1/module  .  -a    拷贝module到当前目录下

makdir export   mv module/  export/ 

mv module/   A 重命名moudule为A

cp A B -a  拷贝一份并命名为B

#include <linux/intt.h>
#include <linux/module.h>
int add(int a,int b)
{return (a+b);
}
EXPORT_SYMBOL_GPL(add);//导出符号表
static int __init hello_init(void)
{return 0;
}
staic int __exit hello_exit(void)
{
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");

进入B,mv hello.c demo.c改下名字

然后vi打开

extern int add(int a,int b);
static int __init hello_init(void)
{printk("sum = %d\n",add(10,345));
}

编译

  make  

 发现报错,提示add没有定义

 所以在执行之前把A里面大M开头文件复制到当前目录下   

mv  cp  ../A/Module.symvers

然后再make

安装:

 先安装提供者 sudo insmod hello.ko

 再安装调用者 sudo insmod  demo.ko

查看信息:dmesg

卸载:

先卸载 demo.ko  再卸载 hello.ko

具体过程

cp -r /

 

 

vi add.c

 

 make

 

 vi hello.c

 

5.字符设备驱动

APP层    ---- 读写操作 ----→

                                     open打开一个文件 --→{ open=hello、read=buf、write=ubuf、close=hello}

内核层    ---- 读写文件 ----→

   |

   v

硬件层    ---- GPIO输出 ----→     LED灯    

字符设备驱动的注册

   int register_chrdev(unsigned int major, const char *name,const struct file_operations *fops)

功能:注册一个字符设备驱动

参数:

@major:主设备号  

  :如果你填写的值大于0,它认为这个就是主设备号

  :如果你填写的值为0,操作系统给你分配一个主设备号   

@name :名字    cat /proc/devices 查看设备名和主设备号

@fops :操作方法结构体

返回值:major>0 ,成功返回0,失败返回错误码(负数) (vi -t EIO 可以查看错误码)

major=0,成功主设备号,失败返回错误码(负数)      

void unregister_chrdev(unsigned int major, const char *name)

功能:注销一个字符设备驱动

参数:

@major:主设备号

@name:名字

返回值:无

总结归纳:

字符设备驱动:

 1、注册驱动register_chrdev(unsigned int major, const char *name,const struct file_operations *fops)

major=0  自动分配设备号  name:驱动的名字   fops:结构体

 2、声明结构体-》注册驱动时第三个参数

 3、open、read、write、release-》按照内核的格式自己写的

 4、把自己写的这些函数->给到结构体里-》.open .read .write .release

 5、注销设备驱动

具体过程:

 开始注册,起一个变量

 

 

 

 1.注册驱动 register_chrdev

    major=0 (自动分配设备号)  name:驱动名字  fops:结构体

2.声明结构体-》注册驱动时第三个参数

3.open、read、write、release-》按照内核的格式自己写的

4.把自己写的函数给到结构体里-》.open .read .write .release

5.注销设备驱动


http://www.ppmy.cn/news/254364.html

相关文章

用anaconda3安装tensorflow的gpu版(显卡是gtx770,操作系统是window7,cuda9.0,cudnn9.0-v7.2)

虽然快毕业了&#xff0c;但是还是想玩玩深度学习&#xff0c;搞了块gtx770随便玩一下。 1.官网下载最新版的anaconda3 2.下载cuda9.0 (之前一直在纠结是否需要vs&#xff0c;问过朋友之后&#xff0c;表示其实不需要。可能需要一些特殊功能的时候需要&#xff0c;这个以后碰…

最新CPU、显卡性能天梯图

最新最全版&#xff1a; 台式CPU性能天梯图 台式显卡性能天梯图 笔记本CPU性能天梯图 笔记本显卡性能天梯图

计算机桌面性能3.3,显卡天梯图2018年3月最新版 三月桌面显卡性能排行 (全文)

伴随着AMD八代APU、NVIDIA网吧特供GTX1060 5G吃鸡显卡上市&#xff0c;新一期的显卡天梯图2018年3月版又与大家见面了。由于近段时间NVIDIA和AMD并没有上市新显卡&#xff0c;因此三月桌面显卡天梯图相比一月版变化也不大&#xff0c;仅供参考吧。 显卡天梯图2018年3月最新版 显…

【分享】2010最新笔记本显卡性能排名总表

以下排名整理自国外网站&#xff0c;以性能排名&#xff0c;越往前性能越好 第一梯队&#xff1a;高端显卡 GeForce GTX 280M SLI Mobility Radeon HD 4870 X2 GeForce GTX 260M SLI GeForce 9800M GTX SLI GeForce GTX 280M GeForce 9800M GT SLI GeForce 9800M GTS SLI Mobil…

08年最新笔记本显卡性能排名和档次划分

08年笔记本显卡性能排名和档次划分注意&#xff1a;类别排名越后&#xff0c;性能越低。第一类笔记本显卡排名&#xff1a; GeForce 8800M GTX SLI GeForce Go 7950 GTX SLI GeForce Go 7900 GTX SLI Quadro FX 3600M GeForce 8800M GTX GeForce Go 7950 GTX Quadro FX 3500M G…

闲话 - 笔记本显卡性能排行

第一梯队&#xff1a;高端显卡GeForce GTX 280M SLIMobility Radeon HD 4870 X2GeForce GTX 260M SLIGeForce 9800M GTX SLIGeForce GTX 280MGeForce 9800M GT SLIGeForce 9800M GTS SLIMobility Radeon HD 3870 X2GeForce 8800M GTX SLIMobility Radeon HD 3850 X2Quadro FX 3…

NVIDIA、AMD、Intel史上所有显卡性能等级总排行

TomsHardware.com近日奉上了一份恢宏巨制&#xff1a;NVIDIA、AMD(ATI)、Intel历史上发布过的所有型号显卡全部被放在同一张表格内&#xff0c;并按大致性能等级进行了排序。无论是独立显卡、集成显卡还是笔记本显卡&#xff0c;无论是最早的TNT、Rage 128、740还是最新的GeFor…

解决SpringBoot配置文件项目重启出现乱码的情况

近日&#xff0c;在创建了SpringBoot项目后往配置文件中写了相关的系统配置&#xff0c;并且在上面加了中文注释&#xff0c;但是在重启项目或开机重启后遇到了注释乱码的情况&#xff0c;查询了各种相关资料&#xff0c;得以解决 发现问题 首先看到我在这个application.prope…