ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

痞子衡嵌入式:FlexSPI复位方式不当会导致i.MXRT系列下OTFAD加密启动失败

2021-04-17 17:54:53  阅读:201  来源: 互联网

标签:FlexSPI 加密 复位 Flash FLEXSPI OTFAD MXRT


  大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家分享的是FlexSPI复位方式不当会导致i.MXRT系列下OTFAD加密启动失败问题。

  本篇是《系统时钟配置不当会导致i.MXRT1xxx系列下OTFAD加密启动失败》 的后续篇,我们为i.MXRT1010解决了OTFAD时钟配置限制问题后,加密的App就一定能正常跑了吗?其实并不一定,如果你的App跟IAP有关(即会调用FlexSPI驱动去擦写Flash),免不了会在FlexSPI驱动里操作FlexSPI外设寄存器的软复位位,软复位操作方式使用不当可能会导致App无法正常运行,今天痞子衡就来好好聊一聊这个FlexSPI复位小限制:

  • Note1: 虽然i.MXRT1170也包含OTFAD,但是本文中的FlexSPI复位限制问题在i.MXRT1170上并不存在。
  • Note2: 三位数系列i.MXRT600同样包含OTFAD,且也受本文中的FlexSPI复位限制影响。

一、问题描述

  从恩智浦官网下载一个SDK包(痞子衡下的是v2.9.1),选择其中 flexspi 例程 \SDK\boards\evkmimxrt1010\driver_examples\flexspi\nor\polling_transfer\ 。编译这个 flexspi_nor_polling_transfer 工程(选择 flexspi_nor_debug build,即XIP工程),得到可执行文件,将其下载到 MIMXRT1010-EVK 板载Flash中离线启动(正常模式,不加密),打开串口调试助手看到如下结果:

  这个结果是例程预期结果,你可能会对这个XIP build也能擦写Flash感到奇怪,按说板载Flash没有RWW功能,擦写Flash操作不能在Flash里原地执行,但是例程的链接文件里已经将涉及Flash擦写代码的源文件直接放在RAM里了,因此例程是可以正常执行的。

  现在让我们根据《系统时钟配置不当会导致i.MXRT1xxx系列下OTFAD加密启动失败》 文中操作使能OTFAD加密,将整个App空间都加密,记得要修复系统时钟配置限制问题,这时候再离线启动,看到串口调试助手没有任何输出,说明例程执行失败了。查看工程源代码,main()函数里第一句打印前调用了 flexspi_nor_flash_init(EXAMPLE_FLEXSPI);, 看起来OTFAD加密后这个Flash初始化函数执行不太正常。

  为了定位问题方便,我们回到不加密模式,给 flexspi_nor_polling_transfer 工程加上一些辅助调试的打印信息,主要是FlexSPI相关API函数调用前加上打印信息。注意:需要将如下三个源文件也放到RAM中才能看到控制台完整输出。

initialize by copy {
  object fsl_debug_console.o,
  object fsl_adapter_lpuart.o,
  object fsl_lpuart.o,
};

  有了辅助打印信息,我们现在再回到OTFAD加密模式,可以看到代码停在 FLEXSPI_UpdateLUT() 函数就没有继续执行下去了。本文不是为了讲述如何一步步找到问题的方法,痞子衡其实知道就是 FLEXSPI_SoftwareReset() 函数惹的祸(没有停在这个函数,是由于系统buffer的缘故),至于是什么原因,详见下节。

static inline void FLEXSPI_SoftwareReset(FLEXSPI_Type *base)
{
    base->MCR0 |= FLEXSPI_MCR0_SWRESET_MASK;
    while (0U != (base->MCR0 & FLEXSPI_MCR0_SWRESET_MASK))
    {
    }
}

二、原因分析

  老规矩,痞子衡直接给答案,这是OTFAD对FlexSPI外设复位的小限制,当OTFAD被使能时,如果被加密的app代码是XIP执行,app里利用FlexSPI->MCR0[SWRESET]位做复位时,这个swreset复位功能会同时清掉FlexSPI->INTR[KEYDONE]位,而FlexSPI的运行依赖OTFAD解析KeyBlob的结果,当FlexSPI->INTR[KEYDONE]位是0时,对Flash的AHB访问会被禁掉,故而发生CPU lockup,代码无法继续执行。

KEYDONE位为1 - 表明OTFAD解析KeyBlob已正常完成;
KEYDONE位为0 - 表明OTFAD正在解析KeyBlob过程中;

  FlexSPI->MCR0[SWRESET]位存在于任何一款i.MXRT芯片型号中,其功能是复位FlexSPI外设,在下面几个场景都可以去做一次FlexSPI外设复位,不用担心,这个外设复位并不影响FlexSPI配置寄存器里的值。不过比较遗憾的是在此时的OTFAD加密启动使能情形下,不能再用MCR0[SWRESET]位去做复位了 。

场景一:初始化FlexSPI,打开MCR0[MDIS]位使能模块时
场景二:更新了FlexSPI的LUT表后
场景三:切换了FlexSPI的工作模式后(比如使能Flash四线)
场景四:完成了FlexSPI的擦、写命令后

三、解决方案

  很多时候FlexSPI->MCR0[SWRESET]位更多是被用来清除AHB TX/RX Buffer(尤其是在Flash擦写之后),在i.MXRT1010 FlexSPI外设的AHBCR寄存器里其实新增了单独的CLRAHBTXBUF和CLRAHBRXBUF控制位,用以实现AHB TX/RX Buffer的清除。因此我们为了避免影响OTFAD加密启动,可以使用AHBCR[CLRAHBTXBUF/CLRAHBRXBUF]位来代替MCR0[SWRESET]位去做复位。

  因此在 flexspi_nor_polling_transfer 工程里,将FLEXSPI_SoftwareReset()函数调用全部改成如下的FLEXSPI_ClearAhbBuffer()函数调用就可以保证工程正常运行了。

static inline void FLEXSPI_ClearAhbBuffer(FLEXSPI_Type *base)
{
#if defined(FSL_FEATURE_SOC_OTFAD_COUNT) && defined(FLEXSPI_AHBCR_CLRAHBRXBUF_MASK)
    base->AHBCR |= FLEXSPI_AHBCR_CLRAHBRXBUF_MASK | FLEXSPI_AHBCR_CLRAHBTXBUF_MASK;
    base->AHBCR &= ~(FLEXSPI_AHBCR_CLRAHBRXBUF_MASK | FLEXSPI_AHBCR_CLRAHBTXBUF_MASK);
#endif
}

  至此,FlexSPI复位方式不当会导致i.MXRT系列下OTFAD加密启动失败问题痞子衡便介绍完毕了,掌声在哪里~~~


标签:FlexSPI,加密,复位,Flash,FLEXSPI,OTFAD,MXRT
来源: https://blog.51cto.com/u_12094353/2713830

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有