STM32F1自带的ISP协议

背景

STM32F1在厂家固件中固定写入一个ISP的驱动,当配制好相应的启动管脚时,就可以通过UART1及相关的通信协议与MCU进行通信。可以进行一个FLASH的读写操作。
从使用的角度添加了一个交互操作方法,用户可以通过这种方式对MCU进行程序烧序,或者通过SWD,或者自己定义程序更新的应用。

硬件电路

BOOT管脚配置

BOOT0 = 1, BOOT1 = 0这种情况下上电即可。

一键ISP电路

配制成串口ISP的时候,若想从MAIN FLASH中开始运行程序,需要将BOOT0,BOOT1的管脚进行重新配置,操作起来比较麻烦。通过一键ISP电路,通过设置UART的RTS,与DTR管脚设置来达到切换BOOT0,BOOT1管脚电平的效果。
可以在不用改动硬件接线的情况下,通过软件设置来达到启动选项的切换。

UART参数设置

UART硬件参数为,1位起始位,8位数据位,偶校检,1位停止位。波特率STM32在收到0x7F这个配对信号后,自动调整与之相对应的波特率。

ISP协议解析

概览


不同版本的ISP协议,命令会有些偏差。
返回代码ACK=0x79,NACK=0x1F

sync

host device note
0x7f - 发送0x7f,单片机收到后会自动匹配波特率。
- 0x79(ACK)/0x1F(NACK) device返回ACK或NACK,表示对host的反应。

在已经发送过其他非0x7f的命令下,再发送0x7f,有时间并不会返回ACK指令,或者会返回NACK指令。
原因在于刚开始的指令造成STM32本身的波特率选择混乱,故不能正常返回。需要在复位后第一时间发送同步0x7f指令。

get command

host device note
0x00 + 0xff -
- 0x79(ACK)/0x1F(NACK)
- N 1字节,表示下面要接收到的字节数。bootloaderversion字节数 + 所有指令字节数 = N+1
- bootloader version 1字节,如0x21代表2.1版本
- 所有支持的指令 多个字节,每个字节数据都表示一个支持的指令
- 0x79(ACK)/0x1F(NACK) 指令执行结束后会返回0x79
返回的所有指令

get version & read protection

host device note
0x01+0xfe -
- 0x79(ACK)/0x1F(NACK)
- bootloader version 0x10 = 1.0
- 2个字节 这两个字节和保护状态有关
- 0x79(ACK)/0x1F(NACK)

get ID command

host device note
0x02+0xfd -
- 0x79(ACK)/0x1F(NACK)
- N 1字节,表示下面 PID字节数 - 1
- PID 多字节(上一个字节已指明字节数),先传高位后传低位。我这次用的stm32f103c8t6是2字节。
- 0x79(ACK)/0x1F(NACK)

Erase Memory command

host device note
0x43+0xbc -
- 0x79(ACK)/0x1F(NACK)
0xff+0x00 - 这是全擦指令
- 0x79(ACK)/0x1F(NACK)

Write Memory command

host device note
0x31+0xCE -
- 0x79(ACK)/0x1F(NACK)
addr - 4字节,下载地址。用户flash起始地址是0x08000000。先发高位,后发低位
addr checksum - 1字节,地址的checksum,就是上面4字节数据的异或。
- 0x79(ACK)/0x1F(NACK)
count - 1字节,表示后面将要传输的字节数,范围(0, 255]。字节数 = 这个值+1,也就是说最大传输256字节。
data - 多字节,字节数 = count + 1,最大256字节。这里下载进去的是bin文件,不是hex
checksum - 1字节,上面的data数据,以及数据个数count的checksum。注意这里的checksum包含数据和个数
- 0x79(ACK)/0x1F(NACK)

Read Memory command

host device note
0x11+0xEE 0x79(ACK)/0x1F(NACK)
addr - 4字节,下载地址。用户flash起始地址是0x08000000。先发高位,后发低位
addr checksum - 1字节,地址的checksum,就是上面4字节数据的异或。
- 0x79(ACK)/0x1F(NACK)
count - 1字节,将要读取的数据个数,0~255。count+1就是将要读取的字节数,最多读取256字节。
checksum - 1字节,count的按位取反。
- 0x79(ACK)/0x1F(NACK)
- data count+1个字节,这就是要读取的数据。

Readout Protect command

host device note
0x82+0x7d - 发送0x7f,单片机收到后会自动匹配波特率。
- 0x79(ACK)/0x1F(NACK) device返回ACK或NACK,表示对host的反应。
- 0x79(ACK)/0x1F(NACK) device返回ACK或NACK,表示对host的反应。

Readout Unprotect command

host device note
0x92+0x6d - 发送0x7f,单片机收到后会自动匹配波特率。
- 0x79(ACK)/0x1F(NACK) device返回ACK或NACK,表示对host的反应。
- 0x79(ACK)/0x1F(NACK) device返回ACK或NACK,表示对host的反应。

Readout Protect 与 Unprotect 命名返回的ACK,是分一个间隔返回的,并不是同时返回的,处理的时候需要一个等待操作
同时无论Protect 还是 Unprotect操作后,ISP的通信都需要重新同步后,才能正常工作。

checksum计算方法

checksum主要计算的是发送的数据的checksum并不包括最早的指令,以addr为例,checksum就是addr的四个字节进行xor计算出checksum的值

uint8_t Isp::check_sum(uint8_t *pData_, int len_)
{
    uint8_t checkSum = 0;
    while(len_--)
    {
        checkSum ^= *pData_++;
    }
    return checkSum;
}

总结

STM32F1的ISP协议给了我们用户多了一种途径对程序固件进行更新的操作方式。
不过STM32F1的ISP容错效果并不是很好,只要一出错就需要将ISP重新开始同步,有时还需要将芯片进行复位操作

参考

https://github.com/nicekwell/stm32ISP

posted @ 2022-09-17 08:44  cau_par  阅读(3560)  评论(0编辑  收藏  举报