一、系统时钟

rt-thread的系统时钟模块采用全局变量rt_tick作为系统时钟节拍,该变量在系统时钟中断函数中不断加1。而系统时钟中断源和中断间隔一般由MCU硬件定时器(如stm32的嘀嗒定时器)决定,rt_tick初始值为0,每次MCU产生硬件定时中断后,在中断函数中不断加1,即rt_tick变量值与MCU硬件定时器定时中断间隔的乘积为系统真正运行时间(例如rt_tick=10,stm32嘀嗒定时器每隔1ms产生中断,则系统上电运行时间为10ms)。

在bsp/stm32f40x/drivers/board.c中设置MCU硬件定时器定时间隔,以及执行相应定时器中断函数:

void  SysTick_Configuration(void)
{
RCC_ClocksTypeDef rcc_clocks;
rt_uint32_t cnts; RCC_GetClocksFreq(&rcc_clocks);//获得系统的晶振频率

//RT_TICK_PER_SECOND在rtconfig.h中配置,表示每秒包含的系统时钟节拍数。默认配置为100,则嘀嗒定时器中断间隔为10ms,rt_tick每隔10ms加1,即默认情况下1s内包含100个系统时钟节拍,每个时钟节拍tick表示10ms。为了提高 精度,一般修改宏定义为1000,即1s内包含1000个系统时钟节拍(此时嘀嗒定时器中断间隔为1ms,每个时钟节拍tick则表示1ms)。
cnts = (rt_uint32_t)rcc_clocks.HCLK_Frequency / RT_TICK_PER_SECOND;
cnts = cnts / ;
    SysTick_Config(cnts);                                //配置系统tick,函数在core_cm4.h中实现,使能嘀嗒定时器中断、定时器时钟源频率HCLK=168MHZ、启动嘀嗒定时器
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//配置定时器时钟源,函数在misc.c中实现,将定时器时源钟频率设置为HCLK/8=21MHZ
} void SysTick_Handler(void)
{
/* enter interrupt */
rt_interrupt_enter();//表示进入中断,在src/irp.c中定义,中断嵌套计数器rt_interrupt_nest加1 rt_tick_increase(); //rt_tick加1,并检查当前运行线程的剩余时间片是否耗尽,若耗尽则让出处理器并重新调度线程,接着执行硬件定时器中断模式下的定时器超时检查rt_timer_check(); /* leave interrupt */
rt_interrupt_leave();//表示进入中断,在src/irp.c中定义,中断嵌套计数器rt_interrupt_nest减1
}

二、硬件定时器中断模式下线程调度驱动

在src/clock.c中:

void rt_tick_increase(void)
{
struct rt_thread *thread; /* increase the global tick */
++ rt_tick; //全局变量系统时钟节拍数加1 /* check time slice */
thread = rt_thread_self(); //获取当前运行的线程 -- thread->remaining_tick; //当前运行线程的剩余时间片减1
if (thread->remaining_tick == )//如果当前运行线程无剩余时间
{
/* change to initialized tick */
thread->remaining_tick = thread->init_tick;//重新将线程的剩余时间片设置为初始化时间片 /* yield */
rt_thread_yield();//将此线程从调度器就绪队列中取出来放到同优先级线程链表末尾,然后再次调度
} /* check timer */
rt_timer_check();//检查定时器链表上是否有时间到达的时钟,即包括自定义的定时器,也包括线程睡眠时启动的线程定时器
}

由上述代码可见,一旦系统产生时钟中断,在嘀嗒定时器中断函数中,系统首先将检查当前正在运行的线程剩余时间片是否耗尽,如果耗尽则将其从调度器就绪队列中取出放到同优先级线程链表末尾,然后再重新调度线程;接着检查是否有休眠的线程时间到达(即线程睡眠时启动的线程定时器是否超时),如果有则触发相应的线程定时器超时函数rt_thread_timeout(将当前挂起的线程加入到调度器就绪队列后重新调度),从而将线程从睡眠中唤醒。

总而言之,在硬件定时器中断模式下,系统时钟中断(MCU硬件定时器中断或嘀嗒定时器中断)是rt-thread线程调度的驱动力。

三、软件定时器线程模式下线程调度驱动

若在rtconfig.h中定义了宏RT_USING_TIMER_SOFT,则使用软件定时器线程模式,此模式下系统中存在定时器线程timer_thread(在rt_system_timer_thread_init中初始化)。在此线程入口函数中通过rt_tick的增加不停地检查定时器链表中是否有定时器超时,其中也包含线程睡眠时启动的线程定时器,一旦线程对应的定时器超时,则触发相应的线程定时器超时函数rt_thread_timeout(将当前挂起的线程加入到调度器就绪队列后重新调度),从而将线程从睡眠中唤醒。

由此可见,在软件定时器线程模式下,rt_system_timer_thread_init中初始化的定时器线程timer_thread就是rt-thread线程调度的驱动力。

RT-thread内核之系统时钟的更多相关文章

  1. 38.Linux驱动调试-根据系统时钟定位出错位置

    当内核或驱动出现僵死bug,导致系统无法正常运行,怎么找到是哪个函数的位置导致的? 答,通过内核的系统时钟,因为它是由定时器中断产生的,每隔一定时间便会触发一次,所以当CPU一直在某个进程中时,我们便 ...

  2. Zephyr学习(四)系统时钟

    每一个支持多进程(线程)的系统都会有一个滴答时钟(系统时钟),这个时钟就好比系统的“心脏”,线程的休眠(延时)和时间片轮转调度都需要用到它. Cortex-M系列的内核都有一个systick时钟,这个 ...

  3. STM32学习笔记(六) SysTick系统时钟滴答实验(stm32中断入门)

    系统时钟滴答实验很不难,我就在面简单说下,但其中涉及到了STM32最复杂也是以后用途最广的外设-NVIC,如果说RCC是实时性所必须考虑的部分,那么NVIC就是stm32功能性实现的基础,NVIC的难 ...

  4. STM32学习笔记:系统时钟和SysTick定时器

    原文:http://blog.sina.com.cn/s/blog_49cb42490100s60d.html 1.     STM32的时钟系统 在STM32中,一共有5个时钟源,分别是HSI.HS ...

  5. STM32F4_RCC系统时钟配置及描述

    Ⅰ.概述 对于系统时钟应该都知道它的作用,就是驱动整个芯片工作的心脏,如果没有了它,就等于人没有了心跳. 对于使用开发板学习的朋友来说,RCC系统时钟这一块知识估计没怎么去配置过,原因在于开发板提供的 ...

  6. LPC17XX 数据手册摘要之系统时钟与功率控制

    系统时钟与功率控制 一.系统时钟 LPC17XX有三个独立的时钟振荡器,分别是主振荡器(MIAN_OSC).内部RC振荡器(IRC_OSC).实时时钟振荡器(RTC_OSC).LPC17XX时钟框图如 ...

  7. 实时时钟、系统时钟和CPU时钟的区别

    http://blog.sina.com.cn/s/blog_68f909c30100pli7.html 实时时钟:RTC时钟,用于提供年.月.日.时.分.秒和星期等的实时时间信息,由后备电池供电,当 ...

  8. stm32之Systick(系统时钟)

    Systick的两大作用: 1.可以产生精确延时: 2.可以提供给操作系统一个单独的心跳(时钟)节拍: 通常实现Delay(N)函数的方法为: for(i=0;i<x;i++) ; 对于STM3 ...

  9. μC/OS-II 的系统时钟

    简介 μC/OS-II 与大多数计算机系统一样,用硬件定时器产生一个周期为 ms 级的周期性中断来实现系统时钟,最小的时钟单位就是两次中断之间相间隔的时间,这个最小时钟单位叫做时钟节拍(Time Ti ...

随机推荐

  1. JavaWeb——升级赛-学生成绩管理系统(1)jsp---19.01.03

    add.jsp <%@ page language="java" contentType="text/html; charset=UTF-8"    pa ...

  2. 青岛Uber优步司机奖励政策(8/10-8/16)

    亲爱的Uber青岛优步的大司机朋友们,又到了每周发布奖励细则的时刻啦!下一周的奖励与上周有所不同,请一定要仔细按照自己的情况阅读!另外,之前参与过投票并表示想加入新小时保底政策的老司机朋友们从本周起, ...

  3. 弹性分布式数据集RDD概述

      [Spark]弹性分布式数据集RDD概述 弹性分布数据集RDD RDD(Resilient Distributed Dataset)是Spark的最基本抽象,是对分布式内存的抽象使用,实现了以操作 ...

  4. Arduino-元件简介

    DS18B20温度传感器 DS18B20是DALLAS公司生产的一种常用的温度传感器,其具有体积小巧.硬件功耗低.抗干扰能力强.精准度高的特点.该传感器具有单总线通讯的能力,电压范围为3.0V~5.5 ...

  5. 「日常训练」Queue(Codeforces Round 303 Div.2 D)

    简单到让人不敢相信是D题,但是还是疏忽了一点. 题意与分析 (Codeforces 545D) 题意:n人排队,当一个人排队的时间超过他需要服务的时间就会厌烦,现在要求一个最优排列使得厌烦的人最少. ...

  6. linux部署MantisBT(二)部署php

    二.部署php 1.下载php安装包 http://php.net/downloads.php 2.安装php yum install libxml2 yum install libxml2-deve ...

  7. flume-kafka-storm-hdfs-hadoop-hbase

    # bigdata-demo 项目地址: https://github.com/windwant/bigdata-demo.git hadoop: hadoop hdfs操作 log输出到flume ...

  8. AVL树和伸展树 -数据结构(C语言实现)

    读数据结构与算法分析 AVL树 带有平衡条件的二叉树,通常要求每颗树的左右子树深度差<=1 可以将破坏平衡的插入操作分为四种,最后通过旋转恢复平衡 破坏平衡的插入方式 描述 恢复平衡旋转方式 L ...

  9. 用 splice 函数分别实现 push、pop、shift、unshift 的方法

    主要需要注意的是不同方法他们本身返回的值应该是什么,是数组当前的长度,还是取出的元素的值,再在splice函数里面进行相应的return就可以了.具体如下: 用 splice函数实现 push方法 f ...

  10. Visual Stdio Code编辑Mark Down

    Visual Studio Code可以一边写Markdown一边预览了,而且不需要任何插件. 方法如下: 新建一个文件,以 .md 为后缀: Visual Studio Code 原生就支持高亮Ma ...