【14】从0到1教你写uC/OS-III————>时间戳(测试任务执行效率)

  1. 简述:
    1. 时间戳主要用来测试任务时行时长,以此来判断该段代码的执行效率;如果时间过长就可以优化调整代码;
    2. 本质上就是一个任务起始——>终止的时间点;
  2. 测试方式:
    1. 比如测量任务A的执行效率,在A任务运行前记录一个时间点TimeStart,运行完记录一个时间点TimeEnd;那么这段代码的运行时长TimeUse = TimeEnd - TimeStart;这两个时间点就叫做时间戳
  3. 实现方式:
    1. 以Crtotex-M3为例,任务的执行时长是ns级的;但通常的硬件定时器只有us级,远远达不到测量几条代码运行时长的精度;
    2. 但在Crotex-M内核中,有一个DWT,该外设有一个32的寄存器叫CYCCNT,它是一个向上的计数器,记录内核时钟HCLK运行的个数,溢出自动清零重新向上计数,该计数器正好可以用来实现时间戳的功能;
    3. 以M3为例,HCLK时钟最高为72Mhz,单个时钟周期 = 1/72M = 14ns;CYCCNT最大记录时间为2^32 * 14 = 60S;
  4. 例程:
    /*
    ************************************************************************************************************************
    *                                              时间戳
    ************************************************************************************************************************
    */
    #if (OS_CFG_TS_EN == 1u)
        #define     OS_TS_GET()     (CPU_TS)CPU_TS_TmrRd()
    #else
        #define     OS_TS_GET()     (CPU_TS)0u
    #endif
    /*********************************************************
     * 函数名:void  CPU_Init (void);
     * 描述  :CPU初始化,包含如下
                1、初始化时间戳
                2、初始化中断使能时间测量
                3、初始化CPU名字
                本实验只写第一个功能
     * 输入  :无
     * 输出  :无
     * 返回  :无 
     * 调用  :内部调用 
     **********************************************************/
    void  CPU_Init (void)
    {
        #if((CPU_CFG_TS_EN == DEF_ENABLED) || (CPU_CFG_TS_TMR_EN == DEF_ENABLED))
            CPU_TS_Init();  //初始化时间戳
        #endif
    }
    
    /*********************************************************
     * 函数名:static  void  CPU_TS_Init (void);
     * 描述  :
                1、初始化时间戳
     * 输入  :无
     * 输出  :无
     * 返回  :无 
     * 调用  :内部调用 
     **********************************************************/
    #if((CPU_CFG_TS_EN == DEF_ENABLED) || (CPU_CFG_TS_TMR_EN == DEF_ENABLED))
    static void CPU_TS_Init(void)
    {
        #if(CPU_CFG_TS_TMR_EN == DEF_ENABLED)
            CPU_TS_TmrFreq_Hz = 0u;
            CPU_TS_TmrInit();   //初始化时间戳定时器
        #endif    
    }
    #endif
    
    /*********************************************************
     * 函数名:void  CPU_TS_TmrInit (void);
     * 描述  :
                1、初始化时间戳定时器
     * 输入  :无
     * 输出  :无
     * 返回  :无 
     * 调用  :内部调用 
     **********************************************************/
    #if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
    void  CPU_TS_TmrInit (void)
    {
        CPU_INT32U  fclk_freq;
        
        fclk_freq = BSP_CPU_ClkFreq();
        
        //使能DWT外设
        BSP_REG_DEM_CR |= (CPU_INT32U)BSP_BIT_DEM_CR_TRCENA;
        //DWT CYCCNT寄存器计数器清0
        BSP_REG_DWT_CYCCNY = (CPU_INT32U)0;
        
        /*注意:当使用软件仿真全速运行的时候,会先停在这里,
                就好像在这里设置了一个断点一样,需要手动运行才能跳过,
                当使用硬件仿真的时候却不会; */
        BSP_REG_DWT_CR |= (CPU_INT32U)BSP_BIT_DWT_CR_CYCCNTENA;
        //设置时间戳定时器频率为系统频率
        CPU_TS_TmrFreqSet((CPU_TS_TMR_FREQ)fclk_freq);  
    }
    #endif
    
    /*********************************************************
     * 函数名:CPU_INT32U  BSP_CPU_ClkFreq (void);
     * 描述  :
                1、获取CPU的HCLK时钟
                2、软件仿真,直接返回25Mhz;
     * 输入  :无
     * 输出  :无
     * 返回  :无 
     * 调用  :内部调用 
     **********************************************************/
    CPU_INT32U  BSP_CPU_ClkFreq (void)
    {
            CPU_INT32U  CPU_HCLK;
            //软件仿真用的25Mhz;
            CPU_HCLK = 25000000;
            
              return CPU_HCLK;    
    }
    
    /*********************************************************
     * 函数名:void  CPU_TS_TmrFreqSet (CPU_TS_TMR_FREQ  freq_hz);   
     * 描述  :
                1、设置时间戳定时器时钟频率(默认等于系统时钟)
     * 输入  :无
     * 输出  :无
     * 返回  :无 
     * 调用  :内部调用 
     **********************************************************/
    #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
    
    /*********************************************************
     * 函数名:CPU_TS_TMR  CPU_TS_TmrRd (void);
     * 描述  :
                1、获取时间戳当前时间
     * 输入  :无
     * 输出  :无
     * 返回  :无 
     * 调用  :内部调用 
     **********************************************************/
    #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)BSP_REG_DWT_CYCCNY;
        
        return ts_tmr_cnts;
    }
    #endif
    

     

  5. 总结:
    1. 本例程需要硬件仿真;
    2. 实际用到;时间戳初始化CPU_Init();
    3. 获取当前时间:OS_TS_GET();
    4.  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值