首页 > 解决方案 > 当微控制器的手册说“检查 XX 是否发生”时,如果没有,应该怎么办?

问题描述

许多微控制器数据表和参考手册包含如下说明 [引自 ST 参考手册]:

  1. 将新的等待状态数编程到 FLASH_ACR 寄存器中的 LATENCY 位
  2. 通过读取 FLASH_ACR 寄存器检查是否考虑了新的等待状态数以访问闪存
  3. 通过写入 RCC_CFGR 寄存器中的 SW 位来修改 CPU 时钟源...

如果参考手册指定了一些情况,在这些情况下该值可能不会立即生效,或者除非重复写入,否则可能根本无法生效,那么代码可以考虑到这种可能性。如果没有任何这样的规范,勤奋的程序员应该如何处理第 2 步?可能性包括:

  1. 设置 FLASH_ACR,检查它,如果值不符合预期,则发出致命错误信号。

  2. 设置 FLASH_ACR 一次,然后在 do-while 循环中检查它,如果正确的值从未出现,则永远循环。

  3. 设置 FLASH_ACR 一次,然后在 do-while 循环中检查它,但如果没有出现正确的值,则在经过一定次数的迭代后发出致命错误信号。

  4. 在 do-while 循环中设置和检查 FLASH_ACR,如果该值从未正确设置,则永远循环。

  5. 在 do-while 循环中设置和检查 FLASH_ACR,但在经过一定次数的迭代后会发出致命错误信号。

  6. 强制读取硬件寄存器以防引入必要的延迟,如果设置了调试器断点则使值可见,否则忽略结果。

  7. 忽略步骤 2,开发期间除外。

某些操作具有延迟效果是很常见的,并且系统要求代码在启动其他操作之前等待某些操作完成。然而,尚不清楚在什么情况下 FLASH_ACR 可能无法正确设置,而芯片损坏严重到足以使任何尝试的程序执行变得毫无意义。我的猜测是,这些检查主要是作为故障排除过程的一部分,以防万一事情没有按预期工作,但不是生产代码的必要部分。其他人如何处理此类检查?

标签: embedded

解决方案


ST 自己的启动代码没有这样的动作。例如,从system_stm32f4xx.c1.6.9 版本开始:

    /* Wait till the main PLL is ready */
    while((RCC->CR & RCC_CR_PLLRDY) == 0)
    {
    }

#if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx)      
    /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
    FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
#endif /* STM32F40_41xxx || STM32F42_43xxx */

#if defined (STM32F401xx)
    /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
    FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_2WS;
#endif /* STM32F401xx */

    /* Select the main PLL as system clock source */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= RCC_CFGR_SW_PLL;

    /* Wait till the main PLL is used as system clock source */
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
    {
    }

在切换之前不要将时序设置为与 PLL 时钟速度不兼容的值,这一点很重要,但如果对寄存器进行编程失败,那么再多的软件都无法解决问题。


推荐阅读