FreeRTOS深入教程(空闲任务和Tick中断深入分析)

简介: FreeRTOS深入教程(空闲任务和Tick中断深入分析)

前言

本篇文章主要带大家深入分析空闲任务和Tick中断的作用。

一、空闲任务源码分析

在启动调度器时会创建出空闲任务:

/* 启动调度器 */
vTaskStartScheduler();

在空闲任务中会调用到prvCheckTasksWaitingTermination();函数。

该函数会检查正在等待终止的任务列表,这是一组任务,它们已经执行完毕,但它们的资源(如堆栈空间和其他数据结构)还没有被完全释放。这个函数负责清理这些已经终止的任务的资源,以便可以重新使用这些资源。

当配置了configUSE_PREEMPTION可抢占时和configIDLE_SHOULD_YIELD时,空闲任务会调用taskYIELD()函数主动释放CPU资源,让其他任务运行。

当配置了configUSE_IDLE_HOOK为1时,可以使用空闲任务的钩子函数:vApplicationIdleHook()。

二、Tick中断深入分析

systick中断分析:

xPortSysTickHandler函数SysTick定时器中断处理程序的一部分,它主要负责处理RTOS的时基计数、任务切换请求以及中断优先级的管理,以确保系统的稳定运行和任务切换的执行。这是实现实时任务调度的关键组成部分。

xTaskIncrementTick函数分析

用于检查调度器是否被挂起。如果调度器没有被挂起,才执行后续的操作。

if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )

这里增加系统的时基计数器 xTickCount,并将结果保存在 xConstTickCount 中,表示增加了一个时基节拍。

将 xConstTickCount 的值更新到系统的时基计数器 xTickCount 中。

const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1;
        /* Increment the RTOS tick, switching the delayed and overflowed
         * delayed lists if it wraps to 0. */
        xTickCount = xConstTickCount;

这是一个条件语句,检查是否发生了时基计数器的溢出。如果 xConstTickCount 的值变为 0,表示发生了溢出。

如果发生了溢出,调用 taskSWITCH_DELAYED_LISTS 函数,用于处理延时任务列表的切换。

if( xConstTickCount == ( TickType_t ) 0U ) /*lint !e774 'if' does not always evaluate to false as it is looking for an overflow. */
        {
            taskSWITCH_DELAYED_LISTS();
        }

检查一个时钟计数变量 xConstTickCount 是否大于等于 xNextTaskUnblockTime。如果条件成立,意味着现在是可以解除任务阻塞的时刻。

if( xConstTickCount >= xNextTaskUnblockTime )

判断阻塞链表是否为空,如果为空那么就没有需要解除阻塞的任务,这时会将xNextTaskUnblockTime 设置为一个无限大的值,这样的话就不需要再次进行判断是否需要接触阻塞了。

if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )
                {
                    /* The delayed list is empty.  Set xNextTaskUnblockTime
                     * to the maximum possible value so it is extremely
                     * unlikely that the
                     * if( xTickCount >= xNextTaskUnblockTime ) test will pass
                     * next time through. */
                    xNextTaskUnblockTime = portMAX_DELAY; /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
                    break;
                }

如果需要接触阻塞的话,需要先获取延时任务列表中头部任务的控制块指针 pxTCB。

然后获取这个任务当中的xStateListItem 链表项的值,该值表示任务应该在何时解除阻塞。

pxTCB = listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too.  Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */
                    xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ) );

如果当前值小于阻塞链表中第一个任务的值,那么更新xNextTaskUnblockTime,并且退出,此时不需要解除阻塞状态。

if( xConstTickCount < xItemValue )
                    {
                        /* It is not time to unblock this item yet, but the
                         * item value is the time at which the task at the head
                         * of the blocked list must be removed from the Blocked
                         * state -  so record the item value in
                         * xNextTaskUnblockTime. */
                        xNextTaskUnblockTime = xItemValue;
                        break; /*lint !e9011 Code structure here is deedmed easier to understand with multiple breaks. */
                    }

xTaskIncrementTick 函数的主要功能是增加系统的时基计数,处理时基计数的溢出,以及检查是否有任务的阻塞时间已到期,如果有,则标记需要进行任务切换。这是实现 FreeRTOS 的任务调度和超时管理的关键部分。

总结

本篇文章主要为大家讲解了空闲任务和Tick中断深入分析,大家可以尝试自己分析一遍FreeRTOS相关的源码。


相关文章
|
1月前
【FreeRTOS】中断管理(三)
【FreeRTOS】中断管理
|
1月前
【FreeRTOS】中断管理(二)
【FreeRTOS】中断管理
|
1月前
|
API C语言
【FreeRTOS】中断管理(一)
【FreeRTOS】中断管理
|
2月前
|
API
FreeRTOS软件定时器的原理以及使用实例
FreeRTOS软件定时器的原理以及使用实例
27 0
|
5月前
|
API 调度
FreeRTOS深入教程(中断管理)
FreeRTOS深入教程(中断管理)
111 0
|
5月前
|
算法 调度
FreeRTOS入门教程(任务优先级,Tick)
FreeRTOS入门教程(任务优先级,Tick)
137 0
|
监控
驱动开发:内核监控进程与线程回调
在前面的文章中`LyShark`一直在重复的实现对系统底层模块的枚举,今天我们将展开一个新的话题,内核监控,我们以`监控进程线程`创建为例,在`Win10`系统中监控进程与线程可以使用微软提供给我们的两个新函数来实现,此类函数的原理是创建一个回调事件,当有进程或线程被创建或者注销时,系统会通过回调机制将该进程相关信息优先返回给我们自己的函数待处理结束后再转向系统层。
332 0
驱动开发:内核监控进程与线程回调
|
消息中间件 API 调度
FreeRTOS记录(八、用软件定时器?还是硬件定时器?)
FreeRTOS软件定时器,相对前面的内容来说,软件定时器还是比较简单的,我们简单测试一下
333 0
FreeRTOS记录(八、用软件定时器?还是硬件定时器?)