Okay, I studied the underlying implementation principle of switch () last night. I found that it is not as mentioned in C language textbooks. Of course, this is for those who are very familiar with assembly, is a piece of cake. In the world, many things are a combination of coincidence and necessity. There is no love for no reason or hate for no reason.-Why am I blocked by a switch? What is the important role of this switch in contiki? Without answering this question, let's take a look at how to use the process_yield () macro expanded last night.
Note: Here we only paste the printed information, analyze the printed information, and no longer paste the code in the analysis process.
One, modify your own hello-world.c file content is as follows:
1 #include "contiki.h" 2 3 #include <stdio.h> /* For printf() */ 4 /*---------------------------------------------------------------------------*/ 5 PROCESS(hello_world_process, "Hello world process"); 6 PROCESS(test_process, "test process"); 7 //AUTOSTART_PROCESSES(&hello_world_process); 8 AUTOSTART_PROCESSES(&hello_world_process, &test_process); 9 /*---------------------------------------------------------------------------*/10 PROCESS_THREAD(hello_world_process, ev, data)11 {12 printf("\n\ntest hello_process...\n\n");13 PROCESS_BEGIN();14 PROCESS_YIELD();15 16 printf("Hello, world\n");17 18 PROCESS_END();19 }20 /*---------------------------------------------------------------------------*/21 PROCESS_THREAD(test_process, ev, data)22 {23 printf("\n\ntest test_process..\n\n");24 PROCESS_BEGIN();25 26 printf("Haha, only test\n");27 28 PROCESS_END();29 }
Note: The above Code adds a new test_process on hello_process. This test_process is used to print a Chinese "Haha", not "Hello World ".
As a result, 6th rows and 21st ~ are added ~ 29 rows, modified 8th rows. For testing purposes, the printf () Statement is added to both process function bodies before process_begin. The code is very simple.
2. Implement your own contiki-main.c Functions
This is implemented in contiki-2.6/platform/native. Just back up the original contiki-main.c.
1 #include <stdio.h> 2 #include <string.h> 3 #include "contiki.h" 4 5 int 6 main(int argc, char **argv) 7 { 8 9 process_init();10 11 autostart_start(autostart_processes);12 13 return 0;14 }15
Very simple, initialize the process, and then automatically start the two processes in the hello-world.c.
<Ps: At the same time, I went to process to make it clearer. c/Pt. some printf () are added to the H file. For example, in some functions, I will add printf ("\ n % s, % d \ n" ,__ func __, __line _); of course, some other printf () content is not detailed. Therefore, some more content will be printed below.>
3, make, execute hello-world.native
1 ./hello-world.native 2 3 process_init, 222 4 5 process_start,105 6 7 call_process, 187 8 9 10 test hello_process...11 12 13 PT_YIELD_FLAG = 014 PT_EXITED = 2, PT_ENDED = 3, PROCESS_EVENT_EXIT = 131,PT_YIELDED = 1, ret = 115 16 process_start,10517 18 call_process, 18719 20 21 test test_process..22 23 Haha, only test24 process end: PT_YIELD_FLAG = 025 PT_EXITED = 2, PT_ENDED = 3, PROCESS_EVENT_EXIT = 131,PT_YIELDED = 1, ret = 326 27 exit_process,13528 exit_process, 155, and call call_process()29 30 call_process, 18731 32 33 test hello_process...34 35 36 PT_YIELD_FLAG = 137 Hello, world38 process end: PT_YIELD_FLAG = 039 PT_EXITED = 2, PT_ENDED = 3, PROCESS_EVENT_EXIT = 131,PT_YIELDED = 1, ret = 340 41 exit_process,13542 exit_process, 155, and call call_process()43 44 call_process, 18745 46 exit_process, 178 ok exit...47 48 exit_process, 178 ok exit...
1. Execute process_init () in the third row ----> main.
2. Execute autostart_start (autostart_processes) In line 2 ----> main. Then the entire function will call the process_start () function in a ().
3, Row 3 ----> after process_start (), the process processing function will be involved. Now call_process is available, which means you are ready to call a process.
4, Row 3 ---> under the action of call_process (), we started executing our own hello_process. The hello_process function is started here.
5, Row 3 ---> the value of (char) pt_yield_flag is 0. In fact, this has already been executed to the process_yield () macro in hello_process. This macro has been expanded above -- If pt_yield_flag is 0, A (pt_yielded = 1) will be returned directly without executing the following code. Note that the process_yield () macro is located behind the process_begin () Macro. In process_begin (), the pt_yield_flag has been initialized to 1. However, process_yield () is forcibly set to 0 again. Of course, process_yield also saves the number of rows in the current row, which is achieved through the macro "_ line.
6, row 14th ---> As mentioned in point 5th, after calling the hello_process () function, call_process gets a return value (pt_yielded = 1) because of the role of process_yield () Macro).
7, 16th rows, 18th rows --> re-opened the execution of process_start and call_process. This is actually starting to call the next process. It can be seen from this that "Hello World" in hello_process is not executed, and the CPU right is immediately given to the next process ---> similar to hello_process ~~
Line 8 ---> enters the function body of the Process test_process. I didn't use process_yield () macro again in test_process, so I ran out of test_process. After the execution is complete, write pt_yielded to 0, which is completed in the process_end () Macro.
9, Row 27 ---> after test_process is executed, it enters the exit stage, prepares to release its own resources, and hand over control of the CPU.
10, row 28th --> in the exit stage, test_process will give the CPU control to the next adjacent process --> Of course, the best way is to start this process. As you can see, in the exit stage, call_process is used again. Of course, the adjacent process of test_process is hello_process, so hello_process is started directly. It seems that test_process only gives control of CPU at exit, but does it actually exit? --> that is, all resources are released, no longer in use?
Lines 11, 30th, and 33 indicate that the program enters hello_process --> that is, hello_process is executed again. What is the result?
Row 12 and row 3: In the macro process_yield (), the value of pt_yield_flag is 1, and the following code is executed. It must be noted that process_yield () contains a case statement that matches the switch in the process_begin () Macro. The working principle is actually similar to a GOTO statement. This is explained in the previous note and will not be repeated.
Lines 13, 37th and 39 are boring and there is no need to talk about it again.
14, Row 3 --> hello_process is ready to exit.
Lines 15, 42nd, and 44 are a process of handing over CPU control. However, it seems that hello_process finds that its adjacent process is null, so when it gets angry, it simply exits, including control and resources. Why is the adjacent process of hello_process null? Because process_list is a linked list, the terminal of the linked list points to null, which determines its fate in process_init.
Lines 16, 46th, and 48 were exited twice, which surprised me and I didn't understand it yet. .
PS: I used to draw the entire process using a flowchart in this note. However, I did not know why I would execute the process twice due to the 46,48 line, the image will not be painted for the moment. I will study it first.
Paste it and expand the Code:
1 static char process_thread_hello_world_process(struct pt *process_pt, process_event_t ev, process_data_t data) 2 { 3 printf("\ntest hello process!\n"); 4 char PT_YIELD_FLAG = 1; 5 if (PT_YIELD_FLAG) {;} 6 switch((process_pt) -> lc) { 7 case 0: 8 do { 9 PT_YIELD_FLAG = 0;10 (process_pt)->lc = __LINE__;11 case __LINE__:12 if(PT_YIELD_FLAG == 0) {13 return PT_YIELDED;14 } 15 }while(0); 16 17 printf("Hello world ! \n");18 };19 PT_YIELD_FLAG = 0;20 process_pt->lc = 0;21 return PT_ENDED;22 }
In this macro development code, the switch usage is very strange, but it is correct. The principle has been clarified in the previous note.
Okay, that's all.
If a friend sees the error, correct it. Thank you! Communicate, learn, and make progress together.
Email: [email protected]
Process_yield () macro usage and Process Analysis <8 of contiki Study Notes>