【09】FreeRTOS的时间片调度

这篇具有很好参考价值的文章主要介绍了【09】FreeRTOS的时间片调度。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.时间片调度简介

  同等优先级任务轮流地享有相同的 CPU 时间(可设置), 叫时间片,在FreeRTOS中,一个时间片就等于SysTick 中断周期。在源码中,SysTick中断服务函数1ms中断一次,一个时间片就是1ms,滴答定时器SysTick的中断周期可以自己设置。
时间片调度运行举例:
freertos时间片调度,FreeRTOS,嵌入式硬件,FreeRTOS,STM32,c#,单片机运行条件:
1、创建三个任务:Task1、Task2、Task3
2、Task1、Task2、Task3的优先级均为1;即3个任务同等优先级
运行过程如下:
1、首先Task1运行完一个时间片后,切换至Task2运行(不管Task1是否运行完成,只运行一个时间片的Task1)
2、Task2运行完一个时间片后,切换至Task3运行
3、Task3运行过程中(还不到一个时间片),Task3阻塞了(系统延时或等待信号量等,下次轮到Task3时还是只允许一个时间片,上次阻塞剩余的时间片,不会再被补回来),此时直接切换到下一个任务Task1
4、Task1运行完一个时间片后,切换至Task2运行

总结:
1、同等优先级任务,轮流执行,时间片流转;
2、一个时间片大小,取决为滴答定时器中断频率;
3、注意没有用完的时间片不会再使用,下次任务Task3得到执行还是按照一个时间片的时钟节拍运行。

2.时间片调度实验

1、实验目的:学会对FreeRTOS 时间片调度使用
2、实验设计:将设计三个任务:start_task、task1、task2,其中task1和task2优先级相同均为2。为了使现象明显,将滴答定时器的中断频率设置为50ms中断一次,即一个时间片50ms
三个任务的功能如下:
start_task:用来创建其他的2个任务
task1:通过串口打印task1的运行次数
task2:通过串口打印task2的运行次数
注意:使用时间片调度需把宏configUSE_TIME_SLICINGconfigUSE_PREEMPTION 置1。
本次实验基于本系列文章中链接:【07】FreeRTOS的列表和列表项工程文件实现。

2.1删除不相关程序

  删除列表和列表项相关程序内容,编译程序无报错

#include "freertos_demo.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "key.h"
#include "delay.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"

/******************************************************************************************************/
/*FreeRTOS配置*/

/* START_TASK 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );

/* TASK1 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );

/* TASK2 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );
/******************************************************************************************************/


/**
 * @brief       FreeRTOS例程入口函数
 * @param       无
 * @retval      无
 */
void freertos_demo(void)
{    
    xTaskCreate((TaskFunction_t         )   start_task,
                (char *                 )   "start_task",
                (configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   START_TASK_PRIO,
                (TaskHandle_t *         )   &start_task_handler );
    vTaskStartScheduler();
}


void start_task( void * pvParameters )
{
		taskENTER_CRITICAL();                              /*进入临界区*/
    xTaskCreate((TaskFunction_t         )   task1,
                (char *                 )   "task1",
                (configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK1_PRIO,
                (TaskHandle_t *         )   &task1_handler );
		xTaskCreate((TaskFunction_t         )   task2,
                (char *                 )   "task2",
                (configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK2_PRIO,
                (TaskHandle_t *         )   &task2_handler );
    vTaskDelete(NULL);
		taskEXIT_CRITICAL();                              /*退出临界区*/
}

/* 任务1,实现LED0每500ms闪烁一次,用来提示系统正在运行 */
void task1( void * pvParameters )
{
    while(1)
    {
			LED0=~LED0;
			vTaskDelay(500);
    }
}
/* 任务2,调用列表和列表项相关API函数,并且通过串口输出相应的信息,进行观察 */
void task2( void * pvParameters )
{
    while(1)
    {
			vTaskDelay(500);
    }
}

2.2使能两个宏

  宏时间片调度configUSE_TIME_SLICING 和宏抢占式调度 configUSE_PREEMPTION在FreeRTOSCofig.h中默认是都为1的,默认支持时间片调度。

#define configUSE_PREEMPTION                            1                       /* 1: 抢占式调度器, 0: 协程式调度器, 无默认需定义 */
#define configUSE_TIME_SLICING                          1                       /* 1: 使能时间片调度, 默认: 1 */

2.3修改滴答定时器中断频率

  在FreeRTOSConfig.h中宏configTICK_RATE_HZ 定义为1000Hz时对应1ms,此时想增大至50ms,时间乘以50倍,对应频率缩小50倍,所以设置宏configTICK_RATE_HZ 为20。

#define configTICK_RATE_HZ                              20                    /* 定义系统时钟节拍频率, 单位: Hz, 无默认需定义 */

2.4完成程序内容

  函数TaskDelay()可以引起任务调度,会将当前正在运行的任务挂载到阻塞列表,和章节1中时间片调度举例类似,如果任务3被阻塞会直接更换运行的任务,去运行Task1,并不能提现到一个时间片为50ms的作用(这里是为了得到Task1一个时间片中的运行次数),所以使用自己写的死延时函数delay_ms()。Task1任务函数中,死延时了10ms,理论上是应该运行Task1任务函数5次,但是函数printf()也会消耗一部分时间,整个运行时间大于10ms,所以运行次数应该是小于5次的(运行4~5次)。最后,将Task1和Task2的任务优先级都设置为2,设置为同等优先级即可。假设在50ms时,Task1运行至函数printf(),此时还没打印完就转向运行Task2,串口打印信息会乱掉,所以需要在printf()函数前后加上开启临界区和关闭临界区,也就是关闭任务调度。由于进入临界区会影响实时性,所以需要在进入和退出临界区之间的代码运行时间尽可能短。

#include "freertos_demo.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "key.h"
#include "delay.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"

/******************************************************************************************************/
/*FreeRTOS配置*/

/* START_TASK 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );

/* TASK1 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );

/* TASK2 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK2_PRIO         2
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );
/******************************************************************************************************/


/**
 * @brief       FreeRTOS例程入口函数
 * @param       无
 * @retval      无
 */
void freertos_demo(void)
{    
    xTaskCreate((TaskFunction_t         )   start_task,
                (char *                 )   "start_task",
                (configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   START_TASK_PRIO,
                (TaskHandle_t *         )   &start_task_handler );
    vTaskStartScheduler();
}


void start_task( void * pvParameters )
{
		taskENTER_CRITICAL();                              /*进入临界区*/
    xTaskCreate((TaskFunction_t         )   task1,
                (char *                 )   "task1",
                (configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK1_PRIO,
                (TaskHandle_t *         )   &task1_handler );
		xTaskCreate((TaskFunction_t         )   task2,
                (char *                 )   "task2",
                (configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK2_PRIO,
                (TaskHandle_t *         )   &task2_handler );
    vTaskDelete(NULL);
		taskEXIT_CRITICAL();                              /*退出临界区*/
}

/* 任务1,实现LED0每500ms闪烁一次,用来提示系统正在运行 */
void task1( void * pvParameters )
{
		uint32_t task1_num=0;
    while(1)
    {
			taskENTER_CRITICAL();                              /*进入临界区*/
			printf("task1运行次数:%d\r\n",++task1_num);
			taskEXIT_CRITICAL();                               /*退出临界区*/
			delay_ms(10);
			
    }
}
/* 任务2,调用列表和列表项相关API函数,并且通过串口输出相应的信息,进行观察 */
void task2( void * pvParameters )
{
		uint32_t task2_num=0;
    while(1)
    {
			taskENTER_CRITICAL();                              /*进入临界区*/
			printf("task2运行次数:%d\r\n",++task2_num);
			taskEXIT_CRITICAL();                               /*退出临界区*/
			delay_ms(10);
    }
}

实验现象:
首先会运行4次Task1,然后运行4次Task2,如此循环。在运行过程中可能会运行5次,是大于1ms但是并没有大多少,执行第5次时可能只执行了一部分,下次继续执行,即可完成运行5次。如果将Task2的任务优先级设置为3,则Task2会一直存在于运行列表,并不会让Task1执行,因为程序中使用的是死延时并不能使Task2挂载到阻塞列表,启动任务调度器。文章来源地址https://www.toymoban.com/news/detail-704238.html

到了这里,关于【09】FreeRTOS的时间片调度的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 嵌入式硬件

    嵌入式硬件是一种在电子设备中集成且运行特定程序的硬件。它通常与特定软件应用紧密相关,用于实现一个以上的特定功能,如压缩解压缩、保安服务等。嵌入式系统通常涉及到至少一个控制器(或微控制器)和其他一些外部芯片,例如存储器、输入/输出(I/O)接口、传感

    2024年02月09日
    浏览(54)
  • 【计算机三级嵌入式】考试自学笔记(三)——嵌入式系统硬件组成、嵌入式处理芯片以及存储器介绍

    常考知识点: 嵌入式最小硬件组成 嵌入式处理芯片 嵌入式系统的存储器 I/O接口及常用I/O设备 ARM内核典型嵌入式处理芯片 嵌入式系统外部通信接口 嵌入式最小硬件系统的组成如下: 嵌入式硬件系统≠嵌入式最小硬件系统 电源电路 :为整个嵌入式系统提供能量 时钟电路 :

    2023年04月12日
    浏览(88)
  • 嵌入式硬件中常见的100种硬件选型方式

    1请列举您知道的电阻、电容、电感品牌(最好包括国内、国外品牌)。 电阻: 美国:AVX、VISHAY 威世 日本:KOA 兴亚、Kyocera 京瓷、muRata 村田、Panasonic 松下、ROHM 罗姆、susumu、TDK 台湾:LIZ 丽智、PHYCOM 飞元、RALEC 旺诠、ROYALOHM 厚生、SUPEROHM 美隆、TA-I 大毅、TMTEC 泰铭、TOKEN德键

    2024年02月06日
    浏览(53)
  • 嵌入式硬件设计与实践(从硬件到产品)

    【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】         很多同学会画电路板,也会写固件代码,但是他们做的这项工作很难称之为产品。这中间的原因是多方面的,第一,这些功能不是根据真实需求开发的;第二,相关功能使用的芯片供

    2023年04月17日
    浏览(40)
  • 嵌入式硬件和软件哪个好?

    嵌入式硬件和软件哪个好? 嵌入式软硬件工程师哪个更有前途呢?一起来看看。 嵌入式是分为软硬件工程师的,首先我们先来看看嵌入式硬件工程师吧! 嵌入式硬件开发工程师主要编写嵌入式系统硬件总体方案和详细方案,要求理解嵌入式系统架构,有一定的C语言基础,熟悉

    2024年02月04日
    浏览(58)
  • 嵌入式硬件电路学习之阻抗

    阻抗(Impedance)是指电路中交流电源施加电压后,电路元件对电流的阻碍程度。它是一个由幅值和相位角组成的复数。 阻抗是交流电路中电阻、电感、电容等元件共同表现出来的电学量,表示为 $Z$。它随输入信号的频率而变化,用复数形式表示。 对于包含电阻 $R$、电感 $

    2024年02月03日
    浏览(50)
  • 嵌入式硬件基础知识——1

    目录 SOC、MCU、MPU、CPU SPI STM32的时钟系统 can是什么 串口和并口 传感器输出引脚高阻抗好还是低阻抗好? iic 运算放大器特点 MOS管和三极管 同步电路和异步电路         SOC 片上系统  手机的核心芯片         MCU 微控系统  单片机         MPU 嵌入式微处理器    

    2024年02月05日
    浏览(50)
  • 嵌入式硬件系统的基本组成

    嵌入式系统的硬件是以包含嵌入式微处理器的SOC为核心,主要由SOC、总线、存储器、输入/输出接口和设备组成。 嵌入式微处理器 每个嵌入式系统至少包含一个嵌入式微处理器 嵌入式微处理器体系结构可采用冯.诺依曼(Von Neumann)结构和哈佛(Harvard)结构 冯.诺依曼结构 冯

    2024年02月15日
    浏览(41)
  • 第三章 嵌入式硬件设计

            本章主要介绍嵌入式硬件设计过程中所设计的基础知识,包括 嵌入式系统电源分类 、 电源管理 和 电子电路设计中的PCB设计 、 电子电路测试基础知识 。         一般来说,嵌入式电源的输入都为 交流市电 ,输出是常见直流12V、5V、3.3V,是一类二次设备。

    2024年02月20日
    浏览(50)
  • 嵌入式硬件需要过哪几关?

    目标是成为一名硬件工程师,用电烙铁和电路板一统江湖,游戏共有九关。 你要有一定的基础,模电,数电这些都得会一些。一般科班出身的专业有电信,通信,自动化等等。 你如果完全没这些基础,连电阻,电容都不认识,那就需要在这关待上很久啦。 模电数电不用太纠

    2024年04月17日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包