驱动学习(一)

目录

1、驱动的概念

2、linux驱动的种类

3.驱动在linux中的层次

 4、linux内核模块

4.1linux内核模块的三要素

4.2linux内核模块的编译

4.3模块操作命令

5.在linux内核中使用打印语句

5.1printk打印语句的格式

5.2内核打印级别(8种)

5.3通过打印级别来过滤信息

6.4printk使用实例

6.5printk打印信息查看方式


1、驱动的概念

驱动:驱动就是计算机程序访问硬件的一个接口(API),这个接口由操作系统提供,作为操作系统涉及到安全管理机制,应用层不能够直接访问硬件,需要通过驱动函数接口来访问硬件。

2、linux驱动的种类

驱动的种类:字符设备驱动、块设备驱动、网卡设备驱动

字符驱动设备:按照字节流来访问,只能顺序访问设备。例如:鼠标、键盘、串口、LED等

块设备驱动:按照block(512字节)访问,可以随机访问的设备,属于块设备驱动。例如:硬盘、磁盘、U盘、SD卡等

网卡设备驱动:没有设备节点、操作网卡芯片实现数据收发功能的代码就是网卡设备驱动。应用程序不能直接访问网卡设备驱动程序。

3.驱动在linux中的层次

 4、linux内核模块

4.1linux内核模块的三要素

三要素:入口、出口、许可证

入口:资源申请工作,在安装驱动时入口执行

static int __init demo_init(void){

    return 0;
}
//static:限定作用域,这个函数只能在当前文件中使用,不能被其他传递文件调用
//__init:告诉编译器,将这个入口函数放在.init.text段中,内核执行驱动的时候就从这个段中找入口并执行
//#define __init __section(".init.text")
module __init__(demo_init);
//告诉内核驱动工程编写的驱动的入口的名字就是demo_init

出口:资源释放工作,在卸载驱动的时候执行

static void __exit demo_exit(void){


}
//static:限定作用域,这个函数只能在当前文件中使用,不能被其他传递文件调用
//__exit:告诉编译器,将这个出口函数放在.exit.text段中,内核卸载驱动的时候就从这个段中找出口并执行
//#define __exit __section(".exit.text")

module_exit(demo_exit);
//告诉内核驱动工程编写的驱动的出口的名字就是demo_exit

许可证:遵从GPL的开源协议

MODULE_LICENSE("GPL");

4.2linux内核模块的编译

驱动程序不可用gcc编译器和交叉编译器编译,需要借助Makefile进行编译。

Makefike

# KERNELDIR:= /home/linux/linux-5.10.61/                 #开发板可安装的驱动
  KERNELDIR:= /lib/modules/$(shell uname -r)/build/         #ubuntu可安装的驱动

#内核的路径
PWD:=$(shell pwd)

#$(shell )在执行makefile的时候起一个终端,在终端上执行pwd命令
#将结果赋值给PWD变量

all:
    make -C $(KERNELDIR) M=$(PWD) modules

@#make -C $(KERNELDIR) 进入内核的路径下
@#进入到上述的路径下之后执行 make M=$(PWD) modules 
@# M=$(PWD)表示只编译当前目录下的模块

clean:
    make -C $(KERNELDIR) M=$(PWD) clean

@#make -C $(KERNELDIR) 进入内核的路径下
@#进入到上述的路径下之后执行 make M=$(PWD) clean 
@# M=$(PWD)表示只清除当前目录下的模块

obi-m:demo.o
#告诉编译器,编译当前目录下的模块的名字叫demo,生成的驱动是demo.ko

4.3模块操作命令

安装驱动:sudo insmod xxx.ko

卸载驱动:sudo rmmod xxx

查看已安装的驱动:lsmod

5.在linux内核中使用打印语句

5.1printk打印语句的格式

printk(打印级别 +printf格式); //驱动工程师指定的消息的级别,

printk(和printf的控制格式是一样的); //使用的默认消息的级别

5.2内核打印级别(8种)

在linux内核中一共有八个打印级别,打印级别是用来过滤信息的。

数值越小级别越高。

 KERN_EMERG   "0"    /* system is unusable */
 KERN_ALERT   "1"    /* action must be taken immediately */
 KERN_CRIT    "2"    /* critical conditions */
 KERN_ERR     "3"    /* error conditions */
 KERN_WARNING "4"    /* warning conditions */
 KERN_NOTICE  "5"    /* normal but significant condition */
 KERN_INFO    "6"    /* informational */                                                   
 KERN_DEBUG   "7"    /* debug-level messages */

5.3通过打印级别来过滤信息

只有当消息级别高于终端级别时,消息才会在终端上显示。

cat /proc/sys/kernel/printk

4  4  1  7

//4:终端的级别 4:默认消息级别  1:终端最高级别 7:终端最低级别

改变ubuntu默认消息的级别

su root
echo 4 3 1 7 >/proc/sys/kernel/printk

//永久改变开发板默认消息级别


/home/linux/nfs/rootfs/etc/init.d/rcS

vi rcS

//最后一行加上

echo 4 3 1 7 >/proc/sys/kernel/printk

6.4printk使用实例

#include <linux/init.h>
#include <linux/moudle.h>

static int __init demo_init(void){
    printk(KERN_ERR "hello init\n");
    printk("init\n");
    return 0;
}
staric void __exit demo_exit(void){
    printk(KERN_INFO "%s:%s:%d\n",__FILE__,__func__,__LINE__);
    printk(KERN_ERR "BYE\n");
    printk("exit\n");
}
module_init(demo_init);
module_exit(demo_exit);
MODILE_LICENSE("GPL");

6.5printk打印信息查看方式

1.进入虚拟终端查看

进入虚拟终端,ubuntu中:ctrl+alt+fn+[F2~F6]

退出虚拟终端的方式:ctrl+alt+fn+F1

2.通过dmesg命令查看

​ dmesg :能查看到从内核启动到现在这一刻起所有的打印信息

​ sudo dmesg -C(直接清除)/-c(先回显后清除) :清除打印信息

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值