RT-Thread 入门学习笔记 - 熟悉软件定时器的使用

前言

  • 通过RT-Thread内核定时器的熟悉,并根据自己的使用,发现,软件定时器的使用需要关心某些事项
  • 软件定时器分为静态初始化与动态创建两种
  • 软件定时器可以创建很多,分为一次性的,周期性的。
  • 两个软件定时器,超时时间可以一样,同时超时,依次执行超时回调,注意超时回调中,不要过多的处理
  • 一些动态申请内存的操作,可以放在软件定时器线程去处理,需要配置开启软件定时器线程
  • 软件定时器分为系统定时器与软件定时器线程的定时器,分为两个独立的定时器链表管理,定时器超时回调函数执行的环境不一样。
  • 可以让定时器在运行的中途停下来(rt_timer_stop),并修改参数,可以调用:rt_timer_control实现如修改超时时间等操作

 

定时器操作

静态初始化定时器

rt_timer_init

  • 主要需要首先定义一个定时器对象(非定时器指针),如struct rt_timer timer;
  • 静态定义的定时器,不需要判断是否为RT_NULL,因为全局静态的变量,内存是确定的。
  • 静态的定时器,不需要了,可以调用:rt_timer_detach,detach后,静态的定时器对象,不会释放,可以再次初始化使用。

动态创建定时器

rt_timer_create

  • 动态创建的定时器,返回为定时器对象的指针,需要判断是否为RT_NULL
  • 删除动态创建的定时器,使用:rt_timer_delete,定时器对象的内存释放

 

使用经验

  • 定时器对象,如:rt_timer_delete后,对象指针还存在(野指针),所以,可以在删除后,手动把定时器对象改为RT_NULL,确保不【重复删除】
  • 定时器启动后,如再次启动,会返回失败。所以,最好管理一个是否启动的标志位,保证不【重复启动】。
  • 如果没有开启软件定时器线程,初始化/创建定时器时,使用RT_TIMER_FLAG_SOFT_TIMER,无效果,依旧是定时器中断环境执行

2021-03-16_084432.png

  • 每个线程创建后,都有一个线程定时器,这个线程定时器,挂在系统定时器链表上,是通过rt_timer_init初始化。
  • 可以使用list_timer,查看系统的定时器。

 

问题与分析

  • 【问题】既然有两个定时器链表,但获取下一个定时器超时的函数,rt_timer_next_timeout_tick,获取的是 系统定时器链表的超时。如果开启了软件定时器线程,定义了RT_TIMER_FLAG_SOFT_TIMER,这个超时是否准确?

【答】:经过验证与内核源码的分析:准确。需要理解(1)每个线程都有一个静态的定时器,是挂在系统定时器链表上的。(2)软件定时器线程,并不是一直在跑,计算好下一个超时后,就会suspend(此时开启了一个定时器)。

  • 【问题】动态申请的线程,定时器的内存空间是动态申请的,为何使用:rt_timer_init

【答】:因为整片内存虽然是动态申请的,但定时器对象是一个静态的对象。所以需要使用:rt_timer_init,线程删除时,使用:rt_timer_detach。因为整个动态申请的线程结构体一起free释放,所以,不用担心内存泄漏问题。

 

总结

  • 使用定时器,可以参考API或官方的定时器文档
  • 使用过程中主要的事项,可以多总结,对照源码调试,思路会更清晰。

猜你喜欢

转载自blog.csdn.net/tcjy1000/article/details/114901076
今日推荐