资产监测设备之华大单片机boot软件升级(代码片段)

瑞奇Ricky 瑞奇Ricky     2023-01-07     333

关键词:

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

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

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

具体流程如下:
/**
** \\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更新中。。。

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

资产监测设备中关于ota升级串口应答帧处理(代码片段)

近期笔者的团队正在筹备对资产监测设备中的OTA升级串口应答帧处理。关于该问题笔者首先需要介绍关于资产监测设备的基础知识,然后再通过代码阐述关于OTA升级串口应答帧处理方式。资产监测设备简介:资产监测设... 查看详情

资产监测设备中关于opl1200芯片ota升级的api说明

近期笔者的研发团队正在研究如何优化资产监测设备的功能,主要从软件和硬件两个方面进行,本期着重于软件方面的升级。但软件升级后,有些提供给客户的API有所改动,作为研发团队需要提供新的API说明,... 查看详情

yunxion资产监测设备,gnssnema语句解析之vtg(代码片段)

物联网作为互联网概念的衍生与发展,通俗来说是将用户延伸到物品之间,使得普通物品能够进行信息交换与通信的新概念。物联网具有三个重要特征即:普通对象设备化、自治终端互联化、普适服务智能化。这一新... 查看详情

资产监测设备中hcl190flas擦写问题分析——boot

笔者的研发团队专门从事资产跟踪类设备的开发,包括了资产跟踪设备、环境监测设备、车辆跟踪设备等。这些设备的工作原理都是通过全球定位技术以及无线传感技术采集数据,然后再通过云端后台将信息展示给客户... 查看详情

资产监测设备智能跟踪器硬件测试项目(代码片段)

随着社会的发展,使用资产监测设备的用户越来越多,主要的作用是监测存储、交付、运输的过程,避免货物受损。近期,团队收到了关于智能跟踪器硬件测试的项目,该项目的主要作用是避免设备在后期使... 查看详情

资产监测设备中opl1200芯片wifiscan功能的实现(代码片段)

笔者最近在研究资产监测设备过程中使用到OPL1200芯片做开发,其中重点使用的功能之一是wifiscan,获取多组mac,并且按照信号强度排序。但笔者团队有新入职的员工对资产监测设备和该功能的实现还较为陌生,借... 查看详情

资产监测设备优化方向之移远模块dtmf功能介绍

近期笔者正在研究如何优化资产监测设备的功能,帮助用户在实行资产跟踪的实际过程中更加便捷。资产监测设备的主要功能是帮助企业实时监测运动中的资产,例如在运输贵重物品、机械、普通货物过程中,只需要... 查看详情

在进行资产监测设备研发时,rtc的相关设计

...绍下资产监测设备中,RTC的相关设计。资产监测设备单片机RTC输 查看详情

yunxion资产监测设备,关于gnssnema语句解析之gll

...。但其他类型企业或个人想要物联网原理,使用重点资产监测功能保障自身的资产安全,则需要根据自身的需求,选择符合要求的智能设备。以便在资产的监测过程中起关键性作用。资产监测主要宗旨是以无线传感创... 查看详情

资产监测设备中c代码ifelse容易忽略的隐藏bug

...础内容C代码ifelse容易忽略的隐藏bug为例,为更多从事资产监测设备开发的工作人员提供帮助。客户在资产监测设备使用过程中,经常会提到关于定位精方式 查看详情

资产监测设备使用时,设置具体指定日期天数计算

...资产所处环境的温湿度、运动情况等。有些资产监测设备单片机RTC采用的是BCD码,从对应寄存器拿取数据,因此无法获得对应CNT天数,以下未获取距离设定日期差距的天数。​//BCD码转十进制函数u 查看详情

资产监测设备中关于aes加密应用

...研究如何建立完善的软件知识培训系统,以满足后期资产监测设备的开发。资产监测设备简介:资产监测设备的主要作用是帮助实现资产监测,包括了资产的实时位置、资产的状态等信息。用户在使用资产监测设备后... 查看详情

资产监测设备c代码中比较符‘==‘容易误写为‘=‘编译器却不报错的建议

近期笔者在开发资产监测设备过程中,对于定位功能的优化。笔者的团队都才软件和硬件方面提出了不同的建议。资产监测设备能够对货物的状态进行实时监测。包括了货物运输的速度、货物运输路径、货物运输的状态、以... 查看详情

yunxion资产监测设备中串口上下拉问题

近期笔者在进行资产监测设备研发,资产监测设备主要通过定位、运动监测及环境监测等功能,实现企业对资产的透明化管理,为企业完善管理提供了技术与平台。为了保障设备能顺利运行,避免数据报错的情况&... 查看详情

资产监测设备中md5信息摘要简介

近期笔者的团队正在研究如何使用资产监测设备在更多领域,拓展资产监测设备的应用范围。除了对设备的外形改观外,还需要对软硬件进行升级。信息传输完整一致也是考察的主要指标之一。介于许多用户对资产监测... 查看详情

环境监测设备中hcl190flas擦写问题定位——boot

笔者一直从事资产跟踪类设备的开发,近期笔者收到了关于环境监测的新项目,客户提出了关于环境监测设备中HCL190FLAS擦写问题定位——BOOT。笔者希望借此机会能够分享环境监测设备的应用以及关于客户的提问,以... 查看详情

yunxion资产监测设备技术中代码优化

近期笔者在进行资产监测设备研发,在进行研发时应用了多项技术,并且通过技术实现了资产监测设备对资产进行定位、运动状态监测、以及资产所处环境的温湿度监测等,为了更好地保障产品的安全,资产监测... 查看详情

资产监测设备中关于hall开环电流传感器介绍

例如资产监测设备是物联网在智慧物流发展方向的衍生产品之一,资产监测设备的主要作用是帮助用户监测资产,包括监测资产的实时位置、运动状态以及是否发生丢失等情况,用户通过云端监测和管理,最终达... 查看详情