Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【FreeRTOS】事件标志组

【FreeRTOS】事件标志组

作者头像
心跳包
发布于 2020-08-31 06:36:24
发布于 2020-08-31 06:36:24
1.7K00
代码可运行
举报
运行总次数:0
代码可运行

为什么要使用事件标志

事件标志组是实现多任务同步的有效机制之一。也许有不理解的初学者会问采用事件标志组多麻烦, 搞个全局变量不是更简单?其实不然,在裸机编程时,使用全局变量的确比较方便,但是在加上 RTOS 后 就是另一种情况了。 使用全局变量相比事件标志组主要有如下三个问题:

  1. 使用事件标志组可以让 RTOS 内核有效地管理任务,而全局变量是无法做到的,任务的超时等机制需要用户自己去实现。
  2. 使用了全局变量就要防止多任务的访问冲突,而使用事件标志组则处理好了这个问题,用户无需担心。
  3. 使用事件标志组可以有效地解决中断服务程序和任务之间的同步问题。

FreeRTOS 任务间事件标志组的实现

任务间事件标志组的实现是指各个任务之间使用事件标志组实现任务的通信或者同步机制。 下面我们来说说 FreeRTOS 中事件标志的实现,根据用户在 FreeRTOSConfig.h 文件中的配置: #define configUSE_16_BIT_TICKS 1 配置宏定义 configUSE_16_BIT_TICKS 为 1 时,每创建一个事件标志组,用户可以使用的事件标志是8 个。 #define configUSE_16_BIT_TICKS 0 配置宏定义 configUSE_16_BIT_TICKS 为 0 时,每创建一个事件标志组,用户可以使用的事件标志是24 个。

FreeRTOS 中断方式事件标志组的实现

FreeRTOS 中断方式事件标志组的实现是指中断函数和 FreeRTOS 任务之间使用事件标志。 下面我们通过如下的框图来说明一下 FreeRTOS 事件标志的实现,让大家有一个形象的认识。

任务 Task1 运行过程中调用函数 xEventGroupWaitBits,等待事件标志位被设置,任务 Task1 由运行态进入到阻塞态。 Task1 阻塞的情况下,串口接收到数据进入到了串口中断服务程序,在串口中断服务程序中设置 Task1等待的事件标志,任务 Task1 由阻塞态进入到就绪态,在调度器的作用下由就绪态又进入到运行态。 上面就是一个简单的 FreeRTOS 中断方式事件标志通信过程。 实际应用中,中断方式的消息机制要注意以下四个问题:

中断函数的执行时间越短越好,防止其它低于这个中断优先级的异常不能得到及时响应。 实际应用中,建议不要在中断中实现消息处理,用户可以在中断服务程序里面发送消息通知任务,在任务中实现消息处理,这样可以有效地保证中断服务程序的实时响应。同时此任务也需要设置为高优先级,以便退出中断函数后任务可以得到及时执行。 中断服务程序中一定要调用专用于中断的事件标志设置函数,即以 FromISR 结尾的函数。 在操作系统中实现中断服务程序与裸机编程的区别。 如果 FreeRTOS 工程的中断函数中没有调用 FreeRTOS 的事件标志组 API 函数,与裸机编程是一样的。 如果 FreeRTOS 工程的中断函数中调用了 FreeRTOS 的事件标志组的 API 函数,退出的时候要检测是否有高优先级任务就绪,如果有就绪的,需要在退出中断后进行任务切换,这点跟裸机编程稍有区别

事件标志组 API 函数

使用如下 11 个函数可以实现 FreeRTOS 的事件标志组: xEventGroupCreate() xEventGroupCreateStatic() vEventGroupDelete() xEventGroupWaitBits() xEventGroupSetBits() xEventGroupSetBitsFromISR() xEventGroupClearBits() xEventGroupClearBitsFromISR() xEventGroupGetBits() xEventGroupGetBitsFromISR() 这里我们重点的说以下 4 个函数: xEventGroupCreate() xEventGroupWaitBits() xEventGroupSetBits() xEventGroupSetBitsFromISR()

函数 xEventGroupCreate 函数原型: EventGroupHandle_t xEventGroupCreate( void ); 函数描述: 函数 xEventGroupCreate 用于创建事件标志组。 返回值,如果创建成功, 此函数返回事件标志组的句柄,如果 FreeRTOSConfig.h 文件中定义的 heap 空间不足会返回 NULL #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 30 * 1024 ) )

函数 xEventGroupSetBits 函数原型: EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, /* 事件标志组句柄 */ const EventBits_t uxBitsToSet ); /* 事件标志位设置 */ 函数描述: 函数 xEventGroupSetBits 用于设置指定的事件标志位为 1。 第 1 个参数是事件标志组句柄。 第 2 个参数表示 24 个可设置的事件标志位,EventBits_t 是定义的 32 位变量,低 24 位用于事件标志设置。变量 uxBitsToSet 的低 24 位的某个位设置为 1,那么被设置的事件标志组的相应位就设置为 1。 变量 uxBitsToSet 设置为 0 的位对事件标志相应位没有影响。比如设置变量 uxBitsToSet = 0x0003 就表示将事件标志的位 0 和位 1 设置为 1,其余位没有变化。

返回当前的事件标志组数值。

使用这个函数要注意以下问题: 1. 使用前一定要保证事件标志组已经通过函数 xEventGroupCreate 创建了。 2. 此函数是用于任务代码中调用的,故不可以在中断服务程序中调用此函数,中断服务程序中使用xEventGroupSetBitsFromISR 3. 用户通过参数 uxBitsToSet 设置的标志位并不一定会保留到此函数的返回值中,下面举两种情况:

a. 如果设置一个位导致等待该位的任务离开阻塞(注意是离开阻塞态,即使没有进入运行态,只要离开阻塞态即可)状态,则该位可能会被自动清除(请参阅xEventGroupWaitBits()的xClearBitOnExit参数)。 b. 调用此函数的任务是一个低优先级任务,通过此函数设置了事件标志后,让一个等待此事件标志 的高优先级任务就绪了,会立即切换到高优先级任务去执行,相应的事件标志位会被函数 xEventGroupWaitBits 清除掉,等从高优先级任务返回到低优先级任务后,函数xEventGroupSetBits 的返回值已经被修改。

函数 xEventGroupSetBitsFromISR 函数原型: BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, /* 事件标志组句柄 */ const EventBits_t uxBitsToSet, /* 事件标志位设置 */ BaseType_t *pxHigherPriorityTaskWoken ); /* 高优先级任务是否被唤醒的状态保存 */ 函数描述: 函数 xEventGroupSetBitsFromISR,用于设置指定的事件标志位为 1。(中断方式) 第 1 个参数是事件标志组句柄。 第 2 个参数表示 24 个可设置的事件标志位,EventBits_t 是定义的 32 位变量(详解 18.1.2 小节说 明),低 24 位用于事件标志设置。变量 uxBitsToSet 的低 24 位的某个位设置为 1,那么被设置的 事件标志组的相应位就设置为 1。 变量 uxBitsToSet 设置为 0 的位对事件标志相应位没有影响。比 如设置变量 uxBitsToSet = 0x0003 就表示将事件标志的位 0 和位 1 设置为 1,其余位没有变化。 第 3 个参数用于保存是否有高优先级任务准备就绪。如果函数执行完毕后,此参数的数值是 pdTRUE, 说明有高优先级任务要执行,否则没有。 返回值,如果消息成功发送给 daemon 任务(就是 FreeRTOS 的定时器任务)返回 pdPASS,否则 返回 pdFAIL,另外 daemon 任务中的消息队列满了也会返回 pdFAIL。 使用这个函数要注意以下问题: 1. 使用前一定要保证事件标志已经通过函数 xEventGroupCreate 创建了。同时要在 FreeRTOSConfig.h文件中使能如下三个宏定义: #define INCLUDE_xEventGroupSetBitFromISR 1 #define configUSE_TIMERS 1 #define INCLUDE_xTimerPendFunctionCall 1 2. 函数 xEventGroupSetBitsFromISR 是用于中断服务程序中调用的,故不可以在任务代码中调用此函数,任务代码中使用的是 xEventGroupSetBits。 3. 函数 xEventGroupSetBitsFromISR 对事件标志组的操作是不确定性操作,因为不知道当前有多少个任务在等待此事件标志。而 FreeRTOS 不允许在中断服务程序和临界段中执行不确定性操作。 为了不在中断服务程序中执行,就通过此函数给FreeRTOS 的 daemon 任务(就是 FreeRTOS 的定时器任务)发送消息,在 daemon 任务中执行事件标志的置位操作。 同时也为了不在临界段中执行此不确定操作,将临界段改成由调度锁来完成。这样不确定性操作在中断服务程序和临界段中执行的问题就都得到解决了。 4. 由于函数 xEventGroupSetBitsFromISR 对事件标志的置位操作是在 daemon 任务里面执行的,如果想让置位操作立即生效,即让等此事件标志的任务能够得到及时执行,需要设置 daemon 任务的优先级高于使用此事件标志组的所有其它任务。 5. 通过下面的使用举例重点看一下函数 xEventGroupSetBitsFromISR 第三个参数的规范用法,初学者务必要注意。

函数 xEventGroupWaitBits 函数原型: EventBits_t xEventGroupWaitBits( const EventGroupHandle_t xEventGroup, /* 事件标志组句柄 */ const EventBits_t uxBitsToWaitFor, /* 等待被设置的事件标志位 */ const BaseType_t xClearOnExit, /* 选择是否清零被置位的事件标志位 */ const BaseType_t xWaitForAllBits, /* 选择是否等待所有标志位都被设置 */ TickType_t xTicksToWait ); /* 设置等待时间 */ 函数描述: 函数 xEventGroupWaitBits 等待事件标志被设置。 第 1 个参数是事件标志组句柄。 第 2 个参数表示等待 24 个事件标志位中的指定标志,EventBits_t 是定义的 32 位变量,低 24 位用于事件标志设置。比如设置变量 uxBitsToWaitFor = 0x0003 就表示等待事件标志的位 0 和位 1 设置为 1。 此参数切不可设置为 0。 第 3 个参数选择是否清除已经被置位的事件标志,如果这个参数设置为 pdTRUE,且函数 xEventGroupWaitBits 在参数 xTicksToWait 设置的溢出时间内返回,那么相应被设置的事件标志位会被清零。 如果这个参数设置为 pdFALSE,对已经被设置的事件标志位没有影响。 第 4 个参数选择是否等待所有的标志位都被设置,如果这个参数设置为 pdTRUE,要等待第 2 个参数 uxBitsToWaitFor 所指定的标志位全部被置 1,函数才可以返回。当然,超出了在参数xTicksToWait 设置的溢出时间也是会返回的。如果这个参数设置为 pdFALSE,第 2 个参数uxBitsToWaitFor 所指定的任何标志位被置 1,函数都会返回,超出溢出时间也会返回。 第 5 个参数设置等待时间,单位时钟节拍周期。 如果设置为 portMAX_DELAY,表示永久等待。 返回值,由于设置的时间超时或者指定的事件标志位被置 1,导致函数退出时返回的事件标志组数值。 使用这个函数要注意以下问题: 1. 此函数切不可在中断服务程序中调用。 2. 这里再着重说明下这个函数的返回值,通过返回值用户可以检测是哪个事件标志位被置 1 了。 如果由于设置的等待时间超时,函数的返回值可能会有部分事件标志位被置 1。 如果由于指定的事件标志位被置1而返回, 并且设置了这个函数的参数xClearOnExit为pdTRUE, 那么此函数的返回值是清零前的事件标志组数值。 另外,调用此函数的任务在离开阻塞状态到退出函数 xEventGroupWaitBits 之间这段时间,如果一个高优先级的任务抢占执行了,并且修改了事件标志位,那么此函数的返回值会跟当前的事件标志组数值不同 。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static void AppTaskCreate(void)
{

        xTaskCreate(vTaskWork,       /* 任务函数  */
                 "vTaskWork",         /* 任务名    */
                  512,                   /* 任务栈大小,单位word,也就是4字节 */
                  NULL,                  /* 任务参数  */
                  1,                     /* 任务优先级*/
                  &xHandleTaskWork );  /* 任务句柄  */
    
    
    xTaskCreate( vTaskLed1,            /* 任务函数  */
                 "vTaskLed1",          /* 任务名    */
                 512,                 /* 任务栈大小,单位word,也就是4字节 */
                 NULL,                /* 任务参数  */
                 2,                   /* 任务优先级*/
                 &xHandleTaskLED1); /* 任务句柄  */
    
    xTaskCreate( vTaskBeep,             /* 任务函数  */
                 "vTaskBeep",           /* 任务名    */
                 512,                     /* 任务栈大小,单位word,也就是4字节 */
                 NULL,                   /* 任务参数  */
                 3,                       /* 任务优先级*/
                 &xHandleTaskBeep );  /* 任务句柄  */
    
    
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*********************************************************************************
  * @ 函数名  : vTaskBeep
  * @ 功能说明: Beep 任务
  * @ 参数    : pvParameters,当任务创建的时候传进来,可以没有  
  * @ 返回值  : 无
  ********************************************************************************/
void vTaskBeep(void *pvParameters)
{
        EventBits_t uxBits;
        const TickType_t xTicksToWait = 5000; /* 最大延迟100ms */
    
    while(1)
    {
        /* 等K1按键按下设置bit0和K2按键按下设置bit1 */
        uxBits = xEventGroupWaitBits(xCreatedEventGroup, /* 事件标志组句柄 */
                                     BIT_ALL,            /* 等待bit0和bit1被设置 */
                                     pdTRUE,             /* 退出前bit0和bit1被清除,这里是bit0和bit1都被设置才表示“退出”*/
                                     pdTRUE,             /* 设置为pdTRUE表示等待bit1和bit0都被设置*/
                                     xTicksToWait);      /* 等待延迟时间 */
        
        if((uxBits & BIT_ALL) == BIT_ALL)
        {
            /* 接收到bit1和bit0都被设置的消息 */
            printf("接收到bit0和bit1都被设置的消息\r\n");
        }
        else
        {
            /* 超时,另外注意仅接收到一个按键按下的消息时,变量uxBits的相应bit也是被设置的 */
            BEEP_TOGGLE; 
        }
    }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/***按键处理任务***/

static void vTaskWork(void *pvParameters)
{

    EventBits_t uxBits;

    while(1)
    {
        
        
        if (key1_flag==1)
        {
            key1_flag=0;
                        /* 设置事件标志组的bit0 */
                    uxBits = xEventGroupSetBits(xCreatedEventGroup, BIT_0);
                    if((uxBits & BIT_0) != 0)
                    {
                        printf("K1键按下,事件标志的bit0被设置\r\n");
                    }
                    else
                    {
                        printf("K1键按下,事件标志的bit0被清除,说明任务vTaskBeep已经接受到bit0和bit1被设置的情况\r\n");
                    }
        }
        if(key2_flag==1)
        {
                    key2_flag=0;
                    uxBits = xEventGroupSetBits(xCreatedEventGroup, BIT_1);
                    if((uxBits & BIT_1) != 0)
                    {
                        printf("K2键按下,事件标志的bit1被设置\r\n");
                    }
                    else
                    {
                        printf("K2键按下,事件标志的bit1被清除,说明任务vTaskBeep已经接受到bit0和bit1被设置的情况\r\n");
                    }
            
        }
    
        
        vTaskDelay(20);
    }
}

创建的任务,按键处理优先级低于事件等待的Beep任务,先按下K1,再按K2,打印如下:

第一个输出毫无疑问,第二行,由于事件等待Beep优先级大于按键处理,所以当K2按下之后,调度器首先回到高优先级的任务Beep,打印出此时K1,K2都被按下以致bit0和bit1被置位的消息,在Beep任务中调用xEventGroupWaitBits函数后,这两个置为1的位bit1和bit0会被清零,此时,调度器再次回到低优先级的按键处理任务时,xEventGroupSetBits的返回值已经更新成清零值,故第三行打印清除的消息。

现在,我们把按键处理的优先级设置成为高于Beep任务的,打印输出如下:

第一个输出也毫无疑问,按下K1,bit0被置位,当我按下K2的时候,此时调度器 不会马上返回低优先级的Beep任务,而会继续执行自身(此实验设置按键处理最高优先级)直到被阻塞,所以会有第二行的打印,但是,注意,第二行按下K2的打印却依旧显示的是被清除了,因为在Beep任务中使用了事件等待,而K2按下的时候,freertos操作系统会知道等待两个按键按下的事件已经触发了,此时,在按键处理任务中,xEventGroupSetBits的返回值,也不是当前获取的置位值了,而是经过xEventGroupSetBits函数自动清零之后的值,所以第二行打印的是清零消息,第三行打印都被置位,为什么不是清零?因为此时xEventGroupWaitBits返回值是清零前的事件标志组数值。

可能你觉得有点奇怪, xEventGroupSetBits函数本就是置位信息的功能,居然还要受xEventGroupWaitBits函数和调用形式影响,哪怕调用xEventGroupWaitBits函数的任务优先级还是低于我们的按键任务的(但是事件标志的设置让低优先级的任务离开了阻塞态(只要离开了阻塞态,返回值就会更新),在就绪态,只是被高优先级任务抢占了),但是,正是因为这样,我们真正实时传递了事件信息啊。试想,要是我的两个按键事件都已经触发了,而我在按键处理任务中还不能立即知道,这样的实时性显然是不满足需求的。就连裸机中,我们通过中断改变一个元素的值,一定是中断改变之后,这个值在被任何使用的时候都已经更新,所以,作为实时操作系统,freertos这样的行为也就可以理解了。

中断方式不再演示,只是需要在中断服务函数中使用xEventGroupSetBitsFromISR,使用方式如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*
*********************************************************************************************************
*    函 数 名: TIM_CallBack1和TIM_CallBack2
*    功能说明: 定时器中断的回调函数,此函数被bsp_StartHardTimer所调用。                        
*    形    参: 无
*    返 回 值: 无
*********************************************************************************************************
*/
static void TIM_CallBack1(void)
{
    BaseType_t xResult;
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    
    /* 向任务vTaskBeep发送事件标志 */
    xResult = xEventGroupSetBitsFromISR(xCreatedEventGroup, /* 事件标志组句柄 */
                                        BIT_0 ,             /* 设置bit0 */
                                        &xHigherPriorityTaskWoken );

    /* 消息被成功发出 */
    if( xResult != pdFAIL )
    {
        /* 如果xHigherPriorityTaskWoken = pdTRUE,那么退出中断后切到当前最高优先级任务执行 */
        portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/04/06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
FreeRTOS源码探析之——事件标志组
事件是一种实现任务间通信的机制,主要用于实现多任务间的同步,但事件通信只能是事件类型的通信,无数据传输。
xxpcb
2020/12/02
1.1K0
FreeRTOS源码探析之——事件标志组
FreeRTOS内核应用开发手记
FreeRTOS内核应用开发学习手记移植任务状态迁移任务创建与删除任务挂起与恢复任务延时消息队列信号量事件软件定时器任务通知内存管理
小锋学长生活大爆炸
2020/08/13
6030
FreeRTOS内核应用开发手记
韦东山freeRTOS系列教程之【第八章】事件组(event group)
秋游回来第二天就要提交一篇心得报告,组长在焦急等待:张三、李四、王五谁先写好就交谁的。
韦东山
2021/12/08
1.1K0
韦东山freeRTOS系列教程之【第八章】事件组(event group)
freeRTOS事件组学习
像其他RTOS一样,freeRTOS同样有对事件标志位的创建和处理,在中断中可以通过事件组传递信息给其他的任务,那么如何创建事件组呢? 要使用创建Event的API,首先必须配置,且包含event的头
用户1605515
2018/04/10
1.6K0
freeRTOS事件组学习
深入探索嵌入式开发中的 FreeRTOS:从入门到精通
在嵌入式系统的广阔天地里,实时操作系统(RTOS)正扮演着愈发关键的角色。FreeRTOS作为一款开源、轻量级且功能卓越的实时操作系统,备受全球开发者的青睐。它为嵌入式开发带来了高效的多任务管理、精准的资源调度等诸多优势,极大地提升了开发效率与系统的可靠性。接下来,让我们一同踏上从入门到深入掌握FreeRTOS的精彩旅程。听说先赞后看,就能家财万贯。
威哥爱编程
2025/02/28
2300
FreeRTOS(十四):事件标志组
前面我们学习了使用信号量来完成同步,但是使用信号量来同步的话任务只能与单个的事件或任务进行同步。有时候某个任务可能会需要与多个事件或任务进行同步,此时信号量就无能为力了。
Jasonangel
2022/02/17
7980
FreeRTOS(十四):事件标志组
韦东山freeRTOS系列教程之【第九章】任务通知(Task Notifications)
我们使用队列、信号量、事件组等等方法时,并不知道对方是谁。使用任务通知时,可以明确指定:通知哪个任务。
韦东山
2021/12/08
1.8K0
韦东山freeRTOS系列教程之【第九章】任务通知(Task Notifications)
【安富莱】【RL-TCPnet网络教程】第10章 RL-TCPnet网络协议栈移植(FreeRTOS)
本章教程为大家讲解RL-TCPnet网络协议栈的FreeRTOS操作系统移植方式,学习了第6章讲解的底层驱动接口函数之后,移植就比较容易了,主要是添加库文件、配置文件和驱动文件即可。另外,RL-TCPnet移植到FreeRTOS要重新配置RL-TCPnet的接口函数,以此来支持RL-TCPnet多任务运行。使用RTX无需重新配置,因为默认情况下就是采用RTX的API函数配置的。
Simon223
2018/09/04
1.8K0
【安富莱】【RL-TCPnet网络教程】第10章 RL-TCPnet网络协议栈移植(FreeRTOS)
【二代示波器教程】第15章 FreeRTOS操作系统版本二代示波器实现
本章教程为大家讲解FreeRTOS操作系统版本的二代示波器实现。主要讲解RTOS设计框架,即各个任务实现的功能,任务间的通信方案选择,任务栈,系统栈以及全局变量共享问题。同时,工程调试方法也专门做了说明。
Simon223
2018/09/04
1.5K0
【二代示波器教程】第15章   FreeRTOS操作系统版本二代示波器实现
【RL-TCPnet网络教程】第21章 RL-TCPnet之高效的事件触发框架
本章节为大家讲解高效的事件触发框架实现方法,BSD Socket编程和后面章节要讲解到的FTP、TFTP和HTTP等都非常适合使用这种方式。实际项目中也推荐大家采用这种方式,不过仅适用于RTOS环境,比如RTX、FreeRTOS或者uCOS-III均可,裸机方式不支持。
Simon223
2018/09/04
2.6K0
【RL-TCPnet网络教程】第21章 RL-TCPnet之高效的事件触发框架
FreeRTOS 消息队列
上面这几中方式中, 除了消息通知, 其他几种实现都是基于消息队列。消息队列作为主要的通信方式, 支持在任务间, 任务和中断间传递消息内容。 这一章介绍 FreeRtos 消息队列的基本使用, 重点分析其实现的方式。
orientlu
2018/09/13
2.5K0
FreeRTOS 消息队列
FreeRTOS例程2-任务挂起恢复与使用中断遇到的坑!
任务挂起简单点理解就是现在不需要执行这个任务,让它先暂停,就是挂起。恢复就是从刚才挂起的状态下继续运行。
xxpcb
2020/08/04
3K0
【STM32H7】第17章 ThreadX事件标志组
论坛原始地址(持续更新):http://www.armbbs.cn/forum.php?mod=viewthread&tid=99514 第17章 ThreadX事件标志组 前面的章节我们
Simon223
2021/07/08
6080
韦东山freeRTOS系列教程之【第十一章】中断管理(Interrupt Management)
在RTOS中,需要应对各类事件。这些事件很多时候是通过硬件中断产生,怎么处理中断呢?
韦东山
2021/12/08
2.6K0
韦东山freeRTOS系列教程之【第十一章】中断管理(Interrupt Management)
FreeRTOS系列第9篇---FreeRTOS任务概述基础篇
应用程序可以使用任务也可以使用协程,或者两者混合使用,但是任务和协程使用不同的API函数,因此在任务和协程之间不能使用同一个队列或信号量传递数据。
李肖遥
2020/07/29
1.7K0
FreeRTOS 信号量
FreeRTOS 信号量和互斥锁是基于队列实现的, 队列介绍见 << FreeRTOS 消息队列 >>。 使用信号量需要在源文件中包含头文件 semphr.h , 该文件定义了信号量的 API, 实际我们使用的信号量 API 都是宏定义, 宏的实际是队列提供的函数。
orientlu
2018/09/13
2.3K0
FreeRTOS 信号量
FreeRTOS 任务调度 系统节拍
文章 < FreeRTOS 任务调度 任务切换 > 记录了 FreeRTOS 中任务切换的过程, 提到触发任务切换的两种情况 : 高优先级任务就绪抢占和同优先级任务时间共享(包括提前挂起)。 系统中,时间延时和任务阻塞,时间片都以 Systick 为单位。
orientlu
2018/09/13
1.9K0
FreeRTOS 任务调度 系统节拍
FreeRTOS 任务调度 任务切换
前面文章 < FreeRTOS 任务调度 任务创建 > 介绍了 FreeRTOS 中如何创建任务以及其具体实现。 一般来说, 我们会在程序开始先创建若干个任务, 而此时任务调度器还没又开始运行,因此每一次任务创建后都会依据其优先级插入到就绪链表,同时保证全局变量 pxCurrentTCB 指向当前创建的所有任务中优先级最高的一个,但是任务还没开始运行。 当初始化完毕后,调用函数 vTaskStartScheduler启动任务调度器开始开始调度,此时,pxCurrentTCB所指的任务才开始运行。 所以, 本章,介绍任务调度器启动以及如何进行任务切换。
orientlu
2018/09/13
5.8K0
FreeRTOS 任务调度  任务切换
使用FreeRTOS要好好理解任务状态机
前面一文利用FreeRTOS点灯,算是将FreeRTOS给跑起来了,要用好RTOS,从黑盒角度去理解一下调度器是怎么工作的是很必要的,当然如果想研究其内部实现原理,可以去读其内部实现代码,但是个人感觉如果是从用的角度,把内核看成黑盒,跳出来梳理一下概念也很有用。
wenzid
2021/08/13
1.3K0
使用FreeRTOS要好好理解任务状态机
FreeRTOS学习笔记 | 基础知识体系梳理
我发现学习 RTOS 是学习 Linux 内核的好方法。大有弯道超车的可能。 1. 任务堆栈 1.1 任务栈大小确定 1.2 栈溢出检测机制 2. 任务状态 3. 任务优先级 3.1任务优先级说明 3.2 任务优先级分配方案 3.3 任务优先级与终端优先级的区别 4. 任务调度 4.1 调度器 5. 临界区、锁与系统时间 5.1 临界区与开关中断 5.2 锁 5.3 FreeRTOS 系统时钟节拍和时间管理 一、 单任务系统(裸机) 主要是采用超级循环系统(前后台系统),应用程序是一个无限的循环,循环中调用
刘盼
2022/09/20
3K0
FreeRTOS学习笔记 | 基础知识体系梳理
推荐阅读
相关推荐
FreeRTOS源码探析之——事件标志组
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文