工具/软件:
您好、
我 I²C 让我们基于 MSP430FR50431 (μ V BSL)的流量传感器实现固件升级机制。 我完全失败了。 我 I²C 从应用程序中启动 BSL、因为接受地址0x48的4 μ s 流量、但事实就是如此。 任何具有正确结构(例如 RX 密码或批量擦除)的命令都会使器件复位并重新开始应用程序代码、而任何从器件读取数据的尝试(例如对命令的响应)都会导致 SDA 和 SCL 无限期保持在低电平、从而导致总线卡滞。
I²C 的器件只有一个外部可访问的 I ² C 接口、因此 BSL 必须从应用中启动。 为了排除应用的任何影响、我现在设置了一个持久标志来告诉启动代码进入 BSL、然后执行看门狗复位、以确保在 BSL 启动时没有外设最终处于配置中途的状态:
#pragma PERSISTENT(persist_enter_bsl) volatile uint8_t persist_enter_bsl = 0; #ifdef __TI_COMPILER_VERSION__ int _system_pre_init(void) #elif __IAR_SYSTEMS_ICC__ int __low_level_init(void) #elif __GNUC__ extern int system_pre_init(void) __attribute__((constructor)); int system_pre_init(void) #else #error Compiler not supported! #endif { /* Insert your low-level initializations here */ /* Disable Watchdog timer to prevent reset during */ /* int32_t variable initialization sequences. */ // Stop WDT WDTCTL = WDTPW + WDTHOLD; /* Disable mass erase on bad BSL password. */ *((uint16_t *)0xff84) = 0xaaaa; *((uint16_t *)0xff86) = 0xaaaa; /* Check for request to enter the BSL. */ if (persist_enter_bsl) { __disable_interrupt(); persist_enter_bsl = 0; /* Switch MCLK and SMCLK to 8MHz from DCO, ACLK to VLO. */ CSCTL0_H = CSKEY >> 8; CSCTL1 = DCOFSEL_6; CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK; CSCTL3 = (DIVA__1 | DIVS__1 | DIVM__1); CSCTL0_H = 0; /* Wait for things to stabilize. */ volatile uint16_t delay_i; for (delay_i = 0; delay_i < 1000; ++delay_i) ; /* Jump into BSL code. */ ((void (*)())0x1000)(); } // Continue with starting the application... }
这就是启动批量擦除(命令0x15)时在信号线上看到的内容:
包括字节48+W、80、01、00、15 64、A3由器件正确写入和确认。 但之后、它只需复位并启动我们的应用程序。 未发生擦除。
RX 密码命令也是如此:
...总计32 0xff 字节...
再次强调、器件只会复位并启动应用程序。
有趣的是、当我在末尾向器件发送一条带有错误 CRC 字节的命令时、它不会*不*复位、而是只是保留在 BSL 中、因此我可以在器件未复位的情况下多次发送此命令。 这表明它至少以某种方式解释它获得的数据、但一旦执行它、就只会进行复位。
更糟糕的是读取。 当我在 BSL 中尝试读取一个字节(例如在批量擦除并显示*错误 CRC*之后)时、器件将接受读取、然后通过将一条或两条数据线保持为低电平来阻止总线(可能是时钟延展):
然后、需要对器件进行下电上电才能使总线再次可用。
这可能是什么? 在进入 BSL 之前是否需要任何类型的初始化/配置?
谢谢、此致、
Philipp