3.驱动模块开发(下)

最简单的hello驱动代码编写

驱动代码编写分为4个部分:
1,头文件
2,驱动模块装载和卸载函数入口到声明
3,实现模块装载和卸载函数入口
4,GPL声明

当ko文件加载到内核时调用装载函数
当ko驱动文件从内核中卸载时会调用卸载函数

//1.头文件
#include <linux/init.h>
#include <linux/module.h>

//3.实现模块装载和卸载函数入口
static int __init hello_drv_init(void)
{

	//一般做系统申请资源
	printk("-------%s-------------\n", __FUNCTION__);
	
	return 0;
}

static void __exit hello_drv_exit(void)
{
	//一般做系统释放资源
	printk("-------%s-------------\n", __FUNCTION__);

}

//2.驱动模块装载和卸载函数入口到声明
module_init(hello_drv_init);
module_exit(hello_drv_exit);

//4.GPL声明
MODULE_LICENSE("GPL");

驱动Makefile编写

make:
判断宏KERNELRELEASE是否为空,首次编译,其为空
编译第一个规则allmake -C $(KERNEL_DIR) 进入内核,读取内核中的Makefile,内核中的Makefile会给KERNELRELEASE赋版本值,继续编译M=$(CUR_DIR) modules指定当前文件夹为生成module的目标文件夹,但不知道把哪个文件编译成ko。
此时Makefile会再次执行ifeq($(KERNELRELEASE), ),此时,由于之前有赋值,会走else分支,告诉编译器要将hello.c编译成ko文件



ROOTFS_DIR = /opt/4412/rootfs

ifeq ($(KERNELRELEASE), )
# 内核目录 内核源码一定要先编译,参考系统移植时的内核编译
KERNEL_DIR = /home/linux/linux-3.14.10/
CUR_DIR = $(shell pwd)

all :
	make -C  $(KERNEL_DIR) M=$(CUR_DIR) modules

clean :
	make -C  $(KERNEL_DIR) M=$(CUR_DIR) clean
	
install:
# 将当前目录下的ko模块拷贝到/opt/rootfs/drv_module目录下
	cp -raf *.ko   $(ROOTFS_DIR)/drv_module


else
# 将hello.c和math.c编译成ko文件
obj-m += hello.o
obj-m += math.o


endif

编译

make
make install

insmod加载ko模块

在开发板上执行,用tftp加载内核和设备树,用nfs挂载根文件系统

加载ko

insmod hello.ko

查看系统中装载过哪些模块

lsmod

卸载ko

mkdir /lib/
rmmod hello

ko模块的传参

加载ko: insmod hello.ko myname=“george” myvalue=33

用途: wifi驱动,wifi硬件中内部也运行内部代码,原厂开发,这些代码叫做固件--firmware.bin
	  装载wifi驱动,必须告诉固件到文件在哪里
		 insmod  rtxxx.ko path=/lib/modules/firmware/xxx.bin

在代码如何处理参数:
module_param(name, type, perm)
参数1:表示参数到名字,比如myname, myvalue
参数2:参数到类型, charp, int
参数3: /sys/modules/表示文件到权限: 0666

用法:
	module_param(myvalue, int, 0644);
	module_param(myname, charp, S_IRUGO|S_IWUSR);
	所有的用户都有读权限,只有USR有写权限
#include <linux/init.h>
#include <linux/module.h>
#include <linux/stat.h>

#include "math.h"

//定义参数
static int myvalue = 56;
static char *myname = "peter";

static int __init hello_drv_init(void)
{

	//一般做系统申请资源
	printk("-------%s-------------\n", __FUNCTION__);
	//使用参数
	printk("name = %s, value = %d\n", myname, myvalue);


	printk("a+b = %d, a-b = %d\n", my_add(33,22), my_sub(44,22));
	
	return 0;
}

static void __exit hello_drv_exit(void)
{
	//一般做系统释放资源
	printk("-------%s-------------\n", __FUNCTION__);

}


module_init(hello_drv_init);
module_exit(hello_drv_exit);

MODULE_LICENSE("GPL");
//申明参数
module_param(myvalue, int, 0644);
module_param(myname, charp, S_IRUGO|S_IWUSR);

make
make install
在开发板上执行:
insmod hello.ko myname="zhangsan" myvalue=12

ko模块符号导出

ko模块可以类似动态库文件一样导出接口供其它ko模块使用
在这里插入图片描述

步骤如下:
1.编写ko接口文件,如:math.c
2.编写接口头文件声明接口,如:math.h
3.在其它ko模块中调用接口,见:hello.c
4.在Makefile中添加接口模块,见:Makefile
5.编译,make, make install
6.在开发板上先加载接口ko再加载使用它的ko,insmod math.ko,insmod hello.ko

//math.c

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



//不需要模块加载和卸载到入口声明,直接定义好一些封装的函数

int my_add(int a, int b)
{
	return a+b;
}

EXPORT_SYMBOL(my_add);

int my_sub(int a, int b)
{
	return a-b;
}

EXPORT_SYMBOL(my_sub);




MODULE_LICENSE("GPL");


//math.h

#ifndef __MATH_H__
#define __MATH_H__


int my_add(int a, int b);
int my_sub(int a, int b);

#endif


//hello.c







/*
1,头文件
2,驱动模块装载和卸载函数入口到声明
3,实现模块装载和卸载函数入口
4,GPL声明

*/

#include <linux/init.h>
#include <linux/module.h>
#include <linux/stat.h>

#include "math.h"

//定义参数
static int myvalue = 56;
static char *myname = "peter";

static int __init hello_drv_init(void)
{

	//一般做系统申请资源
	printk("-------%s-------------\n", __FUNCTION__);
	//使用参数
	printk("name = %s, value = %d\n", myname, myvalue);

	//调用接口
	printk("a+b = %d, a-b = %d\n", my_add(33,22), my_sub(44,22));
	
	return 0;
}

static void __exit hello_drv_exit(void)
{
	//一般做系统释放资源
	printk("-------%s-------------\n", __FUNCTION__);

}


module_init(hello_drv_init);
module_exit(hello_drv_exit);

MODULE_LICENSE("GPL");
//申明参数
module_param(myvalue, int, 0644);
module_param(myname, charp, S_IRUGO|S_IWUSR);


ROOTFS_DIR = /opt/4412/rootfs

ifeq ($(KERNELRELEASE), )
# 内核目录 内核源码一定要先编译
KERNEL_DIR = /home/george/Linux_4412/kernel/linux-3.14
CUR_DIR = $(shell pwd)

all :
	make -C  $(KERNEL_DIR) M=$(CUR_DIR) modules

clean :
	make -C  $(KERNEL_DIR) M=$(CUR_DIR) clean
	
install:
	cp -raf *.ko   $(ROOTFS_DIR)/drv_module


else
# 将hello.c和math.c编译成ko文件
obj-m += hello.o
obj-m += math.o


endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值