contiki-ng文檔:進(jìn)程和事件

Contiki-NG中的應(yīng)用程序通常是使用Process抽象編寫的。 進(jìn)程建立在稱為Protothreads的輕量級(jí)線程庫的頂部。

進(jìn)程定義

首先在源文件的頂部聲明一個(gè)進(jìn)程。 PROCESS()宏帶有兩個(gè)參數(shù):一個(gè)是用于標(biāo)識(shí)進(jìn)程的變量,另一個(gè)是進(jìn)程的名稱。 在第二行中,我們告訴Contiki-NG,該過程應(yīng)在系統(tǒng)啟動(dòng)后立即自動(dòng)啟動(dòng)。 可以在此處指定多個(gè)進(jìn)程,以逗號(hào)分隔。 如果AUTOSTART_PROCESSES()行不包含現(xiàn)有進(jìn)程,則必須使用process_start()函數(shù)手動(dòng)啟動(dòng)該進(jìn)程。

#include "contiki.h" /* Main include file for OS-specific modules. */
#include <stdio.h> /* For printf. */

PROCESS(test_proc, "Test process");
AUTOSTART_PROCESSES(&test_proc);

下面是一個(gè)基本的的進(jìn)程定義

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

  printf("Hello, world!\n");

  PROCESS_END();
}

首先,PROCESS_THREAD()宏采用PROCESS()調(diào)用中指定的進(jìn)程的標(biāo)識(shí)符。 evdata參數(shù)包含傳入事件的值,以及指向事件參數(shù)對象的可選指針。 PROCESS_BEGIN()標(biāo)記將開始執(zhí)行過程的位置。 在大多數(shù)情況下,除變量定義外,程序員應(yīng)避免將代碼放在PROCESS_THREAD()主體中此語句上方。

對于我們的基本流程實(shí)現(xiàn),我們不必關(guān)心任何事件處理,因?yàn)槲覀冎粓?zhí)行一條語句,然后通過讓其到達(dá)PROCESS_END()調(diào)用隱式退出流程。

事件和調(diào)度

Contiki-NG建立在基于事件的執(zhí)行模型上,在該模型中,進(jìn)程通常在告訴調(diào)度程序它們正在等待事件之前執(zhí)行大量工作,從而暫停執(zhí)行。 此類事件可能是計(jì)時(shí)器到期、傳入的網(wǎng)絡(luò)數(shù)據(jù)包或正在傳遞的串口消息。

contiki采用協(xié)同式進(jìn)程調(diào)度,這意味著每個(gè)進(jìn)程負(fù)責(zé)將控制權(quán)自愿交還給操作系統(tǒng),而不去執(zhí)行太長時(shí)間。 因此,應(yīng)用程序開發(fā)人員必須確保將長時(shí)間運(yùn)行的操作拆分為多個(gè)進(jìn)程調(diào)度,以允許調(diào)度程序在上一次停止的位置恢復(fù)。

等待事件

通過在PROCESS_BEGIN()PROCESS_END()之間區(qū)域中調(diào)用PROCESS_WAIT_EVENT_UNTIL(),可以將控制權(quán)交給調(diào)度程序,并且僅在事件到達(dá)時(shí)才恢復(fù)執(zhí)行。 給出了一個(gè)條件作為PROCESS_WAIT_EVENT_UNTIL()的參數(shù),必須滿足此條件才能使進(jìn)程在調(diào)用PROCESS_WAIT_EVENT_UNTIL()之后繼續(xù)執(zhí)行。 如果不滿足該條件,則該過程將控制權(quán)交還給OS,直到傳遞新事件為止。

PROCESS_THREAD(test, ev, data)
{
  /* An event-timer variable. Note that this variable must be static
     in order to preserve the value across yielding. */
  static struct etimer et;

  PROCESS_BEGIN();

  etimer_set(&et, CLOCK_SECOND); /* Trigger a timer after 1 second. */
  while(1) {
    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
    etimer_reset(&et);
  }

  PROCESS_END();
}

暫停和退讓

要自愿釋放對調(diào)度程序的控制,可以調(diào)用PROCESS_PAUSE(),如下例所示。 然后,調(diào)度程序?qū)鬟f所有排隊(duì)的事件,然后立即調(diào)度已暫停的進(jìn)程。

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

  while(have_operations_to_do()) {
    do_some_operations();
    PROCESS_PAUSE();
  }

  PROCESS_END();
}

相比之下,PROCESS_YIELD()會(huì)將控制權(quán)交還給調(diào)度程序,而不希望此后不久再進(jìn)行調(diào)度。 相反,它將等待傳入事件,類似于PROCESS_WAIT_EVENT_UNTIL(),但沒有必需的條件參數(shù)。 可以通過調(diào)用process_poll()由外部進(jìn)程或模塊輪詢已產(chǎn)生的進(jìn)程。 要輪詢使用變量test_proc聲明的進(jìn)程,可以調(diào)用process_poll(&test_proc);。 輪詢進(jìn)程將立即進(jìn)行調(diào)度,并且將向其發(fā)送PROCESS_EVENT_POLL事件。

停止進(jìn)程

一個(gè)過程可以通過三種方式停止:

  • 通過允許到達(dá)并執(zhí)行PROCESS_END()語句,該過程隱式退出。
  • 通過在PROCESS_THREAD主體中調(diào)用PROCESS_EXIT(),顯式退出該進(jìn)程。
  • 另一個(gè)進(jìn)程通過調(diào)用process_exit()終止該進(jìn)程。
    停止進(jìn)程后,可以通過調(diào)用process_start()從頭開始重新啟動(dòng)。

系統(tǒng)定義的事件

Contiki-NG使用基于系統(tǒng)定義的事件進(jìn)行常見操作,如下所示。

Event ID Description
PROCESS_EVENT_NONE 0x80 無事件
PROCESS_EVENT_INIT 0x81 傳遞給正在開始的進(jìn)程
PROCESS_EVENT_POLL 0x82 傳遞給正在輪詢的進(jìn)程.
PROCESS_EVENT_EXIT 0x83 傳遞給正在退出的進(jìn)程。
PROCESS_EVENT_SERVICE_REMOVED 0x84 未使用的.
PROCESS_EVENT_CONTINUE 0x85 交付給從暫停中恢復(fù)執(zhí)行時(shí)的進(jìn)程。
PROCESS_EVENT_MSG 0x86 在發(fā)生傳感器事件時(shí)傳遞給進(jìn)程。
PROCESS_EVENT_EXITED 0x87 Delivered to all processes about an exited process.
PROCESS_EVENT_TIMER 0x88 當(dāng)某個(gè)計(jì)時(shí)器到期時(shí),將其交付給進(jìn)程。
PROCESS_EVENT_COM 0x89 Unused.
PROCESS_EVENT_MAX 0x8a 系統(tǒng)定義的事件的最大數(shù)量。

用戶自定義的事件

還可以指定系統(tǒng)定義的事件未涵蓋的新事件。 應(yīng)該在適當(dāng)?shù)姆秶鷥?nèi)定義和聲明事件變量,以便該事件的所有預(yù)期用戶都可以訪問它。 基本情況是僅在單個(gè)模塊中使用它,然后可以在模塊頂部將其定義為靜態(tài)。

static process_event_t my_app_event;
[...]
my_app_event = process_alloc_event();

請注意,不支持取消事件的方法。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容