2022年参与了两个bootloader项目的开发,两个项目使用的芯片、通讯驱动不同,因此传输协议也不同,年底了将两个项目做一个对比,也顺便加深下对bootloader的理解。
相同点:
modbus | uds | |
刷新流程 | 刷新流程大同小异,简单来说:在应用报文中收到刷新请求报文,将刷新请求标志位置1存在E2中,然后执行复位操作。程序复位后判断存储在E2中的刷新请求标志位是否置1,如果置1了,那么清除刷新请求标志位并执行刷新流程;如果没有置1,则去判断程序有效性标志位是否置1,如果没有置1,那么也需要清除刷新请求标志位并执行刷新流程,如果置1了,说明应用程序是完整的,则直接调到应用程序入口处,执行应用程序。 | |
整帧报文识别机制 | 只要涉及到通讯,那么就需要对整帧报文的判断识别。modbus和uds两种协议各自都有整帧报文的识别方法。 |
不同点:
modbus | uds | |
时间要求不同 | 无 |
|
报文解析不同 | 上位机可以直接解析hex文件,然后发送hex报文,加载引导程序需要对收到的hex报文进行解析,需要熟悉hex报文的构成及语法格式 | 需要用特定工具将hex文件转换为sff文件,然后用上位机发送sff文件里的报文,引导加载程序收到完整的报文后根据报文内的服务内容进行解析 |
整帧报文识别机制不同 | modbus报文规定了两帧报文之间的时间间隔不能超过3.5个uart报文占用的时间,因此可以用这个规则作为一帧完整报文的识别依据,即:每收到一个uart字节,就启动专用的定时器,接下来如果能进到定时器中断里,则说明有一段时间没有收到uart报文,这种情况下认为收到的uart报文是完整的,可以认为是一帧modbus报文。 | uds完整报文的识别比较简答,对于单帧而言,单帧本身已经构成了一帧完整的报文;对于多帧而言,首帧前两个字节中已经包含了该完整报文的长度,因此在接下里多帧的传输过程中,uds接收到的字节数达到报文长度,就可以认为收到了一帧完整的uds报文。 |
架构不同 | 上层的modbus协议和下层的uart协议完全分开,并由各自的状态机进行管理。 uart状态机会对uart接收过程中进行管理; 程序跑到专用定时器中断里,说明uart报文接收过程已经完成,在uart状态机中通过Uart_RxIndication将完整的uart报文托付给modbus状态机,并更新modbus状态机的标志位;modbus状态机在轮询过程中根据标志位进行modbus报文的处理; modbus报文处理完毕后,会将待回复的modbus报文通过Modbus_Reply托付给uart状态机,并更新uart状态机的标志位;uart状态机在轮询过程中根据标志位进行uart报文的发送;
| 上层的uds协议和下层的can协议完全分开。 can报文的接收由硬件支持,uds报文的整帧识别由uds管理。
|
App有效性标志位不同 | App的有效性是以在App中间和结束位置插入的两个tag来保证的,即boot初始化阶段读存放tag的那段地址,若读到的值与设定值一致,则认为App是有效的 | App的有效性是以单独设置的App有效性标志位来保证的,刷新过程结束后,boot会根据软件的完整性和兼容性更新有效性标志位,并存在特定的位置(该位置与app/boot没有关系)。boot初始化阶段会访问该位置读取有效性标志,若读到的值是有效的则认为App是有效的。 |
用Tag保证App有效性的前提是:软件可以在flash被擦除的情况下读flash中的内容。对于S32K144/SPD1178而言,被擦除之后的地址可以直接访问,读到的值是固定的(0/1),而对于TC397,某块地址被擦除之后,该地址存放的值不再是固定的值,在程序中直接访问会引发错误,所以如果也用tag来记录有效性,那么在App被破坏之后,boot初始化访问tag地址段会导致程序卡死。