野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 11167|回复: 10

【STM32时间戳的妙用,ucos 时间戳】如何测量程序的运行时间,精度为ns级别

[复制链接]
发表于 2017-11-17 16:53:26 | 显示全部楼层 |阅读模式
ucos-iii 源码中,有一个功能是测量关中断时间的功能,使用的是STM32的时间戳,即记录程序运行的某个时刻,如果记录下程序前后的两个时刻点,即可以算出这段程序的运行时间。
ucos 时间戳使用的是 Cortex-M内核中的一个时钟计数器来实现的,内核时钟跳动一次,该计数器就加1,精度非常高,决定内核的频率是多少,如果是F103系列,内核时钟是72M,那精度就是1/72M = 14ns,
而程序的运行时间都是微秒级别的,所以14ns的精度是远远够的。

但是有关内核寄存器的描述的资料非常少,还好在arm的官网找到一个,里面有这些内核寄存器的详细描述,其中时间戳相关的寄存器在第10章和11章有详细的描述。

下面的代码是我从ucos-iii里面抽离出来的ucos 时间戳相关的功能代码,测试完全可用,这部分代码可以用来测量程序的运行时间,也可以用来实现us级别的延时。
这个文件是Cortex-M3内核的技术参考手册,里面有内核寄存器的全部描述。
DDI0337E_cortex_m3_r1p1_trm.pdf (2.14 MB, 下载次数: 363) 英文版本 CM3技术参考手册.pdf (1.67 MB, 下载次数: 340) 中文版本
SysTick—系统定时器 STM32 时间戳.7z (179.42 KB, 下载次数: 408)

  1. /*
  2. ************************************************************************************************************************
  3. *                                             时间戳相关寄存器定义
  4. ************************************************************************************************************************
  5. */
  6. /*
  7. 在Cortex-M3里面有一个外设叫DWT(Data Watchpoint and Trace),该外设有一个32位的寄存器叫CYCCNT,它是一个向上的
  8. 计数器,记录的是内核时钟运行的个数,最长能记录的时间为:60s=2的32次方/72000000(假设内核频率为72M,内核跳一次的时间大概为1/72M=14ns)
  9. 当CYCCNT溢出之后,会清0重新开始向上计数。
  10. 使能CYCCNT计数的操作步骤:
  11. 1、先使能DWT外设,这个由另外内核调试寄存器DEMCR的位24控制,写1使能
  12. 2、使能CYCCNT寄存器之前,先清0
  13. 3、使能CYCCNT寄存器,这个由DWT_CTRL(代码上宏定义为DWT_CR)的位0控制,写1使能
  14. */


  15. #define  DWT_CR      *(uint32_t *)0xE0001000
  16. #define  DWT_CYCCNT  *(uint32_t *)0xE0001004
  17. #define  DEM_CR      *(uint32_t *)0xE000EDFC


  18. #define  DEM_CR_TRCENA                   (1 << 24)
  19. #define  DWT_CR_CYCCNTENA                (1 <<  0)


  20. /* 初始化时间戳 */
  21. void CPU_TS_TmrInit(void)
  22. {
  23.     /* 使能DWT外设 */
  24.         DEM_CR |= (uint32_t)DEM_CR_TRCENA;               

  25.         /* DWT CYCCNT寄存器计数清0 */
  26.         DWT_CYCCNT = (uint32_t)0u;
  27.         
  28.         /* 使能Cortex-M3 DWT CYCCNT寄存器 */
  29.     DWT_CR |= (uint32_t)DWT_CR_CYCCNTENA;
  30. }

  31. uint32_t OS_TS_GET(void)
  32. {        
  33.         return ((uint32_t)DWT_CYCCNT);
  34. }

  35. /* CPU相关初始化 */
  36. void  CPU_Init (void)
  37. {
  38.         /* 初始化时间戳 */
  39.         CPU_TS_TmrInit();
  40. }

复制代码



回复

使用道具 举报

发表于 2017-11-17 16:58:53 | 显示全部楼层
火哥厉害了,又学了一招。占楼
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-11-17 17:02:05 | 显示全部楼层
这里面使用的是Cortex-M 内核里面的一个 内核时钟计数器,跟使用TIM,SysTick这些外设不一样,这个内核时钟计数器精度更高,它存在于内核的DWT这个外设中。

DWT的缩写是:Data Watchpoint and Trace,是不是学了这么久STM32,这个外设根本没有听过?

要想使用DWT里面的CYCCNT,还要再使用一个DEMCR这个内核寄存器,DEM是不是也没听说过?
回复 支持 反对

使用道具 举报

发表于 2017-11-17 17:12:22 | 显示全部楼层
顶帖
回复

使用道具 举报

发表于 2017-11-17 17:16:03 | 显示全部楼层
学到了学到了 一定收藏,到时候可以拿出来用
回复 支持 反对

使用道具 举报

发表于 2017-11-17 17:25:28 | 显示全部楼层
学习了,先留个爪印,以后可以拿出来(zhuang)用(bi)
回复 支持 反对

使用道具 举报

发表于 2017-11-17 17:39:17 | 显示全部楼层
嗷。。。。。。。。。。
回复

使用道具 举报

发表于 2017-11-18 11:33:32 | 显示全部楼层
虽然现在看不太懂,但是我以后还会再来看看的
回复 支持 反对

使用道具 举报

发表于 2019-1-17 14:43:12 | 显示全部楼层
mark一下哈哈哈
回复 支持 反对

使用道具 举报

发表于 2019-9-17 18:11:46 | 显示全部楼层
谢谢野火~~
回复

使用道具 举报

发表于 2022-3-30 14:56:49 | 显示全部楼层
不错,学习了。
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-3-28 20:09 , Processed in 0.036043 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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