本文涉及到的Protothread機制知識,在http://www.cnblogs.com/songdechiu/p/5793717.html
一、進程類型
進程類型主要有協同式(cooperative)和搶占式(preemptive)兩種。
協同式進程,要等其他進程運行完進程實體函數(進程不一定運行完,這個時候有可能是阻塞,總之只要執行到return語句,具體看protothread機制),然后才能開始運行。
搶占式進程,會優先運行,當有搶占式進程需要執行時,協同式進程將會被掛起,直到搶占式進程實體函數執行完畢。中斷和實時任務就需要用搶占式進程實現。
二、進程結構
1、進程結構體
struct process { struct process *next;//指向下個進程結構體,在進程鏈表中使用 #if PROCESS_CONF_NO_PROCESS_NAMES//配置進程字符串名字? #define PROCESS_NAME_STRING(process) ""//沒有,空 #else //有字符串名字 const char *name;//定義進程字符串名字 #define PROCESS_NAME_STRING(process) (process)->name//取名字 #endif PT_THREAD((* thread)(struct pt *, process_event_t, process_data_t));//進程執行實體函數 struct pt pt;//pt結構體,存儲實體函數阻塞時的位置 unsigned char state, needspoll;//state是進程狀態,needspoll標志進程是否需要優先執行 };
2、進程鏈表
process_list ----->
參考:http://blog.chinaunix.net/uid-9112803-id-2976187.html
只要抓住了進程鏈表頭process_list,那么進程的各種操作都做得到了。
3、進程執行實體函數
HelloWorld例子
PROCESS_THREAD(hello_world_process, ev, data) { PROCESS_BEGIN(); printf("Hello, world\n"); PROCESS_END(); } #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
最后展開為
static char process_thread_hello_world_process(struct pt *process_pt, process_event_t ev, process_data_t data) { //略 }
這就是進程的執行實體函數
三、事件
1、非同步事件
非同步事件處理中,先將事件放到事件隊列中,然后事件處理程序再把事件傳遞給接收這個事件的進程。
2、同步事件
同步事件處理中,事件立馬就傳遞給了特定的進程,表現為立馬執行ProcessB的執行實體函數。
3、Polling(推舉)
推舉某個進程,讓這個進程盡可能快的執行。搶占式進程的唯一調用方式。
四、進程調度函數
先處理所有poll的進程,再處理一個事件,最后返回剩余的事件數。
int process_run(void) { /* Process poll events. */ if(poll_requested) { do_poll(); } /* Process one event from the queue */ do_event(); return nevents + poll_requested; }
五、參考資料
https://github.com/contiki-os/contiki/wiki/Processes
http://blog.chinaunix.net/uid-9112803-id-2976187.html
源碼:$contiki$\core\sys\process.c
源碼:$contiki$\core\sys\process.h