大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是一种快速定位i.MXRT600板级设计ISP[2-0]启动模式引脚上电时序问题的方法

  我们知道恩智浦i.MXRT600是主打音频市场的MCU产品,其也是i.MXRT三位数平台的第一款型号。这颗MCU已被众多知名国际大厂客户选用,在项目中作为协处理器负责音频相关子功能。不少客户都已经到了量产阶段,最近痞子衡在支持其中一个量产客户,客户遇到了同一批次某几个板卡无法正常启动的问题。痞子衡和同事一起排查,最终发现是ISP[2:0]启动引脚电平上电时序问题。这其实是个典型问题,痞子衡今天教你一招快速定位此类问题的方法:

一、引出上电时序问题

  我们先来看看客户的问题,下面是客户板卡简图,i.MXRT600是负责音频功能的协处理器,它的启动引脚ISP[2:0]与主应用处理器(AP)连接了起来(客户项目设计里,AP并不负责控制i.MXRT600的启动模式),为了防止对i.MXRT600上电ISP引脚采样有影响,客户还特地在中间加了一层反向隔离电路。

  • 注:其实i.MXRT600支持Serial Boot模式,这种模式下i.MXRT600作为协处理器,其应用程序数据可直接由AP通过指定的UART/I2C/SPI/USB下载进i.MXRT600的内部RAM运行,能省去一颗外部Flash。

  客户量产过程中,同一批次几百块板卡,有一两块板卡上i.MXRT600无法启动。客户做了少量ABA实验:将无法启动板卡上的i.MXRT600芯片吹下来,换到能正常启动板卡上,依然无法启动。反过来,能正常启动板卡上的i.MXRT600芯片换到无法正常启动的板卡上,这块板卡就能正常启动了。

  从上面ABA实验来看,似乎不是板级设计问题,像是出问题的板卡上i.MXRT600芯片自身问题。痞子衡拿到一块出问题的板子,上电后测量了ISP[2:0]引脚电平,其值是3'b011 - FlexSPI Boot from Port A,上电稳定后ISP设置是没问题的,但刚上电时i.MXRT600 BootROM到底采样到的是什么ISP电平值没人知道。

  下面是客户板卡上ISP部分反向隔离设计,为了验证是ISP采样时机问题,我们特意对电路进行改造将RT600_BOOT0和RT600_BOOT2分别强行拉高和拉低,然后给板卡重新上电,终于板卡能正常启动了。

  所以我们可以得出初步结论,对于i.MXRT600从上电到BootROM进行ISP采样,这段时间不是一个严格固定值,因芯片制造差异,这个时间应该是在一定范围内,板级供电设计时上电时间应留有足够余量。客户这个项目里上电时间余量留得不足,导致无法满足个别i.MXRT600芯片ISP采样时间要求。

二、BootROM中对于启动模式的处理

  在介绍快速定位ISP采样时机问题方法前,痞子衡先带大家了解下i.MXRT600 BootROM中关于启动模式的处理流程。

  咱们先回顾下痞子衡的旧文 《Boot配置(ISP_Pin/OTP)》,每次i.MXRT600芯片硬复位,OTP中的部分关于系统配置的值会被自动加载到OCOTP模块相应Shadow Register里(关于OCOTP外设基础知识可参考 《OTP及其烧写方法》),BootROM中主要用如下 get_runtime_boot_device_info() 函数来获取最终启动模式,并将其存在全局变量 s_bootDeviceInfo 中。

  • 注:代码中 OCOTP->OTP_SHADOW[0x60] 寄存器低四位即芯片参考手册里提及的 PRIMARY_BOOT_SRC[3:0]
static boot_device_info_t s_bootDeviceInfo;

void get_runtime_boot_device_info(void)
{
// 从OTP Shadow Register获取启动模式
uint32_t bootSrc = OCOTP->OTP_SHADOW[0x60] & 0x0f;
boot_device_info_t bootDeviceInfo = { 0 }; if (bootSrc == 0) // Isp Pin
{
// 从ISP[2:0]引脚获取启动模式
bootSrc = get_bootpin_mode();
// 对 bootDeviceInfo 成员进一步赋值
}
else
{
// 对 bootDeviceInfo 成员进一步赋值
}
s_bootDeviceInfo = bootDeviceInfo;
}

  每一次i.MXRT600系统软复位去重新执行BootROM时,ISP[2:0]引脚状态都会被重新采样,这完全是软件采样。ROM中ISP采样功能函数如下面 get_bootpin_mode() 所示,代码中做了IO电平去抖处理:

#define BOOT_PIN_DEBOUNCE_READ_COUNT 500

uint32_t get_bootpin_mode(void)
{
uint32_t bootSrc = 0; // 使能GPIO外设
CLOCK_EnableClock(kCLOCK_HsGpio1);
RESET_PeripheralReset(kHSGPIO1_RST_SHIFT_RSTn); // 设置ISP引脚为GPIO模式,并使能上拉.
IOPCTL->PIO[1][15] = IOPCTL_PIO_FSEL(0) | IOPCTL_PIO_PUPDENA(1) | IOPCTL_PIO_PUPDSEL(1) | IOPCTL_PIO_IBENA(1);
IOPCTL->PIO[1][16] = IOPCTL_PIO_FSEL(0) | IOPCTL_PIO_PUPDENA(1) | IOPCTL_PIO_PUPDSEL(1) | IOPCTL_PIO_IBENA(1);
IOPCTL->PIO[1][17] = IOPCTL_PIO_FSEL(0) | IOPCTL_PIO_PUPDENA(1) | IOPCTL_PIO_PUPDSEL(1) | IOPCTL_PIO_IBENA(1); // 配置ISP引脚GPIO属性为数字输入模式.
GPIO->DIR[1] &= ~((1U << 15) | (1U << 16) | (1U << 17)); // Note1: 管脚默认上拉是disable的,ROM需要使能管脚上拉.
// Note2: 从使能管脚上拉到读取管脚值之间应间隔10us以上.
sw_delay_us(10); // 采样ISP引脚值
for (uint32_t pin = 17; pin >= 15; pin--)
{
uint32_t readCount = 0;
for (uint32_t i = 0; i < BOOT_PIN_DEBOUNCE_READ_COUNT; i++)
{
readCount += GPIO->B[1][pin] & 0x1;
}
if (readCount >= BOOT_PIN_DEBOUNCE_READ_COUNT / 2)
{
bootSrc |= 0x1;
}
if (pin != 15)
{
bootSrc <<= 1;
}
} return bootSrc;
}

  上面就是BootROM中关于启动模式的处理代码。那么有没有方法挂上调试器通过查后门方式直接读取到 s_bootDeviceInfo 变量值呢?很抱歉,不可以!即使痞子衡也做不到,虽然痞子衡能通过查BootROM map文件得知这个变量放在 0x10012d38 地址处。但是i.MXRT600 BootROM中集成了 《Debug Mailbox机制》,我们无法通过调试器读取正常运行后的ROM状态,这条路行不通。

三、快速定位ISP[2:0]电平采样问题

  第一小节介绍的客户项目启动问题,其实还算比较好定位,因为有ABA实验在先,基本可以明确问题就出在ISP采样时机上。但更多时候,在客户项目研发阶段,没有ABA实验的条件,可能仅有一块板卡,并且Flash配置以及App里启动头是否正确都尚待验证。这种情况下,我们就需要一种快速甄别是否是ISP采样时机因素导致的启动问题。

  当芯片无法启动时,我们第一想法肯定是要得知第二小节介绍里 s_bootDeviceInfo 到底是什么值,这样我们就能反推ISP引脚到底在ROM里是什么采样值,但这条路行不通。换个角度想,我们能不能不让BootROM去采样ISP引脚,换一种替代方式来决定启动模式,如果这种情况下能按替代设置去启动,就也可以反证ISP引脚采样时机有问题。

  这种启动模式替代设置方法就是痞子衡今天要教大家的方法,利用调试器临时改写OCOTP->OTP_SHADOW[0x60]值(对的,我们可以不烧写OTP),改写完成后对芯片做一次软复位即可。OCOTP->OTP_SHADOW寄存器组仅芯片硬件复位或者执行OCOTP更新命令其值才会被重新加载,软复位不会影响其值。

四、在MIMXRT685-EVK上做一次实验

  让我们在MIMXRT685-EVK上做一次实验,这块板卡上Flash连到了FlexSPI0 Port B上,我们随意下载一个SDK XIP工程,并将ISP引脚拨码设为3'b010 - FlexSPI Boot from Port B,复位后芯片能正常启动,工程运行正常。

  现在我们将ISP引脚拨码设为3'b110 - Serial ISP,软复位后芯片进入了ISP下载模式,不会从Flash启动。查芯片头文件得知 OCOTP->OTP_SHADOW[0x60] 寄存器地址是 0x50130180,我们现在尝试改写这个寄存器。

/** OCOTP - Register Layout Typedef */
typedef struct {
__IO uint32_t OTP_SHADOW[496]; /**< OTP shadow register N, array offset: 0x0, array step: 0x4 */
uint8_t RESERVED_0[64];
__IO uint32_t OTP_CTRL; /**< Control/address register, offset: 0x800 */
// 省略...
} OCOTP_Type; /** Peripheral OCOTP base address */
#define OCOTP_BASE (0x50130000u)
/** Peripheral OCOTP base address */
#define OCOTP_BASE_NS (0x40130000u)
/** Peripheral OCOTP base pointer */
#define OCOTP ((OCOTP_Type *)OCOTP_BASE)
/** Peripheral OCOTP base pointer */
#define OCOTP_NS ((OCOTP_Type *)OCOTP_BASE_NS)

  挂上J-Link调试器,打开J-Link Commander,连接芯片,注意选择"MIMXRT685_M33",然后使用w4命令在0x50130180地址处写入0x00000005(在PRIMARY_BOOT_SRC[3:0]定义里,4'b0101是QSPI_B_BOOT)。

  继续执行reset和go命令(或者按一下板载软复位按钮RESET BUTTON SW3),这时候你可以看到芯片从Flash正常启动了,SDK XIP工程又运行起来了,显然这时候ISP引脚电平设置被忽略了,因此我们找到了有效的启动模式替代设置方法。

  最后有一点要注意,在使用J-Link软复位时,如果看到如下log,得检查下配套JLinkScript里的ResetTarget()函数具体功能,要确保内核真的被复位了。

  至此,快速定位i.MXRT600板级设计ISP[2-0]启动模式引脚上电时序问题的方法痞子衡便介绍完毕了,掌声在哪里~~~

欢迎订阅

文章会同时发布到我的 博客园主页CSDN主页知乎主页微信公众号 平台上。

微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。

痞子衡嵌入式:快速定位i.MXRT600板级设计ISP[2:0]启动模式引脚上电时序问题的方法的更多相关文章

  1. 痞子衡嵌入式:揭秘i.MXRT600的ISP模式下用J-Link连接后PC总是停在0x1c04a的原因(Debug Mailbox)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT600中的Debug Mailbox实现对JLink调试的影响. 事情缘起痞子衡的同事 - 喜欢打破砂锅问到底的Kerry小 ...

  2. 痞子衡嵌入式:盘点国内车规级MCU厂商

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是国内车规级MCU厂商及其产品. 在汽车电子领域,MCU的应用非常广泛,大到车身控制与动力总成,小到雨刷车窗等控制单元,都离不开MCU的身 ...

  3. 痞子衡嵌入式:在IAR开发环境下将关键函数重定向到RAM中执行的三种方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在IAR开发环境下将关键函数重定向到RAM中执行的三种方法. 嵌入式项目里应用程序代码正常是放在 Flash 中执行的,但有时候也需要将 ...

  4. 痞子衡嵌入式:在MDK开发环境下将关键函数重定向到RAM中执行的几种方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在MDK开发环境下将关键函数重定向到RAM中执行的几种方法. 这个关键函数重定向到 RAM 中执行系列文章,痞子衡已经写过 <IA ...

  5. 痞子衡嵌入式:MCUXpresso IDE下在线调试时使用不同复位策略的现象总结

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是MCUXpresso IDE下在线调试时使用不同复位策略的现象总结. 本篇实际上是<IAR在线调试时设不同复位类型可能会导致i.M ...

  6. 痞子衡嵌入式:把玩i.MXRT1062 TencentOS Tiny EVB_AIoT开发板(1) - 开发环境搭建与点灯

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT1062 TencentOS Tiny EVB_AIoT开发板环境搭建与点灯. 腾讯 TencentOS 团队于2021年1 ...

  7. 痞子衡嵌入式:把玩i.MXRT1062 TencentOS Tiny EVB_AIoT开发板(2) - 在Flash调试及离线启动

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT1062 TencentOS Tiny EVB_AIoT开发板在Flash调试与离线启动. 腾讯 TencentOS 团队于 ...

  8. 痞子衡嵌入式:降低刷新率是定位LCD花屏显示问题的第一大法(i.MXRT1170, 1280x480 LVDS)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT1170上LCD花屏显示问题的分析解决经验. 痞子衡最近这段时间在参与一个基于i.MXRT1170的大项目(先保个密),需要 ...

  9. 痞子衡嵌入式:恩智浦MCU安全加密启动一站式工具NXP-MCUBootUtility用户指南

    NXP MCU Boot Utility English | 中文 1 软件概览 1.1 介绍 NXP-MCUBootUtility是一个专为NXP MCU安全加密启动而设计的工具,其特性与NXP M ...

随机推荐

  1. 解决IDEA Gradle构建报错"Cause: zip END header not found"

    1 问题描述 某天使用Gradle构建项目时,IDEA报错如下: 2 原因 原因是下载的Gradle,也就是zip压缩包不完整,导致无法使用Gradle构建. 3 解决方法 3.1 删除本地缓存重新下 ...

  2. 14. VUE 子组件修改父组件的值

    在 Vue 当中,父组件 -> 子组件 传值,都是通过属性的形式传递的. 子组件 修改 传递数据 直接操作父组件传递过来的值,用是可以用的,但是打开控制台后,会发现 Vue 有个警告:你不要直接 ...

  3. Day14_85_通过反射机制修改Class的属性值(IO+Properties)动态修改

    通过反射机制修改Class的属性值(IO+Properties)动态修改 import java.io.FileInputStream; import java.io.FileNotFoundExce ...

  4. hdu4282 x^z+y^z+x*y*z=k 解的个数

    题意:      x^z + y^z + x*y*z = k; (x < y ,z > 1),给你一个k问有多少组解. 思路:        暴力枚举z,y,然后二分查找x.注意一点最好用 ...

  5. Intel汇编程序设计-整数算术指令(中)

    7.3  移位和循环移位的应用 7.3.1  多双字移位 要对扩展精度整数(长整数)进行移位操作,可把它划分为字节数组.字数组或双字数组,然后再对该数组进行移位操作.在内存中存储数字时通常采用的方式是 ...

  6. 14.PHP_PHP与XML技术

    PHP与XML技术 先把概念粘过来: 先来个基本模板: <?xml version="1.0" encoding="gb2312" standalone= ...

  7. java之Collection

    java中的Collection可分为List.Set.Queue三种类型. 1.List. List会按照插入的顺序保存对象,较为常用的实现类有ArrayList,LinkedList和Vector ...

  8. ThinkPHP5.1 输出到模板HTML格式被强行转成了字符

    出现问题 控制器传给视图一个input标签,在视图页面显示出来就是 <input type='text'></input>,显示出来的是一个文本,而不是一个可以输入的文本框 解 ...

  9. mysql搭建多主一从源复制环境

    问题描述:搭建过一主多从的环境,由于数据库数据一致性要求高,有些情景会搭建一主多从的架构,搭建多主一从的模式,相对来说适合数据整合,将多个业务的库整合到一起,方便做查询,也可以当做一个监控其他主库数据 ...

  10. Flutter 2.2 更新详解

    Flutter 2.2 版已正式发布!要获取新版本,您只需切换到 stable 渠道并更新目前安装的 Flutter,或前往 flutter.cn/docs/get-started 从头开始安装. 虽 ...