技术文档

单片机0u AOVX资产监测设备之华大单片机Boot软件升级

小编 2024-11-24 技术文档 23 0

AOVX资产监测设备之华大单片机Boot软件升级

近期笔者在研究如何从软件方面提升资产监测设备的性能,从而提升用户的使用体验感。

资产监测设备的主要作用是帮助用户监测设备的实时位置、实时状态避免运动中的货物出现丢失等情况。AOVX环境监测设备在智慧物流方面发挥了重要的作用,例如在运输贵重货物过程中,只需要将该设备安装在货物中,用户即可远程了解货物的位置、货物是否出现暴力扔件、以及避免货物在运输过程中的丢失。

资产监测设备中的华大单片机,对该设备的工作发挥了重要的作用。笔者的软件团队对单片机进行了软件升级。

具体流程如下:

具体流程如下:/**

** \brief 上位机数据帧解析及处理**** \param [in] None**** \retval Ok APP程序升级完成,并接受到跳转至APP命令** \retval OperationInProgress 数据处理中** \retval Error 通讯错误********************************************************************************/en_result_t Modem_Process(void){uint8_t u8Cmd, u8FlashAddrValid, u8Cnt, u8Ret;uint16_t u16DataLength, u16PageNum, u16Ret;uint32_t u32FlashAddr, u32FlashLength, u32Temp;

if (enFrameRecvStatus == FRAME_RECV_PROC_STATUS) //有数据帧待处理, enFrameRecvStatus值在串口中断中调整

{

u8Cmd = u8FrameData[PACKET_CMD_INDEX]; //获取帧指令码

if (PACKET_CMD_TYPE_DATA == u8FrameData[PACKET_TYPE_INDEX]) //如果是数据指令

{

u8FlashAddrValid = 0u;

u32FlashAddr = u8FrameData[PACKET_ADDRESS_INDEX] + //读取地址值

(u8FrameData[PACKET_ADDRESS_INDEX + 1] << 8) +

(u8FrameData[PACKET_ADDRESS_INDEX + 2] << 16) +

(u8FrameData[PACKET_ADDRESS_INDEX + 3] << 24);

if ((u32FlashAddr >= (FLASH_BASE + BOOT_SIZE)) && (u32FlashAddr < (FLASH_BASE + FLASH_SIZE))) //如果地址值在有效范围内

{

u8FlashAddrValid = 1u; //标记地址有效

}

}

switch (u8Cmd) //根据指令码跳转执行

{

case PACKET_CMD_HANDSHAKE : //握手帧 指令码

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_OK; //返回状态为:正确

Modem_SendFrame(&u8FrameData[0], PACKET_INSTRUCT_SEGMENT_SIZE); //发送应答帧给上位机

break;

case PACKET_CMD_ERASE_FLASH : //擦除flash 指令码

if ((u32FlashAddr % FLASH_SECTOR_SIZE) != 0) //如果擦除地址不是页首地址

{

u8FlashAddrValid = 0u; //标记地址无效

}

if (1u == u8FlashAddrValid) //如果地址有效

{

u32Temp = u8FrameData[PACKET_DATA_INDEX] + //获取待擦除flash尺寸

(u8FrameData[PACKET_DATA_INDEX + 1] << 8) +

(u8FrameData[PACKET_DATA_INDEX + 2] << 16) +

(u8FrameData[PACKET_DATA_INDEX + 3] << 24);

u16PageNum = FLASH_PageNumber(u32Temp); //计算需擦除多少页

for (u8Cnt=0; u8Cnt<u16PageNum; u8Cnt++) //根据需要擦除指定数量的扇区

{

u8Ret = Flash_EraseSector(u32FlashAddr + (u8Cnt * FLASH_SECTOR_SIZE));

if (Ok != u8Ret) //如果擦除失败,反馈上位机错误代码

{

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_ERROR;

break;

}

}

if (Ok == u8Ret) //如果全部擦除成功,反馈上位机成功

{

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_OK;

}else //如果擦除失败,反馈上位机错误超时标志

{

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_TIMEOUT;

}

}

else //地址无效,反馈上位机地址错误

{

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_ADDR_ERROR;

}

Modem_SendFrame(&u8FrameData[0], PACKET_INSTRUCT_SEGMENT_SIZE); //发送应答帧到上位机

break;

case PACKET_CMD_APP_DOWNLOAD : //数据下载 指令码

if (1u == u8FlashAddrValid) //如果地址有效

{

u16DataLength = u8FrameData[FRAME_LENGTH_INDEX] + (u8FrameData[FRAME_LENGTH_INDEX + 1] << 8)

- PACKET_INSTRUCT_SEGMENT_SIZE; //获取数据包中的数据长度(不包含指令码指令类型等等)

if (u16DataLength > PACKET_DATA_SEGMENT_SIZE) //如果数据长度大于最大长度

{

u16DataLength = PACKET_DATA_SEGMENT_SIZE; //设置数据最大值

}

u8Ret = Flash_WriteBytes(u32FlashAddr, (uint8_t *)&u8FrameData[PACKET_DATA_INDEX], u16DataLength); //把所有数据写入flash

if (Ok != u8Ret) //如果写数据失败

{

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_ERROR; //反馈上位机错误 标志

}

else //如果写数据成功

{

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_OK; //反馈上位机成功 标志

}

}

else //如果地址无效

{

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_ADDR_ERROR; //反馈上位机地址错误

}

Modem_SendFrame(&u8FrameData[0], PACKET_INSTRUCT_SEGMENT_SIZE); //发送应答帧到上位机

break;

case PACKET_CMD_CRC_FLASH : //查询flash校验值 指令码

if (1u == u8FlashAddrValid) //如果地址有效

{

u32FlashLength = u8FrameData[PACKET_DATA_INDEX] +

(u8FrameData[PACKET_DATA_INDEX + 1] << 8) +

(u8FrameData[PACKET_DATA_INDEX + 2] << 16) +

(u8FrameData[PACKET_DATA_INDEX + 3] << 24); //获取待校验flash大小

if ((u32FlashLength + u32FlashAddr) > (FLASH_BASE + FLASH_SIZE)) //如果flash长度超出有效范围

{

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_FLASH_SIZE_ERROR; //反馈上位机flash尺寸错误

}else

{

u16Ret = Cal_CRC16(((unsigned char *)u32FlashAddr), u32FlashLength);//读取flash指定区域的值并计算crc值

u8FrameData[PACKET_FLASH_CRC_INDEX] = (uint8_t)u16Ret; //把crc值存储到应答帧

u8FrameData[PACKET_FLASH_CRC_INDEX+1] = (uint8_t)(u16Ret>>8);

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_OK; //反馈上位机成功 标志

}

}

else //如果地址无效

{

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_ADDR_ERROR; //反馈上位机地址错误

}

Modem_SendFrame(&u8FrameData[0], PACKET_INSTRUCT_SEGMENT_SIZE+2); //发送应答帧到上位机

break;

case PACKET_CMD_JUMP_TO_APP : //跳转至APP 指令码

Flash_EraseSector(BOOT_PARA_ADDRESS); //擦除BOOT parameter 扇区

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_OK; //反馈上位机成功

Modem_SendFrame(&u8FrameData[0], PACKET_INSTRUCT_SEGMENT_SIZE); //发送应答帧到上位机

return Ok; //APP更新完成,返回OK,接下来执行跳转函数,跳转至APP

case PACKET_CMD_APP_UPLOAD : //数据上传

if (1u == u8FlashAddrValid) //如果地址有效

{

u32Temp = u8FrameData[PACKET_DATA_INDEX] +

(u8FrameData[PACKET_DATA_INDEX + 1] << 8) +

(u8FrameData[PACKET_DATA_INDEX + 2] << 16) +

(u8FrameData[PACKET_DATA_INDEX + 3] << 24); //读取上传数据长度

if (u32Temp > PACKET_DATA_SEGMENT_SIZE) //如果数据长度大于最大值

{

u32Temp = PACKET_DATA_SEGMENT_SIZE; //设置数据长度为最大值

}

Flash_ReadBytes(u32FlashAddr, (uint8_t *)&u8FrameData[PACKET_DATA_INDEX], u32Temp); //读flash数据

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_OK; //反馈上位机成功 标志

Modem_SendFrame(&u8FrameData[0], PACKET_INSTRUCT_SEGMENT_SIZE + u32Temp);//发送应答帧到上位机

}

else //如果地址无效

{

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_ADDR_ERROR; //反馈上位机地址错误 标志

Modem_SendFrame(&u8FrameData[0], PACKET_INSTRUCT_SEGMENT_SIZE); //发送应答帧到上位机

}

break;

case PACKET_CMD_START_UPDATE : //启动APP更新(此指令正常在APP程序中调用)

u8FrameData[PACKET_RESULT_INDEX] = PACKET_ACK_OK; //反馈上位机成功 标志

Modem_SendFrame(&u8FrameData[0], PACKET_INSTRUCT_SEGMENT_SIZE); //发送应答帧到上位机

break;

}

enFrameRecvStatus = FRAME_RECV_IDLE_STATUS; //帧数据处理完成,帧接收状态恢复到空闲状态

}

return OperationInProgress; //返回,APP更新中。。。

}

同样从事软件工作相关的用户,对资产监测设备感兴趣的话可以参考该文档。

GD32 虚拟串口通讯速度测试

GD32 虚拟串口通讯速度测试

硬件说明:

MCU: GD32C103 120M,128K,32k RAM.输入:USB 5V.OBD功能口定义:OBD(2,10)VPWM、OBD 7(K线)、OBD 6(CAN H)、OBD 14(CAN L)、OBD 15(L线).

电路图

例程说明

约定简单通讯协议,测试虚拟串口最大传输速度

测试平台

1 WIN10 32/64位(免驱动),WIN7 32 /64 需安装驱动

2 UsbTest.exe 测试工具,传输速度500K 左右

通讯协议说明

上位机发送一帧数据格式55 AA LEN(2BYTE) DATA ...

下位机发送一帧数据格式55 AA LEN(2BYTE) DATA ...

软件设计

UsbTest 上位机软件按5K一次循环读取选择的文件内容,

按格式 55 AA LEN(2BYTE) DATA ... 发送给下位机,下位机接收完数据后按

55 AA LEN(2BYTE) DATA ... 格式发回给上位机,上位机根据接收到的DATA写进temp.txt

文件中,当文件发送完成后对比temp.txt 和选择的文件可知是否丢失数据。

上位机说明

如下图所示,Open 打开串口,GetFile 选择文件后开始传输数据

2 传输完成后用BCompare软件对比发送和接收的文件,如下图所示 ,18.5M的文件并未丢失数据

(2)下位机代码说明

1 APP.c 文件代码说明

iUsbLen=0; //接收的数据长度

i UsbFlag=0;//接收完成标记

iUsbLenPre=0;

/* main loop */

while (1)

{

if(iUsbFlag==0x80)//一帧数据 接收完毕

{

SendUsbDate(&cdc_acm,iUsbBuf,iUsbLen);//发送数据返回给下位机

iUsbLenPre=0;

iUsbLen=0; //接收的数据长度

iUsbFlag=0;//接收完成标记

iCmt++;

if(iCmt%2) gpio_bit_reset(GPIOB,GPIO_PIN_12);

else gpio_bit_set(GPIOB,GPIO_PIN_12);

}

continue;

}

2 cdc_acm_core.c文件代码说明

USB虚拟串口接收函数

static uint8_t cdc_acm_out (usb_dev *udev, uint8_t ep_num)

{

usb_cdc_handler *cdc = (usb_cdc_handler *)udev->dev.class_data[CDC_COM_INTERFACE];

cdc->packet_receive = 1U;

cdc->receive_length = ((usb_core_driver *)udev)->dev.transc_out[ep_num].xfer_count;

iUsbFlag=0;//接收完成标记

if(cdc->data[0]==0x55&&cdc->data[1]==0xAA)//帧开头

{

iUsbLen=cdc->data[2]*256+cdc->data[3];

}

for(uint8_t i=0;i<cdc->receive_length;i++)

{

if(iUsbLenPre>=10239) break;

iUsbBuf[iUsbLenPre++]=cdc->data[i];

}

if(iUsbLenPre>=iUsbLen||iUsbLenPre>10239)

{

iUsbFlag=0x80;//接收完成标记

}

cdc_acm_data_receive(udev);

return USBD_OK;

}

USB虚拟串口发送函数

void SendUsbDate(usb_dev *udev,uint8_t*Buf,uint32_t len)

{

usb_cdc_handler *cdc = (usb_cdc_handler *)udev->dev.class_data[CDC_COM_INTERFACE];

if (0U != len)

{

cdc->packet_sent = 0U;

usbd_ep_send (udev, CDC_DATA_IN_EP, (uint8_t*)(Buf), len);

cdc->receive_length = 0U;

}

}

源码地址

单片机代码地址https://github.com/siyuan1644/GD32-USB_CDC-TEST.git

VS 代码地址https://github.com/siyuan1644/UsbSpeedTest.git

相关问答

什么是程序存储器,什么是数据存储器?戴尔存储器价格贵吗有...

[回答]在计算机中存储器的主要作用是什么?计算机存储器指计算机的内部存储区域,以芯片格式和集成电路形式存在。计算机存储器应用于录音机或磁盘。通常视...

在座的大侠,有谁能解答一下吗 路由器---网络模块---网络模...

[回答]网络模块是一种高速、高性能、阻燃型信息模块,作为一种网络附件,它扮演的是中间连接器的角色,我们也可以将其理解为信息中转站。无线网络模块分发射...

诸位大神,谁能赐教 回收电子库存?,库存回收有哪些公司生...

[回答]你可以不要,能不能退款就要看你签的合同里面的条款是不是可以退款了。对比了好几家,诚泽再生资源回收无论是在产品介绍、还是销售咨询服务都有良好...

有谁知道:扫地车主要是用来作什么的拜托了帮个忙

[回答]清扫车结构的特点:垃圾倾卸料度高达62,副机空滤进气系统设计先进,可大大提高发动机的使用寿命,设置油冷却器,更有利于车辆在炎热的夏季照常工作,液...

想请教下:360全向雷达贵不贵?

[回答]毫米波雷达的优点;光波在大气中传播衰减严重,器件加工精度要求高。毫米波与光波相比,它们利用大气窗口(毫米波与亚毫米波在大气中传播时,由于气体分...

猜你喜欢