contiki-断点的保存和恢复

保存断点

  保存断点是通过保存行数来完成的,在被中断的地方插入编译器关键字_LINE_,编译器便自动记录所终端的行数。展开那些具有中断功能的宏,可以发现最后保存行数是宏LC_SET,取宏PROCESS_WAIT_EVENT()为例,将其展开得到如下代码:

/**
 * Wait for an event to be posted to the process.
 *
 * This macro blocks the currently running process until the process
 * receives an event.
 *
 * \hideinitializer
 */
#define PROCESS_WAIT_EVENT()        PROCESS_YIELD()
/**
 * Yield the currently running process.
 *
 * \hideinitializer
 */
#define PROCESS_YIELD()             PT_YIELD(process_pt)
/**
 * Yield from the current protothread.
 *
 * This function will yield the protothread, thereby allowing other
 * processing to take place in the system.
 *
 * \param pt A pointer to the protothread control structure.
 *
 * \hideinitializer
 */
#define PT_YIELD(pt)                \
  do {                        \
    PT_YIELD_FLAG = 0;                \
    LC_SET((pt)->lc);                \
    if(PT_YIELD_FLAG == 0) {            \
      return PT_YIELDED;            \
    }                        \
  } while(0)

//保存程序断点,下次再运行该进程直接跳到case __LINE__
#define LC_SET(s) s = __LINE__; case __LINE__:

LC_SET展开还包含语句case _LINE_,用于下次恢复断点,即下次通过switch语句便可跳转到case的下一句。

恢复断点

  被中断程序再次获得执行权时,便从该进程的函数执行体进入,按照Contiki的编程替换,函数体第一条语句是PROCESS_BEGIN()宏,该宏包含一条switch语句,用于跳转到上一次被中断的行,从而恢复执行,宏PROCESS_BEGIN()展开的源代码如下:

/**
 * Define the beginning of a process.
 *
 * This macro defines the beginning of a process, and must always
 * appear in a PROCESS_THREAD() definition. The PROCESS_END() macro
 * must come at the end of the process.
 *
 * \hideinitializer
 */
#define PROCESS_BEGIN()             PT_BEGIN(process_pt)

/**
 * Declare the start of a protothread inside the C function
 * implementing the protothread.
 *
 * This macro is used to declare the starting point of a
 * protothread. It should be placed at the start of the function in
 * which the protothread runs. All C statements above the PT_BEGIN()
 * invokation will be executed each time the protothread is scheduled.
 *
 * \param pt A pointer to the protothread control structure.
 *
 * \hideinitializer
 */
#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; if (PT_YIELD_FLAG) {;} LC_RESUME((pt)->lc)

#define LC_RESUME(s) switch(s) { case 0:
//switch语句跳转到被中断的行

 

posted @ 2016-11-29 14:56  一只奋斗的考拉  阅读(643)  评论(0编辑  收藏  举报