linux驱动学习(四)之module

一、内核模块

内核模块是一种可以动态加载到操作系统内核中并扩展其功能的软件。它们允许在运行的操作系统内核中增加新的功能或驱动程序,而无需重新启动计算机。

在linux系统中,驱动程序是各自独立存在的,而且驱动程序中包含一个moudle,比如:led驱动,按键驱动,lcd驱动。各个驱动程序是由应用程序来进行关联的,利于linux系统对硬件的支持和管理。

可以通过lsmod来查看当前系统中module的存在

[root@GEC6818 /dev]#lsmod
    buttons_drv 2882 0 - Live 0xbf000000 (O)

二、内核模块设计

一个module的框架:

[1]初始化函数 ---- 根据自己驱动的要求来定义一个初始化---- 比如:LED

static int __init gec6818led_init(void)
{
    printk("gec6818_led_init\n"); //相当于应用程序的printf,在驱动程序中,不支持libc
			                    //所有的接口都来看于linux内核的接口:位于include/linux
    //初始化的工作
    return 0;
}

[2]退出函数

static void __exit gec6818led_exit(void)
{
    printk("gec6818led_exit\n");
}

[3] moudle入口和出口

module_init(gec6818led_init); //当用户执行insmod led_drv.ko时,调用module_init,然而,
								  //gec6818led_init被调用
module_exit(gec6818led_exit); //当用户执行rmmod led_drv时,调用moudle_exit

[4] 关于一个驱动的说明

MODULE_AUTHOR("12580.zhang3");
MODULE_DESCRIPTION("GEC6818 LED Device Driver");
MODULE_LICENSE("GPL");

说明:
       1)驱动程序的入口是module_init,应用程序的入口是main
       2)驱动程序的出口是module_exit,应用程序没有出口
       3)驱动程序的头文件要依赖于linux内核源码,应用程序的头文件依赖于libc,所以编译驱动程序要关联内核的源码
       4)驱动程序的编译要用Makefile,应用程序可以用Makefile,也可以用一个命令

三、Makefile文件编译的输出

$ make  ---> 执行make命令

make ARCH=arm CROSS_COMPILE=/home/gec/6818GEC/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin/arm-eabi- -C /home/gec/6818GEC/kernel M=/mnt/hgfs/GZ1853/linux_drvier/4module/code/led_drv modules
	make[1]: Entering directory '/home/gec/6818GEC/kernel'  --->进入内核
	  CC [M]  /mnt/hgfs/GZ1853/linux_drvier/4module/code/led_drv/led_drv.o
	  Building modules, stage 2.
	  MODPOST 1 modules
	  CC      /mnt/hgfs/GZ1853/linux_drvier/4module/code/led_drv/led_drv.mod.o
	  LD [M]  /mnt/hgfs/GZ1853/linux_drvier/4module/code/led_drv/led_drv.ko
	make[1]: Leaving directory '/home/gec/6818GEC/kernel' ----> 离开内核

注意事项:

1)驱动程序的代码路径不能有中文或者空格

2)编译驱动程序之前,一定要先编译内核

make ARCH=arm CROSS_COMPILE=/home/gec/6818GEC/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin/arm-eabi- -C /home/gec/6818GEC/kernel M=/mnt/hgfs/GZ1853/linux_drvier/4module/code/led_drv modules
make[1]: Entering directory '/home/gec/6818GEC/kernel'

ERROR: Kernel configuration is invalid. ---->内核的配置无效
	 include/generated/autoconf.h or include/config/auto.conf are missing.
	 Run 'make oldconfig && make prepare' on kernel src to fix it.


WARNING: Symbol version dump /home/gec/6818GEC/kernel/Module.symvers
	   is missing; modules will have no dependencies and modversions.

CC [M]  /mnt/hgfs/GZ1853/linux_drvier/4module/code/led_drv/led_drv.o
In file included from <command-line>:0:0:
/home/gec/6818GEC/kernel/include/linux/kconfig.h:4:32: fatal error: generated/autoconf.h: No such file or directory
#include <generated/autoconf.h>
							^
compilation terminated.
scripts/Makefile.build:313: recipe for target '/mnt/hgfs/GZ1853/linux_drvier/4module/code/led_drv/led_drv.o' failed
make[2]: *** [/mnt/hgfs/GZ1853/linux_drvier/4module/code/led_drv/led_drv.o] Error 1
Makefile:1365: recipe for target '_module_/mnt/hgfs/GZ1853/linux_drvier/4module/code/led_drv' failed
make[1]: *** [_module_/mnt/hgfs/GZ1853/linux_drvier/4module/code/led_drv] Error 2
make[1]: Leaving directory '/home/gec/6818GEC/kernel'
Makefile:16: recipe for target 'default' failed
make: *** [default] Error 2

 四、安装驱动

#insmod led_drv.ko ----> 安装驱动
#lsmod ---- >查看驱动
#rmmod led_drv.ko  ----> 删除驱动

  问题:
    [root@GEC6818 /6818_driver]#insmod led_drv.ko 
    insmod: can't insert 'led_drv.ko': File exists  ----> 当前系统下,已安装了该驱动
    
    解决办法:利用lsmod查看系统已有的驱动,如果有,则先删除驱动,再插入驱动
 

[root@GEC6818 /6818_driver]#lsmod
led_drv 747 0 - Live 0xbf000000 (O)
[root@GEC6818 /6818_driver]#rmmod led_drv
[  392.193000] gec6818led_exit
[root@GEC6818 /6818_driver]#lsmod
[root@GEC6818 /6818_driver]#         

  五、控制打印信息输出优先级

在linux内核中,对于控制台输出有优先级:

//kernel\kernel\printk.c
int console_printk[4] = {
	DEFAULT_CONSOLE_LOGLEVEL,	/* console_loglevel */              7
	DEFAULT_MESSAGE_LOGLEVEL,	/* default_message_loglevel */      7
	MINIMUM_CONSOLE_LOGLEVEL,	/* minimum_console_loglevel */      1
	DEFAULT_CONSOLE_LOGLEVEL,	/* default_console_loglevel */      7
};
/* printk's without a loglevel use this.. */
#define DEFAULT_MESSAGE_LOGLEVEL CONFIG_DEFAULT_MESSAGE_LOGLEVEL

以CONFIG_的宏,是需要配置内核时候来进行设置,所有的配置项在.config文件中可以找到,当配置完成后,经过编译内核,会把.config配置文件自动生成一个.h文件。

想要在控制台打印消息,则default_message_loglevel(默认消息日志的等级) > default_console_loglevel(默认控制台日志等级)。数值越小,优先级越高。

控制方法一:

查看当前系统控制台日志等级:/proc/sys/kernel/printk
[root@GEC6818 /6818_driver]#cat /proc/sys/kernel/printk
7       7       1       7
修改当前控制台的日志等级 
[root@GEC6818 /]#echo 7 4 1 7 > /proc/sys/kernel/printk  ----> 只当前一次有效

把设置的方法写到配置文件中:/etc/profile	 
echo 7 4 1 7 > /proc/sys/kernel/printk
保存并且退出,重启开发板

控制方法二:修改printk函数打印消息的级别

#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			*/
在驱动程序中,设置printk函数的消息的级别
printk("<4>" "gec6818led_exit\n");  ---> 消息的级别与消息之间用空格隔开
printk(KERN_WARNING "gec6818led_exit\n");

解决办法三:在配置内核中,进行修改

Kernel hacking
      ----->
        CONFIG_DEFAULT_MESSAGE_LOGLEVEL=7
$ make menuconfig  ----> 用菜单来进行内核配置
  HOSTCC  scripts/kconfig/lxdialog/checklist.o
  HOSTCC  scripts/kconfig/lxdialog/inputbox.o
  HOSTCC  scripts/kconfig/lxdialog/menubox.o
  HOSTCC  scripts/kconfig/lxdialog/textbox.o
  HOSTCC  scripts/kconfig/lxdialog/util.o
  HOSTCC  scripts/kconfig/lxdialog/yesno.o
  HOSTCC  scripts/kconfig/mconf.o
  HOSTLD  scripts/kconfig/mconf
scripts/kconfig/mconf Kconfig
#
# configuration written to .config  -----> 把内核的配置写入到.config文件中
#


*** End of the configuration.  ----> 退出菜单配置,完成内核配置
*** Execute 'make' to start the build or try 'make help'.


$ cp .config arch/arm/configs/GEC6818_defconfig ---> 把.config配置文件拷回给具体的硬件平台
$ cd ..
$ ./mk -k  ---->重新编译内核

重新烧写内核到开发板----- boot.img

六、驱动程序调试

$ file led_drv.ko 
	led_drv.ko: ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), BuildID[sha1]=548395fe828e760c1cb522b67f93da3386efca21, not stripped

$ size led_drv.ko
	text	   data	    bss	    dec	    hex	filename
	276	    360	      0	    636	    27c	led_drv.ko


$ modinfo led_drv.ko
	filename:       /mnt/hgfs/GZ1853/linux_drvier/4module/led_drv/led_drv.ko
	license:        GPL
	description:    GEC6818 LED Device Driver
	author:         1853.zhang3
	depends:        
	vermagic:       3.4.39-gec SMP preempt mod_unload ARMv7 p2v8 

觉得有帮助的话,打赏一下呗。。

           

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/675861.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

抽屉式备忘录(共25041字)

Sing Me to Sleep <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>与妖为邻的备忘录</title&g…

【UE5.1 角色练习】09-物体抬升、抛出技能 - part1

前言 在上一篇&#xff08;【UE5.1 角色练习】08-传送技能&#xff09;的基础上继续实现控制物体抬升、抛出的功能。 效果 步骤 一、准备技能动画 1. 在项目设置中新建一个操作映射&#xff0c;这里命名为“Skill_GravityControl”&#xff0c;用按键4触发 2. 通过IK重定向…

ESP使用巴法云远程OTA(VScode + Platform io)

ESP使用巴法云远程OTA&#xff08;Platform&#xff09; 什么是OTA&#xff1a; OTA&#xff08;Over-the-AirTechnology&#xff09;即空中下载技术&#xff0c;是通过移动通信的空中接口实现对移动终端设备及SIM卡数据进行远程管理的技术。OTA升级是物联网&#xff08;IOT&am…

[深度学习]yolov10+deepsort+pyqt5实现目标追踪

YOLOv10DeepSORTPyQt5实现目标追踪系统 在现代智能监控系统中&#xff0c;目标追踪技术扮演着至关重要的角色。结合YOLOv10&#xff08;一种先进的实时目标检测算法&#xff09;与DeepSORT&#xff08;一种多目标追踪算法&#xff09;&#xff0c;并通过PyQt5构建用户界面&…

想要做好海外广告投放?建议这几点先了解清楚

在全球市场竞争日益激烈的今天&#xff0c;跨境电商和出海营销早已经成为了热门选择&#xff0c;随之而来海外广告的投放也受到众多人的青睐。无论是想要提升品牌知名度&#xff0c;还是实现销售增长&#xff0c;正确的广告投放都能事半功倍。错误的选择不仅浪费资源&#xff0…

【Qt秘籍】[006]-Label实现Hello World程序-编程第一步

"Hello,World!" 中文意思是“你好&#xff0c;世界”。 因为 The C Programming Language 中使用它做为第一个演示程序&#xff0c;后来很多程序员在学习编程或进行设备调试时延续了这一习惯。 下面&#xff0c;我们也将演示利用Label显示Qt中的"Hello World!&q…

深度学习笔记:0.cuda安装,成功

B站上说&#xff1a;cs上骗子太多。文章太久&#xff0c;我深以为然。用了一天。才装好。其实很简单。 CUDA安装教程&#xff08;超详细&#xff09;-CSDN博客文章浏览阅读1w次&#xff0c;点赞5次&#xff0c;收藏56次。windows10 版本安装 CUDA &#xff0c;首先需要下载两个…

秋招突击——第四弹——Java的SSN框架快速入门——Spring(2)

文章目录 前言其他Spring加载properties 容器创建容器获取beanBeanFactory容器总结 注解注解开发对定义bean纯注解开发Bean管理Bean作用范围Bean生命周期 注解开发依赖注入第三方bean管理第三方bean管理第三方bean注入 注解开发总结 Spring整合整合mybatis整合Junit AOPAOP核心…

Mybatis实现树形结构方式

1&#xff0c;三级分类树形结构查询 /*** DDD(Domain-Driven Design): 领域驱动设计** 三级分类树形结构&#xff1b;* 支持无限层级&#xff1b;* 当前项目只有三级*/ Data public class CategoryTreeTo {private Long categoryId; //1private String categoryName;private …

外观数列 ---- 模拟

题目链接 题目: 分析: 题目的意思如下:所以我们需要引用双指针来找到连续的字符有几个, 并添加到答案中, 接着将此字符添加到答案中, 让left right , 继续向后遍历整个字符串, 重复上面的操作将答案重新赋给字符串, 继续重复上述操作, 应该重复n - 1 次, 因为n为1的时候, 直…

上网是不是必须路由器和光猫之一负责拨号?

链接&#xff1a;https://www.zhihu.com/question/624856022/answer/3245182557 上网并非一定要“拨号”&#xff0c;使用固定IP地址可以直接上网&#xff0c;不需要拨号。你们公司的宽带属于商用宽带&#xff0c;运营商&#xff08;电信&#xff09;给配置了固定的IP&#…

如何监控企业微信聊天记录内容,第二个方法太赞了!

监控企业微信聊天记录内容是企业为了确保沟通合规、提升工作效率、防止信息泄露以及保护公司利益而采取的一种管理措施。在当前的中国&#xff0c;是法律允许的合法行为。 怎么监控&#xff1f;请看下面详情。 1. 利用企业微信自带功能 企业会话存档&#xff1a; 企业微信提…

43页 | 2024年企业级BI平台白皮书(免费下载)

【1】关注本公众号&#xff0c;转发当前文章到微信朋友圈 【2】私信发送 2024年企业级BI平台白皮书 【3】获取本方案PDF下载链接&#xff0c;直接下载即可。 诚挚邀请您微信扫码加入以下方案驿站知识星球&#xff0c;获取上万份PPT/WORD解决方案&#xff01;&#xff01;&…

【Python Cookbook】S01E16 同时对数据做转换和换算

目录 问题解决方案讨论 问题 当换算&#xff08;sum(), min(), max()&#xff09;同时遇到转换或筛选&#xff0c;怎么做&#xff1f; 解决方案 有一种非常优雅的方法&#xff0c;可以将数据换算和转换结合在一起——在函数参数中使用 生成器表达式。 一个直观的案例&#…

YOLOv8+PyQt5海洋船只检测(可以重新训练,yolov8模型,从图像、视频和摄像头三种路径识别检测)

1.效果视频&#xff1a;海洋船只检测yoloV8检测&#xff08;https://mbd.pub/o/bread/mbd-ZpaYk55r&#xff09;_哔哩哔哩_bilibili资源包含可视化的海洋船只检测系统&#xff0c;可对于高空拍摄到的海洋图片进行轮船检测&#xff0c;基于最新的YOLOv8训练的海洋船只检测模型&a…

Facebook开户|FB10大提升视频广告效果实践

Facebook10大提升视频广告效果实践&#xff01;&#xff01;需要的家人们建议点赞收藏哦~ 一、在前3秒吸引注意力 在视频广告推广活动中&#xff0c;一直都有黄金3秒的说法&#xff0c;指的就是通过前三秒的制作&#xff0c;吸引观众的注意。吸引人的画面、个性的CTA、独特性和…

C语言| 字母金字塔

【思路分析&#xff1a;】 1 考虑左边的空格大写字母&#xff0c;而大写字母 先升序后降序输出 2 升序输出的字母的个数行数最大字母在26个英文字母中排的位置序号 3 降序输出的字母 升序输出的字母个数-1 编程顺序&#xff1a; 1 定义循环变量i,表示字母的顺序,循环变量j 表…

软件测试之黑盒测试与白盒测试知识小结

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 对于很多刚开始学习软件测试的小伙伴来说&#xff0c;如果能尽早将黑盒、白盒测试弄明白&#xf…

Makefile的入门学习

一、Makefile的入门学习 编译工具及构建工具介绍 在之前的课程&#xff0c;都是直接使用gcc对代码进行编译&#xff0c;这对简单的工程是可以的&#xff0c;但当我们遇到复杂的工程时&#xff0c;每次用gcc等编译工具去操作就会显得很低效。因此make工具就出现了&#xff0c;…

MYSQL之主从复制

一&#xff0c;安装MYSQL&#xff0c;两台 二&#xff0c;配置master服务器 vim /etc/my.cnf 在mysqld模块下加入 server-id133 #配置server-id&#xff0c;让主服务器有唯一ID号&#xff08;让从服务器知道 他的主服务器是谁&#xff09;,建议使用ip最后3位 log-binmysql-bi…