周期任务框架在裸机、RTOS上的实现

周期任务框架在裸机、RTOS上的实现

一、任务的类型

运行的程序,有响应指令的触发式程序,也有一直运行的守护程序,周期程序。贴别是在单片机/嵌入式领域,大部分程序都是周期性的执行,进行数据采集,处理,上传等功能,因此我们需要能够适配各种情况的周期任务框架。

二、周期、时钟、定时器

可以先看这篇文章:C/C++语言性能分析方法及性能分析工具的使用

我们一般是通过高中的周期函数来获得对于周期的精确性理解。

下面是有关周期的数学描述:

完成一次振动所需要的时间,称为振动的周期。

若f(x)为周期函数,则把使得f(x+l)=f(x)对定义域中的任何x都成立的最小正数l,称为f(x)的(基本)周期。

在计算机中,完成一个循环所需要的时间;或访问一次存储器所需要的时间,亦称为周期 [4] 。周期函数的实质:两个自变量值整体的差等于周期的倍数时,两个自变量值整体的函数值相等。如:f(x+6) =f(x-2)则函数周期为T=8。

按照我们一般的理解,周期任务是指每个任务的开始执行时刻(或完成该任务的时刻)都相隔一个固定的时间,还是指在一段时间内,该任务必须执行一次。

周期任务的第一种表述更接近数学上的精确描述。

周期任务的第二种表述则更加贴合实际。

在业界,周期任务的表述为:

周期任务是指计算机系统按一定周期到达并请求运行,每次请求称为任务的一个任务实例,任务实例所属任务的起始时刻称为该任务实例的到达时刻,任务实例被置为就绪态的时刻称为该任务实例的释放时刻。

可以看出,这个周期任务的描述更加准确,且考虑到了操作系统对任务的调度。在有操作系统时,任务是不能直接由创建到执行态的,任务是否执行是由操作系统来决定的。我们能控制的,是把该任务置位就绪态,等待操作系统分配CPU资源。

因此,我的周期任务的第二种描述应该是业界周期任务表述的白话版。

实际的周期任务只要能满足在每一段时间内都执行一次就算满足了其周期性。


讲到周期,就必须讲时间,时刻,而这些都需要时间基准和时间度量。

因此我们需要对时钟有一定的了解,可以参考这篇文章:对单片机中时钟的理解


下面我以VxWorks5.5和RTT为例来说明一下定时器。

VxWorks

vxworks中的定时方法:VxWorks几种常用的延时方法

image-20220301222742523

image-20220301222920849

image-20220301222958562

image-20220301223155223

image-20220301223234755

image-20220301223438311

RTT

可以参考官方文档:时钟管理

三、周期任务框架

对以上背景知识了解之后,我们可以构建出怎样的周期任务框架呢?

在裸机上和在RTOS操作系统上有什么不同。

单片机裸机周期任务框架

分享一篇非常非常好的文章,来自无际大佬,单片机怎么做定时器矩阵,彻底解决各种定时问题?

看完这篇文章,我们就对单片机裸机编程中的周期任务框架了然于心了。

RTOS周期任务框架

一般的RTOS都会提供创建任务的接口,但是不一定会提供创建周期任务的接口,因此一般如果要想在RTOS上使用创建周期任务的接口,需要我们使用定时器和创建任务的接口一起来生成一个创建周期任务的接口。当然有的RTOS是提供了创建周期任务的接口,比如接下来我们要介绍的国产开源RTOS——RT-Thread 。

在RT-Thread 官方文档提供的示例代码中:

#include <rtthread.h>

/* 定时器的控制块 */
static struct rt_timer timer1;
static struct rt_timer timer2;
static int cnt = 0;

/* 定时器 1 超时函数 */
static void timeout1(void* parameter)
{
    rt_kprintf("periodic timer is timeout\n");
    /* 运行 10 次 */
    if (cnt++>= 9)
    {
        rt_timer_stop(&timer1);
    }
}

/* 定时器 2 超时函数 */
static void timeout2(void* parameter)
{
    rt_kprintf("one shot timer is timeout\n");
}

int timer_static_sample(void)
{
    /* 初始化定时器 */
    rt_timer_init(&timer1, "timer1",  /* 定时器名字是 timer1 */
                    timeout1, /* 超时时回调的处理函数 */
                    RT_NULL, /* 超时函数的入口参数 */
                    10, /* 定时长度,以 OS Tick 为单位,即 10 个 OS Tick */
                    RT_TIMER_FLAG_PERIODIC); /* 周期性定时器 */
    rt_timer_init(&timer2, "timer2",   /* 定时器名字是 timer2 */
                    timeout2, /* 超时时回调的处理函数 */
                      RT_NULL, /* 超时函数的入口参数 */
                      30, /* 定时长度为 30 个 OS Tick */
                    RT_TIMER_FLAG_ONE_SHOT); /* 单次定时器 */

    /* 启动定时器 */
    rt_timer_start(&timer1);
    rt_timer_start(&timer2);
    return 0;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(timer_static_sample, timer_static sample);

仿真运行结果如下:

\ | /
- RT -     Thread Operating System
 / | \     3.1.0 build Aug 24 2018
 2006 - 2018 Copyright by rt-thread team
msh >timer_static_sample
msh >periodic timer is timeout
periodic timer is timeout
one shot timer is timeout
periodic timer is timeout
periodic timer is timeout
periodic timer is timeout
periodic timer is timeout
periodic timer is timeout
periodic timer is timeout
periodic timer is timeout
periodic timer is timeout复制错误复制成功

周期性定时器 1 的超时函数,每 10 个 OS Tick 运行 1 次,共运行 10 次(10 次后调用 rt_timer_stop 使定时器 1 停止运行);单次定时器 2 的超时函数在第 30 个 OS Tick 时运行一次。

对于一些没有提供创建周期任务接口的RTOS,我们就需要自己写了,但是建议在写之前先参考一下成熟的周期任务接口实现,以防写出来的接口有bug。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
FreeRTOS中的周期任务是指按照一定的时间间隔重复执行的任务周期任务可以通过使用软件定时器来实现。在FreeRTOS中,可以使用xTimerCreate()函数创建一个周期性的软件定时器。周期任务的执行顺序是由任务的优先级决定的。调度器会选择优先级最高的任务投入运行。当一个周期任务到达指定的时间间隔时,它的回调函数会被执行。周期任务可以是一次性的,也可以是自动重载的。一次性周期任务只会执行一次它的回调函数,而自动重载周期任务会按照设定的时间间隔自动重复执行它的回调函数。\[2\]\[3\] #### 引用[.reference_title] - *1* *3* [freeRTOS手册 第五章 . 软件时间任务](https://blog.csdn.net/weixin_45850062/article/details/128878694)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [FreeRTOS --(2)任务管理之入门篇](https://blog.csdn.net/qq_31244951/article/details/123217330)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小熊coder

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值