FreeRTOS 简单内核实现8 时间片轮询


0、思考与回答

0.1、思考一

为什么要增加时间片轮询?

目前的 RTOS 内核已经支持抢占优先级,即高优先级的任务会抢占低优先级的任务得到执行,但是对于同等优先级的任务,如果不支持时间片轮询,则只能有一个任务运行,并且由于优先级相同所以除延时阻塞到期外也不会发生任务调度,因此需要增加时间片轮询保证同等优先级的任务能得到轮流执行

1、内核程序修改

1.1、xTaskIncrementTick( )

在该函数中除了任务延时阻塞时间到期产生任务调度外,增加支持时间片轮询的任务切换,具体如下所示

/*task.c*/
BaseType_t xTaskIncrementTick(void)
{
	// 省略未修改的程序
	......
#if((configUSE_PREEMPTION == 1) && (configUSE_TIME_SLICING == 1))
	// 支持时间片轮询
	if(listCURRENT_LIST_LENGTH(&(pxReadyTasksLists[pxCurrentTCB->uxPriority])) > 1)
	{
		xSwitchRequired = pdTRUE;
	}
#endif
	return xSwitchRequired;
}
/* FreeRTOSConfig.h */
// 支持时间片轮询
#define configUSE_TIME_SLICING                  1

1.2、原理

假设当前系统中只存在两个优先级相同的任务,时间片轮询任务切换流程如下

xTaskIncrementTick()
-> vTaskSwitchContext()
-> taskSELECT_HIGHEST_PRIORITY_TASK()
-> listGET_OWNER_OF_NEXT_ENTRY()

当进入滴答定时器中断服务函数时,如果发现就绪链表数组中的某个链表中链表项的数量大于 1 ,则表示该优先级下有不止一个任务,此时就可以产生任务调度

当有任务调度产生的时候,会调用 vTaskSwitchContext()taskSELECT_HIGHEST_PRIORITY_TASK() 两个函数寻找当前的最高优先级任务,但是系统中只有两个优先级相同的任务,因此最高优先级仍然没变,但是在这个优先级下返回的任务却变成了下一个

为什么呢?

关键在于 listGET_OWNER_OF_NEXT_ENTRY() 函数,这个宏函数每次调用会获取链表中下一个链表项的 pvOwner 参数,由于是双向链表,因此会不断的循环链表中的链表项(两个同等优先级的任务),每次发生任务调度就会切换一次任务,所以就实现了时间片轮询

3、实验

3.1、测试

参考 FreeRTOS 简单内核实现6 优先级 “3.1、测试” 小节内容,将两个任务的优先级修改为一样,然后在两个任务中均使用软件延时模拟任务连续运行,具体程序如下所示

/* main.c */
/* USER CODE BEGIN Includes */
#include "FreeRTOS.h"
/* USER CODE END Includes */

/* USER CODE BEGIN PV */
// 软件延时
void delay(uint32_t count)
{
	for(;count!=0;count--);
}

TaskHandle_t Task1_Handle;
#define TASK1_STACK_SIZE                    128
StackType_t Task1Stack[TASK1_STACK_SIZE];
TCB_t Task1TCB;
UBaseType_t Task1Priority = 2;

TaskHandle_t Task2_Handle;
#define TASK2_STACK_SIZE                    128
StackType_t Task2Stack[TASK2_STACK_SIZE];
TCB_t Task2TCB;
UBaseType_t Task2Priority = 2;

// 任务 1 入口函数
void Task1_Entry(void *parg)
{
	for(;;)
	{
		HAL_GPIO_TogglePin(GREEN_LED_GPIO_Port, GREEN_LED_Pin);
		delay(10000000);
	}
}
// 任务 2 入口函数
void Task2_Entry(void *parg)
{
	for(;;)
	{
		HAL_GPIO_TogglePin(ORANGE_LED_GPIO_Port, ORANGE_LED_Pin);
		delay(10000000);
	}
}
/* USER CODE END PV */

/* USER CODE BEGIN 2 */
// 创建任务 1 和 2
Task1_Handle = xTaskCreateStatic((TaskFunction_t)Task1_Entry,
								 (char *)"Task1",
								 (uint32_t)TASK1_STACK_SIZE,
								 (void *)NULL,
								 (UBaseType_t)Task1Priority,
								 (StackType_t *)Task1Stack,
								 (TCB_t *)&Task1TCB);
														
Task2_Handle = xTaskCreateStatic((TaskFunction_t)Task2_Entry,
								 (char *)"Task2",
								 (uint32_t)TASK2_STACK_SIZE,
								 (void *) NULL,
								 (UBaseType_t)Task2Priority,
								 (StackType_t *)Task2Stack,
								 (TCB_t *)&Task2TCB );
// 启动任务调度器,永不返回
vTaskStartScheduler();
/* USER CODE END 2 */

configUSE_TIME_SLICING 调整为 0 ,然后烧录程序,仍然使用逻辑分析仪捕获两个 LED 的引脚电平,结果如下图所示

![[Kernel_8.1.png]]

可以发现在不启用时间片轮询时,由于两个任务优先级一致,并且两个任务模拟连续运行,因此只有任务 Task2 被运行 (为什么是 Task2 ?)

configUSE_TIME_SLICING 调整为 1,然后烧录程序,仍然使用逻辑分析仪捕获两个 LED 的引脚电平,结果如下图所示

![[Kernel_8.2.png]]

可以发现,对于优先级相同且连续运行的任务几乎是在同时运行,其实是因为每个时间片(滴答定时器间隔)都发生了一次任务调度

3.2、待改进

当前 RTOS 简单内核已实现的功能有

  1. 静态方式创建任务
  2. 手动切换任务
  3. 临界段保护
  4. 任务阻塞延时
  5. 支持任务优先级
  6. 阻塞链表
  7. 时间片轮询

后续 RTOS 简单内核可以增加

  1. 任务间通信机制
    1. 信号量
    2. 互斥锁
    3. 消息队列
  2. 其他功能
    1. 软件定时器
  • 29
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FreeRTOS(Real-time Operating System)是一个开源的实时操作系统内核,适用于嵌入式系统的开发。它提供了基础的多任务调度、定时器、事件控制等功能,使得开发者能够轻松地开发和管理嵌入式设备。本文主要介绍了FreeRTOS内核实现和应用开发实战指南。 首先,文章讲解了FreeRTOS内核实现FreeRTOS内核是一个精简的、高效的实时操作系统,其核心思想是基于优先级的协作式多任务调度。文章详细介绍了FreeRTOS的任务管理、调度器、中断处理以及同步机制等内核组件的实现原理。通过深入理解这些内核组件的实现细节,开发者可以更好地理解FreeRTOS内核的工作原理,并进行定制化的开发。 其次,文章提供了FreeRTOS的应用开发实战指南。通过一个简单的示例,详细演示了如何使用FreeRTOS进行应用开发。文章从创建任务、任务同步、任务间通信等方面进行了讲解,并给出了具体的代码示例。开发者可以根据这个实战指南,快速上手使用FreeRTOS进行应用开发,并在嵌入式系统中实现复杂的功能。 此外,文章还介绍了FreeRTOS的一些应用案例。通过这些案例,开发者可以了解如何将FreeRTOS应用于不同领域的嵌入式系统中。例如,文章介绍了使用FreeRTOS开发物联网设备、嵌入式系统监控等应用案例,展示了FreeRTOS在实际项目中的应用场景和优势。 总的来说,这篇文章通过介绍FreeRTOS内核实现和提供应用开发实战指南,帮助开发者更好地理解和使用FreeRTOS,从而在嵌入式系统开发中实现高效、稳定的应用程序。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值