Contiki操作系统最大的特点(对于嵌入式系统也是最大的优点)是它支持protothread进程,这样一来多个进程可以共享一个栈,以达到最大限度节省内存的目的。
Protothread是用一系列的宏定义API来实现的,不过,做为一个成熟的程序员,我们还是需要了解这些API后面的“真面目”,只有这样才能深入理解protothread的工作原理,同时才能开发正确高效的程序。
现在贴出一个protothread代码和预编译后的C代码,让我们一起看看它是怎样实现的。为了保证正确性,这两份代码都在Contiki-V2.7系统中编译和调试通过。
一个细节:预编译后的C代码中的case (__LINE__ - 1)为什么要添加“减一”呢?答案在本博客的最后面哦。
/*------------------------------------- Contiki Codes --------------------------------------*/
PROCESS(hello_world_process, "Hello world process");
AUTOSTART_PROCESSES(&hello_world_process);
PROCESS_THREAD(hello_world_process, ev, data)
{
clock_time_t tClock;
static struct etimer timer;
PROCESS_BEGIN();
etimer_set(&timer, CLOCK_CONF_SECOND / 2); /* 500ms */
while (1)
{
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
tClock = clock_time();
PRINT_STR("Hello, world! ");
PRINTF(NULL, tClock, PRINTF_FORMAT_DEC);
PRINT_STR("\r\n");
etimer_reset(&timer);
}
PROCESS_END();
}
/*------------------------------------- Convert to C Codes --------------------------------------*/
static char
process_thread_hello_world_process( struct pt *process_pt,
process_event_t ev,
process_data_t data );
struct process hello_world_process =
{
NULL,
"Hello world process",
process_thread_hello_world_process
};
struct process * const autostart_processes[] =
{
&hello_world_process,
NULL
};
static char
process_thread_hello_world_process( struct pt *process_pt,
process_event_t ev,
process_data_t data )
{
clock_time_t tClock;
static struct etimer timer;
{
char PT_YIELD_FLAG = 1;
if (PT_YIELD_FLAG)
{
;
}
switch ((process_pt)->lc)
{
case 0:
etimer_set(&timer, CLOCK_CONF_SECOND / 2); /* 500ms */
while (1)
{
do
{
PT_YIELD_FLAG = 0;
(process_pt)->lc = __LINE__;
case (__LINE__ - 1):
if ((PT_YIELD_FLAG == 0) || !(ev == PROCESS_EVENT_TIMER))
{
return PT_YIELDED;
}
} while(0);
tClock = clock_time();
PRINT_STR("Hello, world! ");
PRINTF(NULL, tClock, PRINTF_FORMAT_DEC);
PRINT_STR("\r\n");
etimer_reset(&timer);
}/*while*/
}/*switch*/
PT_YIELD_FLAG = 0;
(process_pt)->lc = 0;
return PT_ENDED;
}
}
答案:对于C编译器,__LINE__总是代表当前行数。case语句中的行数必须与前一句代码 (process_pt)->lc = __LINE__中的__LINE__是同一个数值,否则将无法正确运行,2个__LINE__相差为1,所以要减一。