前言

  • 很抱歉各位粉丝啊,博主好久没有更新原创文章,从今天起开始恢复写文章的时光。前段时间各种不顺利,到时心情低落。现在恢复状态了。

简介

  • 本文主要来讲讲Linux内核驱动中,EXPORT_SYMBOL()宏定义的用法。

  • 在阅读的Linux内核驱动源码的时候,我们会发现很多的函数带有EXPORT_SYMBOL()宏定义。

  • 从这个宏定义的理解为输出符号。那么他究竟有什么作用。

EXPORT_SYMBOL()宏定义作用

  • EXPORT_SYMBOL宏定义定义的函数或者符号将对内核代码公开,不用修改内核代码就在其他的内核模块中直接调用,即使用EXPORT_SYMBOL可以将一个函数以符号的方式导出给其他模块使用。

使用方法

  1. 在模块函数定义之后使用"EXPORT_SYMBOL(函数名)"来导出。

static int rice_func(void)
{return 0;
}
EXPORT_SYMBOL(rice_func);
  1. 在调用该函数的另外一个模块中使用extern对之声明。

extern int rice_func(void);
  1. 先加载定义该函数的模块,然后再加载调用该函数的模块,先后顺序必须注意。

实验

编写代码

  • 编写两个模块: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

  • 运行结果:

关注微信公众号『Rice嵌入式开发技术分享』,后台回复“微信”添加作者微信,备注”入群“,便可邀请进入技术交流群。

Linux内核驱动开发的EXPORT_SYMBOL相关推荐

  1. 树莓派基于Linux内核驱动开发详解

    一.驱动认知 首先理解Linux内核框图 文件系统认知,Linux内核框图 1.什么是驱动 linux内核驱动.软件层面上的驱动 广义上是指:这一段代码操作了硬件去动,所以这一段代码就叫硬件的驱动程序 ...

  2. 嵌入式 Linux 内核驱动开发【The first day: 36093万字】

    嵌入式 Linux 内核驱动开发[1] 嵌入式 Linux 内核驱动开发前言 第1章 Linux 内核裁剪和定制 [1]Linux 内核开发简介 [2] Linux 源码阅读工具 [1.2.1]Sou ...

  3. Linux内核驱动开发-USB热插拔信息调取

    前言: 前段时间上科大嵌入式安卓开发溜了个作业,开发一个驱动,可以实现读取USB热插拔信息,程序调用显示USB设备名称和插拔时间.代码已经放在了我的Github上,供大家参考. 思路: USB热插拔的 ...

  4. Linux 内核驱动开发基础

    1.裸板驱动和linux驱动的异同点 裸板驱动:uart驱动程序:uart_inituart_putsuart_getsi2c控制器驱动:i2c_starti2c_stopi2c_txi2c_rxg- ...

  5. 树莓派基于Linux内核驱动开发

    一.驱动认知 1.1 为什么要学习写驱动 树莓派开发简单是因为有厂家提供的wiringPi库,实现超声波,实现继电器操作,做灯的点亮-都非常简单. 但未来做开发时,不一定都是用树莓派,则没有wirin ...

  6. 第三阶段:43-47.树莓派基于Linux内核驱动开发

    目录 一.驱动认知 1.1 为什么要学习写驱动 1.2 文件名与设备号 1.3 open函数打通上层到底层硬件的详细过程 二.基于框架编写驱动代码 2.1 编写上层应用代码 2.2 修改内核驱动框架代 ...

  7. Linux内核驱动开发(一)

    Linux内核初探 linux操作系统历史 开发模式 git 分布式管理 git clone 获取 git push 提交 git pull 更新 邮件组 mailing list patch 内核代 ...

  8. linux 内核驱动开发

    一.为什么要学习内核? 有些人要学习内核,而有些人则可以不学习它.你如果以后要从事系统研发或驱动开发的话,就要学习内核. 刚刚接触内核,主要学习内核的接口函数.不要深入的去读内核,因为你读也读不懂,内 ...

  9. linux内核驱动开发 培训,嵌入式Linux驱动开发培训 - 华清远见教育集团官网

    9.LINUX下USB驱动开发基础 9.1 USB规范介绍 9.2 USB主机控制器 9.3 USB HUB 9.4 USB设备状态 9.5 USB描述符 9.6 USB请求 9.7 USB通讯数据格 ...

最新文章

  1. OSI第七层:应用层功能及介绍
  2. 如何在无人机上部署YOLOv4
  3. java长度为100的数组_产生一个int数组,长度为100,并向其中随机插入1-100,不重复...
  4. 告别运营怪圈,不做“背锅侠+加班狗+低薪族”!
  5. 如果java使用什么声明类_如果声明一个类时使用abstract修饰符,则表明该类是()_学小易找答案...
  6. UI Personalization persistent DB database table
  7. intellij 使用_使用IntelliJ书签
  8. 离线安装PostgreSQL
  9. IIS故障问题(Connections_Refused)分析及处理【转】
  10. 【每日算法Day 78】面试经典题:能说出全部四种方法,不录用你都不可能!
  11. Java实现DFA算法对敏感词、广告词过滤功能
  12. Java实现获取汉字的拼音(首拼)
  13. 富勒wms系统里的定时器id_为什么物流行业非常推崇仓库管理系统?
  14. TensorFlow数据读取方式:Dataset用法
  15. RFID固定资产管理系统全生命周期管理办公资产
  16. Python match-search-findall-group(s)的区别
  17. Direct I/O in DOSBOX for COMM serial communications with QBasic, TBasic or Pbasic
  18. 文本摘要相关论文汇总
  19. Arale Base源码分析(含Attribute)
  20. 小组项目的初步构建与需求分析

热门文章

  1. SpringBoot配置全局日期格式转换器
  2. 百色计算机等级考试时间有哪些,2018年3月广西壮族自治区百色计算机等级考试简章...
  3. 全国口译笔译考试CATTI-笔译三级考试大纲
  4. 如何理解vue中 同步异步
  5. 2016-11-11 Redis
  6. 猫眼APP注册界面布局
  7. 吡啶修饰的BODIPY-560/613 氟化硼二吡咯560/613
  8. puppeteer调研--生成页面的屏幕截图和PDF
  9. php培训 pdf,php生成pdf
  10. oracle exfsys 下 rlm$evtcleanup,ORA-27468 EXFSYS.RLM$EVTCLEANUP任务引起的故障