实现APP进行飞控固件升级

This commit is contained in:
OPTOC
2025-10-23 18:40:19 +08:00
parent ee28ccf5a7
commit 9754257a40
4 changed files with 170 additions and 7 deletions

View File

@@ -71,7 +71,7 @@ int send_cmd_wait(stmisp_device_t *stmisp_device, uint8_t cmd, uint32_t timeout)
switch(ack)
{
case 1:
printf("stmisp: ACK to cmd 0x%02x\n", cmd);
// printf("stmisp: ACK to cmd 0x%02x\n", cmd);
return 1;
case 2:
printf("stmisp: NACK to cmd 0x%02x\n", cmd);
@@ -235,7 +235,7 @@ int cmd_write_memory(stmisp_device_t *stmisp_device, uint32_t addr, const uint8_
stmisp_device->send((void *)&data[idx], chunk, 0);
stmisp_device->send(&cs, 1, 0);
if(wait_ack(stmisp_device, 5000) != 1) return 0;
if(wait_ack(stmisp_device, 1000) != 1) return 0;
//是否需要校验写入的数据块
if (verify)
{

View File

@@ -38,6 +38,10 @@ typedef struct
uint32_t adder_offset; //地址偏移
}stmisp_device_t;
typedef struct
{
uint32_t stmisp_file_size;
}stmisp_parm_t;
/**
* @brief 计算校验和
*/

View File

@@ -162,6 +162,12 @@ void app_thread(void* arg)
resend_send_data(&sertrf.resend_device, RESEND_CMD_OTA_GET_PARAM, &ota_parm, sizeof(ota_parm_t), 1000);
sertrf.resend_device.handle_flag = 0;//标志位清零
break;
case RESEND_CMD_FC_ISP_GET_PARAM:
printf("RESEND_CMD_FC_ISP_GET_PARAM\r\n");
stmisp_parm_t stmisp_parm;
resend_send_data(&sertrf.resend_device, RESEND_CMD_FC_ISP_GET_PARAM, &stmisp_parm, sizeof(stmisp_parm), 1000);
sertrf.resend_device.handle_flag = 0;//标志位清零
break;
default:
break;
}
@@ -271,6 +277,58 @@ void data_handle_thread(void* arg)
}
}
break;
case DATA_HANDLE_ISP_DATA:
{
size_t data_size = rb_size(&sertrf.data_handle_buffer);
if(data_size > 0)
{
uint8_t data[data_size];
rb_get_bulk(&sertrf.data_handle_buffer, data, data_size);
uint32_t addr = sertrf.fc_address + sertrf.stmisp_device.adder_offset;
if(cmd_write_memory(&sertrf.stmisp_device, addr, data, data_size, false))
{
resend_send_cmd(&sertrf.resend_device, RESEND_CMD_ACK, 0);
sertrf.stmisp_device.adder_offset += data_size;
SYS_LOG_INF("stmisp write ok %d %d\n",data_size, sertrf.stmisp_device.adder_offset);
}
else
{
sertrf.stmisp_device.adder_offset = 0;
sertrf.mode_status.task_state = DATA_HANDLE_IDLE;
SYS_LOG_DBG("stmisp write error");
}
}
}
break;
case DATA_HANDLE_ISP_DATA_END:
{
size_t data_size = rb_size(&sertrf.data_handle_buffer);
if(data_size > 0)
{
uint8_t data[data_size];
rb_get_bulk(&sertrf.data_handle_buffer, data, data_size);
uint32_t addr = sertrf.fc_address + sertrf.stmisp_device.adder_offset;
if(cmd_write_memory(&sertrf.stmisp_device, addr, data, data_size, true))
{
sertrf.stmisp_device.adder_offset = 0;
sertrf.mode_status.task_state = DATA_HANDLE_IDLE;
}
else
{
SYS_LOG_DBG("stmisp write end error");
}
}
else
{
sertrf.stmisp_device.adder_offset = 0;
sertrf.mode_status.task_state = DATA_HANDLE_IDLE;
}
}
break;
default:
break;
}
@@ -434,20 +492,117 @@ void resend_user_parse(void *resend_device)
esp_restart();
}
break;
case RESEND_CMD_FC_ISP_GET_PARAM:
if(sizeof(stmisp_parm_t) != resend_parse->rx_frame.len)
{
printf("RESEND_CMD_FC_ISP_GET_PARAM len error\r\n");
}
stmisp_parm_t* stmisp_parm = (stmisp_parm_t*)resend_parse->rx_frame.payload;
printf("RESEND_CMD_FC_ISP_GET_PARAM %d\n", stmisp_parm->stmisp_file_size);
resend_send_cmd(resend_device, RESEND_CMD_ACK, 0);
break;
case RESEND_CMD_FC_ISP_START:
/*关闭其他线程中相同串口的使用并复位飞控使其进入isp烧录模式串口切换为偶校验模式
使用sync与isp确定通讯波特率并建立联系 解除其写保护 并重新sync建立连接后擦除全部区域内存*/
//关闭其他线程中相同串口的使用
sertrf.stmisp_device.flag = 1;
// 重启飞控并使其进入isp烧录模式
fc_reboot();
boot_set(0);
os_thread_sleep(1000);
//串口切换为偶校验模式,并清除缓存
uart_set_parity_switch(sertrf.device.embedded_device, 0x02);
os_thread_sleep(100);
// 与isp确定通讯波特率并建立联系
if(!send_sync(&sertrf.stmisp_device, 5))
printf("stmisp: sync error\n");
else
printf("stmisp: sync ok\n");
os_thread_sleep(100);
// 解除写保护
if(!cmd_write_unprotect(&sertrf.stmisp_device))
printf("stmisp: write unprotect error\n");
else
printf("stmisp: write unprotect ok\n");
os_thread_sleep(100);
if(!send_sync(&sertrf.stmisp_device, 5))
printf("stmisp: sync error\n");
else
printf("stmisp: sync ok\n");
os_thread_sleep(100);
boot_set_high_z();
// 全盘擦除
if(!cmd_extended_erase_mass(&sertrf.stmisp_device))
printf("stmisp: erase mass error\n");
else
printf("stmisp: erase mass ok\n");
os_thread_sleep(10);
printf("stmisp: isp start\n");
sertrf.mode_status.task_state = DATA_HANDLE_ISP_DATA;
resend_send_cmd(resend_device, RESEND_CMD_ACK, 0);
break;
case RESEND_CMD_FC_ISP_DATA:
// 使用环形buff
if(rb_size(&sertrf.data_handle_buffer) + sertrf.resend_device.rx_frame.len <= DATA_HANDLE_BUFFER_SIZE)
{
rb_put_bulk(&sertrf.data_handle_buffer, sertrf.resend_device.rx_frame.payload, sertrf.resend_device.rx_frame.len);
}
else
{
SYS_LOG_DBG("RESEND_CMD_FC_ISP_DATA buffer full");
}
// resend_send_cmd(resend_device, RESEND_CMD_ACK, 0);
break;
case RESEND_CMD_FC_ISP_END:
// 告诉数据处理线程ISP烧录数据传输完成
sertrf.mode_status.task_state = DATA_HANDLE_ISP_DATA_END;
// 等待数据处理线程写入完成
SYS_LOG_INF("RESEND_CMD_FC_ISP_END1");
while(sertrf.mode_status.task_state != DATA_HANDLE_IDLE){
os_thread_sleep(10);}
// ISP下跳转到应用层运行地址
if(cmd_go(&sertrf.stmisp_device, sertrf.fc_address))
{
printf("stmisp: go ok\n");
}
else
{
printf("stmisp: go error\n");
}
//开启其他线程中相同串口的使用
sertrf.stmisp_device.flag = 0;
// 将串口切换为无校验模式
uart_set_parity_switch(sertrf.device.embedded_device, 0x00);
SYS_LOG_INF("RESEND_CMD_FC_ISP_END2");
resend_send_cmd(resend_device, RESEND_CMD_ACK, 0);
break;
default:
break;
}
}
void Examples_run(void)
{
//关闭其他线程中相同串口的使用
// // //关闭其他线程中相同串口的使用
sertrf.stmisp_device.flag = 1;
// 重启飞控并使其进入isp烧录模式
// // // 重启飞控并使其进入isp烧录模式
fc_reboot();
boot_set(1);
os_thread_sleep(1000);
boot_set(0);
os_thread_sleep(500);
uart_set_parity_switch(sertrf.device.embedded_device, 0x02);
os_thread_sleep(100);
os_thread_sleep(500);
// 与isp确定通讯波特率并建立联系
if(!send_sync(&sertrf.stmisp_device, 5))
printf("stmisp: sync error\n");
@@ -468,6 +623,8 @@ void Examples_run(void)
else
printf("stmisp: sync ok\n");
os_thread_sleep(100);
boot_set_high_z();
// 全盘擦除
if(!cmd_extended_erase_mass(&sertrf.stmisp_device))
printf("stmisp: erase mass error\n");

View File

@@ -18,6 +18,8 @@ typedef enum
DATA_HANDLE_IDLE = 0,
DATA_HANDLE_OTA_DATA,
DATA_HANDLE_OTA_DATA_END,
DATA_HANDLE_ISP_DATA,
DATA_HANDLE_ISP_DATA_END
}data_handle_e;
typedef struct
{