硬汉嵌入式论坛

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

[FreeRTOS] FreeRTOS 队列接收数据后如何实现函数一直执行?

[复制链接]

38

主题

75

回帖

189

积分

初级会员

积分
189
发表于 2024-6-30 15:49:23 | 显示全部楼层 |阅读模式


我有两个任务A和B,A通过队列每隔1分钟发送一次使能数据0或1给B,B接收到数据后打开或关闭开关。
0表示关闭开关,1表示打开开关。

任务B大致如下,
static void vReceiverTask( void *pvParameters )
{
     for( ;; )
        {
                /* 等待接收来自任务A的开关数据 */
                xStatus = xQueueReceive( xQueue, &switch, portMAX_DELAY );
                if( xStatus == pdPASS )
                {
                         switch_control(switch);  // 要求一旦接收到来自A的开关数据,比如接收到1,要求 switch_control()一直执行,而不是执行一次。
                }
        }
}

A没有发送数据的时候,xQueueReceive一直阻塞,一旦A有数据过来,阻塞解除,执行一次 switch_control(),队列的数据被读走,队列又变为空,又变为阻塞,等待下一次A发送数据。
也就是当A发送一次数据的时候, switch_control(switch)只会执行一次。

我现在想要A发送数据过来的时候,比如发送的是1,那么switch_control(switch)一直执行1相关的功能,而不是执行一次,直到下一次A发送过来比如是0,然后switch_control(switch)一直执行0相关的功能。如何实现呢?

回复

使用道具 举报

3

主题

15

回帖

24

积分

新手上路

积分
24
发表于 2024-6-30 18:42:33 | 显示全部楼层
把接收部分单独放,然后用一个变量存当前的数据状态,任务b按照此变量的值循环执行,这样应该就可以了吧。感觉这需求应该没必要用队列吧,1min发送一次的话?是接收的更慢吗?
回复

使用道具 举报

38

主题

75

回帖

189

积分

初级会员

积分
189
 楼主| 发表于 2024-6-30 22:57:05 | 显示全部楼层
GFeonix 发表于 2024-6-30 18:42
把接收部分单独放,然后用一个变量存当前的数据状态,任务b按照此变量的值循环执行,这样应该就可以了吧。 ...

你说的方法就是用全局变量来做吧,主要是我的任务B里面除了接收开关数据,还有其他很多的接收任务,都是来自其他多个发送任务,感觉用队列比较好管理。

如果用队列的话,有实现的方法吗?

我自己研究了一下,设置一个长度为1的队列,然后用xQueueOverwrite覆盖写入,用xQueuePeek接收,无阻塞式的,第一次队列为空阻塞,当写入一个数据后,就永远不会阻塞,会一直读取数据执行函数,直到有新的数据覆盖写入,就会读取新的值执行相应函数功能。
不知道可行不可行。
回复

使用道具 举报

0

主题

33

回帖

33

积分

新手上路

积分
33
发表于 2024-7-1 08:38:25 | 显示全部楼层
portMAX_DELAY 修改这个参数
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2024-7-28 10:49:25 | 显示全部楼层
static void vReceiverTask(void *pvParameters)
{
    int switchState = 0;  // 初始开关状态,假设为关闭
    int newSwitchState;
    BaseType_t xStatus;

    for(;;)
    {
      
        xStatus = xQueueReceive(xQueue, &newSwitchState, 0);

        if (xStatus == pdPASS)
        {
            
            if (newSwitchState != switchState)
            {
                switchState = newSwitchState;        
                switch_control(switchState);
            }
        }

        vTaskDelay(pdMS_TO_TICKS(100));
    }
}
回复

使用道具 举报

9

主题

156

回帖

183

积分

初级会员

积分
183
发表于 2024-7-28 23:21:48 | 显示全部楼层
switch_control(switch), 大致我认为就是根据传递的值, 然后while(1){一直执行}. 这个好办, 动态的删除和创建任务, 根据switch的值不同创建不同的任务
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-8-12 08:47 , Processed in 0.041164 second(s), 23 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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