硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2333|回复: 11
收起左侧

[FreeRTOS] 使用任务事件标志时的疑问,求助

[复制链接]

20

主题

56

回帖

116

积分

初级会员

积分
116
发表于 2019-2-16 00:15:53 | 显示全部楼层 |阅读模式
将CuBe生成的FreeRTOS框架改写的源代码提取出来
本意是在LEDTask1 发出通知后LEDTask2保留标志并不停闪烁led,LEDTask1 清除通知后LEDTask2被阻塞。但模拟运行的结果是每次有通知后,LEDTask2只循环一次就被阻塞了。
/* LEDTask1 function */
void LEDTask1(void const * argument)
{
        /* definition and creation of myTask02 */
        osThreadDef(myTask02, LEDTask2, osPriorityIdle, 0, 128);
        myTask02Handle = osThreadCreate(osThread(myTask02), NULL);
        for(;;)
        {
                  xTaskNotify(myTask02Handle, 0x01, eSetBits);
                  HAL_GPIO_WritePin(GPIOA, led1_Pin, GPIO_PIN_SET);
                  vTaskDelay(100);
                  xTaskNotifyStateClear(myTask02Handle);
                  HAL_GPIO_WritePin(GPIOA, led1_Pin, GPIO_PIN_RESET);
                  vTaskDelay(100);
        }
}

/* LEDTask2 function */
void LEDTask2(void const * argument)
{
        for(;;)
        {
                  xTaskNotifyWait(0x00000000, 0x00000000, NULL, portMAX_DELAY);// 按照自己的理解,LEDTask1 发出的通知应该不会被清除,但实际上标志还是被清除了
                  HAL_GPIO_WritePin(GPIOA, led2_Pin, GPIO_PIN_SET);
                  vTaskDelay(10);
                  HAL_GPIO_WritePin(GPIOA, led2_Pin, GPIO_PIN_RESET);
                  vTaskDelay(10);
        }
}


回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106726
QQ
发表于 2019-2-16 00:27:02 | 显示全部楼层
先不要使用CMSIS-RTOS V1封装层,全部使用FreeRTOS的原始API设置。比如这些函数
osThreadDef(myTask02, LEDTask2, osPriorityIdle, 0, 128);
myTask02Handle = osThreadCreate(osThread(myTask02), NULL);

全部换了,然后测试。
回复

使用道具 举报

20

主题

56

回帖

116

积分

初级会员

积分
116
 楼主| 发表于 2019-2-16 18:14:59 | 显示全部楼层
本帖最后由 bucker 于 2019-2-16 18:20 编辑
eric2013 发表于 2019-2-16 00:27
先不要使用CMSIS-RTOS V1封装层,全部使用FreeRTOS的原始API设置。比如这些函数
osThreadDef(myTask02, LE ...

如果使用事件标志组(EventGroup)的话是可以实现顶楼所需功能的。就像跑圈赛道的信号灯,始终保持绿灯的话车辆可以直接通行,直到亮红灯车辆停止。
EventGroupHandle_t myEvt;

/* LEDTask1 function */
void LEDTask1(void const * argument)
{
        myEvt = xEventGroupCreate();
        /* definition and creation of myTask02 */
        osThreadDef(myTask02, LEDTask2, osPriorityIdle, 0, 128);
        myTask02Handle = osThreadCreate(osThread(myTask02), NULL);
        for(;;)
        {
                xEventGroupSetBits(myEvt, 0x01);
                HAL_GPIO_WritePin(GPIOA, led1_Pin, GPIO_PIN_SET);
                vTaskDelay(100);
                xEventGroupClearBits(myEvt, 0x01);
                HAL_GPIO_WritePin(GPIOA, led1_Pin, GPIO_PIN_RESET);
                vTaskDelay(100);
        }
}

/* LEDTask2 function */
void LEDTask2(void const * argument)
{
        for(;;)
        {
                xEventGroupWaitBits(myEvt, 0x01, pdFALSE, pdFALSE, portMAX_DELAY);
                HAL_GPIO_WritePin(GPIOA, led2_Pin, GPIO_PIN_SET);
                vTaskDelay(10);
                HAL_GPIO_WritePin(GPIOA, led2_Pin, GPIO_PIN_RESET);
                vTaskDelay(10);
        }
}
使用事件标志组模拟运行结果如图
微信截图_20190216181631.jpg
而使用任务标志,无论接收标志的任务是否清除标志,都无法使任务继续获得标志。

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106726
QQ
发表于 2019-2-16 18:20:31 | 显示全部楼层
bucker 发表于 2019-2-16 18:14
如果使用事件标志组(EventGroup)的话是可以实现顶楼所需功能的。就像跑圈赛道的信号灯,始终保持绿灯的 ...

方便做个不使用CMSIS-RTOS V1封装层的例子不,仅用FreeRTOS的原始API实现,将应用部分的代码发上来,我给你测测。

V1封装层,我基本不使用。
回复

使用道具 举报

20

主题

56

回帖

116

积分

初级会员

积分
116
 楼主| 发表于 2019-2-16 18:43:14 | 显示全部楼层
eric2013 发表于 2019-2-16 18:20
方便做个不使用CMSIS-RTOS V1封装层的例子不,仅用FreeRTOS的原始API实现,将应用部分的代码发上来,我给 ...

我的环境是STM32CUBE4.20+Keil 4.74。
微信截图_20190216183557.jpg
这是顶楼代码的模拟运行结果
Test_FreeRTOS_Event.rar (7.39 MB, 下载次数: 8)
现将工程上传,现在的项目是使用任务事件标志的方法,如果将src文件夹的app.c替换main.c就成了使用事件标志组的方法了。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106726
QQ
发表于 2019-2-16 19:04:03 | 显示全部楼层
你的LED1是高优先级,LED2第优先级,同理,我也做了个。仅仅是LED翻转改成了打印。
LED1:
1.jpg

LED2:

2.jpg

效果:
3.jpg
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106726
QQ
发表于 2019-2-16 19:13:29 | 显示全部楼层
通过测试,我明白你的意思了。

你要注意一点,FreeRTOS的任务事件标志仅仅是个消息,你清除不清除标志都没有任何影响,他仅仅是发个消息给你的其它任务。其它任务收到消息才执行,无消息,不执行,而你接收到后是等所有标志置位还是怎么个处理方式,他不管,这个是用户自己处理。

然后你再结合你的楼主位问题,是不是就好理解了。
回复

使用道具 举报

20

主题

56

回帖

116

积分

初级会员

积分
116
 楼主| 发表于 2019-2-16 20:36:43 | 显示全部楼层
本帖最后由 bucker 于 2019-2-16 20:38 编辑
eric2013 发表于 2019-2-16 19:13
通过测试,我明白你的意思了。

你要注意一点,FreeRTOS的任务事件标志仅仅是个消息,你清除不清除标志都 ...

的确如此,任务事件标志与事件标志组存在差异。我利用V4-329_FreeRTOS实验_任务事件标志组对main进行修改后测试的效果是一致的。不过,疑惑得是既然清不清除标志的效果没区别,为何不做简化的设计,取消多余的参数。
QQ截图20190216203356.jpg
V4-329_FreeRTOS实验_任务事件标志组(改).rar (9.71 MB, 下载次数: 13)



回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106726
QQ
发表于 2019-2-17 00:27:33 | 显示全部楼层
bucker 发表于 2019-2-16 20:36
的确如此,任务事件标志与事件标志组存在差异。我利用V4-329_FreeRTOS实验_任务事件标志组对main进行修改 ...

算是FreeRTOS自己的一种处理机制吧。
回复

使用道具 举报

20

主题

56

回帖

116

积分

初级会员

积分
116
 楼主| 发表于 2019-2-17 10:45:50 | 显示全部楼层
eric2013 发表于 2019-2-17 00:27
算是FreeRTOS自己的一种处理机制吧。

我发现即使发送值为0x00,接收方也会解除阻塞。说明xTaskNotifyWait收到任何通知都会解除阻塞,至于通知的内容只能通过第3个参数来分析。
回复

使用道具 举报

36

主题

2039

回帖

2147

积分

至尊会员

积分
2147
发表于 2019-2-17 11:54:36 来自手机 | 显示全部楼层
bucker 发表于 2019-2-17 10:45
我发现即使发送值为0x00,接收方也会解除阻塞。说明xTaskNotifyWait收到任何通知都会解除阻塞,至于通知 ...

基于任务通知机制的事件标志,消息邮箱等,将其理解成通用的消息队列就容易明白了。
回复

使用道具 举报

20

主题

56

回帖

116

积分

初级会员

积分
116
 楼主| 发表于 2019-2-19 19:19:03 | 显示全部楼层
byccc 发表于 2019-2-17 11:54
基于任务通知机制的事件标志,消息邮箱等,将其理解成通用的消息队列就容易明白了。

的确如此。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-1 17:59 , Processed in 0.320656 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表