浅谈架构方法之时间片轮询

news/2024/10/19 1:25:25/

PS:最近在逛CSDN的时候偶然发现了一篇文章讲到了这个架构,发现之前做过一个项目就用了这个东西,于是我搜了一下,感觉挺多文章都不好理解,由于我也是最近才接触到这个东西,所以我决定自己也写一篇,加深印象。

架构的类型

        首先,在嵌入式中有三种架构,除了我们熟知的裸机系统和操作系统,第三种就是这个时间片轮询。我认为这种架构是介于二者之间的过渡。

        裸机系统能够处理一些相对简单的任务,但是功能单一,只会一直按顺序执行死循环里的任务,CPU只会全力做完一件事才会进行下一项任务,延时的时候也只会等待,浪费资源。

        操作系统的实时性和可靠性高还能同时执行多个任务,但是操作系统较为复杂,需要额外的学习成本,而且其对内存空间的要求需要我们注意内存的大小。

        而时间片轮询不仅能够实现多任务,保证实时性,而且结构简单,占用内存小,在实际开发中也节省时间和精力。

        对于简单且实时性强的简单任务可以使用时间片轮询,但是当任务数较多的时候还是老实用操作系统更好。

代码实现

        这里我只叙述原理,不设定具体的任务,将整个代码拆分来看,防止看的太乱,整体代码放在最后。

        我设置了三个任务,分别是5ms任务、10ms任务和20ms任务。

        在开始之前,我们需要在主函数里进行一个延时。这个延时一般是最大的时间片时间,像这个例子里,我可以延时20ms。

        首先,我们定义一个最大任务数为3的宏:

#define TASKS_MAX   (3)

         接下来定义一个结构体,其内成员含义如下:

                程序运行标志位。

                倒计时时间。

                重装载倒计时。

                任务指针。

        它们的含义会在后面讲。

typedef struct _TASK_COMPONENTS
{uint8_t Run;            uint16_t Timer;            uint16_t ItvTime;              void (*TaskHook)(void);   
} TASK_COMPONENTS; 

        接下来我们创建一个结构体数组用来存放我们定义的结构体成员变量。

        数组中每个元素都对应着我们定义的结构体成员。

/* 任务数组 */
static TASK_COMPONENTS TaskComps[] = 
{{0, 5, 5, task_5ms},            // 5ms任务{0, 10, 10, task_10ms},         // 10ms任务{0, 20, 20, task_20ms},         // 20ms任务
};

        接下来是重点了。

        这个函数需要放到系统定时器中断中执行,同时对所有任务进行计时。

        当有任务的值为0时,将其代入for()循环执行。

        当每个任务的Timer不为0时,进行减减操作,即倒计时。当其减到0的时候,将ItvTime的值赋给Timer,以方便下次计时。同时将程序运行标志位Run置1.

/* 任务启动倒计时 */
void TaskRemarks(void)
{uint8_t i;for (i=0; i<TASKS_MAX; i++)          {if (TaskComps[i].Timer)        {TaskComps[i].Timer--;         if (TaskComps[i].Timer == 0)       {TaskComps[i].Timer = TaskComps[i].ItvTime; TaskComps[i].Run = 1;           }}}
}

        下面这个函数依然是从0开始遍历每个任务,判断它们的Run是否为1,如果是1则执行对应的任务,然后将标志位置0。

void TaskProcess(void)
{uint8_t i;for (i=0; i<TASKS_MAX; i++)           {if (TaskComps[i].Run)           {TaskComps[i].TaskHook();         TaskComps[i].Run = 0;          }}   
}

         至于任务里面实现什么功能,就任由我们按实际需求了。

        当20ms任务执行过一次之后,一个周期就结束了。如果我们把TaskRemarks()放到SysTick的中断服务函数中,那么当这个中断执行的时候,滴答计时器的计数就会重置,同时TaskRemarks()函数也会重新执行,从而达到时间片轮询的效果。

完整代码

#define TASKS_MAX   (3)typedef struct _TASK_COMPONENTS
{uint8_t Run;            uint16_t Timer;            uint16_t ItvTime;              void (*TaskHook)(void);   
} TASK_COMPONENTS; /* 任务数组 */
static TASK_COMPONENTS TaskComps[] = 
{{0, 5, 5, task_5ms},            // 5ms任务{0, 10, 10, task_10ms},         // 10ms任务{0, 20, 20, task_20ms},         // 20ms任务
};/* 任务启动倒计时 */
void TaskRemarks(void)
{uint8_t i;for (i=0; i<TASKS_MAX; i++)          {if (TaskComps[i].Timer)        {TaskComps[i].Timer--;         if (TaskComps[i].Timer == 0)       {TaskComps[i].Timer = TaskComps[i].ItvTime; TaskComps[i].Run = 1;           }}}
}void TaskProcess(void)
{uint8_t i;for (i=0; i<TASKS_MAX; i++)           {if (TaskComps[i].Run)           {TaskComps[i].TaskHook();         TaskComps[i].Run = 0;          }}   
}void task_5ms(void)
{ }
void task_10ms(void)
{ }
void task_20ms(void)
{ }


http://www.ppmy.cn/news/1437722.html

相关文章

HTML--标签

1.加粗标签 <strong>文字内容</strong> 2.分割线 <hr> 3.问题 4.HTML基本骨架 HTML基本骨架是网页模板。 html&#xff1a;整个网页 head&#xff1a;网页头部&#xff0c;存放浏览器看的代码&#xff0c;例如CSS。 body&#xff1a;网页主体&#xf…

设置Ollama在局域网中访问的方法(Ubuntu)

趁着Llama3的热度试了一下Ollama&#xff0c;果然部署推理大模型很有用。一个现实的需求是&#xff0c;如果我们要在局域网中访问Ollama上大模型的服务&#xff0c;应该怎么办呢&#xff1f;参考了一下其他博客的方法 例如&#xff1a;一分钱不花&#xff01;手把手教你部署Go…

自动化测试Selenium(4)

WebDriver相关api 定位一组元素 webdriver可以很方便地使用findElement方法来定位某个特定的对象, 不过有时候我们需要定位一组对象, 这时候就要使用findElements方法. 定位一组对象一般用于一下场景: 批量操作对象, 比如将页面上的checkbox都勾上. 先获取一组对象, 再在这组…

授人以渔 选购篇九:扫地机器人(扫拖机器人)选购要点

文章目录 系列文章自动上下水导航技术&#xff1a;立体激光导航视觉导航&#xff0c;多传感器清洁能力&#xff1a;胶条刷、旋转拖布健康卫生&#xff1a;热水洗拖布、热风烘干智能功能品牌其他 系列文章 授人以渔 选购篇一&#xff1a;信用卡选购要点 授人以渔 选购篇二&…

报错:测试报错postman(测试接口)

报错如下 c.e.exception.GlobalExceptionHandler : 异常信息&#xff1a; Content type multipart/form-data;boundary--------------------------952399813172082093419475;charsetUTF-8 not supported 解决&#xff1a; 异常信息 Content type multipart/form-data;boundary…

Elasticsearch索引别名:管理与优化数据访问

索引别名是Elasticsearch提供的一项强大功能&#xff0c;它允许将一个或多个索引映射到一个易于记忆且可复用的名称&#xff0c;从而简化索引管理、支持数据迁移、优化查询性能以及实现数据过滤与路由。本文将详细阐述索引别名的创建与删除、配合数据过滤与数据路由的应用场景及…

优维应用级数字化架构管理:让企业运维天堑变通途

在优维科技的产品视角中&#xff0c;数字化架构管理就像是一门精妙的艺术&#xff0c;它将上层应用模型的业务概念以可视化的方式呈现出来&#xff0c;使得业务逻辑和流程变得更加直观、清晰。我们将这样的管理方式理解为“给企业搭起一座桥梁”——在这座桥梁的搭建过程中&…

微信小程序连接蓝牙

准备工作&#xff1a; 1&#xff1a;需要一个蓝牙板子和串口软件&#xff08;卖蓝牙板子的商家会提供&#xff09;&#xff0c;手机上需要蓝牙调试助手&#xff08;为了测试蓝牙是否正常连接&#xff09; 2&#xff1a;蓝牙板通过usb插入到电脑端 3&#xff1a;安装好串口调试…