HelloWorld Example
#include"contiki.h"#include<stdio.h>/*For printf ()*//*---------------------------------------------------------------------------*/PROCESS (hello_world_process,"Hello World Process"); Autostart_processes (&hello_world_process);/*---------------------------------------------------------------------------*/process_thread (hello_world_process, Ev, data) {Process_begin (); printf ("Hello, world\n."); Process_end ();}
PROCESS
#ifProcess_conf_no_process_names//is the string name? #definePROCESS (name, strname) \process_thread (name, Ev, data); \//declaring Process Execution entity functions structProcess name ={NULL, process_thread_# #name}//define the process structure body variable name#else#definePROCESS (name, strname) \process_thread (name, Ev, data); structProcess name ={NULL, strname, process_thread_# #name}#endif
Process_thread (name, Ev, data); step-by-step:
#define Process_thread (name, Ev, data) static pt_thread (process_thread_# #name (struct PT *Process_ PT, process_event_t ev, process_data_t data))
Pt_thread See protothread mechanism
Static Char process_thread_hello_world_process (struct pt *process_pt, process_event_t ev, PROCESS_ data_t data);
This statement is equivalent to declaring a function Process_thread_hello_world, and this function is the Process execution entity function . It can be seen in the subsequent definition process structure.
Process structure Body:
structProcess {structProcess *next;//point to the next process structure and use it in the process chain list#ifProcess_conf_no_process_names//Configure the process string name? #defineProcess_name_string (process) ""//No, empty#else //have a string name Const Char*name;//define Process String name#defineProcess_name_string (process)->name//Take a name#endifPt_thread ((* thread) (structPT *, process_event_t, process_data_t));//Process Execution Entity functions structPT PT;//pt struct, where the stored entity function is blockedUnsignedCharState, Needspoll;//State is the status of the process, and NEEDSPOLL flags whether the process requires priority execution};
struct Process hello_world_process =strname
Process_thread_ hello_world_process }
The statement in the back defines a process variable hello_world_process, and assigns the initial value, which is handled by strname to simplify.
In summary, the processmacro definition, which has two functions, declares that the process executes an entity function and defines the processes structure body variable as follows:
Static Char process_thread_hello_world_process(struct pt *process_pt, process_event_t ev, process_data_t data); struct hello_world_process =strname, \ process_thread_hello_world_process
}
Note: This only takes the hello_world_process variable and grabs the whole process.
Autostart_processes
Expand All:
Autostart_processes (&hello_world_process);#if! Cc_no_va_args#ifAutostart_enable#defineAutostart_processes (...)structProcess *ConstAutostart_processes[] ={__va_args__, NULL}#else/* autostart_enable */#defineAutostart_processes (...)extern int_dummy#endif/* autostart_enable */#else#error"C compiler must support __VA_ARGS__ macro"#endif
here C99 features that support variable parameter macros, such as: #define DEBUG (...) printf (__va_args__), the default number represents a parameter table that can be changed, and when the macro expands, the actual parameters are passed to printf (). Example: Debug ("y =%d\n", y); Replaced by printf ("y =%d\n", y) "Reference http://blog.chinaunix.net/uid-9112803-id-2898026.html"
For brevity, we have autostart_enable to analyze
The final expansion is:
struct const autostart_processes[] = {&hello_world_process, NULL};
hello_world_process is the process struct variable declared above, so autostart_processes (&hello_world_process) is defined as an array, This array defines the process structure body variable pointers for the processes to be self-initiated .
We use an example to illustrate how the process is self-priming.
Source Code $CONTIKI$\PLATFORM\STM32TEST\CONTIKI-MAIN.C
intMain () {Dbg_setup_uart (); printf ("initialising\n"); Clock_init (); Process_init (); Process_start (&etimer_process, NULL); Autostart_start (autostart_processes); printf ("Processes running\n"); while(1) { Do { } while(Process_run () >0); Idle_count++; /*idle!*/ /*Stop Processor Clock*/ /*ASM ("WFI"::);*/ } return 0;}
As you can see, the main function starts the etimer_process process after a series of initializations, and then starts the process that needs to be self-initiated.
We further expand the Autostart_start function, where autostart_processes is an array of the upper declaration definition.
void Autostart_start (structconst processes[]) { int i; for 0; Processes[i]! = NULL; + +i) { process_start (processes[i], NULL); PRINTF ("autostart_start:starting process '%s ' \ n", processes[i]-> name);} }
You can see the process of starting each pointer in the autostart_processes array in turn, where the process_start functions, and so on.
Process_thread
Process_thread (hello_world_process, Ev, data) {...}
static char Process_thread_hello_world_process(struct pt *process_pt, process_event_t ev, process_data_t Data
{
......
}
The process_thread here is to define the process execution body function, which is not the same as above, and above is the declaration of such a function.
In summary, Process_thread has two functions: declaring or defining a process execution principal function
Macro definitions using the Protothread mechanism Process_begin
#define Process_begin () pt_begin (PROCESS_PT)
Where process_pt is the process execution body passed in the parameter struct PT *process_pt. Protothread mechanism
This is the sign of the process starting.
Process_end
#define Process_end () pt_end (PROCESS_PT)
Process End flag.
Note: The process Execution Principal statement should be placed between Process_begin and process_end, or there will be an indeterminate error.
Process_wait_event
#define Process_wait_event () Process_yield ()
The Process Execution entity function returns Pt_yield and waits for the arrival of either event (the process is event driven ), returning back to the location where the process execution principal function last blocked , and continuing with the subsequent statement.
Note: It is known by the protothread mechanism that each time the process entity function is executed, it will run to Process_begin, before jumping.
Process_wait_event_until
#define Process_wait_event_until (c) Process_yield_until (c)
Wait for an event, and attach condition C
Process_yield
#define Process_yield () Pt_yield (PROCESS_PT)
YIELD (waiver of executive power)
Process_yield_until
#define Process_yield_until (c) Pt_yield_until (Process_pt, C)
Yield until condition C is established
Process_wait_until
#define Process_wait_until (c) Pt_wait_until (Process_pt, C)
Wait until the condition C
Process_wait_while
#define Process_wait_while (c) Pt_wait_while (Process_pt, C)
When condition C, wait
Process_exit
#define Process_exit () pt_exit (PROCESS_PT)
Process exit
Process_pt_spawn
#define Process_pt_spawn (PT, thread) pt_spawn (Process_pt, PT, thread)
#define Pt_spawn (PT, child, thread) does { pt_init (child)); Pt_wait_thread ((PT), (THREAD)); while (0)
A child process is produced and blocked until the child process finishes executing , and then continues the execution of the program behind it.
Note: Here to clarify a concept, the process is event-driven, only when an event occurs, the Process Execution entity function will begin to execute, that is, once the block, the execution of the entity function return and exit, then only the event comes, will again enter the process to execute the Entity function, finished Process_ Jump to the blocking position after begin to determine whether to continue blocking.
HelloWorld example Expansion Code GCCC language extension implementation version
#include"contiki.h"#include<stdio.h>/*For printf ()*/
Static CharProcess_thread_hello_world_process (structPT *process_pt, process_event_t ev, process_data_t data);structProcess hello_world_process = {NULL,"Hello World Process", process_thread_hello_world_process};
structProcess *Constautostart_processes[] = {&hello_world_process, NULL};
Static CharProcess_thread_hello_world_process (structPT *process_pt, process_event_t ev, process_data_t data) {{CharPt_yield_flag =1; if(Pt_yield_flag) {;}
Do { if(s! =NULL) { Goto*s; } } while(0) printf ("Hello, world\n."); Pt_yield_flag=0; Pt_init (PT); returnpt_ended; }}
Switch Statement Implementation version
#include"contiki.h"#include<stdio.h>/*For printf ()*/Static CharProcess_thread_hello_world_process (structPT *process_pt, process_event_t ev, process_data_t data);structProcess hello_world_process = {NULL,"Hello World Process", process_thread_hello_world_process};structProcess *Constautostart_processes[] = {&hello_world_process, NULL};Static CharProcess_thread_hello_world_process (structPT *process_pt, process_event_t ev, process_data_t data) {{CharPt_yield_flag =1; if(Pt_yield_flag) {;} Switch(s) { Case 0: printf ("Hello, world\n."); }
Pt_yield_flag=0; Pt_init (PT); returnpt_ended; }}
The related macro definition of the process call Protothread mechanism--interpretation with HelloWorld processes