如何post 两个不同的事件到同一个Contiki 进程?

How to post two different events to the same 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 宏可以解决此问题。