【linux-imx6ull-定时器与中断】

目录

  • 1. 前言
  • 2. Linux软件定时器
    • 2.1 内核频率选择
    • 2.2 重要的API函数
    • 2.3 Linux软件定时器的使用配置流程
  • 4. Linux中断
    • 4.1 简单中断使用
      • 4.1.1 简要说明
      • 4.1.2 重要的API函数
      • 4.1.3 中断的简要配置流程
    • 4.2. 中断的上半部和下半部
      • 4.2.1 tasklet实现下半部
      • 4.2.2 work实现下半部

1. 前言

   关于定时器和中断是我们老生常谈的外设,也是每一款单片机基本必备的基础外设,由于之前都是在裸机层面对单片机的定时器和中断进行,我之前也对IMX6ULL的裸机中断系统进行了简要的介绍,连接如下:linux-IMX6ULL中断配置流程,同样我也对IMX6ULL中的定时器进行了简要的分析和介绍,连接如下:linux-IMX6ULL-定时器-GPT-串口配置流程-思路,但是这次进行定时器的操作是在系统层面进行配置,和之前的思路不太一样,我们之前使用的PIT等硬件定时器,但是我在内核中使用的是软件定时器,这种定时器的基准是由硬件产生并通过底层层层上报给内核,我们可以通过内核图形化配置选择这个最终的定时器频率是多少,而且注意的是内核提供的定时器是没有自动重装的模式,我们每次打开一个定时器后,这个定时器结束后就没了,如果要周期性的触发类似中断的效果,就要不断的在定时器服务函数结束的末尾重新启动定时器,并给写入定时周期;

2. Linux软件定时器

2.1 内核频率选择

   我们可以在内核的图形化配置中选择定时器的基准频率,如下:

  我们也称为节拍率,这里我们选择100hz,当然这种选择是根据每个人的实际情况和硬件的性能进行选择的,如果选择1000hz,那么对于硬件来说进入定时器服务函数的频率就会更加频繁,处理负担也是近10倍的增加;
  Linux 内核使用全局变量 jiffies 来记录系统从启动以来的系统节拍数,系统启动的时候会将 jiffies 初始化为 0,jiffies 定义在文件 include/linux/jiffies.h 中,并且对于64位的jiffies而言我们不用考虑绕回的问题,但是对于32位的 jiffies我们就要考虑绕回的问题;

2.2 重要的API函数

  • 时间转换类
  1. int jiffies_to_msecs(const unsigned long j)
  2. int jiffies_to_usecs(const unsigned long j)
  3. u64 jiffies_to_nsecs(const unsigned long j)
  4. long msecs_to_jiffies(const unsigned int m)
  5. long usecs_to_jiffies(const unsigned int u)
  6. unsigned long nsecs_to_jiffies(u64 n)
  • 定时器初始化类
  1. void init_timer(struct timer_list *timer)
  2. void add_timer(struct timer_list *timer)
  3. int del_timer(struct timer_list * timer)
  4. int del_timer_sync(struct timer_list *timer)
  5. int mod_timer(struct timer_list *timer, unsigned long expires):重新激活定时器
  • 内核短延时类
  1. void ndelay(unsigned long nsecs)
  2. void udelay(unsigned long usecs)
  3. void mdelay(unsigned long mseces)

2.3 Linux软件定时器的使用配置流程

  定时器也相当于一个外设,我们是在驱动层面对定时器进行配置,因此我们的基础框架还是字符设备的那一套,总的来说就是在字符设备的基础上添加上我们的定时器配置,例如我们要控制LED定时的开启和关闭,那么对于我们而言我们只需在LED字符设备的基础上添加我们的定时器配置,一般定时器的配置流程如下:



  我们在文件操作函数中可以使用long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);对定时器的相关操作进行写入,当然用write应该也是可以实现这个功能的,不过这里有注意事项,用unlocked_ioctl这个函数进行写入定时器的功能时要进行宏定义:如下图所示:



4. Linux中断

4.1 简单中断使用

4.1.1 简要说明

  在裸机中对于中断是频繁使用的,在裸机中对中断的配置流程也是相对比较繁琐,例如要比如配置寄存器,使能 IRQ,注册中断服务函数 等等,详情可以参考我前言中的IMX6ULL的中断系统的介绍,这里我们已经用上了Linux操作系统,对于中断的使用就变得比较简单,Linux内核已经提供了比较完善的中断框架,我们只需要申请中断然后再注册中段服务函数即可,不需要一系列复杂的寄存器配置;这里就不进行一些理论的详细说明,我们已经再裸机中对中断的配置进行了底层的操控,对于Linux系统而言,就是通过一系列复杂的方式把底层这些内容给整合成了一个个框架,我们这里学习的就是linux中断配置框架;作为初学者过于深入的了解可能会适得其反;

4.1.2 重要的API函数

  获取中断号

  1. static inline int gpio_to_irq(申请的GPIO号):GPIO中断专用
  2. static inline unsigned int irq_of_parse_and_map(设备节点地址,int index):通用

  中断服务函数

  1. static irqreturn_t 中断函数名(int irq, void *dev_id)

  中断申请和释放

  1. request_irq(中断号, 中断函数名,中断触发方式,中断名字,向中断服务函数传入的结构体地址);
  2. free_irq(中断号,向中断服务函数传入的结构体地址);

4.1.3 中断的简要配置流程

  这里的中断简要配置思路就是:获取中断号->申请中断->编写中断服务函数,可以看到还是非常简单的,这里的字符驱动框架是正点原子的key按键驱动框架,加上中断的内容配置如下图:

   

4.2. 中断的上半部和下半部

  对于Linux系统而言,我们要求中断是快进快出,对于一些对时间要求比较严格和处理耗时短暂的程序我们可以放在中断函数中直接进行处理,这个过程称为中断的上半部,因此对于一些耗时的处理内容,我们如果把其直接放在中断函数中去处理,就与前面的中断快进快出的理念相违背,因此我们把这部分内容放到中断外面,中断里面只是起到通知的作用,这样我们就实现了中断的快进快出以及耗时处理内容也放在了中断外面进行处理,这个过程我们称为中断的下半部
  但是对于下半部我们想法很好,但是咋样实现这个通知的过程呢?如果想详细了解可以产靠内核源码,内核大神们以及把这一切都封装成立API,一般有三种方式,软中断、tasklet、工作队列等;

4.2.1 tasklet实现下半部

  主要就是在前面简单中断的基础上进行如下流程:

   
  每个步骤比较重要的API:

  1. 初始化tasklet:tasklet_init(&dev->irqkey[i].tasklet,调度的函数名,(unsigned long)dev);
  2. 中断服务函数中调度通知tasklet:tasklet_schedule(&dev->irqkey[0].tasklet);
  3. 调度的函数:static void 调度的函数名(unsigned long data)

4.2.2 work实现下半部

  使用work来实现下半部和tasklet是类似的,就是换个函数名,操作步骤都是一样的如下:

   

  1. 初始化work:INIT_WORK(&dev->irqkey[i].work,调度的函数名);
  2. 中断服务函数中调度通知work:schedule_work(&dev->irqkey[0].work);
  3. 调度的函数:static void 调度的函数名(unsigned long data)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pytorch 使用GPU加速常见的问题

pytorch如何使用gpu加速 print(torch.cuda.is_available()) # 设置gpu设备 device torch.device(cuda:0 if torch.cuda.is_available() else cpu) # net使用GPU net.to(device)# 数据copy到gpu inputData inputData.to(device)# 开始执行 ... net(inputData) ...两种方式&am…

MySQL数据操作与查询- 聚合函数和分组查询

一、聚合函数 聚合函数主要用来进行数据 汇总 。 1、sum 返回选取的某列的总和。 语法: select sum(字段名) from 表名 where 条件表达式 2、max 返回选取的某列的最大值。 语法: select max(字段名) from 表名 where 条件表达式 3、min 返…

【网络安全的神秘世界】AppScan安装及使用指南

🌝博客主页:泥菩萨 💖专栏:Linux探索之旅 | 网络安全的神秘世界 | 专接本 https://www.hcl-software.com/appscan AppScan是一种综合型漏洞扫描工具,采用SaaS解决方案,它将所以测试功能整合到一个服务中&a…

样式的双向绑定的2种方式,实现样式交互效果

与样式标签实现双向绑定 通过布尔值来决定样式是出现还是消失 show代表着布尔值,show的初始值是false所以文本不会有高亮的效果,当用户点击了按钮,就会调用shows这个函数,并将show的相反值true赋值并覆盖给show,此时show的值为tru…

【秋招突围】2024届秋招笔试-小红书笔试题-第二套-三语言题解(Java/Cpp/Python)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系计划跟新各公司春秋招的笔试题 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 📧 清隆这边…

TalkingData数据统计,如何统计?

Ai文章推荐 1 作为程序员,开发用过最好用的AI工具有哪些? 2 Github Copilot正版的激活成功,终于可以chat了 3 idea,pycharm等的ai assistant已成功激活 4 新手如何拿捏 Github Copilot AI助手,帮助你提高写代码效率 5 Jetbrains的…

Java 中的重写(Override)与重载(Overload)

在Java编程语言中,“重写”(Override)和“重载”(Overload)是两个重要且常见的概念,它们虽然名字相近,但在功能、使用场景和实现方式上有着显著的区别。重写(Override)指…

诊断解决方案——CANdesc和MICROSAR

文章目录 一、CANdesc二、MICROSAR一、CANdesc canbeded是Vector汽车电子开发软件Nun Autosar标准的工具链之一。 canbeded是以源代码的形式提供的可重用的组件,包括CAN Driver,交互层(IL),网络管理(NM),传输层(TP),诊断层(CANdesc) , 通信测量和标定协议(CCP,XCP) 和 通信控…

TS中null和undefined特殊性

NUll&undefined null 与 undefined 也是变量类型,用于定义值为 null 或 undefined undefined 类型只包含一个值undefined,表示未定义(即还未给出定义,以后可能会有定义)。// undefined let Sakun09: undefined un…

嵌入式开发工具代码

文章目录 将字符串中的小写字母转换为大写循环队列(Circular Buffer)断言(Assertion)位域反转(Bit Reversal)固定点数运算(Fixed-Point Arithmetic)字节序转换(Endiannes…

Rust创建基准测试bench

打开终端(或命令提示符)。 导航到父目录。 将 Rust 编译器切换到 nightly 版本: rustup default nightly 在该目录下运行 cargo init 命令来创建一个新的 Rust 项目,这将在当前目录下创建 Cargo.toml 和 src 目录: …

1430. 迷宫出口

一天Extense在森林里探险的时候不小心走入了一个迷宫,迷宫可以看成是由 ��nn 的格点组成,每个格点只有 22 种状态, 00 和 11,前者表示可以通行后者表示不能通行。 同时当Extense处在某个格点时,他只能移动到东南西北(或者说上下左右)四个方向之一的相邻格点上,Extense…

404 页面代码

<template> <div class"container"><h1>404</h1> <div ><p class"text-center">当前页面无法访问,可能没有权限或已删除</p><p class"text-center"> 去别处看看吧</p> </div> <…

Internet Download Manager(IDM6.41)软件安装包下载及安装教程

Internet Download Manager有一个智能下载逻辑加速器&#xff0c;具有智能动态文件分割和安全的多部分下载技术&#xff0c;可以加速下载。与其他下载加速器和管理器不同&#xff0c;Internet下载管理器在下载开始之前对文件进行分段&#xff0c;而Internet下载管理器在下载过程…

Web前端引用图:深度解析与实践指南

Web前端引用图&#xff1a;深度解析与实践指南 在Web前端开发中&#xff0c;引用图&#xff08;Dependency Graph&#xff09;是一个至关重要的概念&#xff0c;它有助于我们更好地理解和管理项目的依赖关系。www.rmrbggkd.com本文将从四个方面、五个方面、六个方面和七个方面…

[Linux] TCP协议介绍(2): TCP协议的“三次握手“过程分析、超时重传机制介绍...

上一篇文章中, 已经介绍了TCP协议的数据格式, 简单分析了其与UDP协议 关于可靠性方面的差异 本篇文章, 介绍分析一下 使用TCP协议通信, 非常重要的一个过程: 三次握手 TCP的"三次握手" TCP协议是有连接的传输层协议, 即使用TCP协议通信, 是需要建立连接的 TCP协议…

一千题,No.0070(组合数的和)

给定 N 个非 0 的个位数字&#xff0c;用其中任意 2 个数字都可以组合成 1 个 2 位的数字。要求所有可能组合出来的 2 位数字的和。例如给定 2、5、8&#xff0c;则可以组合出&#xff1a;25、28、52、58、82、85&#xff0c;它们的和为330。 输入格式&#xff1a; 输入在一行…

【Android面试八股文】HandlerThread是什么?有什么使用场景?

文章目录 一、HandlerThread是什么?1.1 HandlerThread 简介1.2 HandlerThread 源码分析1. 构造函数2. run 方法3. 获取 Looper4. 退出 Looper5. 总结二、HandlerThread有什么使用场景示例代码一、HandlerThread是什么? 1.1 HandlerThread 简介 HandlerThread 是 Android 提…

编程基础知识编程实例解析:深度探索与实战应用

编程基础知识编程实例解析&#xff1a;深度探索与实战应用 编程&#xff0c;作为现代信息社会的核心技能之一&#xff0c;对于理解和应用计算机技术具有至关重要的意义。然而&#xff0c;编程的深奥和复杂常常让人望而生畏。本文将从四个方面、五个方面、六个方面和七个方面对…

JVM-基础知识

JVM-基础知识 什么是JVM JVM是一种跨语言的平台&#xff0c;任何语言只要能编译成.class文件都可以被JVM运行。JVM只和.class文件有关系&#xff0c;和Java语言没关系。JVM是一种虚拟机规范。 java文件是如何交给JVM执行的 JVM的常见实现 HostStop:Oracle官方另外还有IBM的J9、…