说明: 本文依赖于 contiki/platform/native/contiki-main.c 文件。
在项目工程目录下的hello-world.c 文件里面,有许多的宏,但没有最关键的main()函数出现,也无法知道这个 文件里的 "hello world"什么时候打印。那么只能根据makefile文件的框架和提示,进入到 contiki/platform/ 目录下一探明白。由于前面选择的是 contiki/examples/hello-world/ 目录下的工程进行学习,那么这里也就进入到 contiki/platform/native/ 目录下并使用 find 命令查找下 main()即可:
1 find -name "*.c" | xargs grep "main"
当然,它存在于 contiki-main.c 这个文件中。下面将使用最廉价的printf() 来调试程序了。
-----------------------------------------------------------------------
注: 我暂时只关心 contiki-main.c文件中的 main() 函数。
------------------------------------------------------------------------
添加printf()如下:
1 int 2 main(int argc, char **argv) 3 { 4 #if UIP_CONF_IPV6 5 #if UIP_CONF_IPV6_RPL 6 printf(CONTIKI_VERSION_STRING " started with IPV6, RPL "); 7 #else 8 printf(CONTIKI_VERSION_STRING " started with IPV6 "); 9 #endif 10 #else 11 printf(CONTIKI_VERSION_STRING " started "); 12 #endif 13 14 /* crappy way of remembering and accessing argc/v */ 15 contiki_argc = argc; 16 contiki_argv = argv; 17 18 /* native under windows is hardcoded to use the first one or two args */ 19 /* for wpcap configuration so this needs to be "removed" from */ 20 /* contiki_args (used by the native-border-router) */ 21 #ifdef __CYGWIN__ 22 contiki_argc--; 23 contiki_argv++; 24 #ifdef UIP_FALLBACK_INTERFACE 25 contiki_argc--; 26 contiki_argv++; 27 #endif 28 #endif 29 30 printf("contiki-main_function!--> "); 31 process_init(); 32 printf("process init over!------> "); 33 process_start(&etimer_process, NULL); 34 printf("process_start now-------> "); 35 ctimer_init(); 36 printf("ctimer_init()-----------> "); 37 rtimer_init(); 38 printf("rtimer_init()-----------> "); 39 40 #if WITH_GUI 41 process_start(&ctk_process, NULL); 42 #endif 43 44 printf("set_rime_addr()--------> "); 45 set_rime_addr(); 46 47 printf("netstack_init()--------> "); 48 netstack_init(); 49 printf("MAC %s RDC %s NETWORK %s ", NETSTACK_MAC.name, NETSTACK_RDC.name, NETSTACK_NETWORK.name); 50 51 #if WITH_UIP6 52 queuebuf_init(); 53 54 memcpy(&uip_lladdr.addr, serial_id, sizeof(uip_lladdr.addr)); 55 56 process_start(&tcpip_process, NULL); 57 #ifdef __CYGWIN__ 58 process_start(&wpcap_process, NULL); 59 #endif 60 printf("Tentative link-local IPv6 address "); 61 { 62 uip_ds6_addr_t *lladdr; 63 int i; 64 lladdr = uip_ds6_get_link_local(-1); 65 for(i = 0; i < 7; ++i) { 66 printf("%02x%02x:", lladdr->ipaddr.u8[i * 2], 67 lladdr->ipaddr.u8[i * 2 + 1]); 68 } 69 /* make it hardcoded... */ 70 lladdr->state = ADDR_AUTOCONF; 71 72 printf("%02x%02x ", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]); 73 } 74 #else 75 process_start(&tcpip_process, NULL); 76 #endif 77 78 printf("serial_line_init()-----------> "); 79 serial_line_init(); 80 81 printf("autostart_start()-=----------> "); 82 autostart_start(autostart_processes); 83 84 /* Make standard output unbuffered. */ 85 setvbuf(stdout, (char *)NULL, _IONBF, 0); 86 87 select_set_callback(STDIN_FILENO, &stdin_fd); 88 // while(1) { 89 printf("loop.... "); 90 fd_set fdr; 91 fd_set fdw; 92 int maxfd; 93 int i; 94 int retval; 95 struct timeval tv; 96 97 retval = process_run(); 98 99 tv.tv_sec = 0; 100 tv.tv_usec = retval ? 1 : 1000; 101 102 FD_ZERO(&fdr); 103 FD_ZERO(&fdw); 104 maxfd = 0; 105 for(i = 0; i <= select_max; i++) { 106 if(select_callback[i] != NULL && select_callback[i]->set_fd(&fdr, &fdw)) { 107 maxfd = i; 108 } 109 } 110 111 retval = select(maxfd + 1, &fdr, &fdw, NULL, &tv); 112 if(retval < 0) { 113 if(errno != EINTR) { 114 perror("select"); 115 } 116 } else if(retval > 0) { 117 /* timeout => retval == 0 */ 118 for(i = 0; i <= maxfd; i++) { 119 if(select_callback[i] != NULL) { 120 select_callback[i]->handle_fd(&fdr, &fdw); 121 } 122 } 123 } 124 printf("etimer_request_poll!-------------> "); 125 etimer_request_poll(); 126 127 #if WITH_GUI 128 if(console_resize()) { 129 ctk_restore(); 130 } 131 #endif /* WITH_GUI */ 132 // } 133 printf("main_function over....---> "); 134 135 return 0; 136 }
上面是我自己修改后的 main()函数,然后make运行后的结果如下:
1 $./hello-world.native 2 Contiki-2.6-1549-g01bd045 started 3 contiki-main_function!--> 4 process init over!------> 5 process_start now-------> 6 ctimer_init()-----------> 7 rtimer_init()-----------> 8 set_rime_addr()--------> 9 Rime started with address 2.1 10 netstack_init()--------> 11 MAC nullmac RDC nullrdc NETWORK Rime 12 serial_line_init()-----------> 13 autostart_start()-=----------> 14 Hello, world 15 loop.... 16 etimer_request_poll!-------------> 17 main_function over....--->
从上面的打印信息来看,hello world 打印是在执行了下面这行代码后出现的:
1 autostart_start(autostart_processes);
既然如此,那就开始了---看看它们的流程。