Linux驱动1:入口与出口、头文件路径、makefile编译

目录

Linux 驱动两种运行方式

字符设备驱动框架

1、创建目录和编写文件

2、添加头文件路径

3、Makefile编写和解释

4、编译测试


Linux 驱动两种运行方式

第一种就是将驱动编译进 Linux 内核中,这样当 Linux 内核启动的时候就会自动运行驱动程序;

第二种就是将驱动编译成模块(Linux 下模块扩展名为.ko),在Linux 内核启动以后使用“insmod”命令加载驱动模块。

在调试驱动的时候一般都选择将其编译为模块,这样修改驱动以后只需要编译一下驱动代码即可,不需要编译整个 Linux 代码,而且在调试的时候只需要加载或者卸载驱动模块即可,不需要重启整个系统。

将驱动编译为模块最大的好处就是方便开发,当驱动开发完成,确定没有问题以后就可以将驱动编译进Linux 内核中,当然也可以不编译进 Linux 内核中,具体看自己的需求。

模块有加载和卸载两种操作,在编写驱动的时候需要注册这两种操作函数,模块的加载和卸载注册函数,如下

module_init(xxx_init);
module_exit(xxx_exit);
//注册模块加载函数
//注册模块卸载函数

module_init 函数用来向 Linux 内核注册一个模块加载函数,参数 xxx_init 就是需要注册的具体函数,当使用“insmod”命令加载驱动的时候, xxx_init 这个函数就会被调用。 module_exit()函数用来向 Linux 内核注册一个模块卸载函数,参数 xxx_exit 就是需要注册的具体函数,当使用“rmmod”命令卸载具体驱动的时候 xxx_exit 函数就会被调用。

下面开始创建字符设备驱动框架

字符设备驱动框架

1、创建目录和编写文件

在IMX6ULL/Linux_Drivers创建目录1_chrdevbase


在vscode打开目录并并创建chrdevbase.c文件,在chrdevbase.c文件输入下面的代码

#include <linux/module.h>

static int __int chrdevbase_init(void)
{
    return 0;
}

static void __exit chrdevbase_exit(void)
{
    
}

module_init(chrdevbase_init);
module_exit(chrdevbase_exit);

第 4 行,定义了个名为chrdevbase_init 的驱动入口函数,并且使用了“__init”来修饰
第 11 行,定义了个名为chrdevbase_exit 的驱动出口函数,并且使用了“__exit”来修饰
第 17 行,调用函数 module_init 来声明chrdevbase_init 为驱动入口函数

                当加载驱动的时候 chrdevbase_init函数就会被调用
第18行,调用函数module_exit来声明chrdevbase_exit为驱动出口函数

                当卸载驱动的时候chrdevbase_exit函数就会被调用

2、添加头文件路径

这里需要给vscode头文件添加路径,因为是编写 Linux 驱动,因此会用到 移植在开发板上面的Linux 源码中的函数。需要在 VSCode 中添加 Linux源码中的头文件路径。打开 VSCode,按下“Crtl+Shift+P”打开 VSCode 的控制台,然后输入“C/C++: Edit configurations(JSON) ”,打开 C/C++编辑配置文件,如下图 所示

 打开如下图

需要将 Linux 源码里面的头文件路径添加进来,也就是移植的 Linux 源码中的头文件路径,分别是开发板所使用的 Linux 源码下的 include、arch/arm/include 和 arch/arm/include/generated 这三个目录的路径,注意这里使用绝对路径

添加头文件路径(7-8-9行)以后的 c_cpp_properties.json的文件内容如下所示:

 "${workspaceFolder}/**",
                "/home/ubantu22/my_linux/linux-imx-rel_imx_4.1.15_2.1.0_ga_my/include",
                "/home/ubantu22/my_linux/linux-imx-rel_imx_4.1.15_2.1.0_ga_my/arch/arm/include",
                "/home/ubantu22/my_linux/linux-imx-rel_imx_4.1.15_2.1.0_ga_my/arch/arm/include/generated/"

3、Makefile编写和解释

设置好路径之后需要编译测试,也就是将chrdevbase.c 这个文件编译为.ko 模块
创建Makefile,代码如下:

KERNELDIR := /home/ubantu22/my_linux/linux-imx-rel_imx_4.1.15_2.1.0_ga_my

CURRENT_PATH := $(shell pwd)

obj-m := chrdevbase.o

build : kernel_modules

kernel_modules:
    $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules

clean:
    $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean

 第 1 行, KERNELDIR 表示开发板所用的 Linux 内核源码目录,使用绝对路径

                根据自己的实际情况填写

第 3 行, CURRENT_PATH 表示当前路径,直接通过运行“pwd”命令来获取当前所处路径

第 5 行, obj-m 表示chrdevbase.c 这个文件编译为 chrdevbase.ko 外部可加载模块

                chrdevbase.c会先编译成chrdevbase.o文件,再编译成chrdevbase.ko文件

第 7 行,表示要编译构建的是模块

第 9 行,编译构建模块目标

第 10 行,编译构建模块目标的具体编译命令

                $(MAKE),表示"make"命令,输入make就执行

                -C 表示将当前的工作目录切换到指定目录中,就是 KERNERLDIR 目录,即第1行目录

                M 表示模块源码目录,这是CURRENT_PATH,即编译到第3行目录

                以后程序会自动到指定的CURRENT_PATH目录中读取模块的源码并将其编译为.ko 文件

                “ modules ”与前面的“make”搭配,使用"make"命令即表示编译成模块

第 12 行,清理目标

第 13 行,清理目标的具体命令,清理工作目录和指定的目录,命令为"make clean"

这里的makfile不用指定编译器,因已进入到linux内核中, 移植linux的时候中已指定好编译器

4、编译测试

输入 “ make ”命令开始编译 

 编译完成之后,查看可以看到有“.ko”文件,并测试清理命令“ make clean”并重新查看一下

 可以看到编译出来的也被删除了,测试一下用16核编译,命令“ make -j16”

 测试到此,说明框架是可以成功编译的

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值