Linux内核定时器-模块导出符号表

Linux内核定时器

  • 定时器的当前时间如何获取?

jiffies:内核时钟节拍数

jiffies是在板子上电这一刻开始计数,只要

板子不断电,这个值一直在增加(64位)。在

驱动代码中直接使用即可。

  • 定时器加1代表走了多长时间?

在内核顶层目录下有.config

CONFIG_HZ=1000

周期 = 1/CONFIG_HZ

周期是1ms;

  • 分配的对象

struct timer_list mytimer;

  • 对象的初始化

定时器结构体

struct timer_list 
{
			unsigned long expires;   //定时的时间
			void (*function)(unsigned long); //定时器的处理函数
			unsigned long data;      //向定时器处理函数中填写的值
};

定时器初始化

void timer_function(unsigned long data) //定时器的处理函数
{
			
}
init_timer(&mytimer);  //内核帮你填充你未填充的对象	
mytimer.expries = jiffies + 1000;  //1s
mytimer.function = timer_function;
mytimer.data = 0;

对象的添加定时器

void add_timer(struct timer_list *timer);
		//同一个定时器只能被添加一次,
		//在你添加定时器的时候定时器就启动了,只会执行一次

		int mod_timer(struct timer_list *timer, unsigned long expires)
		//再次启动定时器                          jiffies+1000
对象的删除

int del_timer(struct timer_list *timer)
//删除定时器

 Int gpio_get_value(int gpiono);//通过gpiono获取当权gpio的所处状态

  返回0,低电平   非0:高电平

#include<linux/init.h>
#include<linux/module.h>
#include<linux/printk.h>
#include<linux/timer.h>
#include<linux/gpio.h>
#include<linux/interrupt.h>

#define GPIONO(m,n) (m*32+n)
#define GPIO_B8 GPIONO(1,8)
#define GPIO_B16 GPIONO(1,16)

int gpiono[]={GPIO_B8,GPIO_B16};
char *name[]={"interrupt_b8","interrupt_b16"};

int i;

struct timer_list mytimer;

//中断处理函数
irqreturn_t irq_handler(int irq,void *arg)
{
    //启动定时器
    mod_timer(&mytimer,jiffies+100);
    return IRQ_HANDLED;
}
//定时处理函数
void timer_handler(unsigned long data)
{
    //检测引脚状态,如果是低电平,说明产生了中断
    if(gpio_get_value(GPIO_B8)==0)
    {
        printk(KERN_ALERT"+++++++++++++++++++++++++++++++++++\n");//设置为大于终端打印权限,不然只能在demsg中查看
    }
    if(gpio_get_value(GPIO_B16)==0)
    {
        printk(KERN_ALERT"-----------------------------------\n");//设置为大于终端打印权限,不然只能在demsg中查看
    }
}
static int __init timer_init(void)
{
    //初始化定时器
    init_timer(&mytimer);//内核自动初始化定时器
    mytimer.expires= jiffies+100;//定时时长
    mytimer.function=timer_handler;
    mytimer.data=0;
    //添加定时器
    add_timer(&mytimer);
    //注册中断
    for(i=0;i<sizeof(gpiono)/sizeof(int);i++)
    {
        if(request_irq(gpio_to_irq(gpiono[i]),irq_handler,IRQF_TRIGGER_FALLING,name[i],NULL)!=0)
        {
            printk("%s request_ire err.\n",name[i]);
            return -EBUSY;
        }
    }
    return 0;
}
static void __exit timer_exit(void)
{
    //注销中断
    for(i=0;i<sizeof(gpiono)/sizeof(int);i++)
    {
        free_irq(gpio_to_irq(gpiono[i]),NULL);
    }
}
module_init(timer_init);
module_exit(timer_exit);
MODULE_LICENSE("GPL");

模块导出符号表

思考1应用层两个app程序,app1中拥有一个add函数,app1运行时app2是否可以调用app1中的add函数? 不行,因为应用层app运行的空间是私有的(0-3G)没有共享。

思考2两个驱动模块,module1中的函数,module2是否可以调用?可以,他们公用(3-4G)内核空间,只是需要找到函数的地址就可以。好处:减少代码冗余性,代码不会再内存上被重复加载。代码更精简,一些代码可以不用写,直接调用别人写好的函数就可以。

编写驱动代码找到其他驱动中的函数,需要用模块导出符号表将函数导出,被人才可以使用这个函数。他是一个宏函数

在驱动的一个模块中,想使用另外一个模块中的函数/变量,只需要使用EXPORT_SYMBOL_GPL将变量或者函数的地址给导出。使用者就可以用这个地址来调用它了。

EXPORT_SYMBOL_GPL(sym)

sym:变量名或函数名

代码举例1:两个独立的代码驱动模块

代码举例2:提供者为内核已经安装使用的驱动

总结

编译:

1.先编译提供者,编译完成之后会产生一个Module.symvers

2.将Module.symvers拷贝到调用者的目录下

3.编译调用者即可

安装:

先安装提供者

再安装调用者

卸载:

先卸载调用者

再卸载提供者

如果调用者和提供者时两个独立(xx.ko)驱动模块,他们间传递地址的时候,是通过Module.symvers传递的。

如果提供者是内核的模块(uImage),此时调用者和提供者间就不需要Module.symvers文件传递信息

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/274833.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一.windows2012搭建fpt服务器和常见端口介绍

一.windows2012搭建fpt服务器和常见端口介绍 1.打开防火墙2.创建组2.1打开计算机管理2.2创建组并且设置名称和描述 3.创建用户3.1设置用户密码和名称3.2把用户归属于组3.3把user删除掉3.4点击添加然后点高级3.5点击立即查找选择之前设定的组 4.安装ftp服务器4.1点击添加角色和功…

重生奇迹mu中玩家之间的交易操作

重生奇迹mu游戏中的直接交易 在重生奇迹mu中的交易总共有四种方式。第一种就是玩家之间直接进行交易&#xff0c;具体操作就是点击你所要交易的玩家&#xff0c;这个点击的意思是指你把鼠标移动到这名玩家的角色身上&#xff0c;然后你就锁定了此玩家&#xff0c;同时游戏界面…

每日一题 2735. 收集巧克力(中等)

暴力枚举&#xff0c;真难甭 class Solution:def minCost(self, nums: List[int], x: int) -> int:n len(nums)f nums[:]ans sum(f)for k in range(1, n):for i in range(n):f[i] min(f[i], nums[(i k) % n])ans min(ans, k * x sum(f))return ans

深入探索MongoDB集群模式:从高可用复制集

MongoDB复制集概述 MongoDB复制集主要用于实现服务的高可用性&#xff0c;与Redis中的哨兵模式相似。它的核心作用是数据的备份和故障转移。 复制集的主要功能 数据复制&#xff1a;数据写入主节点&#xff08;Primary&#xff09;时&#xff0c;自动复制到一个或多个副本节…

【头歌实训】Spark 完全分布式的安装和部署(新)

文章目录 第1关&#xff1a; Standalone 分布式集群搭建任务描述相关知识课程视频Spark分布式安装模式主机映射免密登录准备Spark安装包配置环境变量修改 spark-env.sh 配置文件修改 slaves 文件分发安装包启动spark验证安装 编程要求测试说明答案代码 第1关&#xff1a; Stand…

Google Chrome 现在会在后台扫描泄露的密码

谷歌表示&#xff0c;Chrome 安全检查功能将在后台运行&#xff0c;检查网络浏览器中保存的密码是否已被泄露。 如果桌面用户正在使用标记为危险的扩展程序&#xff08;从 Chrome Web Store 中删除&#xff09;、最新的 Chrome 版本&#xff0c;或者如果启用安全浏览来阻止 Go…

uniapp Vue3 日历 可签到 跳转

上干货 <template><view class"zong"><view><view class"top"><!-- 上个月 --><view class"sgy" click"sgy">◀</view><view class"nianyue">{{ year }}年{{ month 1 }}…

uniapp Vue3 面包屑导航 带动态样式

上干货 <template><view class"bei"><view class"container"><view class"indicator"></view><!-- 遍历路由列表 --><view v-for"(item, index) in routes" :key"index" :class&quo…

数据结构入门到入土——List的介绍

目录 一&#xff0c;什么是List&#xff1f; 二&#xff0c;常见接口介绍 三&#xff0c;List的使用 一&#xff0c;什么是List&#xff1f; 在集合框架中&#xff0c;List是一个接口&#xff0c;继承自Collection。 Collection也是一个接口&#xff0c;该接口中规范了后序容…

鸿蒙Harmony(八)ArkUI--状态管理器之@State

状态管理 在声明式UI中&#xff0c;是以状态驱动视图更新 状态&#xff1a;指驱动视图更新的数据&#xff08;被装饰器标记的变量&#xff09; StateProp 和 LinkProvide和 Consume State State装饰器标记的变量必须初始化&#xff0c;不能为空值State支持Object 、class、…

音视频学习(二十二)——rtmp发流(tcp方式)

前言 本文主要介绍自研的RtmpStreamSender.dll&#xff0c;rtmp库提供接口接收裸流数据&#xff0c;支持将裸流数据封装为flv格式并通过rtmp协议发流。 关于rtmp协议基础介绍可查看&#xff1a;https://blog.csdn.net/www_dong/article/details/131026072 关于rtmp收流介绍可…

java设计模式学习之【状态模式】

文章目录 引言状态模式简介定义与用途实现方式 使用场景优势与劣势在Spring框架中的应用状态示例代码地址 引言 设想你正在使用一个在线视频播放器观看电影。随着你的互动&#xff0c;播放器可能处于不同的状态&#xff1a;播放、暂停、缓冲或结束。每个状态下&#xff0c;播放…

工具系列:TimeGPT_(6)同时预测多个时间序列

TimeGPT提供了一个强大的多系列预测解决方案&#xff0c;它涉及同时分析多个数据系列&#xff0c;而不是单个系列。该工具可以使用广泛的系列进行微调&#xff0c;使您能够根据自己的特定需求或任务来定制模型。 # Import the colab_badge module from the nixtlats.utils pac…

HTML+CSS制作动漫绿巨人

🎀效果展示 🎀代码展示 <!DOCTYPE html> <html lang="en" > <head>

115基于matlab的用于铣削动力学建模的稳定性叶瓣图分析(stablity lobe)

基于matlab的用于铣削动力学建模的稳定性叶瓣图分析(stablity lobe)&#xff0c;程序已调通&#xff0c;可直接运行。 115matlab铣削动力学 (xiaohongshu.com)

ajax请求——XMLHttpRequest请求

个人练习笔记-----Ajax01 一、GET <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</t…

【Pytorch】学习记录分享9——PyTorch新闻数据集文本分类任务实战

【Pytorch】学习记录分享9——PyTorch新闻数据集文本分类任务 1. 认为主流程code2. NLP 对话和预测基本均属于分类任务详细见3. Tensorborad 1. 认为主流程code import time import torch import numpy as np from train_eval import train, init_network from importlib impo…

在 Android 手机上从SD 卡恢复数据的 6 个有效应用程序

如果您有 Android 设备&#xff0c;您可能会将个人和专业的重要文件保存在设备的 SD 卡上。这些文件包括照片、视频、文档和各种其他类型的文件。您绝对不想丢失这些文件&#xff0c;但当您的 SD 卡损坏时&#xff0c;数据丢失是不可避免的。 幸运的是&#xff0c;您不需要这样…

Redis的缓存过期淘汰策略

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理、分布式技术原理、数据库技术&#x1f525;如果感觉博主的文章还不错的…