FreeRTOS 原理 --- 临界区(critical section)

关调度器

void vTaskSuspendAll( void )
{
    /* A critical section is not required as the variable is of type
    BaseType_t.  Please read Richard Barry's reply in the following link to a
    post in the FreeRTOS support forum before reporting this as a bug! -
    http://goo.gl/wu4acr */
    ++uxSchedulerSuspended;
}

通过一个变量表示是否关调度器,大于0表示关调度器,等于0表示没有关调度器。

关调度器后,不允许主动或被动线程切换(因为关调度器和开调度器是成对出现,如果 delay 主动让出CPU,其他线程没有开调度器操作,delay 时间到也回不去,因为 tick 中断也 bypass 了,无法检查时间到从而切换线程),切换前都会检查是否关了调度器,关状态还主动切换会断言。

如下 delay 主动切换线程

    void vTaskDelay( const TickType_t xTicksToDelay )
    {
    BaseType_t xAlreadyYielded = pdFALSE;

        /* A delay time of zero just forces a reschedule. */
        if( xTicksToDelay > ( TickType_t ) 0U )
        {
            configASSERT( uxSchedulerSuspended == 0 );

如下 tick 中断被动切换线程,如果关调度器,直接 bypass 

复制代码
BaseType_t xTaskIncrementTick( void )
{
TCB_t * pxTCB;
TickType_t xItemValue;
BaseType_t xSwitchRequired = pdFALSE;

    /* Called by the portable layer each time a tick interrupt occurs.
    Increments the tick then checks to see if the new tick value will cause any
    tasks to be unblocked. */
    traceTASK_INCREMENT_TICK( xTickCount );
    if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
    {
        /* Minor optimisation.  The tick count cannot change in this
        block. */
        const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1;
复制代码

 关中断

如果线程和中断都会修改共同的数据,就需要通过关中断来实现临界区

 

posted @   流水灯  阅读(200)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
历史上的今天:
2017-10-19 matlab --- 无约束遗传算法
2017-10-19 matlab --- 矩阵的操作
2016-10-19 Altium Designer 15 --- 元器件编号及命名
点击右上角即可分享
微信分享提示