【北京迅为】《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开发板上面给驱动模块传普通参数和数组参数了。

相关推荐
饮啦冰美式24 分钟前
22.04Ubuntu---ROS2使用rclcpp编写节点
linux·运维·ubuntu
wowocpp24 分钟前
ubuntu 22.04 server 安装 和 初始化 LTS
linux·运维·ubuntu
Huaqiwill26 分钟前
Ubuntun搭建并行计算环境
linux·云计算
wclass-zhengge28 分钟前
Netty篇(入门编程)
java·linux·服务器
Lign1731430 分钟前
ubuntu unrar解压 中文文件名异常问题解决
linux·运维·ubuntu
vip4511 小时前
Linux 经典面试八股文
linux
大霞上仙1 小时前
Ubuntu系统电脑没有WiFi适配器
linux·运维·电脑
孤客网络科技工作室2 小时前
VMware 虚拟机使用教程及 Kali Linux 安装指南
linux·虚拟机·kali linux
颇有几分姿色3 小时前
深入理解 Linux 内存管理:free 命令详解
linux·运维·服务器
极客小张4 小时前
基于STM32的智能充电桩:集成RTOS、MQTT与SQLite的先进管理系统设计思路
stm32·单片机·嵌入式硬件·mqtt·sqlite·毕业设计·智能充电桩