搜索
bottom↓
回复: 2

如何获取启动到现在CPU经过的周期数?

[复制链接]

出0入0汤圆

发表于 2012-9-26 10:01:53 | 显示全部楼层 |阅读模式
现在我是用SysTick实现的,但是发现偶尔会出现返回的周期数比上一次小的情况!不知道是哪里出了问题,请大家帮我看一下,谢谢!

这是SysTick中断处理函数
  1. /* sys tick handler */
  2. #define TICK_PERIOD_MS  256
  3. static unsigned long _clock_per_tick = 0;
  4. static volatile unsigned long _ms;
  5. void systick_handler(void)
  6. {
  7.         _ms += TICK_PERIOD_MS;
  8. }

  9. /* get current CPU cycle */
  10. uint64_t get_cycle()
  11. {
  12. #ifdef DEBUG
  13.         static int64_t last_cycle = 0;
  14. #endif
  15.         uint32_t ms, ms_before, ms_after, st_cur, st_ctrl;
  16.         int64_t cycle;
  17.         ms_before = _ms;
  18.         st_cur = HWREG(NVIC_ST_CURRENT);
  19.         st_ctrl = HWREG(NVIC_ST_CTRL);
  20.         ms_after = _ms;
  21.         if ( (_clock_per_tick - st_cur) < 32768 )
  22.                 ms = ms_after;/* Maybe _ms has been changed after we first read it */
  23.         else
  24.                 ms = ms_before;
  25.         if ( (st_ctrl & NVIC_ST_CTRL_ENABLE) == 0 )
  26.                 return 0;
  27.         if ( (st_ctrl & NVIC_ST_CTRL_COUNT) != 0 )
  28.                 ms += TICK_PERIOD_MS;
  29.         cycle = (int64_t)(ms / TICK_PERIOD_MS) * (int64_t)_clock_per_tick
  30.                 + (int64_t)(_clock_per_tick - 1 - st_cur);
  31. #ifdef DEBUG
  32.         if ( cycle < last_cycle ) {
  33.                 while ( 1 ) {};
  34.         }
  35.         last_cycle = cycle;
  36. #endif
  37.         return cycle;
  38. }
复制代码
主程序中这样初始化SysTick
  1.         /* Set the clocking to run at 50MHz from the PLL. */
  2.         SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_8MHZ);

  3.         /* Enable all processor interrupts. */
  4.         IntPrioritySet(FAULT_SYSTICK, 0x20);
  5.         IntPrioritySet(INT_ETH, 0xff);
  6.         IntMasterEnable();
  7.         IntEnable(FAULT_MPU);
  8.         IntEnable(FAULT_BUS);
  9.         IntEnable(FAULT_USAGE);

  10.         /* Initialize SysTick */
  11.         /* _clock_per_tick = (uint32_t)((uint64_t)SysCtlClockGet() * (uint64_t)TICK_PERIOD_MS / 1000); */
  12.         _clock_per_tick = TICK_PERIOD_MS * (SysCtlClockGet() / 1000);
  13.         SysTickPeriodSet(_clock_per_tick);
  14.         SysTickEnable();
  15.         SysTickIntEnable();
复制代码

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

 楼主| 发表于 2012-9-26 15:43:49 | 显示全部楼层
发现上面的函数只要把以太网打开并使能以太网中断处理,连续调用get_cycle就有可能出现返回值比上一次的小的情况。
但是我明明设置了以太网中断的优先级为0xff,而SYSTICK优先级为0x20,以太网中断应该不会抢占SysTick中断呀?

出0入0汤圆

 楼主| 发表于 2012-9-27 13:39:49 | 显示全部楼层
应该是我在中断中又调用了get_cycle,导致这个函数重入,而中断中的调用在时间上是后调用但是先返回,而主程序中的调用时先调用(然后被中断抢占)后返回,因此造成了时间回退的假象!

回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-6-6 16:00

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表