2

我有两个 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被忽略或丢弃。

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

4

1 回答 1

2

问题是它PROCESS_WAIT_EVENT_UNTIL 会消耗所有事件,直到循环的条件变为真。

通过在由 PROCESS_BEGIN() 和 PROCESS_END() 调用分隔的区域中调用 PROCESS_WAIT_EVENT_UNTIL(),可以将控制权交给调度程序,并且仅在传递事件时恢复执行。一个条件作为 PROCESS_WAIT_EVENT_UNTIL() 的参数给出,并且必须满足该条件才能使进程在调用 PROCESS_WAIT_EVENT_UNTIL() 后继续执行。如果条件不满足,则进程将控制权交还给操作系统,直到交付新事件。

这是您的示例中的操作顺序:

  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宏可以解决此问题。

于 2018-03-13T11:28:32.363 回答