一、系统时钟

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线程调度的驱动力。

最新文章

  1. python中IndentationError: expected an indented block错误的解决方法
  2. 《InsideUE4》-7-GamePlay架构(六)PlayerController和AIController
  3. 用类(function(){})()实现点击显示index索引值的详解
  4. Visual Studio2012打开时弹出“遇到异常:这可能是由某个扩展导致的”错误的解决办法
  5. 用CocoaPods做iOS程序的依赖管理(转摘)
  6. db2常用函数(1)
  7. 如何向AcmeAir注入问题代码
  8. .NET 里操作Excel 出现有些列的数据取不到的问题
  9. 通知栏发送消息Notification(可以使用自定义的布局)
  10. C语言变量声明加冒号的用法
  11. Tuna项目总结
  12. cf455A Boredom
  13. 解開32位元Win 7記憶體4GB限制
  14. Android Studio 安装后首次启动的 Config path ...... is invalid 问题(转)
  15. python文件名和文件路径操作
  16. 面试必问的 volatile,你了解多少?
  17. 微信小程序 sha1 实现密码加密
  18. [3.24校内训练赛by hzwer]
  19. nginx系列 3 nginx.conf介绍(1)
  20. C# Winform 国际化

热门文章

  1. Java设计模式(8)——结构型模式之组合模式(Composite)
  2. 杭州优步uber司机第三组奖励政策
  3. Question | 你所遇到的验证码问题可能都在这里了
  4. 开胃小菜——impress.js代码详解
  5. 「日常训练」ZgukistringZ(Codeforces Round #307 Div. 2 B)
  6. mysql新手入门随笔4
  7. mpvue笔记
  8. cronolog:日志分割工具
  9. 面试应该get这三大技能
  10. mysql下分组取关联表指定提示方法,类似于mssql中的cross apply