diff --git a/.gitignore b/.gitignore
index cbfaeaa4d8661683c829fa584859fc89634f74e6..2fe594f7c736fc8bcdf91f7ece917a4fc9e2bebb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,3 +37,6 @@ Objects/BootLoader.axf
Objects/BootLoader.htm
Objects/menu.d
Objects/menu.o
+Objects/BootLoader_sct.Bak
+Objects/bsp_gpio.d
+Objects/bsp_gpio.o
diff --git a/BootLoader.uvoptx b/BootLoader.uvoptx
index 1c05aa112c56511c241b27f726862923d5f1ddc1..8c569ecba89656fe4962996adaf15aa74bdd4bec 100644
--- a/BootLoader.uvoptx
+++ b/BootLoader.uvoptx
@@ -179,7 +179,7 @@
1
1
1
- 0
+ 1
0
0
.\bsp_uart.c
@@ -259,6 +259,18 @@
0
0
+
+ 1
+ 8
+ 1
+ 0
+ 0
+ 0
+ .\bsp_gpio.c
+ bsp_gpio.c
+ 0
+ 0
+
@@ -269,7 +281,7 @@
0
2
- 8
+ 9
1
0
0
@@ -281,7 +293,7 @@
2
- 9
+ 10
1
0
0
diff --git a/BootLoader.uvprojx b/BootLoader.uvprojx
index 6dc9beade7fe47bc0f8d94c342ead09f3e65d86f..26ca09cf6641dc997a4b3c53cf5f25eca361f27d 100644
--- a/BootLoader.uvprojx
+++ b/BootLoader.uvprojx
@@ -277,7 +277,7 @@
1
0x8000000
- 0x300000
+ 0x8000
1
@@ -419,6 +419,11 @@
5
.\ymodem.h
+
+ bsp_gpio.c
+ 1
+ .\bsp_gpio.c
+
diff --git a/bsp_gpio.c b/bsp_gpio.c
new file mode 100644
index 0000000000000000000000000000000000000000..c5d8d9e28a0f2bdf517e68c30979e1481907aac0
--- /dev/null
+++ b/bsp_gpio.c
@@ -0,0 +1,38 @@
+/*
+ * @Author: Ma Yuchen
+ * @Date: 2022-11-24 23:09:29
+ * @LastEditors: Ma YuChen
+ * @LastEditTime: 2022-11-25 00:18:25
+ * @Description: file content
+ * @FilePath: \BootLoader\bsp_gpio.c
+ */
+
+#include "bsp_gpio.h"
+#include "gd32f4xx_gpio.h"
+
+void InitGpio(void)
+{
+ rcu_periph_clock_enable(RCU_GPIOD);
+
+ gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_1);
+ gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1);
+
+ gpio_mode_set(GPIOD, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_0);
+}
+
+void PowerOnBmcPeriph(void)
+{
+ gpio_bit_set(GPIOD, GPIO_PIN_1);
+}
+
+void PowerOffBmcPeriph(void)
+{
+ gpio_bit_reset(GPIOD, GPIO_PIN_1);
+}
+
+void ResetGpio(void)
+{
+ gpio_bit_reset(GPIOD, GPIO_PIN_1);
+ gpio_deinit(GPIOD);
+ rcu_periph_clock_disable(RCU_GPIOD);
+}
diff --git a/bsp_gpio.h b/bsp_gpio.h
new file mode 100644
index 0000000000000000000000000000000000000000..04ef3e71d37f2413d7354dcc3a5b61eabd50e665
--- /dev/null
+++ b/bsp_gpio.h
@@ -0,0 +1,18 @@
+/*
+ * @Author: Ma Yuchen
+ * @Date: 2022-11-24 23:07:45
+ * @LastEditors: Ma YuChen
+ * @LastEditTime: 2022-11-24 23:20:08
+ * @Description: file content
+ * @FilePath: \BootLoader\bsp_gpio.h
+ */
+
+#ifndef BSP_GPIO_H
+#define BSP_GPIO_H
+
+void InitGpio(void);
+
+void PowerOnBmcPeriph(void);
+void PowerOffBmcPeriph(void);
+void ResetGpio(void);
+#endif
diff --git a/bsp_ocflash.h b/bsp_ocflash.h
index 0f8c833db635b5aafb04ed3286dc781e5cb6f176..f754e874d027aad27fa3b6d8e7bf4656fb8e3815 100644
--- a/bsp_ocflash.h
+++ b/bsp_ocflash.h
@@ -2,24 +2,37 @@
* @Author: Ma Yuchen
* @Date: 2022-11-23 12:18:51
* @LastEditors: Ma YuChen
- * @LastEditTime: 2022-11-23 22:20:10
+ * @LastEditTime: 2022-11-24 22:26:37
* @Description: file content
* @FilePath: \BootLoader\bsp_ocflash.h
*/
#ifndef BSP_OCFLASH_H
#define BSP_OCFLASH_H
+#include
#include
#define APPLICATION_ADDRESS (uint32_t)0x08008000
+#define USER_FLASH_END_ADDRESS (uint32_t)0x0807FFFF
+
+#define USER_FLASH_SIZE (USER_FLASH_END_ADDRESS-APPLICATION_ADDRESS+1)
#define APPLICATION_START_SECTOR 2
-#define APPLICATION_END_SECTOR 11
+#define APPLICATION_END_SECTOR 7
typedef void (*pFunction)(void);
void Flash_IF_Init(void);
int Flash_IF_App_Erase(int StartSectorId, int EndSectorId);
+/**
+ * @brief 按照4字节单位将缓存区数据烧写到Flash
+ *
+ * @param address [in out] 传输地址的指针
+ * @param buffer [in] 数据缓存区
+ * @param length [in] 数据缓存区长度
+ * @return int 0 正确 -1 烧写错误 -2 回读错误
+ */
+int Flash_IF_Write(__IO uint32_t *address, uint32_t *buffer, int length);
#endif
diff --git a/bsp_uart.c b/bsp_uart.c
index 21ee7b41ca7d2dc4063cedff730e7145284b3485..fbfe9b67972ae2ab8fc60d4ebf93a1610e118f79 100644
--- a/bsp_uart.c
+++ b/bsp_uart.c
@@ -2,112 +2,112 @@
* @Author: Ma Yuchen
* @Date: 2022-11-22 21:43:39
* @LastEditors: Ma YuChen
- * @LastEditTime: 2022-11-24 11:11:37
+ * @LastEditTime: 2022-11-24 23:51:11
* @Description: file content
* @FilePath: \BootLoader\bsp_uart.c
*/
#include "bsp_uart.h"
-#include "gd32f4xx_usart.h" // GigaDevice::Device:StdPeripherals:USART
+#include "gd32f4xx_usart.h" // GigaDevice::Device:StdPeripherals:USART
-#define IS_AF(c) ((c >= 'A') && (c <= 'F'))
-#define IS_af(c) ((c >= 'a') && (c <= 'f'))
-#define IS_09(c) ((c >= '0') && (c <= '9'))
-#define ISVALIDHEX(c) IS_AF(c) || IS_af(c) || IS_09(c)
-#define ISVALIDDEC(c) IS_09(c)
-#define CONVERTDEC(c) (c - '0')
+#define IS_AF(c) ((c >= 'A') && (c <= 'F'))
+#define IS_af(c) ((c >= 'a') && (c <= 'f'))
+#define IS_09(c) ((c >= '0') && (c <= '9'))
+#define ISVALIDHEX(c) IS_AF(c) || IS_af(c) || IS_09(c)
+#define ISVALIDDEC(c) IS_09(c)
+#define CONVERTDEC(c) (c - '0')
-#define CONVERTHEX_alpha(c) (IS_AF(c) ? (c - 'A'+10) : (c - 'a'+10))
-#define CONVERTHEX(c) (IS_09(c) ? (c - '0') : CONVERTHEX_alpha(c))
+#define CONVERTHEX_alpha(c) (IS_AF(c) ? (c - 'A' + 10) : (c - 'a' + 10))
+#define CONVERTHEX(c) (IS_09(c) ? (c - '0') : CONVERTHEX_alpha(c))
/**
* @brief 初始化串口通信
- *
+ *
*/
void InitSerial(void)
{
- rcu_periph_clock_enable(RCU_UART6);
-
- nvic_irq_enable(UART6_IRQn, 2U,0U);
-
- gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_8);
- gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_7);
-
- gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8);
- gpio_af_set(GPIOE, GPIO_AF_8, GPIO_PIN_7 | GPIO_PIN_8);
-
- usart_deinit(UART6);
- usart_baudrate_set(UART6, 115200U);
- usart_word_length_set(UART6,USART_WL_8BIT);
- usart_stop_bit_set(UART6,USART_STB_1BIT);
- usart_parity_config(UART6,USART_PM_NONE);
-
- usart_receive_config(UART6,USART_RECEIVE_ENABLE);
- usart_transmit_config(UART6, USART_TRANSMIT_ENABLE);
-
- // usart_interrupt_enable(UART6, USART_INTEN_RBNEIE);
- usart_enable(UART6);
+ rcu_periph_clock_enable(RCU_GPIOE);
+ rcu_periph_clock_enable(RCU_UART6);
+
+ // nvic_irq_enable(UART6_IRQn, 2U,0U);
+
+ gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_8);
+ gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_7);
+
+ gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8);
+ gpio_af_set(GPIOE, GPIO_AF_8, GPIO_PIN_7 | GPIO_PIN_8);
+
+ usart_baudrate_set(UART6, 115200U);
+ usart_word_length_set(UART6, USART_WL_8BIT);
+ usart_stop_bit_set(UART6, USART_STB_1BIT);
+ usart_parity_config(UART6, USART_PM_NONE);
+
+ usart_receive_config(UART6, USART_RECEIVE_ENABLE);
+ usart_transmit_config(UART6, USART_TRANSMIT_ENABLE);
+
+ // usart_interrupt_enable(UART6, USART_INTEN_RBNEIE);
+ usart_enable(UART6);
}
void ResetSerial(void)
{
- usart_disable(UART6);
- usart_deinit(UART6);
+ usart_deinit(UART6);
+ gpio_deinit(GPIOE);
}
/**
* @brief 从串口设备中获取一个字节
- *
+ *
* @param[out] key 存放字节数据的指针
* @return uint32_t 1:读取出一个数据 0:无数据
*/
-uint32_t SerialKeyPressed(uint8_t* key)
+uint32_t SerialKeyPressed(uint8_t *key)
{
- if(SET == usart_flag_get(UART6, USART_FLAG_RBNE))
- {
- usart_flag_clear(UART6, USART_FLAG_RBNE);
- *key= (uint8_t)usart_data_receive(UART6);
- return 1;
- }
- else
- {
- return 0;
- }
+ if (SET == usart_flag_get(UART6, USART_FLAG_RBNE))
+ {
+ usart_flag_clear(UART6, USART_FLAG_RBNE);
+ *key = (uint8_t)usart_data_receive(UART6);
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
}
uint8_t GetKey(void)
{
- uint8_t key=0;
- while (1)
+ uint8_t key = 0;
+ while (1)
+ {
+ if (SerialKeyPressed(&key))
{
- if(SerialKeyPressed(&key))
- {
- break;
- }
+ break;
}
- return key;
+ }
+ return key;
}
void SerialPutChar(uint8_t c)
{
- usart_data_transmit(UART6, c);
+ usart_data_transmit(UART6, c);
- while (RESET == usart_flag_get(UART6, USART_FLAG_TC))
- {
- //roll wait
- }
+ while (RESET == usart_flag_get(UART6, USART_FLAG_TC))
+ {
+ // roll wait
+ }
}
-void Serial_PutString(uint8_t* s)
+void Serial_PutString(uint8_t *s)
{
- while(*s !='\0')
- {
- SerialPutChar(*s);
- s++;
- }
+ while (*s != '\0')
+ {
+ SerialPutChar(*s);
+ s++;
+ }
}
-int Int2Str(uint8_t* str, int32_t intnum)
+int Int2Str(uint8_t *str, int32_t intnum)
{
uint32_t i, Div = 1000000000, j = 0, Status = 0;
@@ -117,7 +117,7 @@ int Int2Str(uint8_t* str, int32_t intnum)
intnum = intnum % Div;
Div /= 10;
- if ((str[j-1] == '0') & (Status == 0))
+ if ((str[j - 1] == '0') & (Status == 0))
{
j = 0;
}
@@ -129,11 +129,11 @@ int Int2Str(uint8_t* str, int32_t intnum)
}
/**
- * @brief Intel String trans to Integer
- *
- * @param inputstr
- * @param intnum
- * @return int
+ * @brief Intel String trans to Integer
+ *
+ * @param inputstr
+ * @param intnum
+ * @return int
*/
int Str2Int(uint8_t *inputstr, int32_t *intnum)
{
@@ -174,7 +174,7 @@ int Str2Int(uint8_t *inputstr, int32_t *intnum)
}
else /* max 10-digit decimal input */
{
- for (i = 0;i < 11;i++)
+ for (i = 0; i < 11; i++)
{
if (inputstr[i] == '\0')
{
diff --git "a/doc/BMC\344\274\240\347\273\237\345\272\224\347\224\250\350\277\201\347\247\273\344\270\272IAP\345\272\224\347\224\250\346\223\215\344\275\234\346\211\213\345\206\214.docx" "b/doc/BMC\344\274\240\347\273\237\345\272\224\347\224\250\350\277\201\347\247\273\344\270\272IAP\345\272\224\347\224\250\346\223\215\344\275\234\346\211\213\345\206\214.docx"
new file mode 100644
index 0000000000000000000000000000000000000000..a16cc9bfe46aecb8d93b3dba580901641099e9dd
Binary files /dev/null and "b/doc/BMC\344\274\240\347\273\237\345\272\224\347\224\250\350\277\201\347\247\273\344\270\272IAP\345\272\224\347\224\250\346\223\215\344\275\234\346\211\213\345\206\214.docx" differ
diff --git a/main.c b/main.c
index 3be3b344e1a33f28e450535255272db6ee25c776..a2c78ed6bdf23fb3496e333a399d4672ff8b62e1 100644
--- a/main.c
+++ b/main.c
@@ -2,12 +2,13 @@
* @Author: Ma Yuchen
* @Date: 2022-11-22 21:03:02
* @LastEditors: Ma YuChen
- * @LastEditTime: 2022-11-24 11:27:04
+ * @LastEditTime: 2022-11-26 11:49:43
* @Description: file content
* @FilePath: \BootLoader\main.c
*/
#include
#include "menu.h"
+#include "bsp_gpio.h"
#include "bsp_uart.h"
#include "bsp_ocflash.h"
#include "systick.h"
@@ -21,24 +22,34 @@ static int ExistApplication(void);
int main(void)
{
-
//初始化Core时钟
systick_config();
+ //初始化GPIO并打开V3.3外设供电
+ InitGpio();
+ PowerOnBmcPeriph();
+ delay_1ms(10);
+
//初始化串口
InitSerial();
+
+ SerialPutString("\r\nThanks for use this bootLoader\r\n");
if(GetIAPIntper() == 1)
//如果获取到IAP请求中断则打印菜单进行IAP操作
{
+ Flash_IF_Init();
PrintMenu();
}
//如果无请求则跳转到APP启动
else
{
+ SerialPutString("\r\nRun App...\r\n");
RunApp();
}
- return 0;
+ while(1)
+ {
+ }
}
int GetIAPIntper(void)
@@ -75,7 +86,7 @@ void RunApp(void)
int ExistApplication(void)
{
- if((*(__IO uint32_t *)APPLICATION_ADDRESS) & 0x2FFE0000 == 0x20000000)
+ if(((*(__IO uint32_t *)APPLICATION_ADDRESS) & 0x2FFE0000) == 0x20000000)
{
return 1;
}
diff --git a/menu.c b/menu.c
index 7255d540d931bd4d63180378bacf62b3907c84f4..90bcae6b80607d3acc1d013033a8cc990d349a55 100644
--- a/menu.c
+++ b/menu.c
@@ -2,19 +2,20 @@
* @Author: Ma Yuchen
* @Date: 2022-11-24 10:03:28
* @LastEditors: Ma YuChen
- * @LastEditTime: 2022-11-24 11:25:49
+ * @LastEditTime: 2022-11-25 15:19:15
* @Description: file content
* @FilePath: \BootLoader\menu.c
*/
#include "gd32f4xx.h"
#include "menu.h"
+#include "bsp_gpio.h"
+#include "systick.h"
-pFunction Jump_To_Application;
-uint32_t JumpAddress;
+static pFunction Jump_To_Application;
+static uint32_t JumpAddress;
-uint8_t tab_1024[PACKET_DATA_LENGTH] = {0};
-uint8_t FileName[FILE_NAME_LENGTH] = {0};
+static uint8_t tab_1024[PACKET_DATA_LENGTH] = {0};
void SerialDownLoad(void);
@@ -25,6 +26,7 @@ void SerialDownLoad(void);
void PrintMenu(void)
{
uint8_t key = 0;
+ uint8_t printProgramMenu=1;
SerialPutString("\r\n=========================================================\r\n");
SerialPutString("\r\n= =\r\n");
@@ -34,10 +36,14 @@ void PrintMenu(void)
while (1)
{
+ if(printProgramMenu!=0)
+ {
+ printProgramMenu=0;
SerialPutString("\r\n========================Main Menu========================\r\n");
SerialPutString("\r\n== Download Image To the GD32F4xx Internal Flash--------1\r\n");
SerialPutString("\r\n== Exec New Program-------------------------------------2\r\n");
SerialPutString("\r\n=========================================================\r\n");
+ }
key = GetKey();
@@ -45,14 +51,21 @@ void PrintMenu(void)
// Download Image & program in flash
{
SerialDownLoad();
+ printProgramMenu=1;
}
else if (key == 0x32)
{
LoadRunApplication();
+ printProgramMenu=1;
+ return ;
+ }
+ else if(key == 0x1B)
+ {
+
}
else
{
- SerialPutString("Invalid Num ! ==> The number should be either1,2\r\n");
+ SerialPutString("\r\nInvalid Num ! ==> The number should be either1,2\r\n");
}
}
}
@@ -63,7 +76,7 @@ void SerialDownLoad(void)
int32_t Size=0;
SerialPutString("\r\n Waiting for file to be sent ...\r\n");
- Size=Ymodem_Receive(&tab_1024);
+ Size=Ymodem_Receive(tab_1024);
if(Size>0)
{
@@ -73,13 +86,22 @@ void SerialDownLoad(void)
SerialPutString("\r\n Size: ");
SerialPutString(Number);
SerialPutString("Bytes\r\n");
- stringPutString("--------------------------\r\n");
+ SerialPutString("--------------------------\r\n");
+ }
+ else
+ {
+ SerialPutString("\r\n Warning Receive File failed!!\r\n");
}
-
}
void LoadRunApplication(void)
{
+ PowerOffBmcPeriph();
+ ResetSerial();
+ ResetGpio();
+
+ delay_1ms(500);
+
nvic_irq_disable(EXTI0_IRQn);
JumpAddress = *(__IO uint32_t *)(APPLICATION_ADDRESS + 4); // application main address
diff --git a/menu.h b/menu.h
index 901ed972f4ba4cb9240473ccb358d9fe9c3e033a..3537aa2f67113760aa47035a53fb3fcec22be152 100644
--- a/menu.h
+++ b/menu.h
@@ -15,6 +15,8 @@
#include "bsp_ocflash.h"
#include "bsp_uart.h"
+
+
void PrintMenu(void);
void LoadRunApplication(void);
diff --git a/ymodem.c b/ymodem.c
index 586530ff806665da3d6195551584b5e81edebbe1..cb6579317020c49bdef9339057afbaf9fdabd6f2 100644
--- a/ymodem.c
+++ b/ymodem.c
@@ -2,7 +2,7 @@
* @Author: Ma Yuchen
* @Date: 2022-11-23 23:29:58
* @LastEditors: Ma YuChen
- * @LastEditTime: 2022-11-24 11:18:50
+ * @LastEditTime: 2022-11-26 12:03:43
* @Description: file content
* @FilePath: \BootLoader\ymodem.c
*/
@@ -10,8 +10,311 @@
#include "bsp_ocflash.h"
#include "bsp_uart.h"
-int Ymodem_Receive(uint8_t* buffer)
+typedef struct _YModemInfo
{
- //TODO
+ int packet_length;
+ int file_size;
+ uint8_t session_done;
+ uint8_t session_begin;
+ uint8_t errors;
+
+ uint8_t pakcets_received;
+ uint8_t file_done;
+
+ uint8_t packet_data[PACKET_OVERHEAD + PACKET_DATA_LENGTH];
+
+ uint8_t revice[2];
+} YModemInfo;
+
+uint8_t FileName[FILE_NAME_LENGTH] = {0};
+
+static int Receive_Byte(uint8_t *c, uint32_t timeout)
+{
+ while (timeout-- > 0)
+ {
+ if (1 == SerialKeyPressed(c))
+ {
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+static int Send_Byte(uint8_t c)
+{
+ SerialPutChar(c);
+ return 0;
+}
+
+static uint16_t UpdateCrc16(uint16_t crc, uint8_t d)
+{
+ uint8_t count = 8;
+ uint16_t newCrc = crc;
+ uint16_t data = d;
+
+ while ((count--) > 0)
+ {
+ if (newCrc & 0x8000)
+ {
+ newCrc <<= 1;
+ newCrc += (((data <<= 1) & 0x0400) != 0);
+ newCrc ^= 0x1021;
+ }
+ else
+ {
+ newCrc <<= 1;
+ newCrc += (((data <<= 1) & 0x0400) != 0);
+ }
+ }
+
+ return newCrc;
+}
+
+static uint16_t ClcCrc16(const uint8_t *datas, int size)
+{
+ uint16_t crc = 0;
+
+ const uint8_t *endofDatas = datas + size;
+
+ while (datas < endofDatas)
+ {
+ crc = UpdateCrc16(crc, *datas);
+ datas++;
+ }
+ crc = UpdateCrc16(crc, 0);
+ crc = UpdateCrc16(crc, 0);
+
+ return (crc & (uint16_t)0xffff);
+}
+
+/**
+ * @brief
+ *
+ * @param buffer
+ * @param length
+ * @param timeout
+ * @return int
+ * 0 ok
+ * -1 receive timeout or header falied
+ * -2 packet no error
+ * -3 crc error
+ */
+static int Receive_Packet(uint8_t *buffer, int32_t *length, uint32_t timeout)
+{
+ uint16_t i, packet_size, computedcrc;
+ uint8_t data;
+ *length = 0;
+
+ if (Receive_Byte(&data, timeout) != 0)
+ {
+ return -1;
+ }
+
+ switch (data)
+ {
+ case SOH:
+ packet_size = PACKET_SIZE;
+ break;
+ case STX:
+ packet_size = PACKET_DATA_LENGTH;
+ break;
+ case CAN:
+ //if two CAN return length -1
+ if((Receive_Byte(&data, timeout) == 0) && (CAN == data))
+ {
+ *length=-1;
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+ case EOT:
+ return 0;
+ default:
+ return -1;
+ }
+
+ *buffer = data; // buffer store header in buffer[0];
+
+ // receive packet
+ for (i = 1; i < packet_size; i++)
+ {
+ if (Receive_Byte(buffer + i, timeout) != 0)
+ {
+ return -1;
+ }
+ }
+
+ // check packet no
+ if (buffer[PACKET_NO_INDEX] != ((buffer[PACKET_NO_N_INDEX] ^ 0xff) & 0xff))
+ {
+ return -2;
+ }
+
+ computedcrc = ClcCrc16(buffer[PACKET_HEADER], (int)packet_size);
+
+ if (computedcrc != (((uint16_t)buffer[packet_size + 3] << 8) | buffer[packet_size + 4]))
+ {
+ return -3;
+ }
+
+ *length = packet_size;
+
return 0;
}
+
+/**
+ * @brief 完成Ymodem 下Receiver的功能
+ * 1.接收数据包 如果是第一次能判定为文件信息描述包
+ * 2.接收所有的数据数据包,如果接收到合法的数据包,则提取数据后,直接烧写flash中
+ *
+ * @param buffer
+ * @return int
+ */
+int Ymodem_Receive(uint8_t *buffer)
+{
+ YModemInfo yModemInfo;
+ int i;
+ uint8_t* buf_ptr;
+ uint8_t* file_ptr;
+ uint8_t fileSizeStr[FILE_SIZE_LENGTH]={0};
+ //int fileLength = 0;
+ uint32_t flashDestination = APPLICATION_ADDRESS;
+ uint32_t ramSourceAddr=0;
+
+ memset(&yModemInfo, 0, sizeof(YModemInfo));
+
+
+
+ //session
+ while (yModemInfo.session_done == 0)
+ {
+ yModemInfo.pakcets_received=0;
+ yModemInfo.file_done=0;
+ //packet
+ while (yModemInfo.file_done == 0)
+ {
+ switch (Receive_Packet(yModemInfo.packet_data, &(yModemInfo.packet_length), NAK_TIMEOUT))
+ {
+ case 0:
+ yModemInfo.errors=0;
+
+ switch (yModemInfo.packet_length)
+ {
+ //CAN
+ //abort by Sender
+ case -1:
+ Send_Byte(ACK);
+ return 0;
+ //End of this file transmission
+ case 0:
+ Send_Byte(ACK);
+ yModemInfo.file_done=1;
+ break;
+ default://Normal Packet
+ //Check receive pakcet number
+ if((yModemInfo.packet_data[PACKET_NO_INDEX] & 0xff) != (yModemInfo.pakcets_received & 0xff))
+ {
+ Send_Byte(NAK);
+ }
+ else
+ {
+ if(yModemInfo.pakcets_received==0)
+ //Filename Packet
+ {
+ if(yModemInfo.packet_data[PACKET_HEADER] !=0)
+ {
+ for(i=0, file_ptr=yModemInfo.packet_data+PACKET_HEADER;
+ (*file_ptr!=0) && i (int32_t)(USER_FLASH_SIZE))
+ {
+ //end session
+ Send_Byte(CAN);
+ Send_Byte(CAN);
+
+ return -1;
+ }
+
+ Flash_IF_App_Erase(APPLICATION_START_SECTOR, APPLICATION_END_SECTOR);
+ Send_Byte(ACK);
+ Send_Byte(CRC16);
+ }
+ else
+ {
+ Send_Byte(ACK);
+ yModemInfo.file_done=1;
+ yModemInfo.session_done=1;
+ break;
+ }
+ }
+ //Data Packet
+ else
+ {
+ // buf_ptr=buffer;
+ // memcpy(buf_ptr, yModemInfo.packet_data+PACKET_HEADER, (uint32_t)yModemInfo.packet_length);
+
+ // ramSourceAddr=(uint32_t)buf_ptr;
+ ramSourceAddr=(uint32_t)(yModemInfo.packet_data+PACKET_HEADER);
+ if(0 == Flash_IF_Write(&flashDestination, (uint32_t *)ramSourceAddr, yModemInfo.pakcets_received/4))
+ {
+ Send_Byte(ACK);
+ }
+ else
+ {
+ Send_Byte(CAN);
+ Send_Byte(CAN);
+ return -2;
+ }
+ }
+
+ yModemInfo.pakcets_received++;
+ yModemInfo.session_begin=1;
+ }
+ break;
+ }
+ break;
+ case 1:
+ Send_Byte(CAN);
+ Send_Byte(CAN);
+ return -3;
+ default:
+ // 如果session已经开始
+ if (yModemInfo.session_begin > 0)
+ // 则累计一次错误计数
+ {
+ yModemInfo.errors++;
+ }
+
+ if (yModemInfo.errors > MAX_ERRORS)
+ {
+ Send_Byte(CAN);
+ Send_Byte(CAN);
+ return 0;
+ }
+
+ Send_Byte(CRC16); // Send ‘C' to CommInit
+ break;
+ }
+ }
+ }
+
+ return yModemInfo.file_size;
+}
diff --git a/ymodem.h b/ymodem.h
index 6a96b909de468e2796538c2ec84ebfbfbed5ad09..a71a416e69fbd5d1e5e771350208aeb3d7fbe2bf 100644
--- a/ymodem.h
+++ b/ymodem.h
@@ -2,14 +2,14 @@
* @Author: Ma Yuchen
* @Date: 2022-11-23 23:30:07
* @LastEditors: Ma YuChen
- * @LastEditTime: 2022-11-24 11:18:30
+ * @LastEditTime: 2022-11-24 18:51:22
* @Description: Y Modem File Transport Protocol Define func
* this Protocel can be used when uart is only IO interface on MCU
* @FilePath: \BootLoader\ymodem.h
*/
#ifndef Y_MODEM_H
#define Y_MODEM_H
-
+#include
#include
/*Ymodem Frame base on ASCII Encode*/
@@ -32,10 +32,14 @@
#define FILE_NAME_LENGTH (256)
#define FILE_SIZE_LENGTH (16)
+#define PACKET_NO_INDEX (1)
+#define PACKET_NO_N_INDEX (2)
+
#define NAK_TIMEOUT (0x100000)
#define MAX_ERRORS (5)
+extern uint8_t FileName[];
int Ymodem_Receive(uint8_t* buffer);