123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- /**
- * @Author: 李建
- * @Date: 2024/9/7 13:06
- * Description:
- * Copyright: Copyright (©) 2024 永续绿建. All rights reserved.
- */
- #include "ymodem_update.h"
- #include "port.h"
- #include "mb.h"
- #include "flash.h"
- #include <stdio.h>
- static enum UPDATE_STATE Update_State = TO_START;
- /* 设置升级的步骤 */
- static inline void Set_State(enum UPDATE_STATE state)
- {
- Update_State = state;
- }
- /* 查询升级的步骤 */
- static inline uint8_t Get_State(void)
- {
- return Update_State;
- }
- #define POLY 0x1021
- /**
- * @brief CRC-16 校验
- * @param addr 开始地址
- * @param num 长度
- * @param crc CRC
- * @return crc 返回CRC的值
- */
- static uint16_t CRC16(uint8_t *addr, int num, uint16_t crc)
- {
- int i;
- for (; num > 0; num--) /* Step through bytes in memory */
- {
- crc = crc ^ (*addr++ << 8); /* Fetch byte from memory, XOR into CRC top byte*/
- for (i = 0; i < 8; i++) /* Prepare to rotate 8 bits */
- {
- if (crc & 0x8000) /* b15 is set... */
- crc = (crc << 1) ^ POLY; /* rotate and XOR with polynomic */
- else /* b15 is clear... */
- crc <<= 1; /* just rotate */
- } /* Loop for 8 bits */
- crc &= 0xFFFF; /* Ensure CRC remains 16-bit value */
- } /* Loop until num=0 */
- return(crc); /* Return updated CRC */
- }
- /**
- * @brief 获取数据包的类型, 顺便进行校验
- * @param buf 开始地址
- * @param len 长度
- * @return 1 通过校验 0 没通过校验
- */
- uint8_t Check_CRC(uint8_t* buf, int len)
- {
- uint16_t crc = 0;
- /* 进行CRC校验 */
- crc = CRC16(buf+3, len - 5, crc);
- if(crc != (buf[131]<<8|buf[132]))
- {
- return 0; /* 没通过校验 */
- }else{
- return 1; /* 通过校验 */
- }
- }
- void Code_Storage_Done(void)
- {
- uint32_t update_flag = Startup_Update; // 对应bootloader的启动步骤
- flash_write((Application_2_Addr + Application_Size - 4), &update_flag,4 ); //在APP2中添加标记 0x801DFFC
- }
- /**
- * 串口写文件回调,内容为ymodem协议报文
- * @param header
- * @param pucRegBuffer
- * @return
- */
- eMBErrorCode eMBWriteFileCB(UCHAR * header, UCHAR * pucRegBuffer, USHORT * usLen) {
- switch (*header) {
- case SOH:{
- static uint8_t Data_State = 0;
- static uint16_t pack_offset = 0;
- if(Check_CRC(pucRegBuffer, *usLen - 1)) {
- // 如果是起始帧
- if(Get_State() == TO_START && pucRegBuffer[1] == 0&&(pucRegBuffer[2] == (uint8_t)(~pucRegBuffer[1]))) {
- Set_State(TO_RECEIVE_DATA);
- Data_State = 0x01;
- pack_offset = 1;
- pucRegBuffer[0] = ACK;
- flash_erase(Application_2_Addr, (Application_2_Addr + Application_Size) / FLASH_PAGE_SIZE);
- DEBUG_PRINTF("flash_erase\r\n");
- } else if((Get_State()==TO_RECEIVE_END)&&(pucRegBuffer[1] == 0x00)&&(pucRegBuffer[2] == (uint8_t)(~pucRegBuffer[1])))
- {
- Code_Storage_Done(); //APP2区代码存放完成
- DEBUG_PRINTF("Code_Storage_Done\r\n");
- Set_State(TO_START); //标记可以继续接收Ymodem数据
- pucRegBuffer[0] = ACK;
- pack_offset = 0;
- HAL_NVIC_SystemReset(); //重启系统
- } else if((Get_State()==TO_RECEIVE_DATA)&&(pucRegBuffer[1] == Data_State)&&(pucRegBuffer[2] == (uint8_t)(~pucRegBuffer[1]))) {
- /* 烧录程序 */
- flash_write((Application_2_Addr + (pack_offset -1) * 128), pucRegBuffer+3, 128);
- pack_offset++;
- if(Data_State++ == 0xFF) {
- Data_State = 0x01;
- }
- pucRegBuffer[0] = ACK;
- DEBUG_PRINTF("flash_write:%d\r\n", Data_State);
- }
- } else {
- pucRegBuffer[0] = NACK;
- DEBUG_PRINTF("crc error:%d\r\n", Data_State);
- }
- }
- break;
- case EOT: {
- if(Get_State()==TO_RECEIVE_DATA)
- {
- Set_State(TO_RECEIVE_EOT2);
- pucRegBuffer[0] = NACK;
- }
- else if(Get_State()==TO_RECEIVE_EOT2)
- {
- Set_State(TO_RECEIVE_END);
- pucRegBuffer[0] = ACK;
- }
- else
- {
- //Receive EOT, But error...
- }
- }
- break;
- }
- return MB_ENOERR;
- }
|