本帖最后由 zjh20070904 于 2022-6-15 09:53 编辑
1 概述
最近处理测试软件执行时间、分析MCU性能,是通过同相对比Keil中debug有个参数states实现,对该数据的理解很浅,,在网上查找了资料,暂无明确数据说明,网上有用51单片机作举例的,但是我用的芯片是M3内核的,同时也没有详细的数据。
于是乎!自己用DWT测量代码运行时间,统计数据、分析states和程序运行时间的关系。
2 DWT是什么DWT是内核的一个模块,有一个功能是统计CPU的执行周期数,。 在应用可以用来测量某一段代码的执行时间、延时功能,单位是系统时钟的周期。
具体资料可以到网上查找。在这里是用DWT测量代码执行的时间,并和Keil 中的states作比较,通过数据分析states的单位是什么、在实际应用中有什么作用。
说明:DWT的配置方法参考了野火的DWT例程配置方法。
3 测试代码volatile uint32_t tick = 0;
#define DWT_CR *(uint32_t *)0xE0001000
#define DWT_CYCCNT *(uint32_t *)0xE0001004
#define DEM_CR *(uint32_t *)0xE000EDFC
#define DEM_CR_TRCENA (1 << 24)
#define DWT_CR_CYCCNTENA (1 << 0)
void SoftDelay(uint32_t m)
{
while(m--);
}
void SysTick_Delay_ms(__IO uint32_t ms)
{
tick = 0;
SysTick_Config(SystemCoreClock / 1000);
while(tick < ms);
SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;
}
//为了方便在调试中显示数值,定义为全局变量
uint32_t CNT_Start = 0,CNT_End = 0 ,CNT_Use = 0, time_us=0;
int main(void)
{
//初始化DWT的计数系统时钟个数功能,参考了野火的例程
DEM_CR |= (uint32_t)DEM_CR_TRCENA;
DWT_CYCCNT = (uint32_t)0u;
DWT_CR |= (uint32_t)DWT_CR_CYCCNTENA;
//获取当前的计数个数
CNT_Start=DWT_CYCCNT;
//执行测试代码
SoftDelay(1000000);
// SysTick_Delay_ms(100);
CNT_End=DWT_CYCCNT;
CNT_Use = CNT_End-CNT_Start;
time_us = (CNT_Use) / ( SystemCoreClock / 1000 ); //转化为单位为us的数值
while(1)
{
}
}
void SysTick_Handler(void)
{
tick++;
}
4 实验数据与结论4.1 运行SysTick硬件延时
4.1.1 72MHz
4.1.2 24MHz
系统时钟 | | | | | 4302167502-4294967310=7200192 | | | 4297367465-4294967310=2400155 | | 1、states记录的数据变化值就是SYSCLK的个数 2、states的单位是系统时钟的周期 |
4.2 运行软件延时
4.2.1 72MHz
4.2.2 24MHz
系统时钟 | | | | | 4303967387-4294967310=9000077 | | | 4298967366-4294967310=4000056 | | 1、同样的软件延时在不同的系统时钟下消耗的时间: 9000027/72000=125ms; 4000017/24000=166ms 降低系统时钟频率时,同样的代码消耗的系统时钟周期数量减少,但整体运行的时间是延长的 2、但消耗的系统时钟周期并不是倍数的关系,不知道是否和M3内核的使用一个3级流水线有关(不理解其原因),还是和Flash的取指令、等待周期、预取缓存设计有关,这个问题先放在这吧,有大神知道的话,请答复,不胜感激。 |
|