我不知道为什么我可以通过 USB 将文本从 PC 发送到 MCU,但是在 MCU 重置后我不能让 MCU 向 PC 发送文本。
我正在使用 STM32F103C8。Bootloader起始地址为0x8000000
,Firmware起始地址为0x8004000
。当然,Bootloader 和 Firmware 的 NVIC 表基地址分别是0x8000000
和0x8004000
。
在我的固件中,PC 使用虚拟 COM 端口识别 MCU,因此我可以通过 USB VCOM 端口进行 tx/rx。将 USB 相关寄存器备份到备份寄存器后,我的固件通过使用NVIC_GenerateSystemReset()
.
- - - - - 固件 - - - - - - - -
BKP_WriteBackupRegister(BKP_DR5, GetCNTR());
BKP_WriteBackupRegister(BKP_DR6, GetISTR());
BKP_WriteBackupRegister(BKP_DR7, GetDADDR());
BKP_WriteBackupRegister(BKP_DR8, GetBTABLE());
BKP_WriteBackupRegister(BKP_DR9, GetENDPOINT(0));
BKP_WriteBackupRegister(BKP_DR10, GetENDPOINT(1));
BKP_WriteBackupRegister(BKP_DR11, GetENDPOINT(2));
BKP_WriteBackupRegister(BKP_DR12, GetENDPOINT(3));
BKP_WriteBackupRegister(BKP_DR3, 10); // this is for indicating a jump from firmware.
NVIC_GenerateSystemReset();
------------BOOTLOADER(伪代码)--------------
if((BKP_ReadBackupRegister(BKP_DR3) == 10))
{
// DO NOT CHANGE USB_DISCONNECT PIN which is for controlling the
// PULL-UP status of USBDP.
// (If I do this, USB virtual com port will be disconnected from PC.
// I don't want this to happen.
// But I found that if I put this pin high and then put it low,
// tx/rx both work fine but VCOM port will be disconnected and then reconnected.)
USB_Init();
// SET CNTR, DADDR, BTABLE,
// ENDPOINT0, ENDPOINT1, ENDPOINT2, ENDPOINT3 according to backup registers.
}
之后,我发现PC在Firmware运行时保留了已识别的VCOM端口(再次进入bootloader后没有重新连接),我可以通过这个usb虚拟com端口向MCU发送字符。
但是 MCU 无法通过 USB 向 PC 发送字符。
extern void USB_TxDByte(u8 dat)
{
Delay(1);
UserToPMABufferCopy(&dat, ENDP1_TXADDR,1);
SetEPTxCount(ENDP1, 1);
SetEPTxValid(ENDP1);
}
以下是寄存器值(在引导加载程序期间):
EP0 EP1 EP2 EP3 CNTR ISTR FNR DADDR BTABLE
5210 0031 0622 3003 8600 0000 A475 0087 0000
5210 0031 0622 3003 8600 0000 A5B3 0087 0000
5210 0031 0622 3003 8600 0000 A6F1 0087 0000
5210 0031 0622 3003 8600 0000 6030 0087 0000
5210 0031 0622 3003 8600 0000 A16E 0087 0000
5210 0031 0622 3003 8600 0000 A2AC 0087 0000
5210 0031 0622 3003 8600 0000 63EA 0087 0000
5210 0031 0622 3003 8600 0000 6529 0087 0000
5210 0031 0622 3003 8600 0000 A667 0087 0000
5210 0031 0622 3003 8600 0000 A7A5 0087 0000
5210 0031 0622 3003 8600 0000 A0E3 0087 0000
5210 0031 0622 3003 8600 0000 A221 0087 0000
5210 0031 0622 3003 8600 0000 A360 0087 0000
5210 0031 0622 3003 8600 0000 A49E 0087 0000
5210 0031 0622 3003 8600 0000 A5DC 0087 0000
5210 0031 0622 3003 8600 0000 A71A 0087 0000
当我可以在固件中正确执行 tx/rx 时,我发现只有 ISTR 寄存器为 0x0900,其他值相同(FNR 除外 ...)。但ISTR寄存器不能设置,只能复位。