cortex-M3粗略延时 计算

来源:互联网 发布:女神联盟2进阶12数据 编辑:程序博客网 时间:2024/05/17 03:51

最近调试磁铁驱动程序时,遇到一个奇怪的情况:(问题描述在下边这个帖子中)

OSTimeDly在ucos最高优先级任务中,多次使用,有什么说法?

只是知道问题大概出现在哪块,没找到出现这种状况的理由。顺带着理清楚一些基本的常识性的东西。如下:

基本概念:

AHB:Advanced High performance Bus,先进的高性能总线,这是一种“系统总线”。AHB 是在地址/控制阶段和数据阶段之间具有固定流水线的总线协议。它只支持由
AMBA AXI 协议提供的功能性的子集。 完全的 AMBA AHB 协议规范包括许多对于主机和从机 IP 开发来说不是必需的属性,因此 ARM 公司建议通常只使用该协议的子集。这个子集定义为 AMBA AHB-Lite协议。 

AMBA:Advanced Microcontroller  Bus Architecture,先进的微控制器总线架构(AMBA),AMBA是描述互连策略的协议规范系列。它是 ARM 公开的片内总线标准,该片内总线规范详述了互连策略以及对组成片上系统(SoC)的功能模块的管理。它协助带有一个或多个 CPU或信号处理器和多个外设的嵌入式处理器的开发。 AMBA 通过定义一个用于 SoC 模块的通用骨干(backbone)来对可重复使用的设计方法作了补充。

SoC:System on Chip片上系统

APB:Advanced Peripheral Bus,先进的外设总线(APB) 。APB 是一个比 AXI 和 AHB 相对简单的总线协议。它是为配件,或诸如定时器、中断控制器、UART、I/O 口等通用外设而设计的。它与主要系统总线的连接是通过系统到外设总线桥来实现的,这样有助于降低系统功耗。

AHB-AP:AHB Access Ports,AHB 访问端口(AHB-AP) 。

AHB-Lite:AHB-Lite 是完全的 AMBA AHB 协议规范的子集。它提供大多数 AMBA AHB 从机和主机设计所必需的所有基本功能,尤其是与多层 AMBA 互连一起使用时。

内核:内核是处理器的一部分,包含 ALU,数据路径,通用寄存器,程序计数器以及指令译码和控制电路。

PLL:phase locked loop,锁相环。PLL的作用主要有频率合成和CDR(时钟数据恢复)。

HSI:High Speed Internal Clock Signal,高速内部时钟信号。

HSE:High Speed External Clock Signal高速外部时钟信号。


系统时钟配置:

void  BSP_Init (void){   BSP_IntInit();   RCC_DeInit(); /*将外设RCC寄存器重设为缺省值 */   RCC_HSICmd(ENABLE);  //使能内部高速晶振   while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY)== RESET);//等待HSI就绪   RCC_HCLKConfig(RCC_SYSCLK_Div1);   /*设置AHB时钟(HCLK) RCC_SYSCLK_Div1——AHB时钟 = 系统时*/    RCC_PCLK2Config(RCC_HCLK_Div1);   /* 设置高速APB时钟(PCLK2)RCC_HCLK_Div1——APB2时钟 = HCLK*/       RCC_PCLK1Config(RCC_HCLK_Div2); /*设置低速APB时钟(PCLK1)RCC_HCLK_Div2——APB1时钟 = HCLK / 2*/        FLASH_SetLatency(FLASH_Latency_2);   /*设置FLASH存储器延时时钟周期数FLASH_Latency_2  2延时周期*/     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);  /*选择FLASH预取指缓存的模,预取指缓存使能*/   RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_16);/*设置PLL时钟源及倍频系数,频率为8/2*16=64Mhz*/      RCC_PLLCmd(ENABLE);   /*使能PLL */   while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) ; /*检查指定的RCC标志位(PLL准备好标志)设置与否*/      RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);  /*设置系统时钟(SYSCLK) */    while(RCC_GetSYSCLKSource() != 0x08);     /*驱动初始配置*/  OC_SPI_Init();  DrawerInterfaceInit();  //ReadFlash();  CAN_Config();  initStruct();  OC_LED_Ctrl(0x0000);}
不多解释,强调使用内部时钟作为系统时钟。内核时钟频率64MHz。


估算一段延时函数的时间:

for(u16 i=0;i<50000;i++);
反汇编:

  for(u16 i=0;i<50000;i++);    <span style="background-color: rgb(51, 255, 51);">0x8001fa6: 0x2000         MOVS      R0, #0</span>  for(u16 i=0;i<50000;i++);??<span style="background-color: rgb(255, 255, 0);">drawerStateCtr_0:    0x8001fa8: 0xf24c 0x3150  MOVW      R1, #50000              ; 0xc350    0x8001fac: 0xb280         UXTH      R0, R0    0x8001fae: 0x4288         CMP       R0, R1    0x8001fb0: 0xd201         BCS.N     ??drawerStateCtr_1      ; 0x8001fb6</span>  for(u16 i=0;i<50000;i++);   <span style="background-color: rgb(255, 0, 0);"> 0x8001fb2: 0x1c40         ADDS      R0, R0, #1    0x8001fb4: 0xe7f8         B.N       ??drawerStateCtr_0      ; 0x8001fa8</span>  bitsClear(num);??drawerStateCtr_1:    0x8001fb6: 0x0020         MOVS      R0, R4    0x8001fb8: 0xb2c0         UXTB      R0, R0    0x8001fba: 0xf7ff 0xffb8  BL        bitsClear               ; 0x8001f2e

涉及到的指令 及其 相应的周期数(内核周期):

MOVS    1+P1
MOVW      1
UXTH       1
CMP         1+P1
BCS.N      1+P1
ADDS       1+P1
B.N           1+P1

其中,P1=流水线重载。

可知for延时的大概内核周期数:至少 = 1+6*50000=300000个内核周期;-----这么算有问题没?待定....

(300000*1/72000000)*1000=4.17ms   

关于延时可以参见:STM32在系统时钟为72M下的几个延时函数—V3.5库


其他:

Cortex-M3 处理器内核采用 ARMv7-M 架构,

关于指令的流水线:采用三级流水线  

参见: ARM流水线


时钟周期,机器周期,指令周期的区别:

对于cortex-M3 处理器:

时钟周期=1/内核时钟频率;

机器周期约等于1个时钟周期;

指令周期:执行一条指令所需要的时间,一般由若干个机器周期组成。指令不同,所需的机器周期也不同。

这几个概念,对于cortex-M3来说,未必这样子,以上纯属个人理解。

..........................











0 0