Linux驱动开发笔记(一):helloworld驱动源码编写、makefile编写以及驱 ...

发布网友 发布时间:23分钟前

我来回答

1个回答

热心网友 时间:14分钟前

前言

基于linux的驱动开发学习笔记,本篇主要介绍了一个字符驱动的基础开发流程,适合有嵌入式开发经验的读者学习驱动开发。

笔者自身情况

我具备硬件基础、单片机软硬基础和linux系统基础等,但缺乏linux驱动框架基础,也未进行过linux系统移植和驱动移植开发。因此,学习linux系统移植和驱动开发将有助于打通嵌入式整套流程。虽然作为技术leader不一定要亲自动手,但对产品构架中的每一块业务和技术要有基本了解。

推荐

建议参考xun为的视频教程,教程过程清晰,适合拥有丰富知识基础的资深研发人员学习。该教程不陷入固有思维误区,也不需要理解imx6的庞杂汇报,直接以实现目标为目的,无需从裸机开始开发学习,所有步骤都解释得清清楚楚。结合多年相关从业经验,确实能够融会贯通。从业多年,首次推荐,因为确实非常好。

驱动

驱动分为四个部分

第一个驱动源码:Hello world!

步骤一:包含头文件

包含宏定义的头文件init.h,包括初始化和宏头文件,如module_init、module_exit等。

#include

包含初始化加载模块的头文件

步骤二:写驱动文件的入口和出口

使用module_init()和module_exit()宏定义入口和出口。

module_init(); module_exit();

步骤三:声明开源信息

告诉内核,本模块驱动有开源许可证。

MODULE_LICENSE("GPL");

步骤四:实现基础功能

入口函数

static int hello_init(void) { printk("Hello, I’m hongPangZi\n"); return 0; }

出口函数

static void hello_exit(void) { printk("bye-bye!!!\n"); }

此时可以修改步骤二的入口出口宏

module_init(hello_init); module_exit(hello_exit);

总结,按照四步法,搭建了基础的驱动代码框架。

Linux驱动编译成模块

将驱动编译成模块,然后加载到内核中。将驱动直接编译到内核中,运行内核则会直接加载驱动。

步骤一:编写makefile

1 生成中间文件的名称

obj-m += helloworld.o

2 内核的路径

内核在哪,实际路径在哪

KDIR:=

3 当前路径

PWD?=$(shell pwd)

4 总的编译命令

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

make进入KDIR路径,当前路径编译成模块。

obj-m = helloworld.o KDIR:= PWD?=$(shell pwd) all: make -C $(KDIR) M=$(PWD) modules

步骤二:编译驱动

编译驱动之前需要注意以下几点:

1 内核源码要编译通过

驱动编译成的目标系统需要与内核源码对应,且内核源码需要编译通过。

2 内核源码版本

开发板或系统运行的内核版本需要与编译内核驱动的内核源码版本一致。

3 编译目标环境

在内核目录下,确认是否为需要的构架:

make menu configure export ARCH=arm

修改构架后,使用menu configure查看标题栏的内核构架。

4 编译器版本

找到使用的arm编译器(实际为arm-linux-gnueabihf-gcc,取gcc前缀):

export CROSS_COMPILE=arm-linux-gnueabihf-

5 编译

直接输入make,编译驱动,会生成hellowold.ko文件,ko文件就是编译好的驱动模块。

步骤三:加载卸载驱动

1 加载驱动

将驱动拷贝到开发板或目标系统,然后使用加载指令:

insmod helloworld.ko

会打印入口加载的printk输出。

2 查看当前加载的驱动

lsmod

可以查看到加载的驱动模块。

3 卸载驱动

rmmod helloworld

可以移除指定驱动模块(PS:卸载驱动不需要.ko后缀),卸载成功会打印之前的printk输出。

总结

学习了驱动的基础框架,为了方便测试,下一篇将使用ubuntu18.04编译驱动,并做好本篇文章的相关实战测试。

热心网友 时间:15分钟前

前言

基于linux的驱动开发学习笔记,本篇主要介绍了一个字符驱动的基础开发流程,适合有嵌入式开发经验的读者学习驱动开发。

笔者自身情况

我具备硬件基础、单片机软硬基础和linux系统基础等,但缺乏linux驱动框架基础,也未进行过linux系统移植和驱动移植开发。因此,学习linux系统移植和驱动开发将有助于打通嵌入式整套流程。虽然作为技术leader不一定要亲自动手,但对产品构架中的每一块业务和技术要有基本了解。

推荐

建议参考xun为的视频教程,教程过程清晰,适合拥有丰富知识基础的资深研发人员学习。该教程不陷入固有思维误区,也不需要理解imx6的庞杂汇报,直接以实现目标为目的,无需从裸机开始开发学习,所有步骤都解释得清清楚楚。结合多年相关从业经验,确实能够融会贯通。从业多年,首次推荐,因为确实非常好。

驱动

驱动分为四个部分

第一个驱动源码:Hello world!

步骤一:包含头文件

包含宏定义的头文件init.h,包括初始化和宏头文件,如module_init、module_exit等。

#include

包含初始化加载模块的头文件

步骤二:写驱动文件的入口和出口

使用module_init()和module_exit()宏定义入口和出口。

module_init(); module_exit();

步骤三:声明开源信息

告诉内核,本模块驱动有开源许可证。

MODULE_LICENSE("GPL");

步骤四:实现基础功能

入口函数

static int hello_init(void) { printk("Hello, I’m hongPangZi\n"); return 0; }

出口函数

static void hello_exit(void) { printk("bye-bye!!!\n"); }

此时可以修改步骤二的入口出口宏

module_init(hello_init); module_exit(hello_exit);

总结,按照四步法,搭建了基础的驱动代码框架。

Linux驱动编译成模块

将驱动编译成模块,然后加载到内核中。将驱动直接编译到内核中,运行内核则会直接加载驱动。

步骤一:编写makefile

1 生成中间文件的名称

obj-m += helloworld.o

2 内核的路径

内核在哪,实际路径在哪

KDIR:=

3 当前路径

PWD?=$(shell pwd)

4 总的编译命令

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

make进入KDIR路径,当前路径编译成模块。

obj-m = helloworld.o KDIR:= PWD?=$(shell pwd) all: make -C $(KDIR) M=$(PWD) modules

步骤二:编译驱动

编译驱动之前需要注意以下几点:

1 内核源码要编译通过

驱动编译成的目标系统需要与内核源码对应,且内核源码需要编译通过。

2 内核源码版本

开发板或系统运行的内核版本需要与编译内核驱动的内核源码版本一致。

3 编译目标环境

在内核目录下,确认是否为需要的构架:

make menu configure export ARCH=arm

修改构架后,使用menu configure查看标题栏的内核构架。

4 编译器版本

找到使用的arm编译器(实际为arm-linux-gnueabihf-gcc,取gcc前缀):

export CROSS_COMPILE=arm-linux-gnueabihf-

5 编译

直接输入make,编译驱动,会生成hellowold.ko文件,ko文件就是编译好的驱动模块。

步骤三:加载卸载驱动

1 加载驱动

将驱动拷贝到开发板或目标系统,然后使用加载指令:

insmod helloworld.ko

会打印入口加载的printk输出。

2 查看当前加载的驱动

lsmod

可以查看到加载的驱动模块。

3 卸载驱动

rmmod helloworld

可以移除指定驱动模块(PS:卸载驱动不需要.ko后缀),卸载成功会打印之前的printk输出。

总结

学习了驱动的基础框架,为了方便测试,下一篇将使用ubuntu18.04编译驱动,并做好本篇文章的相关实战测试。

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com