楼主: dvd1478

[EVAL-WSN]操作系统篇——Contiki分析之etimer

[复制链接]
  • TA的每日心情
    奋斗
    2023-7-8 16:17
  • 签到天数: 971 天

    连续签到: 1 天

    [LV.10]以坛为家III

    发表于 2016-1-16 08:17:35 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 dvd1478 于 2016-1-16 08:20 编辑

    contiki-2.5\core\sys\etimer.c

    1 etimer结构体


    etimer提供一种timer机制产生timed events,可以理解成etimer是Contiki特殊的一种事件。当etimer到期时,会给相应的进程传递事件PROCESS_EVENT_TIMER,从而使该进程启动 。etimer结构体源码如下:
    struct etimer
    {
      struct timer timer;
      struct etimer *next;
      struct process *p;
    };
    struct etimer 继承了struct timer
    /*****timer定义*****/
    struct timer
    {
      clock_time_t start;
      clock_time_t interval;
    };

    typedef unsigned int clock_time_t;


    timer仅包含起始时刻和间隔时间,所以timer只记录到期时间。通过比较到到期时间和新的当前时钟,从而判断该定时器是不是到期。
    1.2 timerlist
    全局静态变量timerlist,指向系统第一个etimer,图示timerlist如下:
    static struct etimer *timerlist;//etimer 链表队列


    1.jpg


    具体的操作如下:

    如下图显示了一个etimer定时器插入前、插入后和超时调用后,这三种情况下etimer链表数据结构。很容易看出,当一个etimer超时并处理后它将从链表中摘除,如果用户需要再次使用该定时器则需要继续调用etimer_set()函数。
    2.jpg
    Etimer的调用时序如下图(etimer调用时序)所示,call_process调用etimer_set()添加一个etimer定时器后,经过interval时长该定时器超时,这里etimer_process向call_process发送超时消息,当call_process接收到超时消息后执行对应的逻辑动作 3.jpg

    2、etimer 代码分析
    Functions called from application programs
    void etimer_set (struct etimer *et, clock_time_t interval)

    Set an event timer.
    void etimer_reset (struct etimer *et)

    Reset an event timer with the same interval as was previously set.
    void etimer_restart (struct etimer *et)

    Restart an event timer from the current point in time.
    void etimer_adjust (struct etimer *et, int td)

    Adjust the expiration time for an event timer.
    clock_time_t etimer_expiration_time (struct etimer *et)

    Get the expiration time for the event timer.
    clock_time_t etimer_start_time (struct etimer *et)

    Get the start time for the event timer.
    int etimer_expired (struct etimer *et)

    Check if an event timer has expired.
    void etimer_stop (struct etimer *et)

    Stop a pending event timer.

    Functions called from timer interrupts, by the system
    void etimer_request_poll (void)

    Make the event timer aware that the clock has changed.
    int etimer_pending (void)

    Check if there are any non-expired event timers.
    clock_time_t etimer_next_expiration_time (void)

    Get next event timer expiration time.





    [EVAL-WSN]操作系统篇——Contiki最简单的实例
    https://www.cirmall.com/bbs/forum.php?mod=viewthread&tid=46018&fromuid=23447

    在process_init初始化后就调用process_start(&etimer_process, NULL);//设置etimer_process 进程

    但关键的分析etimer_process 这个进程,就能明白其原理
    1. <span style="background-color: white;">/*---------------------------------------------------------------------------*/
    2. PROCESS_THREAD(etimer_process, ev, data)
    3. {
    4.     /*
    5.     进程退出时,需向所有进程(当然也包括etimer_process)发送事件PROCESS_EVENT_EXITED。
    6.     etimer_process收到该事件,就会遍历timerlist,并把与该退出进程相关的etimer从timerlist删除。
    7.     紧接着,遍历timerlist,检查etimer是否有到期的,凡有timer到期就把事件PROCESS_EVENT_TIMER
    8.     加入到事件队列中,并将该etimer成员变量p指向PROCESS_NONE。在这里,PROCESS_NONE用于标识
    9.     该etimer是否到期,即由etimer_expired函数根据etimer的p是否指向PROCESS_NONE来判断该etimer是否到期
    10.     */
    11.     struct etimer *t, *u;

    12.     PROCESS_BEGIN();

    13.     timerlist = NULL;

    14.     while(1) {
    15.         PROCESS_YIELD();/*进程主动让出执行权 : 首次运行,或者已经处理所有工作*/
    16.         /* 进程退出时,需向所有进程(当然也包括etimer_process)发送事件PROCESS_EVENT_EXITED。
    17.         etimer_process收到该事件,就会遍历timerlist,并把与该退出进程相关的etimer从timerlist删除 */
    18.         if(ev == PROCESS_EVENT_EXITED) {
    19.             struct process *p = data;/* 此时通过data传递将要退出的进程,data是void *类型 */

    20.             /* 遍历timerlist,查找是否有etimer绑定该退出进程 */
    21.             while(timerlist != NULL && timerlist->p == p) {
    22.                 timerlist = timerlist->next;
    23.             }

    24.             /* 有etimer绑定该退出进程,将etimer从timerlist删除 */
    25.             if(timerlist != NULL) {
    26.                 t = timerlist;
    27.                 while(t->next != NULL) {
    28.                     if(t->next->p == p) {
    29.                         t->next = t->next->next;
    30.                     } else
    31.                         t = t->next;
    32.                 }
    33.             }
    34.             continue;/* 删除所有与退出进程绑定的etimer */
    35.         } else if(ev != PROCESS_EVENT_POLL) {
    36.             continue;
    37.         }

    38. again:

    39.         u = NULL;
    40.         /*遍历timerlist*/
    41.         for(t = timerlist; t != NULL; t = t->next) {
    42.             if(timer_expired(&t->timer)) {/* 检查该etimer的timer是不是到期,返回1表示过期 */
    43.                 if(process_post(t->p, PROCESS_EVENT_TIMER, t) == PROCESS_ERR_OK) {
    44.                     /* 把事件PROCESS_EVENT_TIMER加入到事件队列 */
    45.                     /* Reset the process ID of the event timer, to signal that the
    46.                        etimer has expired. This is later checked in the
    47.                        etimer_expired() function. */
    48.                     /* 成功加入事件队列 */
    49.                     t->p = PROCESS_NONE; /*如果etimer的p指向的是PROCESS_NONE,则表示该etimer已到期。用于后续etimer_expired()函数判断该etimer是否到期,etimer_expired() */
    50.                     if(u != NULL) {
    51.                         u->next = t->next;
    52.                     } else {
    53.                         timerlist = t->next;
    54.                     }
    55.                     t->next = NULL;
    56.                     update_time();/* 求出下一个到期时间next_expiration (全局静态变量),即还有next_expiration时间,就有timer到期 */
    57.                     goto again;
    58.                 } else {
    59.                     etimer_request_poll(); /* 若加入事件PROCESS_EVENT_TIMER出错(可能是事件队列已满),执行etimer_request_poll(),即process_poll(&etimer_process),使其有更高的优先级 */
    60.                 }
    61.             }
    62.             u = t;
    63.         }

    64.     }

    65.     PROCESS_END();
    66. }</span>
    复制代码
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2016-8-15 09:28
  • 签到天数: 222 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2016-1-18 16:36:43 | 显示全部楼层
    好高级!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2023-7-24 08:00
  • 签到天数: 946 天

    连续签到: 1 天

    [LV.10]以坛为家III

    发表于 2016-2-20 08:10:50 | 显示全部楼层
    真的太给力了,我也在学习。
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    手机版|小黑屋|与非网

    GMT+8, 2024-4-23 16:14 , Processed in 0.136770 second(s), 19 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.