can通讯bootloader程序升级;

1.传输协议

2. boot里交互(两车必须要完成握手双方才能收到,即相互发送数据等待传数据)

.c文件

#include "WirelessCommunicate.h"
#include "string.h"
#include "iap.h"
#include "CRCDataCale.h"
#include "cmsis_os.h"
#include "WirelessUartDataWIFI.h"
#include "flash_port.h"
#include "F750_CAN_HW.h"

// #include "cart_ctrl_main.h"
// #include "config_data.h"


#define GoToAppTime 300.0f // 定义如果没有接收到串口数据帧跳转到app应用程序的时间
uint8_t step = 0;
WirelessMsg MsgRecieve;
WirelessMsg MsgSend;
unsigned short DataReadAddress; // 无线通信读取起始地址
unsigned char DataReadLength;	// 无线通信写起始地址

小车优先级
// #define USART_REC_LEN  			100//定义最大接收字节数 320K
// unsigned char USART_RX_BUF[USART_REC_LEN][1024] __attribute__ ((at(0X20000000)));//接收缓冲,最大USART_REC_LEN个字节,起始地址为0X20021000.
#define USART_REC_LEN1 512													   // 250//定义最大接收字节数 320K
unsigned char USART_RX_BUF1[1024 * 512] __attribute__((section(".flashRAM"))); // 1024*512字节   把所有的程序数据接收到这里-ram块2区,后面一起写入flash

#define MAX_PROGRAMFRAME 512					  // 250 //可下载的最长程序长度
#define MAX_PROGRAMSIZE (1024 * MAX_PROGRAMFRAME) // 可下载的最长程序长度

/* 标记升级完成 */
void Set_Update_Down(void)
{
	unsigned int update_flag = 0xAAAAAAAA;													 ///< 对应bootloader的启动步骤
	falsh_write_uint32((uint32_t)(FLASH_APP1_ADDR + Application_Size - 4), &update_flag, 1); // 往程序末尾写入特定数据,确保下次不会重复升级
}

/**
 * @bieaf 读若干个数据
 *
 * @param addr       读数据的地址
 * @param buff       读出数据的数组指针
 * @param word_size  长度
 * @return
 */
static void ReadFlash(uint32_t addr, uint32_t *buff, uint16_t word_size)
{
	for (int i = 0; i < word_size; i++)
	{
		buff[i] = *(__IO uint32_t *)(addr + 4 * i);
	}
	return;
}
/* 读取启动模式 */
unsigned int Read_Start_Mode(void)
{
	unsigned int mode = 0;
	ReadFlash((FLASH_APP1_ADDR + Application_Size - 4), &mode, 1);
	return mode;
}
// 接收到的数据先往RAM区暂存
bool AddProgramDataToRam(int frameNo, unsigned char *pData, uint32_t i)
{
	if (frameNo < USART_REC_LEN1)
	{
		memcpy(&USART_RX_BUF1[0 + (i * 1024)], pData, 1024);//i 数据编号
	}
	else
		return false;
	return true;
}

unsigned int ReportErrorTime = 0;
unsigned short currentDownloadFrame = 0; // 当前程序下载帧 --每帧1024字节
unsigned short mProgramFrameNum = 0;	 // 下载的程序的总帧数
unsigned int mProgramLength = 0;		 // 下载程序的总长度
int mDownloadProgramCrc32, mProgramCaleCrc32;
int handshakeSignal = 0;		   // 握手信号
bool mDownloadProgramFlag = false; // 程序下载成功标志位 0失败,1成功
bool ReplyFlag = false;			   // 应答标志位 0不应答,1应答
bool RecieveFlag = false;
static float timeCount = 0, systemTick = 0;
int remain_time = 0;
unsigned short percent_rate = 0;
unsigned short current_frame = 0;
unsigned short total_frame = 0;
static uint32_t KByte_num = 0;

//canboot部分
static bool  master_rcv_wf_updata_flag;//前车接收完wifi需要更新的程序,即将发给后车
uint8_t m_send_bootsuccess_state_flag = 0;//主车发送正确数据标志,1发送正确0发送错误
uint8_t s_rcv_bootsuccess_state_flag = 0;//从车接收到正确数据标志,1发送正确0发送错误
uint32_t slave_rcv_mProgramLength = 0 ;//后车接收到程序长度
uint32_t canboot_currentDownloadFrame = 0;//下载程序数据字节次数
uint8_t  slave_rcv_flag_1 = 0;//从车开始接收程序数据
extern uint8_t io_can_init_sign;//can初始化完成
static bool s_can_get_ws_sign = 0;//从车激活
static bool m_can_get_ws_sign = 0;//从车激活
static uint8_t index_cont = 0;//程序包序号
static uint8_t up_index_cont = 0;//上一程序包序号
static uint16_t ccc;
uint32_t sramget_master_or_slave_sign = 0;//获取到的前后车
struct{
    uint8_t  slave_head_sign;                                   //小车从车头工作标记
    float    slave_speed;                                       //从车头的运行速度,单位m/min
    int16_t  master_speed;                                      //主车头的运行速度,单位m/min
} dual_head_sign = {0};

static void DealReachMsg(void)
{
	int i = 0;
	// 接收返回
	MsgSend.SrcWebID = 0;
	MsgSend.DesWebID = MsgRecieve.SrcWebID;

	i = sizeof(MsgSend.Data[0]);
	memset(&MsgSend.Data[0], 0, MAXDATALENGTH * i);
	MsgSend.DataLength = 0;
	MsgSend.CmdNo = MsgRecieve.CmdNo;
	MsgSend.Data[0] = MsgRecieve.Data[0];
	MsgSend.Data[1] = MsgRecieve.Data[1];//接收的数据帧编号
	/*接收命令标识分析*/
	switch (MsgRecieve.CmdNo) // 命令标识
	{
	case 0xFA:		   // 请求程序下载
		timeCount = 0; // 时间计时清零
		mProgramLength = MsgRecieve.Data[2];
		mProgramLength <<= 8;
		mProgramLength |= MsgRecieve.Data[3];
		mProgramLength <<= 8;
		mProgramLength |= MsgRecieve.Data[4];
		mProgramLength <<= 8;
		mProgramLength |= MsgRecieve.Data[5];

		handshakeSignal = MsgRecieve.Data[6];
		handshakeSignal <<= 8;
		handshakeSignal |= MsgRecieve.Data[7];
		handshakeSignal <<= 8;
		handshakeSignal |= MsgRecieve.Data[8];
		handshakeSignal <<= 8;
		handshakeSignal |= MsgRecieve.Data[9];

		if (mProgramLength > MAX_PROGRAMSIZE)
			MsgSend.Data[2] = 2;
		else if (handshakeSignal != 0x0a1f55a0)
		{
			// MsgSend.Data[3]=2;
			MsgSend.Data[2] = 1; // personal veiw //返回状态
		}
		else
			MsgSend.Data[2] = 0;

		MsgSend.DataLength = 3;
		// FLASH_If_Erase(FLASH_APP1_ADDR);

		ReplyFlag = true;
		break;
	case 0xFB:		   // 下载程序数据
		timeCount = 0; // 时间计时清零

		currentDownloadFrame = MsgRecieve.Data[2];
		currentDownloadFrame <<= 8;
		currentDownloadFrame |= MsgRecieve.Data[3];

		mProgramFrameNum |= MsgRecieve.Data[4];
		mProgramFrameNum <<= 8;
		mProgramFrameNum |= MsgRecieve.Data[5];

		AddProgramDataToRam(currentDownloadFrame, &MsgRecieve.Data[6], MsgRecieve.index); // 程序每来一帧就写入RAM区
		percent_rate = (((float)(MsgRecieve.index * 1024) / (float)mProgramLength) * 100);
		if (mProgramLength > MAX_PROGRAMSIZE)
			MsgSend.Data[2] = 2;
		else
			MsgSend.Data[2] = 0;
		MsgSend.DataLength = 3;
		ReplyFlag = true;
		if (((float)(MsgRecieve.index * 1024) > (float)mProgramLength))
		{
			percent_rate = 100;
		}
		break;
	case 0xFC:		   // 请求更新程序
		timeCount = 0; // 时间计时清零
		mProgramLength = MsgRecieve.Data[2];
		mProgramLength <<= 8;
		mProgramLength |= MsgRecieve.Data[3];
		mProgramLength <<= 8;
		mProgramLength |= MsgRecieve.Data[4];
		mProgramLength <<= 8;
		mProgramLength |= MsgRecieve.Data[5];

		mDownloadProgramCrc32 = MsgRecieve.Data[6];
		mDownloadProgramCrc32 <<= 8;
		mDownloadProgramCrc32 |= MsgRecieve.Data[7];
		mDownloadProgramCrc32 <<= 8;
		mDownloadProgramCrc32 |= MsgRecieve.Data[8];
		mDownloadProgramCrc32 <<= 8;
		mDownloadProgramCrc32 |= MsgRecieve.Data[9];

		// mProgramCaleCrc32=calculate_CRC32((uint8_t *)FLASH_APP1_ADDR,mProgramLength);
		mProgramCaleCrc32 = calculate_CRC32(USART_RX_BUF1, mProgramLength);
		if (mProgramCaleCrc32 == mDownloadProgramCrc32)
		{
			master_rcv_wf_updata_flag = 1;//前车接收wifi到更新数据
		
			#if CAN_BOOT_onoff
			if (m_send_bootsuccess_state_flag == 1)//后车头收到正确程序包后前车再写入,下面的写入对于双车头后车更新完后前车后不会进入,所以没啥用
			#endif
			{
				MsgSend.Data[2] = 0;
				mDownloadProgramFlag = true;
				taskDISABLE_INTERRUPTS(); // 开启写入flash动作之前需先关闭所有中断任务
				// falsh_erase_bank(FLASH_APP1_ADDR);
				falsh_write_uint8(FLASH_APP1_ADDR, USART_RX_BUF1, mProgramLength); // 此处已有擦除动作
				Set_Update_Down();												   // 往程序最后一段之后写入固定数据用做标识
				taskDISABLE_INTERRUPTS();
				KByte_num = 0;
			}
		}
		else
			MsgSend.Data[2] = 1;
		MsgSend.DataLength = 3;
		ReplyFlag = true;
		break;
	default:
		break;
	}
}


void WirelessTranslateMsg(float timeCycle) // 处理接收到的数据串
{
	timeCount += timeCycle;
	systemTick += timeCycle;
	remain_time = (20 - timeCount);
	if (timeCount < 2.0f)
	{
		if (systemTick > 0.1f)
		{
			HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_7); // LED灯0.1s闪烁一次
			systemTick = 0;
		}
	}
	else
	{
		if (systemTick > 0.1f)
		{
			HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_7);
			systemTick = 0;
		}
	}
	if ((mDownloadProgramFlag == true)

		#if CAN_BOOT_onoff
		&& ((m_send_bootsuccess_state_flag == 1) || (s_rcv_bootsuccess_state_flag == 1))
		#endif

		)//从车头收到正确程序包后再跳转到app && (m_send_bootsuccess_state_flag == 1)
	{
		mDownloadProgramFlag = false;
		osDelay(10);
		//		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET);
		IAP_ExecuteApp((uint32_t)FLASH_APP1_ADDR);
		//		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET);
	}
	else if (timeCount > GoToAppTime)
	{
		// if(Read_Start_Mode()==0xAAAAAAAA)
		{
			IAP_ExecuteApp((uint32_t)FLASH_APP1_ADDR); // 执行FLASH APP代码 //超时先不向app里跳
		}
		// else
		{
			timeCount = 0;
		}
	}
	else
	{
		GetWirelessWIFIRecMsg(&MsgRecieve, &RecieveFlag);
		if (RecieveFlag == true) // 如果接收到WiFi发送过来的命令
		{
			RecieveFlag = false;
			DealReachMsg(); // 处理写FLASH命令
			if (ReplyFlag == true)
			{
				ReplyFlag = false;
				SetSendWirelessWIFIMsg(MsgSend); // 回应WiFi服务器端
			}
		}
		CAN boot 处理部分///
		#if CAN_BOOT_onoff
		else
		{
			get_master_or_slave_sign();
			if (sramget_master_or_slave_sign != 0)
				can_upboot();
		}
		#endif
	}
	#if CAN_BOOT_onoff
	if(slave_rcv_flag_1 != 0)//后车
	{
		current_frame = canboot_currentDownloadFrame / 1024;
		total_frame = slave_rcv_mProgramLength / 1024;
	}

	else
	#endif
	{
		current_frame = currentDownloadFrame;
		total_frame = mProgramLength / 1024;

	}
	

///测试can通信//
	
// 	static uint8_t time_for_speed_can_send = 0;
// 	if((io_can_init_sign == 1))//(dual_head_sign.slave_head_sign == SLAVE_HEAD)
// 	{	
// 			static uint8_t  rx_buffer[32] = {0};
// 			static uint8_t  rx_buffer_hc[8] = {0};
// 			uint8_t  buffer[8]={0x11,0x11,0x11,0,0,0,0,0};//激活的数据
// 			uint8_t  tx_buffer_data[32]={0x55,0x55,0x55,0,0,0,0,0  ,0x66,0x66,0x66,0,0,0,0,0  ,0x77,0x77,0x77,0,0,0,0,0};//发送的数据
// 			static uint8_t xxx=0;
// 			static uint8_t w=0;
// 			static uint8_t yyy=0;//发完就走
//
// 		//  time_for_speed_can_send ++;
// 		// if(time_for_speed_can_send > 5)
// 			time_for_speed_can_send = 0;
// 		if((time_for_speed_can_send == 0) && (io_can_init_sign == 1) && (xxx == 0)) //激活
// 		{
// 			for (uint8_t i = 0; i < 2; i++)
// 			{
// 				// time_for_speed_can_send ++;
// 				CAN_sendMsg_dual_hend(1, &buffer[0], 8);
// 				// osDelay(1); // 休眠5ms
// 			}	
// 		}
//
// 		// for (size_t i = 0; i < 4; i++) // yyy = 0; yyy < 2; yyy++
// 		// {
// 		// 	if (CAN_sendMsg_dual_hend(5, &tx_buffer_data[ w * 8 ], 8) == 0) //发送
// 		// 	{
// 		// 		w++;
// 		// 		xxx++;
// 		// 		break;
// 		// 	}
//			
// 		// }
//
// 		for (size_t i = 0; i < 4; i++)
// 		{
// 			if (CAN_revMsg_dual_head(&rx_buffer[ w * 8 ], 8) == 1) //接收
// 			{
// 				xxx++;
// 				// memset(&rx_buffer[ w * 8 ], 0, 8);
// 				// memcpy(&rx_buffer[ w * 8 ], rx_buffer, 1024);//i 数据编号
// 				w++;
// 				break;
// 			}
// 		}
//		
// 		// if((rx_buffer[0] == 0x11) && (rx_buffer[1] == 0x22) && (rx_buffer[2] == 0x33))
// 		// {
// 		// 	IAP_ExecuteApp((uint32_t)FLASH_APP1_ADDR);
// 		// }
// 	}

}

///



// uint32_t aaac = 0;

// uint32_t bbbc = 0;
// void sram_boot()
// {
//     uint8_t i;
//     BackupSRAM_ReadData(BACKUPSRAM_DIS_can_boot, (uint8_t *)&bbbc, 4);
//     // aaac++;
//     //  aaac = 30;
//     // BackupSRAM_WriteData(BACKUPSRAM_DIS_can_boot, (uint8_t *)&aaac, 4);
//     // i++;
// }



#if CAN_BOOT_onoff
//读取备份寄存器前后车头数据
void get_master_or_slave_sign(void)
{
    uint8_t i;
    BackupSRAM_ReadData(BACKUPSRAM_DIS_can_boot, (uint8_t *)&sramget_master_or_slave_sign, 4);
    // aaac++;
    //  aaac = 30;
    // BackupSRAM_WriteData(BACKUPSRAM_DIS_can_boot, (uint8_t *)&aaac, 4);
    // i++;
}
//can 更新程序
static void can_upboot(void)
{
	// if ((m_send_bootsuccess_state_flag != 1))
	if ((s_rcv_bootsuccess_state_flag != 1) && (m_send_bootsuccess_state_flag != 1))
	{
		master_send_slave_canboot();
	}
	// if ((s_rcv_bootsuccess_state_flag == 1)) //加else if
	else if (s_rcv_bootsuccess_state_flag == 1) //后车头写入   //加else if     || (m_send_bootsuccess_state_flag == 1)
	{
			mDownloadProgramFlag = true;
			taskDISABLE_INTERRUPTS(); // 开启写入flash动作之前需先关闭所有中断任务
			// falsh_erase_bank(FLASH_APP1_ADDR);
			falsh_write_uint8(FLASH_APP1_ADDR, USART_RX_BUF1, slave_rcv_mProgramLength); // 此处已有擦除动作
			Set_Update_Down();												   // 往程序最后一段之后写入固定数据用做标识
			taskDISABLE_INTERRUPTS();			
	}
	else if(m_send_bootsuccess_state_flag == 1)//前车头写入
	{
		MsgSend.Data[2] = 0;
		mDownloadProgramFlag = true;
		taskDISABLE_INTERRUPTS(); // 开启写入flash动作之前需先关闭所有中断任务
		// falsh_erase_bank(FLASH_APP1_ADDR);
		falsh_write_uint8(FLASH_APP1_ADDR, USART_RX_BUF1, mProgramLength); // 此处已有擦除动作
		Set_Update_Down();												   // 往程序最后一段之后写入固定数据用做标识
		taskDISABLE_INTERRUPTS();
		KByte_num = 0;
	}
}

static uint8_t tx_validate_data_cont = 0;//程序传输验证次数
static uint32_t tx_Progra_data_cont = 0;//程序传输需要次数
static uint8_t m_tx_Progra_finish_flag = 0;//程序数据传输完成
static uint8_t Progra_number_flag = 0;//已传输数量等于需要传输的数量,可能还有余数

//开始相互发握手后 就可以直接进行数据交互了。必须发送(可以连续发送)一帧后接收端就接收(不能连续接收),不然接收端接收到的消息会被覆盖
master_send_slave_canboot()
{
	static uint8_t m_surplus = 0;//每次传完8个后的余数
	static uint32_t m_tx_Progra_cont = 0;//程序传输需要次数
	uint8_t master_send_Program_msg[8] = {0};//需要发送给后车管理信息
	static uint8_t master_rcvack_Program_state[8] = {0};//前车接收后车的管理信息状态
	static uint8_t master_rcvack_Program_state_2[8] = {0};//前车接收后车接收到程序的状态,成功或失败
	static uint8_t master_rcvack_flag_1 = 0;//两车已握手获取到程序信息,可进入正式传程序阶段
	uint8_t time_for_speed_can_send = 0;
	static uint8_t rx_buffer_tmp[8] = {0};//前车交互阶段接收
	static uint8_t master_rcv_slave_erro_ack[8] = {0};//接收传程序过程中后车的应答
	static uint32_t m_tx_front_Progra_cmd = 0;//上一次指令次数
	static uint8_t Program_tx_start_flag = 0;//让前车先发送后接收
	bool tx_state_flag = 1;//0失败1成功
	static uint16_t no_rcv_slave_ack = 0;//超时未接收到计数
	static uint8_t erro_cont = 0;//测试数		
	uint8_t cmd = 0XA3;	
	uint8_t master_tx_Program_state[8] = {cmd , index_cont , 0 , 0 , 0 , 0 , 0 , 0};//程序数据传输

	//参数区分前后车
	if(sramget_master_or_slave_sign == DUAL_HEAD_FRONT)
        dual_head_sign.slave_head_sign = MASTER_HEAD;
    else if(sramget_master_or_slave_sign == DUAL_HEAD_BACK)
        dual_head_sign.slave_head_sign = SLAVE_HEAD;
    else
        return;

	// //变量写死区分前后车
	// if(sign_master_or_slave == DUAL_HEAD_FRONT)
    //     dual_head_sign.slave_head_sign = MASTER_HEAD;
    // else if(sign_master_or_slave == DUAL_HEAD_BACK)
    //     dual_head_sign.slave_head_sign = SLAVE_HEAD;
    // else
    //     return 0;

//激活处理  
	uint8_t master_buffer_q[8]={ 0xA1, 0, 0, 0, 0, 0, 0, 0 };//前车激活发送
	uint8_t slave_buffer_h[8]={ 0xA1, 0, 0, 0, 0, 0, 0, 0 };//后车激活发送

    time_for_speed_can_send = 0;
    if(time_for_speed_can_send == 0 && io_can_init_sign == 1)//前后车握手
    {
        if((dual_head_sign.slave_head_sign == MASTER_HEAD))// CAN_sendMsg_dual_hend(1, &master_buffer[0], 8);  && (m_can_get_ws_sign == 0)
        {
			if (m_can_get_ws_sign == 0)
			{
				CAN_sendMsg_dual_hend(6, &master_buffer_q[0], 8);//前车激活发送
			}
        } 
        else
        {
            if(s_can_get_ws_sign == 0)
            {
                CAN_sendMsg_dual_hend(7, &slave_buffer_h[0], 8);//后车激活发送 一直发
            }      
        }
    }
/***************************前8个字节为更新程序的信息************************
 * 
 * 		帧头1字节           程序下载总长度3字节     	  crc校验4字节
 * 		0XA2				mProgramLength				mProgramCaleCrc32
 *       
 * **************************************************************************/
	master_send_Program_msg[0] = 0XA2;	
	master_send_Program_msg[1] = MsgRecieve.Data[3];//总长度 2 3 4 5
	master_send_Program_msg[2] = MsgRecieve.Data[4];
	master_send_Program_msg[3] = MsgRecieve.Data[5];
	master_send_Program_msg[4] = MsgRecieve.Data[6];//crc校验6 7 8 9 
	master_send_Program_msg[5] = MsgRecieve.Data[7];
	master_send_Program_msg[6] = MsgRecieve.Data[8];
	master_send_Program_msg[7] = MsgRecieve.Data[9];

	if ((dual_head_sign.slave_head_sign == MASTER_HEAD) && (io_can_init_sign ==1))
	{
		if( (master_rcv_wf_updata_flag == 1) && (m_can_get_ws_sign == 1))//wf收到更新,前后车已连接上
		{
			timeCount = 0; // 时间计时清零 屏幕计时器,
			uint8_t	master_send_validate_cont = 1;//初始程序标识信息,可以舍去
			if (tx_validate_data_cont < 1)// &&(mProgramLength <= 0X80000)
			{
				for (uint8_t i = 0; i < master_send_validate_cont; i++)
				{
					if (CAN_sendMsg_dual_hend(0, &master_send_Program_msg[ tx_validate_data_cont * 8 ], 8) == 0)
					{
						tx_validate_data_cont++;
						break;
					}
				}
			}
			//发了过后有收到信息标识再进入下一部
			if (tx_validate_data_cont == 1)
			{
				//接收握手信号
				if (CAN_revMsg_dual_head(&master_rcvack_Program_state, 8) == 1)
				{
					if ((master_rcvack_Program_state[0] == 0xA2) && (master_rcvack_Program_state[1] == 0x50))
					{
						master_rcvack_flag_1 = 1;//主车头接收到从车头接收正确标识信息完成,接下来开始传输数据
						tx_validate_data_cont++;//接收是握手信号就不接收了,不让正式传程序的时候进入此判断执行
					}
					else
					tx_validate_data_cont = 0;
				}
				else
					tx_validate_data_cont = 0;//没收到验证应答,前车继续发验证信息
			}
			m_tx_Progra_cont = mProgramLength / 6;
			m_surplus = mProgramLength % 6;
			if (master_rcvack_flag_1 == 1)//发送程序传输
			{
				if ((Program_tx_start_flag != 0))
				{
					m_tx_front_Progra_cmd = tx_Progra_data_cont;// - 1;//记录上一次发送指令
					up_index_cont = index_cont ;//- 1;//上一次序号
					//传完接收到应答再传下一包,若不是侧继续发上一包数据// {0xA5, 0xF5, 0, 0, 0x5A, 0x5A, 0, 0};//正确5a 错误95
					if ((CAN_revMsg_dual_head(&master_rcv_slave_erro_ack, 8) == 1) && (master_rcv_slave_erro_ack[0] != 0))
					{
						// timeCount = 0; // 时间计时清零 屏幕计时器,
						if ((master_rcv_slave_erro_ack[0] == 0xA3) && (master_rcv_slave_erro_ack[1] < 260))
						{
							if ((master_rcv_slave_erro_ack[1] == up_index_cont))
							{
								tx_Progra_data_cont++;
								index_cont++;
								if (tx_Progra_data_cont == m_tx_Progra_cont)
								{
									Progra_number_flag = 1;
								}										
								tx_state_flag = 1;
								uint8_t onrcv_erro = 1;					
							}
							else if ((master_rcv_slave_erro_ack[1] != up_index_cont))
							{
								tx_state_flag = 0;
								master_tx_Program_state[1] = up_index_cont;							
								memcpy(&master_tx_Program_state[2], &USART_RX_BUF1[m_tx_front_Progra_cmd * 6], 6);
								if (CAN_sendMsg_dual_hend(8, &master_tx_Program_state, 8) == 0)
								{
									// m_tx_front_Progra_cmd++;
									// tx_Progra_data_cont = m_tx_front_Progra_cmd;
								}
							}
						}
						else
						erro_cont++;						
					}
					else//处理未接收到应答超时处理
					{
						no_rcv_slave_ack ++;
						if (no_rcv_slave_ack == 1000)
						{
							tx_state_flag = 0;
							master_tx_Program_state[1] = up_index_cont;							
							memcpy(&master_tx_Program_state[2], &USART_RX_BUF1[m_tx_front_Progra_cmd * 6], 6);
							if (CAN_sendMsg_dual_hend(9, &master_tx_Program_state, 8) == 0);
						}												
					}
				}	
				if (tx_Progra_data_cont <= m_tx_Progra_cont)// = 为最后剩余几个字节的处理
				{
					Program_tx_start_flag = 1;
					if ((tx_state_flag != 0) && (Progra_number_flag == 0))// && (up_index_cont == index_cont - 1) 未接收到这会重发
					{	
						master_tx_Program_state[1] = index_cont;
						memcpy(&master_tx_Program_state[2], &USART_RX_BUF1[tx_Progra_data_cont * 6], 6);
						if (CAN_sendMsg_dual_hend(2, &master_tx_Program_state, 8) == 0)
						{							
							// tx_Progra_data_cont++;
							// index_cont++;
							// if (tx_Progra_data_cont == m_tx_Progra_cont)	
							// 	Progra_number_flag = 1;
						}							
					}
					else if ((tx_state_flag != 0) && (Progra_number_flag == 1))//剩余数量发送,不能与上面发送冲突
					{
						if (m_surplus == 0)
						{
							tx_state_flag = 0;
							Progra_number_flag = 0;
							master_rcvack_flag_1 = 0;
							m_tx_Progra_finish_flag = 1;
						}
						else
						{
							master_tx_Program_state[1] = index_cont;
							memcpy(&master_tx_Program_state[2], &USART_RX_BUF1[mProgramLength - m_surplus], m_surplus);
							if (CAN_sendMsg_dual_hend(1, &master_tx_Program_state, (m_surplus + 2)) == 0)
							{
								tx_state_flag = 0;//清除发送完继续发
								Progra_number_flag = 0;
								master_rcvack_flag_1 = 0;
								m_tx_Progra_finish_flag = 1;
							}								
						}
					}			
						
				}
			}
			else if ((m_tx_Progra_finish_flag == 1) && (master_rcvack_flag_1 == 0))//前车头收到从车接发来的程序状态 增加else if
			{
				// memset(&master_rcvack_Program_state_2[0], 0, 8);
				if (CAN_revMsg_dual_head(&master_rcvack_Program_state_2, 8) == 1)
				{
					if((master_rcvack_Program_state_2[0] == 0xA4) && (master_rcvack_Program_state_2[1] == 0x22))
					{
						m_tx_Progra_finish_flag = 0;
						m_send_bootsuccess_state_flag = 1;//接收是对的数据
					}
					else if((master_rcvack_Program_state_2[0] == 0xA4) && (master_rcvack_Program_state_2[1] == 0x33))
					{
						m_send_bootsuccess_state_flag = 0;
						if (m_send_bootsuccess_state_flag == 0)//校验错误清除一系列标志位,从新传输
						{
							memset(&master_tx_Program_state[2], 0, 6);
							index_cont = 0;
							up_index_cont = 0;
							tx_Progra_data_cont = 0;
							m_tx_front_Progra_cmd = 0;
							master_rcvack_flag_1 = 1;
							Program_tx_start_flag = 0;
							m_tx_Progra_finish_flag = 0;
							Progra_number_flag = 0;
							tx_state_flag = 1;	
						}
					}
				}
			}	
		}
		if (m_can_get_ws_sign == 1)
		{
			;
		}
		//前车不收到wf更新指令,两车一直交互
		else if(((CAN_revMsg_dual_head(&rx_buffer_tmp[0], 8) == 1) && (io_can_init_sign ==1) ))// || (m_can_get_ws_sign == 1)    && (master_rcv_wf_updata_flag == 1)
		{
			m_can_get_ws_sign = 1;
		}
	}
	//后车激活发送///
	if((dual_head_sign.slave_head_sign == SLAVE_HEAD) && (io_can_init_sign == 1))
	{
		slave_rcv_master_canboot();
	}

}
// static uint8_t aaa=0;
slave_rcv_master_canboot()
{
	static uint8_t slave_rx_buffer_boot[8] = {0}; 								//后车交互阶段接收
	static uint8_t slave_rcv_Program_msg[8] = {0};								//后车接收到的管理信息
	static uint8_t slave_rcv_validate_cont = 0;
	static uint8_t s_surplus = 0;												//接收到程序个数对6的余数
	static uint32_t slave_rcv_crc = 0;//接收到管理信息的crc值
	static uint32_t sDownloadProgramCrc32 = 0;//计算接收到数据的crc
	uint8_t slave_sendack_Program_success[8] = {0xA4, 0x22, 0, 0, 0, 0, 0, 0};//校验成功后需回应车的数据
	uint8_t slave_sendack_Program_error[8] = {0xA4, 0x33, 0, 0, 0, 0, 0, 0};//校验失败后需回应前车的数据
	uint8_t slave_ack[8] = {0xA2, 0x50, 0, 0, 0, 0, 0, 0};//接收到管理信息回应前车

	static uint32_t s_rcv_Progra_data_cont = 0;//从车程序传输需要次数
	static uint8_t s_rcv_Progra_finish_flag = 0;//程序接收完成
	uint8_t slave_success_ack[8] = {0xA3, 0, 0, 0, 0, 0x5A, 0, 0};//程序传输阶段应答前车,正确5a错误95
	uint8_t slave_erro_ack[8] = {0xA3, 0, 0, 0, 0, 0x95, 0, 0};
	static uint8_t slave_rx_buffer_error[] = {0}; //测试监控接收到的错误数据
	static uint32_t s_ack_erro_cont = 0;//测试监控错误
	static uint32_t sp_erro_cont = 0;//测试监控错误
	static uint32_t aaa_erro_cont = 0;//收到上次相同编号的应答

	if (s_can_get_ws_sign == 1)
	{
		slave_rcv_validate_cont = 1;//初始程序标识信息
		if (tx_validate_data_cont < 1)//接收程序标识信息传输
		{
			for (uint8_t i = 0; i < slave_rcv_validate_cont; i++)
			{
				if (CAN_revMsg_dual_head(&slave_rcv_Program_msg[ tx_validate_data_cont * 8 ], 8) == 1)
				{
					tx_validate_data_cont++;
					break;
				}	
			}
		}
		if (tx_validate_data_cont == 1)
		{
			slave_rcv_mProgramLength = slave_rcv_Program_msg[1];//总长度
			slave_rcv_mProgramLength <<= 8;
			slave_rcv_mProgramLength |= slave_rcv_Program_msg[2];
			slave_rcv_mProgramLength <<= 8;
			slave_rcv_mProgramLength |= slave_rcv_Program_msg[3];
			slave_rcv_crc = slave_rcv_Program_msg[4];//crc校验 (也需要识别包头 FB 5A)
			slave_rcv_crc <<=8;
			slave_rcv_crc |= slave_rcv_Program_msg[5];
			slave_rcv_crc <<=8;
			slave_rcv_crc |= slave_rcv_Program_msg[6];
			slave_rcv_crc <<=8;
			slave_rcv_crc |= slave_rcv_Program_msg[7];
			if((slave_rcv_Program_msg[0] == 0XA2) && (slave_rcv_mProgramLength <= 0X80000))
			{
				slave_rcv_flag_1 = 1;//从车头接收正确标识信息完成,接下来开始传输数据
				//从车头接收到数据后应主车头开始传输数据
				if (CAN_sendMsg_dual_hend(4, &slave_ack[0], 8) == 0)//处理后车发送冲突
				{					
					tx_validate_data_cont++;//不让正式传程序的时候进入此判断执行
				}
			}
			else 
			{
				tx_validate_data_cont = 0;
			}
		}
		if (slave_rcv_flag_1 != 0)
		{
			timeCount = 0; // 时间计时清零 屏幕计时器,
		}
		s_surplus = slave_rcv_mProgramLength % 6;//每次接收完8个后的余数
		s_rcv_Progra_data_cont = slave_rcv_mProgramLength / 6;
		static uint8_t slave_rcv_Program_state[8] = {0};//接收到的程序数据
		static uint8_t slave_rcv_cmd_index = 0;//接收到的程序编号

		//注意处理发送两次包一样的情况的处理,
		if (slave_rcv_flag_1 == 1)//接收程序传输 
		{
			if (tx_Progra_data_cont <= s_rcv_Progra_data_cont)
			{
				if (Progra_number_flag != 1)
				{	
					// timeCount = 0; // 时间计时清零 屏幕计时器,								
					//接收到应答前车头,若没接收到返回上次数据编号
					if ((CAN_revMsg_dual_head(&slave_rcv_Program_state, 8) == 1) && (slave_rcv_Program_state[0] != 0))//接收整包数据
					{
						if ((slave_rcv_Program_state[0] == 0XA3) && (slave_rcv_Program_state[1] < 260))//  && (slave_rcv_Program_state[1] == index_cont)
						{	
							slave_rcv_cmd_index = slave_rcv_Program_state[1];														
							slave_success_ack[1] = slave_rcv_cmd_index;//返回接收到的编号

							if((slave_rcv_Program_state[1]) == index_cont ) 
							{
								if (CAN_sendMsg_dual_hend(33, &slave_success_ack, 8) == 0)//后车ack 21
								{
									index_cont++;
									memcpy(&USART_RX_BUF1[tx_Progra_data_cont * 6], &slave_rcv_Program_state[2], 6);
									tx_Progra_data_cont++;
									if ((tx_Progra_data_cont == s_rcv_Progra_data_cont))
									{
										Progra_number_flag = 1;
										///										
									}
								}
								canboot_currentDownloadFrame = canboot_currentDownloadFrame + 6;//接收到的字节数
							}
							else// if ((slave_rcv_Program_state[1]) == index_cont - 1)处理后车接收到的不是这次应该接收的数据,发送上一次应答
							{
								aaa_erro_cont++;
								if (CAN_sendMsg_dual_hend(34, &slave_success_ack, 8) == 0);//重复ack 22
							}
							// else
							// 	ccc++;																						
						}
						else//处理后接收到错误数据,发送上一次应答
						{
							sp_erro_cont++;
							if (sp_erro_cont == 1000)
							{
								sp_erro_cont = 0;
								slave_erro_ack[1] = slave_rcv_cmd_index;//返回接收到的上次编号
								if (CAN_sendMsg_dual_hend(37, &slave_erro_ack, 8) == 0);//重复ack 25
								// memcpy(&slave_rx_buffer_error, &slave_rcv_Program_state, 8);//监控接收到的错误数据
								// memset(&slave_rcv_Program_state[2], 0, 6);
								// if (CAN_sendMsg_dual_hend(9, &slave_erro_ack[0], 8) == 0)//返回错位编号
								// {
								// 	;
								// }	
							}	
											
						}
					}
					else//处理长时间后车接收不到数据can异常死机,导致前车一直发送相同指令
					{	
						s_ack_erro_cont++;
						if (s_ack_erro_cont == 300)
						{
							s_ack_erro_cont = 0;
							slave_erro_ack[1] = slave_rcv_cmd_index;//返回接收到的上次编号
							if (CAN_sendMsg_dual_hend(36, &slave_erro_ack, 8) == 0);//重复ack 24
						}																		
					}
				}
				else if ((Progra_number_flag == 1))//处理接收数量有余数
				{
													
					if (s_surplus == 0)
					{
						slave_rcv_flag_1++;//接收成功后就不接收了
						s_rcv_Progra_finish_flag = 1;
					}
					else
					{
						memset(&slave_rcv_Program_state[2], 0, 6);
						if (CAN_revMsg_dual_head(&slave_rcv_Program_state, (s_surplus + 2)) == 1)
						{
							if ((slave_rcv_Program_state[0] == 0XA3))
							{						
								memcpy(&USART_RX_BUF1[tx_Progra_data_cont * 6], &slave_rcv_Program_state[2], s_surplus);
								// tx_Progra_data_cont++;
								slave_rcv_cmd_index = slave_rcv_Program_state[1];
								slave_success_ack[1] = slave_rcv_cmd_index;//返回接收到的编号
								// if (CAN_sendMsg_dual_hend(35, &slave_success_ack[0], 8) == 0)//ack 23 最后接收到后可以不用回复
								{
									index_cont++;
									slave_rcv_flag_1++;
									s_rcv_Progra_finish_flag = 1;
								}
								canboot_currentDownloadFrame = canboot_currentDownloadFrame + s_surplus;//接收到的字节数
							}

						}
						// else if(s_rcv_Progra_finish_flag != 1)///
						// {
						// 	s_erro_cont++;
						// 	if (CAN_sendMsg_dual_hend(9, &slave_erro_ack[0], 8) == 0)//返回错位编号
						// 	{
						// 		;
						// 	}					
						// }
	
					}						
				}
				percent_rate = (((float)canboot_currentDownloadFrame / (float)slave_rcv_mProgramLength) * 100);//传输进度
				if (((float)canboot_currentDownloadFrame > (float)slave_rcv_mProgramLength))
				{
					percent_rate = 100;
				}	
			}
		}

		if ((s_rcv_Progra_finish_flag == 1) && (slave_rcv_flag_1 == 2))//向前车反馈接收到的数据情况  增加else if
		{
			sDownloadProgramCrc32 = calculate_CRC32(USART_RX_BUF1, slave_rcv_mProgramLength);
			if(slave_rcv_crc == sDownloadProgramCrc32)
			{
				if (CAN_sendMsg_dual_hend(5, &slave_sendack_Program_success[0], 8) == 0)//应答成功
				{
					s_rcv_Progra_finish_flag = 0;//发送成功后就不发了
					s_rcv_bootsuccess_state_flag = 1;
				}	
			}
			else
			{
				if (CAN_sendMsg_dual_hend(5, &slave_sendack_Program_error[0], 8) == 0)//应答失败 需要从新传输
				{
					s_rcv_bootsuccess_state_flag = 0;
					if (s_rcv_bootsuccess_state_flag == 0)//校验错误清除一系列标志位,从新传输
					{
						memset(&USART_RX_BUF1, 0, slave_rcv_mProgramLength);
						index_cont = 0;
						tx_Progra_data_cont = 0;
						slave_rcv_cmd_index = 0;
						slave_rcv_flag_1 = 1;
						s_rcv_Progra_finish_flag = 0;
						Progra_number_flag = 0;	
						canboot_currentDownloadFrame = 0;
						percent_rate = 0;
					}

				}

			}		
		}	
	}

	if (s_can_get_ws_sign == 1)
	{
		;
	}

	else if ((CAN_revMsg_dual_head(&slave_rx_buffer_boot[0], 8) == 1) && (io_can_init_sign == 1))// || (s_can_get_ws_sign == 1)  && (slave_rcv_flag_1 == 1)
	{
		s_can_get_ws_sign = 1;
	}
}

#endif

.h文件 主要为读取bkp备份寄存器中区分前后车参数

#ifndef _WirelessCommunicate_H__
#define _WirelessCommunicate_H__

// extern "C"
// {
    // #include "CAN_def.h"

// }

void WirelessTranslateMsg(float timeCycle); // 处理接收到的数据串
extern int remain_time;
extern unsigned short percent_rate;
extern unsigned short current_frame;
extern unsigned short total_frame;

//can boot 前后车头/
void slave_rcv_master_canboot();
void master_send_slave_canboot();
static void can_upboot(void);
void get_master_or_slave_sign();

#define DUAL_HEAD_FRONT     1
#define DUAL_HEAD_BACK      2
#define MASTER_HEAD         0
#define SLAVE_HEAD          1
//目前测试用,区分1前车头2后车头
// #define sign_master_or_slave      1
#define CAN_BOOT_onoff            1  //boot can相关开关

//sram前后车数读取参数地址
#define BACKUPSRAM_ODOMETER 0                              // 里程mm 在备份RAM存储地址偏移0
#define BACKUPSRAM_AXIS_TOTAL (BACKUPSRAM_ODOMETER + 4)    // 电机错误总计数 在备份RAM存储地址偏移4
#define BACKUPSRAM_AXIS_ERROR (BACKUPSRAM_AXIS_TOTAL + 4)  // axis 错误计数
#define BACKUPSRAM_AXIS_MOTOR (BACKUPSRAM_AXIS_ERROR + 4)  // 电机 错误计数
#define BACKUPSRAM_AXIS_CTRL (BACKUPSRAM_AXIS_MOTOR + 4)   // 电机控制 错误计数
#define BACKUPSRAM_AXIS_ENCODER (BACKUPSRAM_AXIS_CTRL + 4) // 电机编码器 错误计数
#define BACKUPSRAM_AXIS_DRV (BACKUPSRAM_AXIS_ENCODER + 4)  // 电机驱动 错误计数
#define BACKUPSRAM_AXIS_ERR_CODE (BACKUPSRAM_AXIS_DRV + 4)
#define BACKUPSRAM_AXIS_CTRL_CODE (BACKUPSRAM_AXIS_ERR_CODE + 4)
#define BACKUPSRAM_AXIS_CTRL_MODE_CODE (BACKUPSRAM_AXIS_CTRL_CODE + 4)
#define BACKUPSRAM_AXIS_MOTOR_CODE (BACKUPSRAM_AXIS_CTRL_MODE_CODE + 4)
#define BACKUPSRAM_AXIS_DRV_CODE (BACKUPSRAM_AXIS_MOTOR_CODE + 4)
#define BACKUPSRAM_AXIS_ENC_CODE (BACKUPSRAM_AXIS_DRV_CODE + 4)
#define BACKUPSRAM_RFID (BACKUPSRAM_AXIS_ENC_CODE + 4)
#define BACKUPSRAM_ENCODER (BACKUPSRAM_RFID + 4)
#define BACKUPSRAM_ENCODER_CNT (BACKUPSRAM_ENCODER + 4)
#define BACKUPSRAM_ENCODER_ERR_CNT (BACKUPSRAM_ENCODER_CNT + 4)
#define BACKUPSRAM_DIS_DATA_LIVE_START_RFID (BACKUPSRAM_ENCODER_ERR_CNT + 4)
#define BACKUPSRAM_DIS_START_RFID (BACKUPSRAM_DIS_DATA_LIVE_START_RFID + 4)
//canboot 记录双车头前后车头
#define BACKUPSRAM_DIS_can_boot (BACKUPSRAM_DIS_START_RFID + 4)


#endif


3. boot里交互(两车必须要完成握手双方才能收到,即相互发送数据等待传数据)

应用程序app实现跳转功能,收到wifi更新指令后两车进入boot,前车接收完毕后向后车传程序,都无误后再写入flash

原双车头app程序在前或跳转程序在前中都有接收函数,所以做了处理,跳转程序在前做了baff缓冲向app传递防止超时

//20个周期来回切换,暂时能用有bug
        if (dual_head_sign.slave_head_sign == MASTER_HEAD)//前车在收到fw更新指令后才运行切换到canupboot函数,否则一直运行can数据交互函数
        {
            if (master_rcv_fw_upboot_flag == 1)
            {
                dual_head_cart_boot_process();//canboot放在双车头前
            }
            else
            {
                dual_head_cart_process();//原双车头
            }             
        }
        else if (dual_head_sign.slave_head_sign == SLAVE_HEAD)
        {
            dual_head_cart_boot_process();//canboot放在双车头前
            if (slave_rcv_boot_flag_1 != 1)//后车接收到upboot停止双车头数据交互
            {
                dual_head_cart_process();
            }
    
        }

boot接收到的数据向原双车头应用程序传递

uint8_t app_flag = 0;
void dual_head_cart_process(void)
{
    //canboot
    uint8_t app_testing_tmp[8] = {0};//检测后车是否接收实际数据,全0

    uint8_t rx_buffer_tmp[8] = {0};
    uint16_t I_data = 0;
    static uint8_t time_for_speed_can_send = 0;
    static uint16_t can_connect_sign_time = 0;//用于can通信计时,通信成功会清0该时间,时间计时超过警戒时间报警CAN通信异常
    static uint16_t can_error_time = 0;
    static bool can_get_already_sign = 0;
    if(cart_ctrl.config_data->dual_head_cart_sign == DUAL_HEAD_FRONT)
        dual_head_sign.slave_head_sign = MASTER_HEAD;
    else if(cart_ctrl.config_data->dual_head_cart_sign == DUAL_HEAD_BACK)
        dual_head_sign.slave_head_sign = SLAVE_HEAD;
    else
        return;
    if ((dual_head_sign.slave_head_sign == SLAVE_HEAD) && (memcmp(pboot_rx_buffer_tmp, app_testing_tmp, 8) != 0))// sizeof(pboot_rx_buffer_tmp)//
    {
        memcpy(&rx_buffer_tmp, &pboot_rx_buffer_tmp, 8);
        app_flag = 1;
        
    }
    //get_head_with_corners_sign();
    // if(CAN_revMsg_dual_head(&rx_buffer_tmp[0], 8) == 1)
    if((CAN_revMsg_dual_head(&rx_buffer_tmp[0], 8) == 1) || (app_flag == 1))
    {
        //canboot
        app_flag = 0;
        memset(&pboot_rx_buffer_tmp[0], 0, 8);

        can_connect_sign_time = 0;
        can_get_already_sign = 1;
        if(cart_ctrl.config_data->dual_head_cart_sign == DUAL_HEAD_FRONT)
        {
            motor_current_current_form_slave = u8_to_u16(rx_buffer_tmp[1], rx_buffer_tmp[0], cart_ctrl.config_data->endian_type);
            slave_sign_to_master = u8_to_u16(rx_buffer_tmp[3], rx_buffer_tmp[2], cart_ctrl.config_data->endian_type);
            if(slave_sign_to_master & 0x0004)
            {
                send_event_message(EVENT_CALL_TYPE, CONDITION_CMD_WAIT, MSG_TYPE_WIFI, NULL, 0);
                set_cart_state(CART_STSTE_MOTOR_ERR, 1);
            }
            master_get_from_slave_real_speed = u8_to_u32(rx_buffer_tmp[7], rx_buffer_tmp[6], rx_buffer_tmp[5], rx_buffer_tmp[4], cart_ctrl.config_data->endian_type);
        }

app接收到更新指令后向boot跳转的逻辑代码

//有握手动作///

// /*
//后车接收can boot
extern uint8_t master_rcv_fw_upboot_flag;//前车头接收到wf更新指令
uint8_t slave_rcv_boot_flag_1 = 0;//后车头接收到前车头发送的boot指令
uint8_t master_rcv_boot_flag_1 = 0;//前车头接收到后车头应答标志,后车进入boot前
uint32_t boot_master_or_slave = 0;//写入sram用于boot区分前后车,1前车2后车
static uint8_t pboot_rx_buffer_tmp[8] = {0};//暂存接收到不是升级指令的数据给双车头数据交互

uint8_t dual_head_cart_boot_process(void)
{
    static bool can_get_ws_sign = 0;//两车交互
    static uint8_t boot_go_app_sign = 0;//避免从车还没发完就跳转

    uint8_t master_buffer[8]={ 0, 0, 0, 0, 0, 0, 0, 0x01 };//前车激活发送
    uint8_t slave_buffer[8]={ 0, 0, 0, 0, 0, 0, 0, 0x02 };//后车激活发送

    // uint8_t master_buffer[8]={ 0xD1, 0x11, 0, 0, 0, 0, 0, 0 };//前车激活发送 //d1 a1 开头小车出现更新完后重启
    // uint8_t slave_buffer[8]={ 0xD1, 0x12, 0, 0, 0, 0, 0, 0 };//后车激活发送
    uint8_t master_tx_buffer[8] = { 0xD2, 0x11, 0, 0, 0, 0, 0, 0x55 };//前车头接收到wf更新指令后,向后车头发的握手指令
    uint8_t slave_ack1_buffer[8]={ 0xD3, 0x11, 0, 0, 0, 0, 0, 0x55 };//后车应答1
    uint8_t time_for_speed_can_send = 0;
    static uint8_t rx_buffer_tmp[8] = {0};
    static uint8_t master_rx_buffer_boot1[8] = {0}; //前车接收后车ack1
    static uint8_t slave_rx_buffer_boot[8] = {0}; //后车接收前车boot
    static bool s_can_get_ws_sign = 0;//从车激活
    static bool m_can_get_ws_sign = 0;//从车激活

    if(cart_ctrl.config_data->dual_head_cart_sign == DUAL_HEAD_FRONT)
    {
        dual_head_sign.slave_head_sign = MASTER_HEAD;
        boot_master_or_slave = DUAL_HEAD_FRONT;//前车写入
        BackupSRAM_WriteData(BACKUPSRAM_DIS_can_boot, (uint8_t *)&boot_master_or_slave, 4);
    }
    else if(cart_ctrl.config_data->dual_head_cart_sign == DUAL_HEAD_BACK)
    {
        dual_head_sign.slave_head_sign = SLAVE_HEAD;
        boot_master_or_slave = DUAL_HEAD_BACK;//后车写入
        BackupSRAM_WriteData(BACKUPSRAM_DIS_can_boot, (uint8_t *)&boot_master_or_slave, 4);
    }    
    else
        return 0;

    if((io_can_init_sign == 1) && (can_get_ws_sign == 0))//前后车握手
    {
        if((dual_head_sign.slave_head_sign == MASTER_HEAD))// CAN_sendMsg_dual_hend(1, &master_buffer[0], 8);  && (m_can_get_ws_sign == 0)
        {
			CAN_sendMsg_dual_hend(6, &master_buffer[0], 8);//前车激活发送
        } 
        else
        {
            CAN_sendMsg_dual_hend(7, &slave_buffer[0], 8);//后车激活发送 一直发
        }
    }

    if( (io_can_init_sign == 1) && (can_get_ws_sign == 1))//wf收到更新,前后车已连接上
    {
        if((master_rcv_fw_upboot_flag == 1))//前车头接收到wf更新指令,向后车发送信号
        {
            if (CAN_sendMsg_dual_hend(1, &master_tx_buffer[0], 8) == 0)
            {
                ;
            } 
        }
        else if((dual_head_sign.slave_head_sign == SLAVE_HEAD))//后车接收前车进入boot指令
        {
            if (CAN_revMsg_dual_head(&slave_rx_buffer_boot[0], 8) == 1)
                {                  
                    if(((slave_rx_buffer_boot[0] == 0xD2) && (slave_rx_buffer_boot[1] == 0X11) && (slave_rx_buffer_boot[7] == 0X55)) || (slave_rcv_boot_flag_1 == 1))
                    {
                        // memset(&pboot_rx_buffer_tmp[0], 0, 8);
                            // can_get_ws_sign=1;
                        slave_rcv_boot_flag_1 = 1;
                        if( CAN_sendMsg_dual_hend(4, &slave_ack1_buffer[0], 8) == 0 )
                        {
                            boot_go_app_sign++;
                            // osDelay(1);//前车头为啥此时进入了boot?
                            // IAP_ExecuteApp(0x08000000);//后车头进入boot
                        }
                    }
                    else
                    {
                        memcpy(&pboot_rx_buffer_tmp, &slave_rx_buffer_boot, 8);
                        return 0;
                    }                           
                }
            else if (boot_go_app_sign != 0)
            {
                boot_go_app_sign = 0;
                IAP_ExecuteApp(0x08000000);//后车头进入boot
            }     
        }
        if((dual_head_sign.slave_head_sign == MASTER_HEAD))//前车头接收后车头进入boot判断,后车进入boot前
        {
            if (CAN_revMsg_dual_head(&master_rx_buffer_boot1[0], 8) == 1)
            {
                // if((master_rx_buffer_boot1[0] != 0xD3) && (master_rx_buffer_boot1[1] != 0X11) && (master_rx_buffer_boot1[7] != 0X55))
                if((master_rx_buffer_boot1[0] != 0xD3) || (master_rx_buffer_boot1[1] != 0X11) || (master_rx_buffer_boot1[7] != 0X55))
                    return 0;      
                master_rcv_boot_flag_1 = 1;
                IAP_ExecuteApp(0x08000000);//前车头进入boot测试
            }        
        }
    }
    
    if (can_get_ws_sign == 1)
    {
        ;
    }
	//前车不收到wf更新指令,两车一直交互
	else if(((CAN_revMsg_dual_head(&rx_buffer_tmp[0], 8) == 1) && (io_can_init_sign ==1) ))// || (m_can_get_ws_sign == 1)    && (master_rcv_wf_updata_flag == 1)
	{
        // if((rx_buffer_tmp[0] == 0x12))//  (rx_buffer_tmp[0] == 0xD1) // && ((rx_buffer_tmp[1] == 0x11) || (rx_buffer_tmp[1] == 0x12))
		    can_get_ws_sign = 1;

	}
    
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值