免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1398 | 回复: 0
打印 上一主题 下一主题

The accuracy of gettimeofday in ARM architecture [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-08-10 11:28 |只看该作者 |倒序浏览

                                                In the time subsystem, gettimeofday() always return current wall time. The wall time is expected to record the real world time. But in arm architecture, it happily gives you a biased wall time. When time goes on, the value is far from the real world time.
Lets look at how gettimeofday() is implemented. Firstly gettimeofday() is called in the user application. And then:
1. it calls sys_gettimeofday() in the kernel space
   
   ...
   /* load registers(R0, R1) with respective arguments */
   swi  __NR_GETTIMEOFDAY
   ...
2. sys_gettimeofday() calls do_gettimeofday()
   ...
   if (likely(tv != NULL)) {
       struct timeval  ktv;
       do_gettimeofday(&ktv);
       ...
   }
   ...
3. do_gettimeofday() is implemented in the specific architecture. In this article  
   it is discussed in the ARM architecture
   /* arch/arm/kernel/time.c */
   #ifndef  CONFIG_GENERIC_TIME
   void do_gettimeofday(struct timeval *ktv)
   {
      ...
   }
   #endif
   CONFIG_GENERIC_TIME means the time subsystem uses a classic time subsystem
   (please refer to relative documents). Now lets look at the code
   in do_gettimeofday()
   ...
   do {
      seq = read_seqbegin_irqsave(&xtime_lock, flags);
      usec = systme_timer->offset();
      sec = xtime.tv_sec;
      usec += xtime.tv_nsec / 1000;
   } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
   ...
   system_timer refers to specific ARM MCU, such as s3c2410, at91sam9263 etc.
4. Now the control is transferred to at91sam926x_time.c(e.g. at91sam9263). In
   this MCU, the linux system is drived by a PIT, which is very simple hardware
   implementation.
   struct sys_timer at91sam926x_timer = {
      .init    = at91sam926x_timer_init,
      .offset  = at91sam926x_timer_offset,
      ...
   };
   at91sam926x_timer is assigned to system_timer in arch/arm/kernel/setup.c
   So time offset is calculated with at91sam926x_timer_offset().
   static unsigned long at91sam926x_timer_offset(void)
   {
      ...
      unsigned long t = at91_sys_read(AT91_PIT_PIIR);
      elapsed = (PIT_PICNT(t) * LATCH) + PIT_CPIV(t);
      return  (unsigned long)(elapsed * jiffes_to_usec(1) / LATCH);
   }
From the above codes, it seems that when user call gettimeofday(), he/she should get the real world time. The time is:
  last_time = xtime when last tick occurs
  current_time = last_time + elapsed_time after last_time
Note: AT91_PIT_PIIR records the elapsed time. Please refer to AT91SAM9263 datasheet
But the time De facto is slower than the real world time.

Why?
(to be continue...)
               
               
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/103132/showart_2023144.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP