1. 程式人生 > >一.Contiki之程序(2)——建立程序

一.Contiki之程序(2)——建立程序

      Contiki中建立程序的步驟可分為三步,具體方法和過程總結如下:(以後可直接按此模板建立一個程序)

#include <stdio.h>


/*****1.PROCESS巨集完成兩個功能:
(1) 宣告一個函式,該函式是程序的執行體,即程序的thread函式指標所指的函式#define PROCESS(name, strname) PROCESS_THREAD(name, ev, data);
(2) 定義一個程序struct process name = { NULL, strname, process_thread_##name }*****/
PROCESS(HW, "HWP");


/*****2.AUTOSTART_PROCESSES巨集實際上是定義一個指標陣列,存放Contiki系統執行時需自動啟動的程序*****/
AUTOSTART_PROCESSES(&HW);


/*****3.程序結構體中聲明瞭函式PT_THREAD((*thread)(struct pt *, process_event_t, process_data_t)); 實現如下:*****/
PROCESS_THREAD(HW, ev, data)
{
    PROCESS_BEGIN();//PROCESS_BEGIN巨集,程序的主體函式從這裡開始
    
	//此處放自己的程式碼
	
    PROCESS_END();//PROCESS_END巨集,程序的主體函式從這裡結束
}
       對上述建立程序的步驟具體分析,按照原始碼將整個過程展開如下:
#include "contiki.h" 
#include "debug-uart.h"
#include <stdio.h>

/*****PROCESS(HW, "HWP")展開如下:(具體步驟及Ⅰ、Ⅱ、Ⅲ編號見文章末尾表)
Ⅰ #define PROCESS(name, strname) PROCESS_THREAD(name, ev, data); 
struct process name = { NULL, strname, process_thread_##name }
Ⅱ #define   PROCESS_THREAD(name, ev, data)    static PT_THREAD(process_thread_##name(struct pt *process_pt, 
process_event_t  ev, process_data_t  data))
Ⅲ #define PT_THREAD(name_args)  char name_args
第一句為程序執行體,第二句為定義一個程序。定義程序時只有3個引數,lc、state、needspoll預設,預設為0。*****/
static char process_thread_hello_world_process(struct pt *process_pt, process_event_t ev, process_data_t data);
struct process hello_world_process = { ((void *)0), "Hello world process", process_thread_hello_world_process};


/*****AUTOSTART_PROCESSES(&HW)展開如下:
AUTOSTART_PROCESSES定義一個指標陣列,存放Contiki系統執行時需自動啟動的程序;
#define  AUTOSTART_PROCESSES(...)  struct process * const autostart_processes[] = {__VA_ARGS__, NULL};
可變引數巨集:…代表一個可以變化的引數表,__VA_ARGS__只是一個保留名;
如果讓多個執行緒自啟動:AUTOSTART_PROCESSES(&hello_process,&world_process);
(void *)0相當於NULL,程式設計技巧,設定一個哨兵,以提高遍歷整個陣列的效率。*****/
struct process * const autostart_processes[] = {&hello_world_process, ((void *)0)};


/*****PROCESS_THREAD(HW, ev, data)展開如下:*****/
char process_thread_hello_world_process(struct pt *process_pt, process_event_t ev, process_data_t data) 
{ 


/*****#define  PROCESS_BEGIN()  PT_BEGIN(process_pt)
#define  PT_BEGIN(pt)  { 
char PT_YIELD_FLAG = 1; 
LC_RESUME((pt)->lc)
#define  LC_RESUME(s)  switch(s) { 
case 0:*****/
        char PT_YIELD_FLAG = 1; 
        switch((process_pt)->lc) 
        { 
            case 0: 
                ; 
				
				
                //此處放自己程式碼
				
				
/*****#define  PROCESS_END()  PT_END(process_pt)
#define  PT_END(pt)  LC_END((pt)->lc); 
PT_YIELD_FLAG = 0; 
 PT_INIT(pt); 
return PT_ENDED; 
}
#define  LC_END(s)  }
#define  PT_INIT(pt)  LC_INIT((pt)->lc)
#define  LC_INIT(s)  s = 0;
#define  PT_ENDED  3*****/
        }; 
     PT_YIELD_FLAG = 0; 
     (process_pt)->lc = 0;; 
     return 3; 
}