声明:所有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(使用前将#替换为@)