1949啦网--小小 痛苦,是因为能力和欲望不匹配造成的

can控制器 Bootloader刷新流程,及其完整代码c写的(stm32 N32 系列MCU可用)

可以帮忙调试,QQ:778292363



Bootloader是在ECU上电初始化时运行的一段代码,它通过can线接收来自上位机的命令,将数据写进ECU的指定Flash区段中。 本文件主要约束控制器(以下简称ECU)的Bootloader数据刷写流程。该项目中BT刷新流程采用UDS统一诊断服务来实现。

该项目需要将ECU待刷写的区域划分成逻辑块,并对每个块进行编号,每个块的大小和起始地址一经确定,后续不允许修改,需要供应商根据功能类别进行准确定位。本项目对ECU的块的个数有限制要求,根据待刷写程序的类别,要求擦除程序、引导程序、应用程序、应用数据各自只能有1个逻辑块。如果同种类型有多个块,请与陕汽刷写工程师联系确定最终状态。 

待刷写的ECU内部不需要内置擦除程序,擦除程序的块号编号为0,每次刷写时都需要从数据管理平台上下载;引导程序的块编号为1,应用程序的块编号为2,应用数据的块编号为3。 

块的使用体现34服务和31服务上,在34服务中表示即将传输的程序的块编号,31服务中表示需要对某个块进行编程完整性和兼容性检查。BT中使用的34服务的数据格式定义和UDS国际标准定义完全不一样,详细的定义见服务描述。

 ECU供应商提供给OEM生产线或者售后服务处的应用程序与应用数据文件使用.bin格式。需要ECU供应商反馈bin文件的基本信息,

整个项目完整代码已经在前装车载设备上使用:

#include "main.h"  #include "bt_define.h"      uint8_t flash_driver_arr[FLASH_DRIVER_LENGTH] __attribute__((at(0x20007000))) = {0};    typedef void (*pFunction)(void);  pFunction Jump_To_Application;  uint32_t JumpAddress;    void Jump_To_App(uint32_t address)  {      /* Judge whether the top of stack address is legal or not */      if (((*(__IO uint32_t*)address) & 0x2FFE0000) == 0x20000000)      {  				/* 屏蔽所有中断,防止在跳转过程中,中断干扰出现异常 */  				__disable_irq();          /* Jump to user application */          JumpAddress = *(__IO uint32_t*) (address + 4);          Jump_To_Application = (pFunction) JumpAddress;  			          /* Initialize user application's Stack Pointer */          __set_MSP(*(__IO uint32_t*) address);          Jump_To_Application();      }  }    //#include "n32g43x_crc.h"    int main(void)  {  		Systick_MS_Config(); //Setup SysTick Timer for 1 msec interrupts  		tim6_7_init();  		can0_init();    		earse_flash_4_page();  		  		uds_init();    		if(flash_read(REQ_PROGRAM_UPDATE_FLAG_ADDR) == 0x1)  		{  						  				//如果ECU在正确的条件下收到“$10 $02”指令,ECU将重编程请求标志状态位设为有效,并执行ECU重启。  				flash_write(REQ_PROGRAM_UPDATE_FLAG_ADDR, 0x0);  			  				m_SecurityLevel = UDS_SA_NON;  				uds_session = (uds_session_t)UDS_SESSION_PROG;  				uds_timer_start (UDS_TIMER_S3server);    		}  		else  		{  				sys_delay_ms(15);  				if(is_force_update == 0x1)  				{  						is_force_update = 0x0;  					  						m_SecurityLevel = UDS_SA_NON;  						uds_session = (uds_session_t)UDS_SESSION_PROG;  						uds_timer_start (UDS_TIMER_S3server);  				}  				else  				{  					  						RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_CRC, ENABLE);  						__IO uint32_t CRCValue   = 0;  						/* Compute the 32bit CRC of "DataBuffer" */  						CRC32_ResetCrc();  						CRCValue = CRC32_CalcBufCrc((uint32_t*)FLASH_APP1_ADDR, FLASH_APP1_CRC_LENGTH/0x4);  						CRC32_ResetCrc();  						if(CRCValue == (*(__IO uint32_t*)(FLASH_APP1_CRC_ADRR)) && 0x2 == (*(__IO uint32_t*)(FLASH_APP1_LOGIC_BLOCK_ADRR)))  						{  								flash_write(FLASH_APP1_VALID_ADRR, 0x1);  							  								CRC32_ResetCrc();  								CRCValue = CRC32_CalcBufCrc((uint32_t*)(FLASH_APP1_ADDR+0xC800), FLASH_APP1_CRC_LENGTH/0x4);  								CRC32_ResetCrc();  								if(CRCValue != (*(__IO uint32_t*)(FLASH_APP1_CRC_ADRR+0xC800)))  								{  										bt_flash_erase(FLASH_APP2_ADDR, FLASH_APP2_LENGTH);  										bt_flash_write(FLASH_APP2_ADDR, (u8 *)FLASH_APP1_ADDR, FLASH_APP2_LENGTH);  								}  						}  						else  						{  								flash_write(FLASH_APP1_VALID_ADRR, 0x0);  								bt_flash_erase(FLASH_APP1_ADDR, FLASH_APP1_LENGTH);  								bt_flash_write(FLASH_APP1_ADDR, (u8 *)FLASH_APP2_ADDR, FLASH_APP1_LENGTH);  								/* Compute the 32bit CRC of "DataBuffer" */  								CRC32_ResetCrc();  								CRCValue = CRC32_CalcBufCrc((uint32_t*)FLASH_APP1_ADDR, FLASH_APP1_CRC_LENGTH/0x4);  								CRC32_ResetCrc();  								if(CRCValue == (*(__IO uint32_t*)(FLASH_APP1_CRC_ADRR)) && 0x2 == (*(__IO uint32_t*)(FLASH_APP1_LOGIC_BLOCK_ADRR)))  								{  										flash_write(FLASH_APP1_VALID_ADRR, 0x1);  								}  								else  								{  										flash_write(FLASH_APP1_VALID_ADRR, 0x0);  								}  						}  						  						if(flash_read(FLASH_APP1_VALID_ADRR) == 0x1)  						{  								if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)  								{  										Jump_To_App(FLASH_APP1_ADDR);				//跳转到APP起始地址,期间不能被其他中断打断,否则会跳转失败  								}  						}    				}  		}    		while(1)  		{  			  //				u8 send_buf[8] = {0x0};  //				can_send_mess(0x222, send_buf, 8);  				sys_delay_ms(1);    		}  }





微信扫码关注

更新实时通知

作者:xialibing 分类:软件笔记 浏览: