GD32F450VI系列单片机IAP远程升级代码示例
#include "gd32f450vi.h" #include "gd32f450vi_eval.h" #include "iap.h"
/* \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0定义IAP程序起始地址和大小 / #define IAP_APP_ADDRESS\u00a0\u00a0\u00a0\u00a0\u00a0 0x08008000\u00a0\u00a0\u00a0\u00a0/ IAP程序起始地址 / #define IAP_APP_SIZE\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 0x00010000\u00a0\u00a0\u00a0\u00a0/ IAP程序大小(64KB) */
/* \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0定义用于接收升级数据的缓冲区 */ #define BUFFER_SIZE\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 1024
/* \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0定义串口通信接口 */ #define UART_PORT\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 USART0 #define UART_BAUDRATE\u00a0\u00a0\u00a0\u00a0\u00a0 115200
/* \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0定义IAP状态 / typedef enum { \u00a0\u00a0\u00a0\u00a0 IAP_IDLE = 0,\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0/ 空闲状态 / \u00a0\u00a0\u00a0\u00a0 IAP_RECEIVING,\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0/ 接收升级数据中 / \u00a0\u00a0\u00a0\u00a0 IAP_COMPLETE\u00a0\u00a0\u00a0\u00a0\u00a0/ 接收升级数据完成 */ } IAP_State;
volatile IAP_State iapState = IAP_IDLE; volatile uint32_t iapAddress = IAP_APP_ADDRESS; volatile uint32_t iapSize = 0;
/* \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0串口接收数据回调函数 / void uart_receive_callback(uint8_t data) { \u00a0\u00a0 static uint8_t buffer[BUFFER_SIZE]; \u00a0\u00a0 static uint32_t bufferIndex = 0; \u00a0\u00a0 \u00a0\u00a0 if (iapState == IAP_IDLE) { \u00a0\u00a0 \u00a0\u00a0 if (data == 'U') { \u00a0\u00a0 \u00a0\u00a0 \u00a0\u00a0 / 收到升级请求,进入接收状态 / \u00a0\u00a0 \u00a0\u00a0 \u00a0\u00a0 iapState = IAP_RECEIVING; \u00a0\u00a0 \u00a0\u00a0 \u00a0\u00a0 bufferIndex = 0; \u00a0\u00a0 \u00a0\u00a0 } \u00a0\u00a0 } else if (iapState == IAP_RECEIVING) { \u00a0\u00a0 \u00a0\u00a0 / 接收升级数据 / \u00a0\u00a0 \u00a0\u00a0 buffer[bufferIndex++] = data; \u00a0\u00a0 \u00a0\u00a0 \u00a0\u00a0 \u00a0\u00a0 if (bufferIndex >= BUFFER_SIZE) { \u00a0\u00a0 \u00a0\u00a0 \u00a0\u00a0 / 缓冲区已满,写入IAP程序存储区 */ \u00a0\u00a0 \u00a0\u00a0 \u00a0\u00a0 flash_erase_page(iapAddress); \u00a0\u00a0 \u00a0\u00a0 \u00a0\u00a0 flash_program_buffer(iapAddress, (uint32_t )buffer, BUFFER_SIZE / 4); \u00a0\u00a0 \u00a0\u00a0 \u00a0\u00a0 iapAddress += BUFFER_SIZE; \u00a0\u00a0 \u00a0\u00a0 \u00a0\u00a0 bufferIndex = 0; \u00a0\u00a0 \u00a0\u00a0 } \u00a0\u00a0 \u00a0\u00a0 \u00a0\u00a0 \u00a0\u00a0 if (iapAddress >= (IAP_APP_ADDRESS + IAP_APP_SIZE)) { \u00a0\u00a0 \u00a0\u00a0 \u00a0\u00a0 / 接收完成,进入完成状态 */ \u00a0\u00a0 \u00a0\u00a0 \u00a0\u00a0 iapState = IAP_COMPLETE; \u00a0\u00a0 \u00a0\u00a0 } \u00a0\u00a0 } }
int main(void) { \u00a0\u00a0 /* 初始化串口通信 / \u00a0\u00a0 gd_eval_com_init(EVAL_COM1, UART_BAUDRATE); \u00a0\u00a0 gd_eval_com_irq_callback_register(EVAL_COM1, uart_receive_callback); \u00a0\u00a0 \u00a0\u00a0 / 进入主循环 / \u00a0\u00a0 while (1) { \u00a0\u00a0 \u00a0\u00a0 / 判断IAP状态 / \u00a0\u00a0 \u00a0\u00a0 if (iapState == IAP_COMPLETE) { \u00a0\u00a0 \u00a0\u00a0 \u00a0\u00a0 / 升级完成,跳转到IAP程序 */ \u00a0\u00a0 \u00a0\u00a0 \u00a0\u00a0 NVIC_SystemReset(); \u00a0\u00a0 \u00a0\u00a0 } \u00a0\u00a0 } }
上述代码中,通过串口通信接收升级数据,并将数据写入IAP程序存储区。当接收完成后,会跳转到IAP程序开始执行。
请注意,上述代码仅为示例代码,仍有一些细节需要根据具体的应用场景进行调整和完善。
原文地址: https://www.cveoy.top/t/topic/p0t3 著作权归作者所有。请勿转载和采集!