OTA 升级问题的分析
背景:
我们在使用LIN总线做OTA升级的时候,偶发OTA升级不过。其中LIN总线使用TJA1128J的驱动芯片充当物理层。
问题1:为什么LIN总线在写入和擦除时需要初始化操作
分析:
物理电路差异:LIN(Local Interconnect Network)总线和CAN(Controller Area Network)总线在物理层和协议层都有显著差异。LIN总线通常使用一个主节点和多个从节点,通信速率较低,硬件实现也相对简单。CAN总线则更加复杂,支持更高的通信速率和更强的容错能力。这些物理电路上的差异会导致LIN驱动在中断处理方式上与CAN驱动有所不同。
中断禁用与LIN驱动初始化:在禁用中断期间,LIN控制器的状态可能发生改变。例如:接收缓冲区溢出、发送过程被打断等。某些LIN控制器可能不具备在中断被禁用后自动恢复到正常工作状态的能力。因此,在重新启用中断之前,需要对LN驱动进行初始化,以确保LIN控制器处于正确的状态,能够正常接收和发送数据,并响应中断。
保证再次进入中断:LIN驱动的初始化过程可能包括以下步骤:
重置LIN控制器:将LN控制器的寄存器设置为初始值,清除任何错误标志。
配置LIN控制器:设置UN控制器的波特率、中断使能等参数。使能LIN控制器:启动LIN控制器,使其开始监听总线上的数据。
通过这些步骤,可以确保LIN控制器在中断重新启用后能够正确地响应总线上的事件,并触发相应的中断。
CAN驱动的对比:相比之下,CAN控制器通常具有更强的硬件容错能力,可以在中断被禁用后自动恢复到正常工作状态。此外,CAN驱动的中断处理机制也可能更加完善,不需要在每次中断禁用和启用之间进行初始化。
总而言之,LIN驱动的物理电路特性和中断处理机制可能导致其需要在中断禁用和启用之间进行初始化,以确保其正常工作和能够再次进入中断。而CAN驱动则可能由于其硬件容错能力和中断处理机制的不同,不需要进行类似的初始化。
问题2:为什么LIN总线在写入和擦除时初始化操作的位置不一样
写入操作时LIN初始化发生在中断禁止之后,中断启动之前。擦除操作时LIN初始化发生在中断启动之后。
分析:
写入操作时LIN初始化发生在中断禁止之后,中断启动之前是为了避免中断启动后LIN驱动没准备好的问题。启动中断后再初始化总线上的流控帧存在丢失的风险。
擦除操作时LIN初始化发生在中断启动之后可能原因如下
关键因素分析
MemAbs_udtEraseBlock的操作特性:
MemAbs_udtEraseBlock函数用于擦除Flash存储器的指定块。从fls.c文件中的Fls_Erase函数实现来看,该函数通过调用底层的FLASH_DRVEraseSector函数来完成擦除操作。
查看Flash_driver.c中的FLASH_DRV_EraseSector函数,该函数通过轮询FTFx_FSTAT寄存器的CCIF位来等待擦除操作完成。在等待期间,它会定期调用用户提供的回调函数pSSDConfig->CallBack()。
这段代码的核心在于对Flash硬件的操作,依赖于中断的可能性相对较低。但是FLASH_DRV_EraseSector函数中,在等待CCIF标志时,会周期性地调用pSSDConfig->CallBack()。这意味着,擦除操作期间,即使中断被禁用,仍有可能通过这个回调函数间接影响LIN驱动。
LINAPP_Init的作用:
从com文件中可以看到LINAPP_Init()的作用是初始化LIN通信。这可能包括初始化LIN控制器、配置LIN节点地址、使能LIN中断等操作。中断保护的范围:
中断禁用区域只保护了MemAbs_udtEraseBlock和MemAbs_udtGetJobResult的调用。这表明,这些操作是需要原子性保护的关键区域。
考虑到以上因素,以下是关于为什么LINAPP_Init放置在中断启用后的几种可能解释:
回调函数的中断竞争:在FLASH_DRV_EraseSector等待CCIF时,会周期性调用pSSDConfig->CallBack。如果这个回调函数与LIN驱动存在中断竞争关系(例如 回调函数中使用了LIN驱动的某些共享资源),那么禁用中断可以防止竞争条件。而在中断保护结束后,重新初始化LIN驱动,可以保证LIN驱动的正常运作。
总结
总而言之。LINAPP_Init()放置在中断启用后,可能是为了解决FLASH_DRV_EraseSector中回调函数可能与LIN驱动产生的潜在中断竞争。

浙公网安备 33010602011771号