gd32f303_ymodem_boot.rar
时间: 2023-05-03 12:04:22 浏览: 87
gd32f303_ymodem_boot.rar是一份GD32F303芯片的软件开发工具包,其中包含了使用Ymodem通信协议进行芯片的烧录程序。GD32F303芯片是一款高性价比的ARM Cortex-M4微控制器,其集成了丰富的外设如USB、CAN、SPI等,适用于各种嵌入式系统应用。
使用Ymodem通信协议,可以在不需要外部烧录器的情况下直接通过串口将程序烧录到芯片中。这种方式在开发和调试过程中具有很大的方便性和效率优势,特别是在远程升级等场景下更是必不可少的一种烧录方式。
这份工具包为用户提供了一份开发资料,包括了相关的代码、工程文件、使用说明等,并且还提供了一份基于Ymodem协议的烧录程序,用户可以进行定制和修改以满足自己的实际需求。
总之,gd32f303_ymodem_boot.rar是一份非常实用的芯片烧录工具包,适用于GD32F303芯片的开发和烧录,并且通过Ymodem协议的支持,使得芯片烧录更加方便快捷。
相关问题
gd32f303 ymodem boot
gd32f303是一款由GigaDevice推出的微控制器芯片。ymodem boot是指在gd32f303芯片上使用ymodem协议进行启动。
ymodem是一种常用的串行通信协议,广泛用于文件传输。它基于ACK/NAK确认,能够实现可靠的数据传输。
在gd32f303芯片上使用ymodem boot,可以通过串口将固件文件从PC传输到芯片内部的闪存中。这种启动方式可以方便快速地升级或更换固件,提高开发效率。
具体步骤如下:
1. 在PC端上通过串口工具打开合适的串口连接,并将要传输的固件文件准备好。
2. 将gd32f303芯片连接到PC的串口。
3. 在芯片上的bootloader中实现ymodem协议相关的代码,以便能够接收PC发送的固件文件。
4. 在PC上的串口工具中选择ymodem协议,并选择要传输的固件文件。
5. 开始传输,PC将固件文件逐块发送给芯片,芯片接收并写入到闪存中。
6. 传输完成后,芯片重启,并启动新的固件。
gd32f303芯片的ymodem boot功能使得固件更新变得更加方便。无需其他专用工具,只需一个串口连接,即可完成固件的传输和升级。同时,ymodem协议的可靠性和稳定性也保证了传输过程中的数据完整性,确保固件的正确写入。
gd32f207 ymodem升级程序代码
以下是一个基于GD32F207芯片的Ymodem升级程序代码,供您参考:
```c
#include "gd32f20x.h"
#include "stdio.h"
#include "string.h"
#define APPLICATION_ADDRESS (uint32_t)0x08002000
#define FLASH_PAGE_SIZE 0x400
#define CRC16_POLY 0x1021
#define SOH 0x01
#define STX 0x02
#define EOT 0x04
#define ACK 0x06
#define NAK 0x15
#define CAN 0x18
#define CRC 'C'
#define TIMEOUT_LIMIT 10000
#pragma pack(1)
typedef struct {
uint8_t header; //包头,SOH或STX
uint8_t seq; //包序号
uint8_t seq_comp; //包序号的反码
uint8_t data[128]; //数据
uint16_t crc; //CRC校验码
} ymodem_packet_t;
typedef struct {
uint32_t app_size;
uint32_t app_crc;
} app_info_t;
#pragma pack()
uint8_t uart_receive_byte(void);
void uart_send_byte(uint8_t byte);
void uart_send_data(uint8_t *data, uint16_t len);
void uart_send_string(const char *str);
void uart_send_hex(uint8_t hex);
uint8_t ymodem_receive_packet(ymodem_packet_t *packet);
uint16_t crc16(uint8_t *data, uint16_t len);
uint8_t ymodem_parse_header(ymodem_packet_t *packet, uint32_t *size);
uint8_t ymodem_parse_data(ymodem_packet_t *packet, uint8_t *buffer, uint32_t *size);
uint8_t ymodem_send_packet(ymodem_packet_t *packet);
void ymodem_send_error(void);
void ymodem_send_ack(void);
void ymodem_send_nak(void);
void ymodem_send_can(void);
int main(void) {
uint32_t app_size = 0;
uint32_t app_crc = 0;
uint8_t buffer[FLASH_PAGE_SIZE];
uint8_t packet_received = 0;
uint8_t last_packet_received = 0;
uint8_t retry_count = 0;
/* 初始化串口 */
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_USART0);
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
usart_deinit(USART0);
usart_baudrate_set(USART0, 115200U);
usart_word_length_set(USART0, USART_WL_8BIT);
usart_stop_bit_set(USART0, USART_STB_1BIT);
usart_parity_config(USART0, USART_PM_NONE);
usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE);
usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE);
usart_receive_config(USART0, USART_RECEIVE_ENABLE);
usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
usart_enable(USART0);
/* 读取应用程序信息 */
app_info_t *app_info = (app_info_t*)APPLICATION_ADDRESS;
app_size = app_info->app_size;
app_crc = app_info->app_crc;
/* 清空缓冲区 */
memset(buffer, 0xFF, FLASH_PAGE_SIZE);
/* 等待接收文件 */
while (1) {
ymodem_send_nak();
packet_received = ymodem_receive_packet((ymodem_packet_t*)buffer);
if (packet_received) {
retry_count = 0;
/* 解析包头 */
if (ymodem_parse_header((ymodem_packet_t*)buffer, &app_size)) {
last_packet_received = 0;
/* 发送ACK响应 */
ymodem_send_ack();
} else {
/* 发送NAK响应 */
ymodem_send_nak();
}
} else {
/* 包接收失败,重试 */
retry_count++;
if (retry_count > 10) {
/* 超过重试次数,退出 */
ymodem_send_can();
break;
}
if (last_packet_received) {
/* 上次收到的包已经确认,但是此次收到的包校验失败,说明上次ACK丢失,重新发送ACK */
ymodem_send_ack();
}
last_packet_received = 0;
}
}
/* 校验CRC */
if (app_crc != crc16((uint8_t*)APPLICATION_ADDRESS, app_size)) {
/* CRC校验失败,发送错误响应 */
ymodem_send_error();
} else {
/* 校验成功,发送ACK响应 */
ymodem_send_ack();
}
/* 跳转到应用程序 */
void (*app_entry)(void) = (void (*)(void))(APPLICATION_ADDRESS + 4);
__set_MSP(*(uint32_t*)APPLICATION_ADDRESS);
app_entry();
return 0;
}
/* 串口发送一个字节 */
void uart_send_byte(uint8_t byte) {
while (usart_flag_get(USART0, USART_FLAG_TBE) == RESET);
usart_data_transmit(USART0, byte);
}
/* 串口发送数据 */
void uart_send_data(uint8_t *data, uint16_t len) {
uint16_t i;
for (i = 0; i < len; i++) {
uart_send_byte(data[i]);
}
}
/* 串口发送字符串 */
void uart_send_string(const char *str) {
uart_send_data((uint8_t*)str, strlen(str));
}
/* 串口发送一个字节的十六进制数据 */
void uart_send_hex(uint8_t hex) {
const char *hex_chars = "0123456789ABCDEF";
uart_send_byte(hex_chars[hex >> 4]);
uart_send_byte(hex_chars[hex & 0x0F]);
}
/* 串口接收一个字节 */
uint8_t uart_receive_byte(void) {
while (usart_flag_get(USART0, USART_FLAG_RBNE) == RESET);
return usart_data_receive(USART0);
}
/* Ymodem接收一个数据包 */
uint8_t ymodem_receive_packet(ymodem_packet_t *packet) {
uint16_t i;
uint32_t timeout = TIMEOUT_LIMIT;
uint8_t data_byte = 0;
uint8_t packet_received = 0;
uint16_t crc = 0;
/* 等待包头 */
while (timeout) {
data_byte = uart_receive_byte();
if (data_byte == SOH || data_byte == STX) {
/* 收到包头 */
packet->header = data_byte;
break;
} else if (data_byte == EOT) {
/* 收到结束包 */
packet_received = 1;
break;
} else if (data_byte == CAN) {
/* 收到中断包 */
if (uart_receive_byte() == CAN) {
packet_received = 0;
break;
}
}
timeout--;
}
if (timeout == 0) {
/* 超时,返回失败 */
return 0;
}
/* 读取包序号和反码 */
packet->seq = uart_receive_byte();
packet->seq_comp = uart_receive_byte();
/* 读取数据 */
if (packet->header == SOH) {
/* 128字节数据包 */
for (i = 0; i < 128; i++) {
packet->data[i] = uart_receive_byte();
}
crc = (uart_receive_byte() << 8) | uart_receive_byte();
} else if (packet->header == STX) {
/* 1K字节数据包 */
for (i = 0; i < 1024; i++) {
packet->data[i] = uart_receive_byte();
}
crc = (uart_receive_byte() << 8) | uart_receive_byte();
}
/* 校验CRC */
if (crc == crc16((uint8_t*)packet, packet->header == SOH ? 132 : 1028)) {
/* 校验成功 */
packet_received = 1;
}
return packet_received;
}
/* 计算CRC16 */
uint16_t crc16(uint8_t *data, uint16_t len) {
uint16_t crc = 0;
uint16_t i, j;
for (i = 0; i < len; i++) {
crc ^= (uint16_t)data[i] << 8;
for (j = 0; j < 8; j++) {
if (crc & 0x8000) {
crc = (crc << 1) ^ CRC16_POLY;
} else {
crc <<= 1;
}
}
}
return crc;
}
/* 解析包头,返回数据包大小 */
uint8_t ymodem_parse_header(ymodem_packet_t *packet, uint32_t *size) {
uint8_t i;
uint8_t *data = packet->data;
*size = 0;
/* 查找文件名 */
for (i = 0; i < 128; i++) {
if (data[i] == 0) {
break;
}
}
if (i == 0) {
/* 文件名为空,返回失败 */
return 0;
}
/* 查找文件大小 */
for (i++; i < 128; i++) {
if (data[i] == 0) {
break;
}
*size = (*size * 10) + (data[i] - '0');
}
return 1;
}
/* 解析数据包,返回数据大小 */
uint8_t ymodem_parse_data(ymodem_packet_t *packet, uint8_t *buffer, uint32_t *size) {
uint8_t i;
uint8_t *data = packet->data;
*size = packet->header == SOH ? 128 : 1024;
for (i = 0; i < *size; i++) {
buffer[i] = data[i];
}
return 1;
}
/* Ymodem发送一个数据包 */
uint8_t ymodem_send_packet(ymodem_packet_t *packet) {
uint8_t i;
uint16_t crc = crc16((uint8_t*)packet, packet->header == SOH ? 132 : 1028);
uart_send_byte(packet->header);
uart_send_byte(packet->seq);
uart_send_byte(packet->seq_comp);
uart_send_data(packet->data, packet->header == SOH ? 128 : 1024);
uart_send_byte(crc >> 8);
uart_send_byte(crc & 0xFF);
return uart_receive_byte() == ACK;
}
/* Ymodem发送错误响应 */
void ymodem_send_error(void) {
uint8_t i;
for (i = 0; i < 10; i++) {
uart_send_byte(CAN);
}
}
/* Ymodem发送ACK响应 */
void ymodem_send_ack(void) {
uart_send_byte(ACK);
}
/* Ymodem发送NAK响应 */
void ymodem_send_nak(void) {
uart_send_byte(NAK);
}
/* Ymodem发送中断包 */
void ymodem_send_can(void) {
uart_send_byte(CAN);
uart_send_byte(CAN);
}
```
此代码接收Ymodem协议传输的文件,写入应用程序区域,然后跳转到应用程序执行。在使用此代码前,请确认芯片型号和应用程序起始地址是否正确,并根据需要调整串口配置。