Linux驱动 简单的Linux驱动基础知识
一、简述
记--Linux驱动学习笔记。
Linux驱动程序初始化硬件设备,并提供硬件控制接口给更上一层的应用调用。
例如使用QT应用程序控制一个LED灯,需要有一个驱动程序初始化LED灯,并准备好给其它应用程序的可调用接口,然后QT应用程序通过接口进行控制LED灯。
二、设备分类
一般分为字符设备、块设备、网络设备。
字符设备:如串口,像操作文件一样
块设备:如U盘,像操作文件一样
网络设备:如网卡,使用socket相关函数进行操作
三、简单驱动程序的编写
就是.c源文件
3.1 引用相关的头文件
#include <linux/init.h> //module_init(),module_exit()
#include <linux/module.h> //MODULE_LICENSE(), MODULE_AUTHOR()
3.2 需要编写一个初始化/加载函数--init()函数和一个退出/卸载函数--exit()函数。
其中使用module_init(初始化函数)来指定初始化函数,使用module_exit(退出函数)来指定退出函数。
模块加载时会调用初始化函数,模块卸载时会调用退出函数。
驱动编写3要素: module_init(初始化函数)、module_exit(退出函数)、MODULE_LICENSE("GPL")
3.3 添加模块相关描述信息
MODULE_LICENSE("GPL"); 说明遵循GPL协议
MODULE_AUTHOR("Genven_Liang"); 说明作者信息
3.4 driverTest.c文件
#include <linux/init.h> //__init, __exit
#include <linux/module.h> //module_init(), module_exit(),MODULE_LICENSE(),MODULE_AUTHOR(),MODULE_DESCRIPTION()
MODULE_LICENSE("GPL"); //声明协议
MODULE_AUTHOR("Genven_Liang"); //作者信息
MODULE_DESCRIPTION("test for linux driver."); //对本驱动程序的描述
//初始化函数 执行insmod时会调用该函数
static int __init hello_init(void)
{
printk("hello_init!\n");
return 0;
}
//退出函数 执行remod时会调用该函数
static void __exit hello_exit(void)
{
printk("hello_exit!\n");
}
module_init(hello_init);
module_exit(hello_exit);
四、驱动程序的编译
4.1 编译方式有:
1)内部编译:将驱动程序源码放在内核源码目录中进行编译
2)外部编译:将驱动程序源码放在内核源码目录外进行编译
3)静态编译:编译进uImage中
4)动态编译 (.ko文件,动态加载驱模块)
4.2 编译器:
x86等架构使用gcc即可,arm嵌入式设备需要使用相关交叉编译工具链。
4.3 编写Makefile文件进行编译
以下使用外部编译、动态编译、也就是编译为.ko驱动文件
KERN_DIR ?= /usr/src/linux-headers-$(shell uname -r)/ #内核源码目录/usr/src/linux-headers-$(shell uname -r)/
PWD := $(shell pwd)
obj-m := driverTest.o
all:
make -C $(KERN_DIR) M=$(PWD) modules
clean:
make -C $(KERN_DIR) M=$(PWD) clean
编译:make
查看生成的.ko文件, modinfo xxx.ko
五、使用驱动程序
5.1 查看当前已经加载的驱动程序:lsmod
信息比较多的话,使用grep进行检索过滤。lsmod | grep driverTest
5.2 加载驱动:insmod driverTest.ko
管理员运行
5.3 查看内核打印信息:demsg
注:demsg信息太多时可先使用demsg -c进行清空消息。
5.4 卸载驱动:rmmod driverTest
更多推荐
Linux驱动 简单的Linux驱动基础知识
发布评论