RK3568驱动指南|驱动基础进阶篇-进阶3 驱动代码使用Makefile的宏

发布时间:2024年01月15日

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工智能应用。RK3568 支持安卓 11 和 linux 系统,主要面向物联网网关、NVR 存储、工控平板、工业检测、工控盒、卡拉 OK、云终端、车载中控等行业。

?
【公众号】迅为电子

【粉丝群】824412014(加群获取驱动文档+例程)

【视频观看】嵌入式学习之Linux驱动(驱动基础进阶篇_全新升级)_基于RK3568

【购买链接】迅为RK3568开发板瑞芯微Linux安卓鸿蒙ARM核心板人工智能AI主板


进阶3 驱动代码使用Makefile的宏

在第一章的开头有这样一段内容,module_init 宏定义在内核源码目录下的“include/linux/module.h”文件中,具体内容如下所示:

#ifndef MODULE
#define module_init(x)  __initcall(x);
#define module_exit(x)  __exitcall(x);
#else /* MODULE */
?..........
#define module_init(initfn)                 \
    static inline initcall_t __maybe_unused __inittest(void)        \
    { return initfn; }                  \
    int init_module(void) __copy(initfn) __attribute__((alias(#initfn)));
..........
#endif

module_init的具体内容由MODULE宏定义来决定,该宏定义在内核源码的顶层Makefile中,在本节课中将对Makefile中的宏进行进一步探究。

3.1 内核模块的编译选项的变量

在Makefile中KBUILD_CFLAGS_MODULE和EXTRA_CFLAGS都是用于指定编译内核模块时的编译选项的变量,下面是两个变量的详细介绍。

1KBUILD_CFLAGS_MODULE:
KBUILD_CFLAGS_MODULE是一个makefile变量,用于指定编译内核模块时的编译选项。在makefile中,可以使用KBUILD_CFLAGS_MODULE变量来添加特定于模块的编译选项。

通常,通过在makefile中使用KBUILD_CFLAGS_MODULE变量,可以将特定于模块的编译选项添加到模块的编译命令中。例如,可以使用KBUILD_CFLAGS_MODULE添加宏定义、优化选项、警告选项等。

在给KBUILD_CFLAGS_MODULE赋值时,可以使用+=操作符来追加编译选项,以确保不覆盖已有的编译选项。

例如,KBUILD_CFLAGS_MODULE += -DDEBUG表示将-DDEBUG编译选项添加到模块的编译命令中,定义了一个名为DEBUG的宏。

2EXTRA_CFLAGS:
EXTRA_CFLAGS也是一个makefile变量,用于指定额外的编译选项。与KBUILD_CFLAGS_MODULE类似,可以使用EXTRA_CFLAGS变量来添加编译选项。

同样地,在给EXTRA_CFLAGS赋值时,也可以使用+=操作符来追加编译选项,以确保不覆盖已有的编译选项。

例如,EXTRA_CFLAGS += -DDEBUG表示将-DDEBUG编译选项添加到全局的编译命令中,定义了一个名为DEBUG的宏。

注:两个变量的最终效果是相同的,在目前的内核中主要使用KBUILD_CFLAGS_MODULE变量的方式,EXTRA_CFLAGS已经弃之不用了,但仍旧支持这种方法。

3.2 实验程序的编写

本实验对应的网盘路径为:iTOP-RK3568开发板【底板V1.7版本】\03_【iTOP-RK3568开发板】指南教程\02_Linux驱动配套资料\04_Linux驱动例程\50_define\

本实验将通过KBUILD_CFLAGS_MODULE参数来添加特定于模块的编译选项,根据编译选项的内容来打印不同的值。

编写完成的define.c代码如下所示:

#include <linux/module.h>
#include <linux/kernel.h>

static int __init helloworld_init(void) //驱动入口函数
{
#ifndef DEBUG
    printk("helloworld a!\n");
#else
    printk("helloworld b!\n");
#endif
    return 0;                                                                                                                                                                                                                                             
}

static void __exit helloworld_exit(void) //驱动出口函数
{
    printk(KERN_EMERG "helloworld_exit\r\n");
}

module_init(helloworld_init); //注册入口函数
module_exit(helloworld_exit); //注册出口函数
MODULE_LICENSE("GPL v2"); //同意 GPL 开源协议
MODULE_AUTHOR("topeet"); //作者信息

3.3 运行测试

3.3.1 编译驱动程序

在上一小节中的define.c代码同一目录下创建 Makefile 文件,Makefile 文件内容如下所示:

KBUILD_CFLAGS_MODULE += -DDEBUG
export ARCH=arm64#设置平台架构
export CROSS_COMPILE=aarch64-linux-gnu-#交叉编译器前缀
obj-m +=define.o    #此处要和你的驱动源文件同名
KDIR :=/home/topeet/Linux/linux_sdk/kernel    #这里是你的内核目录                                                                                                                            
PWD ?= $(shell pwd)
all:
    make -C $(KDIR) M=$(PWD) modules    #make操作
clean:
    make -C $(KDIR) M=$(PWD) clean    #make clean操作

对于Makefile的内容注释已在上图添加,保存退出之后,来到存放define.c和Makefile文件目录下,如下图(图3-1)所示:

图 3-1

然后使用命令“make”进行驱动的编译,编译完成如下图(图3-2)所示:

图 3-2

编译完生成define.ko目标文件,如下图(图3-3)所示:

图 3-3

至此驱动模块就编译成功了。

3.3.2 运行测试

开发板启动之后,使用以下命令进行驱动模块的加载,如下图(图3-4)所示:

insmod define.ko

根据打印信息可以确定DEBUG宏定义已经被定义了,所以才会打印“helloworld b!”,如果删除Makefile文件中的第一行内容之后,重新加载内核就会打印“helloworld a!”如下图(图3-5)所示:?

图 3-5

最后,使用以下命令对该内核进行卸载,如下图所示:

rmmod define.ko

?

图 3-6

至此,驱动代码使用Makefile的宏实验就完成了。

文章来源:https://blog.csdn.net/BeiJingXunWei/article/details/135596696
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。