前言
-
很抱歉各位粉丝啊,博主好久没有更新原创文章,从今天起开始恢复写文章的时光。前段时间各种不顺利,到时心情低落。现在恢复状态了。
简介
-
本文主要来讲讲Linux内核驱动中,EXPORT_SYMBOL()宏定义的用法。
-
在阅读的Linux内核驱动源码的时候,我们会发现很多的函数带有EXPORT_SYMBOL()宏定义。
![834fee0b7a9822f65259da2556d580fc.png](https://img-blog.csdnimg.cn/img_convert/834fee0b7a9822f65259da2556d580fc.png)
-
从这个宏定义的理解为输出符号。那么他究竟有什么作用。
EXPORT_SYMBOL()宏定义作用
-
EXPORT_SYMBOL宏定义定义的函数或者符号将对内核代码公开,不用修改内核代码就在其他的内核模块中直接调用,即使用EXPORT_SYMBOL可以将一个函数以符号的方式导出给其他模块使用。
使用方法
-
在模块函数定义之后使用"EXPORT_SYMBOL(函数名)"来导出。
static int rice_func(void)
{
return 0;
}
EXPORT_SYMBOL(rice_func);
-
在调用该函数的另外一个模块中使用extern对之声明。
extern int rice_func(void);
-
先加载定义该函数的模块,然后再加载调用该函数的模块,先后顺序必须注意。
实验
编写代码
-
编写两个模块:rice_export.ko 和 rice_import.ko,其中:
-
rice_export.ko:导出定义的函数
-
rice_import.ko:调用导出的函数
-
导出函数模块的代码(rice_export.c)
-
导出函数为:rice_drv_export,函数含义:外部输入一个字符串,然后打印出来
#include "rice_export.h"
#define CLASS_NAME "rice_export"
#define DEVICE_NAME "rice_export"
typedef struct {
int major_number;
struct device *device;
struct class *class;
} Rice_Driver;
Rice_Driver rice_drv;
static int rice_drv_export(char *name) {
printk(KERN_ALERT "Rice Export: %s\n", name);
return 0;
}
EXPORT_SYMBOL(rice_drv_export);
static int __init rice_export_init(void) {
rice_drv.major_number = register_chrdev(0, DEVICE_NAME, NULL);
if (rice_drv.major_number < 0) {
printk(KERN_ALERT "Register fail!!\n");
return rice_drv.major_number;
}
printk(KERN_ALERT "Registe success, major number is %d\n", rice_drv.major_number);
rice_drv.class = class_create(THIS_MODULE, CLASS_NAME);
if (IS_ERR(rice_drv.class)) {
unregister_chrdev(rice_drv.major_number, DEVICE_NAME);
return PTR_ERR(rice_drv.class);
}
rice_drv.device = device_create(rice_drv.class, NULL, MKDEV(rice_drv.major_number, 0), NULL, DEVICE_NAME);
if (IS_ERR(rice_drv.device)) {
class_destroy(rice_drv.class);
unregister_chrdev(rice_drv.major_number, DEVICE_NAME);
return PTR_ERR(rice_drv.device);
}
printk(KERN_ALERT "rice export ko init!!\n");
return 0;
}
static void __exit rice_export_exit(void) {
device_destroy(rice_drv.class, MKDEV(rice_drv.major_number, 0));
class_unregister(rice_drv.class);
class_destroy(rice_drv.class);
unregister_chrdev(rice_drv.major_number, DEVICE_NAME);
printk(KERN_ALERT "rice export ko exit!!\n");
}
module_init(rice_export_init);
module_exit(rice_export_exit);
MODULE_AUTHOR("RieChen");
MODULE_LICENSE("GPL");
电泳函数模块的代码(rice_import.c)
-
调用函数声明:extern int rice_drv_export(char *name);,含义:声明外部函数
#include "rice_import.h"
#define CLASS_NAME "rice_import"
#define DEVICE_NAME "rice_import"
typedef struct {
int major_number;
struct device *device;
struct class *class;
} Rice_Driver;
Rice_Driver rice_drv;
extern int rice_drv_export(char *name);
static int __init rice_import_init(void) {
rice_drv.major_number = register_chrdev(0, DEVICE_NAME, NULL);
if (rice_drv.major_number < 0) {
printk(KERN_ALERT "Register fail!!\n");
return rice_drv.major_number;
}
printk(KERN_ALERT "Registe success, major number is %d\n", rice_drv.major_number);
rice_drv.class = class_create(THIS_MODULE, CLASS_NAME);
if (IS_ERR(rice_drv.class)) {
unregister_chrdev(rice_drv.major_number, DEVICE_NAME);
return PTR_ERR(rice_drv.class);
}
rice_drv.device = device_create(rice_drv.class, NULL, MKDEV(rice_drv.major_number, 0), NULL, DEVICE_NAME);
if (IS_ERR(rice_drv.device)) {
class_destroy(rice_drv.class);
unregister_chrdev(rice_drv.major_number, DEVICE_NAME);
return PTR_ERR(rice_drv.device);
}
printk(KERN_ALERT "rice import ko init!!\n");
rice_drv_export("RiceChen");
return 0;
}
static void __exit rice_import_exit(void) {
device_destroy(rice_drv.class, MKDEV(rice_drv.major_number, 0));
class_unregister(rice_drv.class);
class_destroy(rice_drv.class);
unregister_chrdev(rice_drv.major_number, DEVICE_NAME);
printk(KERN_ALERT "rice import ko exit!!\n");
}
module_init(rice_import_init);
module_exit(rice_import_exit);
MODULE_AUTHOR("RieChen");
MODULE_LICENSE("GPL");
编译运行
-
将两个模块编译完,push到板子,先加载导出模块--rice_export.ko,然后再加载调用模块--rice_import.ko
-
运行结果:
![ba8e22e042012cf9854fda9223c0db10.png](https://img-blog.csdnimg.cn/img_convert/ba8e22e042012cf9854fda9223c0db10.png)
关注微信公众号『Rice嵌入式开发技术分享』,后台回复“微信”添加作者微信,备注”入群“,便可邀请进入技术交流群。
![9a56c0a1f152a07db81a86a8ca5f3978.png](https://img-blog.csdnimg.cn/img_convert/9a56c0a1f152a07db81a86a8ca5f3978.png)