八、(正点原子)Linux内核定时器实验

        定时器是我们最常用到的功能,一般用来完成定时功能,本章我们就来学习一下 Linux 内核提供的定时器 API 函数,通过这些定时器 API 函数我们可以完成很多要求定时的应用。 Linux内核也提供了短延时函数,比如微秒、纳秒、毫秒延时函数,本章我们就来学习一下这些和时间有关的功能。

一、Linux时间管理和内核定时器介绍

        1、内核时间管理

        在FreeRTOS或者UCOS中需要一个硬件定时器提供系统时钟,一般使用Systick作为系统的时钟源。同理, Linux 要运行,也是需要一个系统时钟,Linux内核会选择Cortex-A7内核中的一个通用定时器来作为Linux系统的时钟源,对于Linux驱动编写来说,我们不需要深入研究怎么选择时钟源,怎么配置时钟源,Linux内核编写者已经编写好了,我们只需要会使用相应的API函数即可。

        Linux 内核中有大量的函数需要时间管理,比如周期性的调度程序、延时程序、对于我们驱动编写者来说最常用的定时器。硬件定时器提供时钟源,时钟源的频率可以设置, 设置好以后就周期性的产生定时中断,系统使用定时中断来计时。中断周期性产生的频率就是系统频率,也叫做节拍率(tick rate)(有的资料也叫系统频率),比如 1000Hz, 100Hz 等等说的就是系统节拍率。系统节拍率是可以设置的,单位是 Hz,我们在编译 Linux 内核的时候可以通过图形化界面设置系统节拍率,按照如下路径打开配置界面:

> Kernel Features
        -> Timer frequency (<choice> [=y])

         Linux 内核会使用 CONFIG_HZ 来设置自己的系统时钟。打开文件 include/asm-generic/param.h,有如下内容:

        HZ:表示1s时间内进入中断的次数,也叫做节拍数。通常说为节拍率。

        选择高节拍率和低节拍率的优缺点 :

        ①、高节拍率会提高系统时间精度,如果采用 100Hz 的节拍率,时间精度就是 10ms,采用
1000Hz 的话时间精度就是 1ms,精度提高了 10 倍。高精度时钟的好处有很多,对于那些对时间要求严格的函数来说,能够以更高的精度运行,时间测量也更加准确。

        ②、高节拍率会导致中断的产生更加频繁,频繁的中断会加剧系统的负担, 1000Hz 和100Hz的系统节拍率相比,系统要花费 10 倍的“精力”去处理中断。中断服务函数占用处理器的时间增加,但是现在的处理器性能都很强大,所以采用 1000Hz 的系统节拍率并不会增加太大的负载压力。根据自己的实际情况,选择合适的系统节拍率,我们全部采用默认的 100Hz 系统节拍率。
        Linux内核使用全局变量jiffies来记录系统从启动以来的系统节拍数,系统启动会将jiffies初始化为0,当然jiffies很重要,这也是我们设置定时器定时时间就是使用jiffies来完成的。jiffies 定义在文件 include/linux/jiffies.h 中,定义如下:

        jiffies_64jiffies是同一个东西, jiffies_64用于64位系统,jiffies用于32位系统,为了兼容不同的硬件,其实jiffies就是jiffies_64的低32位。

        前面说了 HZ 表示每秒的节拍数, jiffies 表示系统运行的节拍数,所以 jiffies/HZ 就是系统运行时间,单位为秒。不管是 32 位还是 64 位的 jiffies,都有溢出的风险,溢出以后会重新从 0 开始计数,相当于绕回来了,因此有些资料也将这个现象也叫做绕回。假如 HZ 为最大值 1000 的时候, 32 位的 jiffies 只需要 49.7 天就发生了绕回,对于 64 位的 jiffies 来说大概需要5.8 亿年才能绕回,因此 jiffies_64 的绕回忽略不计。处理 32 位 jiffies 的绕回显得尤为重要,Linux 内核提供了几个 API 函数来处理绕回,如下如:

函数 描述(unkown为jiffies,known通常是对比的值)
time_after(unkown, known)  unkown 超过 known 的话, time_after 函数返回真,否则返回假。
time_before(unkown, known) 如果 unkown 没有超过 known 的话 time_before 函数返回真,否则返回假
time_after_eq(unkown, known) time_af
<think>好的,用户想要查找与正点原子相关的示例代码或教程。首先,我需要回忆一下用户提供的引用内容。引用1提到了正点原子Linux教程,分为裸机代码、嵌入式Linux移植(包括u-boot、Linux内核、根文件系统)和驱动开发。引用2是关于LCD显示的示例代码,引用3是输入捕获的程序解读,引用4是USMART调试工具的使用。这些引用都涉及到不同的开发模块和示例代码。 用户可能是在学习STM32或者嵌入式Linux,需要具体的示例来参考。我应该根据这些引用内容,整理出正点原子常见的示例代码和教程资源。比如,他们的开发板通常配套有丰富的实验例程,比如GPIO控制、定时器、USART通信、LCD显示、文件系统等。此外,他们的教程可能分为初级、中级和高级,涵盖从基础到应用的不同层面。 接下来需要考虑用户可能的实际需求。他们可能正在寻找如何快速上手正点原子开发板,或者需要某个特定功能的代码示例,比如输入捕获或USMART调试。我应该提供获取这些资源的途径,比如官方资料、在线平台和社区论坛,并举例说明常见的实验内容,这样用户可以根据自己的开发板型号和需求找到对应的资料。 还要注意用户提到的demo或示例代码可能分布在不同的地方,比如资料光盘、官方网站、GitHub等。需要建议用户检查购买开发板时附带的资料,或者访问正点原子的官网下载。另外,社区和论坛如电子工程世界、优快云可能有用户分享的代码和教程,这也是一个资源来源。 最后,生成的相关问题需要围绕用户可能遇到的下一步问题,比如如何移植u-boot、优化LCD显示、调试输入捕获问题,或者使用USMART工具,这些都能帮助用户进一步深入学习和解决问题。</think>根据正点原子官方资料和技术文档,其示例代码主要分布在以下几个方向: ### 一、STM32基础功能示例 1. **GPIO控制** 包含LED流水灯、按键检测、外部中断等基础外设控制代码,通常以`HAL库`和`标准库`双版本提供[^1][^3]。 2. **定时器应用** 如输入捕获实现红外遥控解码(引用[3]中的捕获状态寄存器设计)、PWM电机控制等: ```c // 输入捕获状态寄存器定义(TIM5CH1_CAPTURE_STA) #define CAPTURE_FLAG_DONE 0x80 // 完成捕获标志位 #define CAPTURE_FLAG_HIGH 0x40 // 高电平捕获标志 ``` 3. **通信协议** 包含USART、I2C、SPI等协议实现,如引用[4]中的USMART串口调试工具: ```c usmart_dev.init(72); // 初始化USMART组件(F1系列主频72MHz) ``` ### 二、嵌入式Linux示例 1. **u-boot移植** 提供NAND Flash启动配置、设备树修改模板[^1]。 2. **驱动开发** 涵盖字符设备驱动、GPIO子系统、中断处理等,配套`insmod`/`rmmod`测试脚本。 3. **根文件系统** 使用Buildroot/Yocto构建的定制化文件系统镜像。 ### 三、典型应用场景代码 1. **LCD显示** 引用[2]中的`LCD_ShowChar`函数实现字符渲染,支持多种字号和抗锯齿效果: ```c void LCD_ShowChar(uint16_t x, uint16_t y, char chr, uint8_t size); ``` 2. **文件系统** FATFS移植案例,支持SD卡文件读写操作。 3. **物联网协议** 包含MQTT、CoAP等协议在STM32+ESP8266硬件组合上的实现。 ### 四、获取途径 1. **官方资料** - 开发板配套资料光盘中的`实验例程`目录 - 正点原子在线文档平台(需注册账号) 2. **开源平台** - GitHub搜索`正点原子开源仓库`(注意区分官方和非官方版本) - Gitee镜像仓库(国内访问更稳定) 3. **社区资源** - 电子工程世界论坛的正点原子专区 - 优快云博客#正点原子教程#标签
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tofu_Cabbage

你的打赏是我的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值