contiki - 如何将两个不同的事件发布到同一个 Contiki 进程?

标签 contiki contiki-process

我有两个 Contiki 进程,其中一个进程 master 将两个不同的事件发送到第二个进程 send。发送的第一个事件是 PROCESS_EVENT_CONTINUE,第二个事件是 PROCESS_EVENT_MSG

我从名为 main 的进程中依次发布这些事件。

完整代码为:

#include "contiki.h"
#include "lib/list.h"
#include "lib/memb.h"
#include "lib/random.h"
#include "net/rime/rime.h"

#include<stdio.h>

PROCESS(master, "master_DGHS"); 
PROCESS(send, "master_DGHS"); 

AUTOSTART_PROCESSES( &master, &send);

PROCESS_THREAD(master, ev, data)
{
    PROCESS_BEGIN();

    process_post(&send, PROCESS_EVENT_CONTINUE, NULL);
    process_post(&send, PROCESS_EVENT_MSG, NULL);

    PROCESS_END();
}


PROCESS_THREAD(send, ev, data)
{
    static struct etimer et;

    PROCESS_BEGIN();

    while(1)
    {
        PROCESS_WAIT_EVENT(); 
        if(ev == PROCESS_EVENT_CONTINUE)
        {
            printf("PROCESS_EVENT_CONTINUE\n");
            etimer_set(&et, CLOCK_SECOND );
            PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));

        }else
        if(ev == PROCESS_EVENT_MSG)
        {
            printf("PROCESS_EVENT_MSG\n");
            etimer_set(&et, CLOCK_SECOND  );
            PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
        }

    }
    PROCESS_END();
 }

问题是第二个进程send看到第一个事件(它打印PROCESS_EVENT_CONTINUE),但它没有看到第二个事件(它不打印PROCESS_EVENT_MSG)。

换句话说,第二个事件丢失了。但是,如果我删除源行

PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));

第二个进程send看到这两个事件(PROCESS_EVENT_CONTINUEPROCESS_EVENT_MSG都被打印)。因此,添加此源代码行会导致第二个事件 PROCESS_EVENT_MSG 被忽略或丢弃。

为什么添加此源代码行会导致第二个事件丢失?

最佳答案

问题在于PROCESS_WAIT_EVENT_UNTIL consumes all events直到循环条件变为真。

By calling PROCESS_WAIT_EVENT_UNTIL() in the area separated by the PROCESS_BEGIN() and PROCESS_END() calls, one can yield control to the scheduler, and only resume execution when an event is delivered. A condition is given as an argument to PROCESS_WAIT_EVENT_UNTIL(), and this condition must be fulfilled for the processes to continue execution after the call to PROCESS_WAIT_EVENT_UNTIL(). If the condition is not fulfilled, the process yields control back to the OS until a new event is delivered.

这是示例中的操作顺序:

  1. send 进程获取 PROCESS_EVENT_CONTINUE 事件。
  2. 进程执行第一个 printf,设置计时器,并输入 PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
  3. send 进程紧接着获取 PROCESS_EVENT_MSG 事件。
  4. 该进程仍处于 WAIT_EVENT_UNTIL 循环中,并丢弃第二个事件,因为计时器尚未到期。
  5. 计时器到期,send 进程获取 PROCESS_EVENT_TIMER 事件。
  6. 进程退出等待循环。

因此,第二个事件被进程接收,但没有执行,因为进程正在等待另一个事件。希望您现在明白为什么删除 WAIT_EVENT_UNTIL 宏可以解决此问题。

关于contiki - 如何将两个不同的事件发布到同一个 Contiki 进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49244792/

相关文章:

c - 在cooja模拟器中的Contiki中生成网关场景

Contiki编译错误

c - 在 Contiki 中发送和接收结构 - 处理指针和结构

process - Contiki编译错误, “ERROR: address 0x820003 out of range at line 1740 of…”

c - 尝试使用线程和计时器通过 UDP 发送两条不同的消息失败

Contiki定时器不暂停进程

process - 'Yield'在Contiki rtos中意味着什么

c - Contiki OS中是否有适合Atmega128平台的双线接口(interface)/I2C读写库?