uC/OS 时间戳和时间戳的使用

2023-05-16

声明:所有uC/OS代码均来自于官方uC/OS内核

关于时间戳,首先要明白一点:时间戳是一个计数器,且记录的是内核的HCLK运行的个数。

看代码

时间戳(time stamp)即TS.

时间戳的初始化代码在函数void  CPU_Init (void);

#define  DEF_DISABLED                                      0u
#define  DEF_ENABLED                                       1u

#if    ((CPU_CFG_TS_32_EN == DEF_ENABLED) || \
        (CPU_CFG_TS_64_EN == DEF_ENABLED))
#define  CPU_CFG_TS_EN                          DEF_ENABLED
#else
#define  CPU_CFG_TS_EN                          DEF_DISABLED
#endif


void  CPU_Init (void)
{
                                                         
#if ((CPU_CFG_TS_EN     == DEF_ENABLED) || \
     (CPU_CFG_TS_TMR_EN == DEF_ENABLED))

    CPU_TS_Init();                                           
#endif
……
}

时间戳的初始化:CPU_TS_Init();

#if ((CPU_CFG_TS_EN     == DEF_ENABLED) || \
     (CPU_CFG_TS_TMR_EN == DEF_ENABLED))
static  void  CPU_TS_Init (void)
{
#if (((CPU_CFG_TS_32_EN    == DEF_ENABLED     )  && \
      (CPU_CFG_TS_TMR_SIZE <  CPU_WORD_SIZE_32)) || \
     ((CPU_CFG_TS_64_EN    == DEF_ENABLED     )  && \
      (CPU_CFG_TS_TMR_SIZE <  CPU_WORD_SIZE_64)))
    CPU_TS_TMR  ts_tmr_cnts;
#endif


                                                                /* ----------------- INIT CPU TS TMR ------------------ */
#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
    CPU_TS_TmrFreq_Hz   = 0u;                                   /* Init/clr     ts tmr freq (see Note #1a).             */
	/*时间戳定时器初始化函数*/
    CPU_TS_TmrInit();                                           /* Init & start ts tmr      (see Note #1b).             */
#endif

……

}

继续深入void  CPU_TS_TmrInit (void);

#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
void  CPU_TS_TmrInit (void)
{
    CPU_INT32U  fclk_freq;


    fclk_freq = BSP_CPU_ClkFreq();//获取HCLK频率HCLK_Frequency
		/*启用DWT外设*/
    CPU_REG_DEM_CR     |= (CPU_INT32U)CPU_BIT_DEM_CR_TRCENA;    /* Enable Cortex-M4's DWT CYCCNT reg.                   */
    CPU_REG_DWT_CYCCNT  = (CPU_INT32U)0u;//清理DWT cyccnt
	/*当使用硬件全速运行时,会先停在这里,需要手动运行才能跳过,但是当使用硬件仿真时却不会*/
	
    CPU_REG_DWT_CR     |= (CPU_INT32U)CPU_BIT_DWT_CR_CYCCNTENA;// 启用Cortex-M4's DWT CYCCNT寄存器

    CPU_TS_TmrFreqSet((CPU_TS_TMR_FREQ)fclk_freq);
}
#endif

首先DWT(Data Watchpoint and Trace)作用为使能DWT CYCCNT reg,即使能CYCCNT寄存器

然后清零    CPU_REG_DWT_CYCCNT  = (CPU_INT32U)0u;

再启用Cortex-M4's DWT CYCCNT寄存器 

CPU_REG_DWT_CR     |= (CPU_INT32U)CPU_BIT_DWT_CR_CYCCNTENA;

然后获取HCLK频率HCLK_Frequency fclk_freq = BSP_CPU_ClkFreq();

CPU_INT32U  BSP_CPU_ClkFreq (void)
{
    RCC_ClocksTypeDef  rcc_clocks;

    RCC_GetClocksFreq(&rcc_clocks);
    return ((CPU_INT32U)rcc_clocks.HCLK_Frequency);
}

其中函数RCC_GetClocksFreq(&rcc_clocks)为将芯片内各模块的时钟频率保存在参数RCC_Clocks中,包含SYSCLK、HCLK、PCLKx、ADCCLK时钟频率值

void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)
{
……
}
typedef struct
{
  uint32_t SYSCLK_Frequency; //!<  SYSCLK clock frequency expressed in Hz 
  uint32_t HCLK_Frequency;   //!<  HCLK clock frequency expressed in Hz   
  uint32_t PCLK1_Frequency;  //!<  PCLK1 clock frequency expressed in Hz  
  uint32_t PCLK2_Frequency;  //!<  PCLK2 clock frequency expressed in Hz  
}RCC_ClocksTypeDef;

至此,完成获取HCLK频率HCLK_Frequencyfclk_freq = BSP_CPU_ClkFreq();

再继续深入:    CPU_TS_TmrFreqSet((CPU_TS_TMR_FREQ)fclk_freq);

#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
void  CPU_TS_TmrFreqSet (CPU_TS_TMR_FREQ  freq_hz)
{
    CPU_TS_TmrFreq_Hz = freq_hz;
}
#endif

其中

typedef  unsigned  int         CPU_INT32U;    

#define  CPU_CORE_EXT  extern

typedef  CPU_INT32U  CPU_TS_TMR_FREQ;

CPU_CORE_EXT  CPU_TS_TMR_FREQ  CPU_TS_TmrFreq_Hz;

即:extern   unsigned  int   CPU_TS_TmrFreq_Hz;

也就是定义了一个全局变量,且该全局变量通过

fclk_freq = BSP_CPU_ClkFreq();//获取HCLK频率HCLK_Frequency

CPU_TS_TmrFreqSet((CPU_TS_TMR_FREQ)fclk_freq);

赋值为HCLK_Frequency;

至此 时间戳初始化完毕

下面该使用他了:

 //其中uint32_t TimeStart = 0,TimeEnd = 0 ,TimeUse = 0;是全局变量

TimeStart = OS_TS_GET();		
Delay_Ms( 20 );
TimeEnd = OS_TS_GET();
TimeUse = (TimeEnd - TimeStart) / ( 72000000 / 1000 );  单位为ms 

其中OS_TS_GET()为:

#if      OS_CFG_TS_EN == 1u
#define  OS_TS_GET()               (CPU_TS)CPU_TS_TmrRd()   /* See Note #2a.                                          */
#else
#define  OS_TS_GET()               (CPU_TS)0u
#endif

其中函数CPU_TS_TmrRd():

#define  CPU_REG_DEM_CR                       (*(CPU_REG32 *)0xE000EDFC)//使能DWT外设
#define  CPU_REG_DWT_CR                       (*(CPU_REG32 *)0xE0001000)//使能Cortex-M3 DWT CYCCNT寄存器 
#define  CPU_REG_DWT_CYCCNT                   (*(CPU_REG32 *)0xE0001004)//时间戳计数器变量向上计数
typedef  CPU_INT32U  CPU_TS_TMR;
#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
CPU_TS_TMR  CPU_TS_TmrRd (void)
{
    CPU_TS_TMR  ts_tmr_cnts;


    ts_tmr_cnts = (CPU_TS_TMR)CPU_REG_DWT_CYCCNT;

    return (ts_tmr_cnts);
}
#endif

至此时间戳讲解完毕,写文章不易,记得一键三连

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

uC/OS 时间戳和时间戳的使用 的相关文章

  • 普通用户使用docker命令

    普通用户使用docker命令 add docker group sudo cat etc group docker sudo groupadd g 999 docker add user to docker group sudo gpass
  • samba服务器

    samba服务器 install samba edit etc samba smb conf default comment 61 default path 61 opt es backups valid users 61 zsk13 wr
  • linux安装mongodb

    install mongodb tar zxvf mongodb linux x86 64 4 0 22 tgz useradd mongod init passwd with mongod passwd mongod mkdir for
  • linux制作iso启动盘

    制作iso启动盘 sudo fdisk l umount dev sdb umount dev sdb1 umount dev sdd2 umount dev sdd3 sudo mkfs ext4 dev sdb sudo dd if 6
  • ros2+opencv抓取rtsp视频流

    遇到的坑 xff1a rtsp视频流和转ros2 topic放到一个线程里 xff0c 频繁提示解码丢帧的情况 解决这个问题需要将opencv获取rtsp视频流单独开一个线程 xff0c 不能在里面处理任何多余的代码 代码如下 xff1a
  • 机械臂标定实战

    硬件资源 xff1a 机械臂viper300 摄像头realsense d435i 软件版本 xff1a 操作系统 xff1a Ubuntu18 04 ROS Melodic 标定算法 xff1a 采用easy handeye 算法包 ht
  • Linux 下的 Docker 安装及创建私有仓(三)

    Linux 下的 Docker 安装及创建私有仓 xff08 三 xff09 辛苦打工人 xff0c 今天继续搬砖 xff0c 搞搞私有仓用户和密码 废话不说 xff0c 开工 xff01 1 安装httpd tools 授权需要用到 xf
  • .Net Core Web API 发布到Linux Docker(一)

    Net Core Web API 发布到Linux Docker xff08 一 xff09 Net Core Web API 项目已经建好 xff0c 想要发布到Linux Docker 上 xff0c 具体研究了一下 xff0c 发现有
  • 设置mysql允许外网访问

    mysql的root账户 我在连接时通常用的是localhost或127 0 0 1 公司的测试服务器上的mysql也是localhost所以我想访问无法访问 测试暂停 解决方法如下 1 修改表 登录mysql数据库 切换到mysql数据库
  • .Net Core Web API 发布到Linux Docker(二)

    Net Core Web API 发布到Linux Docker xff08 二 xff09 本章将尝试 Net Core Web API 直接发布到私有仓 Net Core Web API 直接发布到Docker私有仓 1 选择需要发布的
  • .Net Core微服务入门——Consul集群搭建(一)

    Net Core微服务入门 Consul集群搭建 xff08 一 xff09 前几天一直在本地机器试用Consul xff0c 今天特意在服务器上试试 xff0c 并搭建下集群 一 服务器安装consul 获取镜像 docker pull
  • .Net Core微服务入门——Consul集群搭建(二)

    Net Core微服务入门 Consul集群搭建 xff08 二 xff09 1 先启动第一个consul服务 xff1a consul1 docker run name consul1 d p 8500 span class token
  • .Net Core微服务入门——Consul集群搭建(三)

    Net Core微服务入门 Consul集群搭建 xff08 三 xff09 本章将介绍 Consul 集群 Client 还记得第一篇中 xff0c 我们再Consul中启动了2个MyAPI服务么 xff0c 我们重启下 xff0c 看下
  • .Net Core微服务入门——Consul集群搭建(四)

    Net Core微服务入门 Consul集群搭建 xff08 四 xff09 多台服务器集群搭建 1 先关闭几台集群服务器防火墙 当然 xff0c 不关闭也可以 xff0c 那就必须开通端口权限 consul 涉及的端口 xff1a 850
  • Docker 同一主机容器间通信

    Docker 容器间通信 本文我们采用bridge网络通信 1 创建bridge网络 docker network create testnet 2 查看Docker网络 docker network ls 3 运行容器连接到testnet
  • Centos7端口查看开放,防火墙开启关闭命令等

    1 开放 关闭端口 开放5001端口 firewall cmd zone 61 public add port 61 5001 tcp permanent 关闭5001端口 firewall cmd zone 61 public remov
  • .Net Core微服务入门——Ocelot API网关接入(一)

    Net Core微服务入门 Ocelot API网关接入 上一章我们测试了一个简单的Client 端访问Consul实现服务注册与发现 xff0c 但是现实生产环境我们直接通过Client自行连接Consul实现服务注册与发现 xff0c
  • .Net Core微服务入门——Ocelot API网关接入(二)

    Net Core微服务入门 Ocelot API网关接入 xff08 二 xff09 我们先接入Consul xff0c 实现服务发现 服务发现 1 引入 Ocelot Provider Consul 包 2 修改ocelot json x
  • .NET Core根据环境变量支持多个 appsettings.json配置文件

    NET Core根据环境变量支持多个 appsettings json配置文件 在项目开发的过程当中 xff0c 开发环境 测试环境 生产环境的配置肯定是不一样的 xff0c 单靠一个 appsettings json xff0c 没法满足

随机推荐