【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第四十三章 驱动模块传参

i.MX8MM处理器采用了先进的14LPCFinFET工艺,提供更快的速度和更高的电源效率;四核Cortex-A53,单核Cortex-M4,多达五个内核 ,主频高达1.8GHz,2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT、4G模块、CAN、RS485等接口一应俱全。H264、VP8视频硬编码,H.264、H.265、VP8、VP9视频硬解码,并提供相关历程,支持8路PDM接口、5路SAI接口、2路Speaker。系统支持Android9.0(支持获取root限)Linux4.14.78+Qt5.10.1、Yocto、Ubuntu20、Debian9系统。适用于智能充电桩,物联网,工业控制,医疗,智能交通等,可用于任何通用工业和物联网应用、

【公众号】迅为电子

【粉丝群】258811263


四十三 章 驱动模块

本章导读

在编写应用程序的时候,我们可以给main函数传递参数,比如void main(int argc,char *argv[]),这个功能大家用起来已经很熟练了。其实在使用insmod命令加载模块的时候,也是可以给模块传递参数的。

43.1章节讲解了驱动模块传参的理论知识。

43.2章节编写了驱动模块传普通参数的驱动程序,并运行测试验证。

43.3章节编写了驱动模块传数组的驱动程序,并运行测试。

本章内容对应视频讲解链接(在线观看):

驱动模块传参数 → https://www.bilibili.com/video/BV1Vy4y1B7ta?p=14

程序源码在网盘资料"iTOP-i.MX8MM开发板\02-i.MX8MM开发板网盘资料汇总(不含光盘内容)\嵌入式Linux开发指南(iTOP-i.MX8MM)手册配套资料\2.驱动程序例程\05-驱动模块传参"路径下。

43 .1 驱动 模块传参简介

什么是驱动传参

在装载内核模块时,用户可以向模块传递参数,形式为"insmode(或modprobe)模块名参数名=参数

值",如果不传递,参数将使用模块内定义的缺省值。如果模块被内置,就无法insmod了,但是bootloader

可以通过在bootargs里设置"模块名.参数名=值"的形式给该内置的模块传递参数。

驱动传参的作用

  • 设置驱动的相关参数,比如设置缓冲区的大小
  • 设置安全校验,防止我们写的驱动被人盗用

怎么给驱动传参数

传递普通的参数,比如 char int类型,使用如下函数:

|--------|-------------------------------|
| 函数 | module_param(name,type,perm); |
| 参数name | 要传递进去参数的名称 |
| 参数type | 要传递进去参数的类型 |
| 参数perm | 要传递进去参数的读写权限 |

部分常用参数权限解释如下:

|----------------------|----------------|
| 宏定义 | 权限解释 |
| #defineS_IRUSR 00400 | 文件所有者可读 |
| #defineS_IWUSR00200 | 文件所有者可写 |
| #defineS_IXUSR 00100 | 文件所有者可执行 |
| #defineS_IRGRP00040 | 与文件所有者同组的用户可读 |
| #defineS_IWGRP00020 | |
| #defineS_IXGRP 00010 | |
| #defineS_IROTH 00004 | 与文件所有者不同组的用户可读 |
| #defineS_IWOTH00002 | |
| #defineS_IROTH 00004 | 与文件所有者不同组的用户可读 |
| #defineS_IWOTH00002 | |
| #defineS_IXOTH 00001 | |

其它的可以使用下面的方法来判断:

可以将数字最后三位转化为二进制:xxx xxx xxx,高位往低位依次看,第一位为 1 表示文件所有者可读,第二位为 1 表示文件所有者可写,第三位为 1 表示文件所有者可执行;接下来三位表示文件所有者同组成员的权限;再下来三位为不同组用户权限。

传递数组使用以下函数:

|--------|-----------------------------------------|
| 函数 | module_param_array(name,type,nump,perm) |
| 参数name | 要传递进去参数的名称 |
| 参数type | 要传递进去参数的类型 |
| 参数nump | 实际传入进去参数的个数 |
| 参数perm | 要传递进去参数的读写权限 |

43 .2 驱动模块传普通参数

程序源码在网盘资料"iTOP-i.MX8MM开发板\02-i.MX8MM开发板网盘资料汇总(不含光盘内容)\嵌入式Linux开发指南(iTOP-i.MX8MM)手册配套资料\2.驱动程序例程\05-驱动模块传参\001"路径下。

通过43.1章节驱动理论基础的学习,我们已经把驱动传参的基本概念搞懂了。我们在ubuntu的/home/topeet/imx8mm/001目录下新建parameter.c文件。完整驱动代码如下图所示:

cpp 复制代码
#include <linux/init.h>
#include <linux/module.h>

//定义整型变量a
static int a;
//传递普通的参数a,参数权限为S_IRUSR,意为可读
module_param(a,int,S_IRUSR);

static int hello_init(void){
    //打印变量a
    printk("a = %d \n",a);
    printk("hello world! \n");
    return 0;
}

static void hello_exit(void){
    //打印变量a
    printk("a = %d \n",a);
    printk("goodbye \n");
}

module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");

以I.MX8MM开发板为例,请参考本手册++++第三十++++ ++++七++++ ++++章++++++++Linux内核模块++++ 。我们将parameter.c文件拷贝到Ubuntu的/home/topeet/imx8mm/05/001目录下。将上次编译helloworld的Makefile文件和build.sh文件拷贝到parameter.c同级目录下,修改Makefile为:

cpp 复制代码
obj-m += parameter.o
KDIR:=/home/topeet/linux/linux-imx
PWD?=$(shell pwd)
all:
	make -C $(KDIR) M=$(PWD) modules ARCH=arm64
clean:
	make -C $(KDIR) M=$(PWD) clean

编译驱动成功如下图所示:

我们通过nfs将编译好的驱动程序加载模块,我们进入到共享目录,加载驱动模块如图所示:

insmod parameter.ko

我们卸载驱动,然后改变参数的值,再次加载驱动模块,如下图所示:

rmmod parameter

insmod parameter.ko a=5

我们进入到/sys/module/parameter/目录下,查看变量a的读写权限,如下图所示:

cd /sys/module/parameter/

ls

cd parameters/

ls

ls -l

如上图所示,查看到变量a的读写权限为-r,意为可读,驱动程序里面设置的变量a的权限为S_IRUSR,意为可读,所以变量a传参成功。

43.3 驱动模块传数组

程序源码在网盘资料"iTOP-i.MX8MM开发板\02-i.MX8MM开发板网盘资料汇总(不含光盘内容)\嵌入式Linux开发指南(iTOP-i.MX8MM)手册配套资料\2.驱动程序例程\05-驱动模块传参\002"路径下。

通过43.2章节驱动理论基础的学习,我们已经把驱动传普通参数学会了。本小节我们来学习如何在驱动模块传数组。我们在ubuntu的/home/topeet/imx8mm/002目录下新建parameter.c文件。完整驱动代码如下图所示:

cpp 复制代码
#include <linux/init.h>
#include <linux/module.h>

//定义数组b
static int b[5];
//定义实际传入进去参数的个数
static int count;

//定义整型变量a
static int a;
//传递普通的参数a,参数权限为S_IRUSR,意为可读
module_param(a, int, S_IRUSR);

//传递数组的参数
module_param_array(b, int, &count, S_IRUSR);

static int hello_init(void)
{
    int i;
    //循环遍历数组b的值
    for (i = 0; i < count; i++)
    {
        //打印数组b的值
        printk("b[%d] = %d \n", i, b[i]);
    }
    //打印传入参数的个数
    printk("count= %d \n", count);
    return 0;
}

static void hello_exit(void)
{

    printk("goodbye \n");
}

module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");

我们再将驱动传入数组的代码编译成驱动模块,加载驱动模块,如下图所示:

rmmod parameter

insmod parameter.ko b=1,2,3,4,5

同样我们可以进入到/sys/module/parameter/目录下,查看变量b的权限,如下图所示:

cd /sys/module/parameter/

ls

cd parameters/

ls

ls b -l

如果我们多传入进去参数,会发生什么呢?我们试试传入六个数

到此,我们已经学会了在iTOP-i.MX8MM开发板上面给驱动模块传普通参数和数组参数了。

相关推荐
王哲晓29 分钟前
Linux通过yum安装Docker
java·linux·docker
gopher951142 分钟前
linux驱动开发-中断子系统
linux·运维·驱动开发
@@庆1 小时前
stm32 PWR电源控制(修改主频&睡眠模式&停机模式&待机模式)
stm32·单片机·嵌入式硬件
JT灬新一1 小时前
STM32巡回研讨会总结(2024)
stm32·单片机·嵌入式硬件
码哝小鱼1 小时前
firewalld封禁IP或IP段
linux·网络
鼠鼠龙年发大财1 小时前
【x**3专享】安装SSH、XFTP、XShell、ARM Linux
linux·arm开发·ssh
nfgo1 小时前
快速体验Linux发行版:DistroSea详解与操作指南
linux·ubuntu·centos
爱桥代码的程序媛2 小时前
鸿蒙OpenHarmony【轻量系统芯片移植案例】标准系统方案之瑞芯微RK3568移植案例
嵌入式硬件·harmonyos·鸿蒙·鸿蒙系统·移植·openharmony·鸿蒙开发
Rookie_explorers2 小时前
Linux下go环境安装、环境配置并执行第一个go程序
linux·运维·golang
weixin_424215842 小时前
shell运算实战案例-KFC点餐系统
linux·centos