请选择 进入手机版 | 继续访问电脑版

安富莱电子论坛

 找回密码
 立即注册

扫一扫,访问微社区

查看: 228|回复: 11
收起左侧

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

[复制链接]

19

主题

67

帖子

105

积分

初级会员

积分
105
发表于 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);
        }
}


回复

使用道具 举报

5667

主题

3万

帖子

4万

积分

管理员

做人第一,工作第二

Rank: 9Rank: 9Rank: 9

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

全部换了,然后测试。
淘宝小店: https://armfly.taobao.com/
专注,努力,用心的做好每一件事情,Fighting!
回复

使用道具 举报

19

主题

67

帖子

105

积分

初级会员

积分
105
 楼主| 发表于 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
而使用任务标志,无论接收标志的任务是否清除标志,都无法使任务继续获得标志。

回复

使用道具 举报

5667

主题

3万

帖子

4万

积分

管理员

做人第一,工作第二

Rank: 9Rank: 9Rank: 9

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

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

V1封装层,我基本不使用。
淘宝小店: https://armfly.taobao.com/
专注,努力,用心的做好每一件事情,Fighting!
回复

使用道具 举报

19

主题

67

帖子

105

积分

初级会员

积分
105
 楼主| 发表于 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, 下载次数: 5)
回复

使用道具 举报

5667

主题

3万

帖子

4万

积分

管理员

做人第一,工作第二

Rank: 9Rank: 9Rank: 9

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

LED2:

2.jpg

效果:
3.jpg
淘宝小店: https://armfly.taobao.com/
专注,努力,用心的做好每一件事情,Fighting!
回复

使用道具 举报

5667

主题

3万

帖子

4万

积分

管理员

做人第一,工作第二

Rank: 9Rank: 9Rank: 9

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

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

然后你再结合你的楼主位问题,是不是就好理解了。
淘宝小店: https://armfly.taobao.com/
专注,努力,用心的做好每一件事情,Fighting!
回复

使用道具 举报

19

主题

67

帖子

105

积分

初级会员

积分
105
 楼主| 发表于 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, 下载次数: 7)
回复

使用道具 举报

5667

主题

3万

帖子

4万

积分

管理员

做人第一,工作第二

Rank: 9Rank: 9Rank: 9

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

算是FreeRTOS自己的一种处理机制吧。
淘宝小店: https://armfly.taobao.com/
专注,努力,用心的做好每一件事情,Fighting!
回复

使用道具 举报

19

主题

67

帖子

105

积分

初级会员

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

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

使用道具 举报

25

主题

1336

帖子

1386

积分

至尊会员

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

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

使用道具 举报

19

主题

67

帖子

105

积分

初级会员

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

的确如此。
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|手机版|安富莱电子论坛 ( 鄂ICP备09023347号,公安机关备案号42010602000201 )

GMT+8, 2019-5-21 07:38 , Processed in 0.213974 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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