解析Contiki系统protothread的预编译C代码

来源:互联网 发布:修车技术资料大全软件 编辑:程序博客网 时间:2024/05/22 14:16

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,所以要减一。

 


0 0