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

时间:2个月前   阅读:490

可以帮忙调试,QQ:778292363

html.png

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);

		}
}



微信扫码关注

更新实时通知

上一篇:xs5013模拟视频编码,bt1120转ahd tvi cvi格式,调试资料和教程

下一篇: can控制器 uds诊断完整代码(c写的keil项目)遵循iso sae J1939标准(stm32 N32 系列MCU可用)

网友评论

请先 登录 再评论,若不是会员请先 注册