2017.9.5 mqtt 升级 相关记录

最近一直在调试mqtt升级相关的东西,总结问题其实不大,最开始一直W25Q16擦除不干净, 然后再BootLoader程序中,校验一直出现很奇怪的问题。
然后找啊找,找原因找了好久好久。。。。。。
最后在小伙伴的帮助下 终于发现spi初始化 出现了问题,导致在第一调用spi相关的函数都失效,mmp的,最后强制在 spi初始化的时候加了一个  SPI_Flash_WAKEUP(); 函数,先调用一下,解决初始化问题。
其实问题还没有解决,还是没有明白为啥第一次调用spi相关的函数会失效。。。。后续需要继续查找。

好吧 还是记录MQTT升级相关的。
代码分析:
(1)在一个任务里,主动订阅升级任务,当平台发布升级信息后,进入接受任务,校验接受数据。

topicString.cstring = Mqtt_topic.topic_updateprocess;
len = MQTTSerialize_subscribe(buf, buflen, 0, msgid, 1, &topicString, &req_qos);
rc = transport_sendPacketBuffer(mysock, buf, len);

(2)当接受的数据为升级包后 ,订阅第一包升级包,包的大小为1024 (平台那边发过来的,接受就好)

if(UpdateMsg.DeviceTypeValue == DEVICE_TYPE_INVERTER_ARM || UpdateMsg.DeviceTypeValue == DEVICE_TYPE_INVERTER_DSP)
    {
            if(UpdateMsg.PackageSizeValue>2097152)
            return;

            if(UpdateMsg.DeviceTypeValue == DEVICE_TYPE_INVERTER_ARM)   //升级 arm
            { 
//              SPI_FLASH_Write_Enable(); 
                for(u16 secpos=0;secpos<16;secpos++)
                {
                        SPI_Flash_Erase_Sector(secpos);    //清除前1M
                }
            }   
            else if(UpdateMsg.DeviceTypeValue == DEVICE_TYPE_INVERTER_DSP)       //升级DSP
            {
//              SPI_FLASH_Write_Enable(); 
                for(u16 secpos=16;secpos<32;secpos++)
                {
                        SPI_Flash_Erase_Sector(secpos);   //清楚后1M 数据
                }
            }       
        sprintf(Mqtt_topic.topic_updateprocess, update/package/%32.32s/%d",UpdateMsg.TaskIDValue,1);
        MQTT_Subscrib(Mqtt_topic.topic_updateprocess);    //订阅第一个固件包

        UpdatePara.RetryCnt = 0;
        UpdatePara.UpdateTimeout = 0;
        UpdatePara.StartUpdateFlag = 1;       
        UpdatePara.temp_blockNum = 1;  

(3)接受就是循环订阅接受 订阅接受 固件包了 ,将收到的 数据 按顺序 存放在W25Q16中,获取一次,地址加一次,同时订阅下一个 固件包。

                W25QXX_Write(hex_con,ARM_Flash_Add,size_j);
                ARM_Flash_Add = ARM_Flash_Add+size_j;
                size_j =0 ;
                UpdatePara.temp_blockNum++;                        //请求包数 加
                sprintf(Mqtt_topic.topic_updateprocess, "update/package/%32.32s/%d", UpdateMsg.TaskIDValue, UpdatePara.temp_blockNum);      
                MQTT_Subscrib(Mqtt_topic.topic_updateprocess);

                UpdatePara.RetryCnt = 0;
                UpdatePara.UpdateTimeout = 0;

(4)在后来测试的时候,发现固件包太大,要超过1M,(原定计划是q16中前1M用于存放ARM固件,后1M用于存放DSP固件) 所以只能另外想办法。
后来发现hex文件的存储方式是以ascii的方式存储的,这就造成了内存的浪费啊,本来一个字节就可以存储的信息,非得用两字节存储,真是的。
so。。。。。。用一下方式吧hex文件转存下,大小立刻就缩小为原来的一般左右。。。



    /*  ????????   */
static unsigned char ChartoByte(char c)
{   
    if(c - 'a' >= 0) return  (c - 'a' + 10);
    else if(c - 'A' >= 0) return (c - 'A' +10);
    else return (c - '0');  
}
    /*  ?????????????   */
static unsigned char Char2toByte(char *s)
{   
    return (ChartoByte(*s)*16 + ChartoByte(*(s + 1)));
}   

unsigned char data_hex[1024];        //报文原始数据
unsigned char hex_con[1024];         //转换后的数据
int i=0,size_j=0;                         //    size_j 表示转存后的大小

char misplace_temp[2]={0};           //用于存储 如果包的最后一个字节如果被分开[0]存储包的最后一个半字节 [1] 用于存下一个包的 第一个半字节
char misplace_flag = 0;              //标记为,用于记录报文最后一个字节是否被分开        




                    size_j=0;
                    for(i=0;i<1024;i++)
                    {

                        if(misplace_flag == 1)
                        {   
                            misplace_flag = 0 ;
                            misplace_temp[1]=data_hex[0];
                            hex_con[size_j++]=Char2toByte(misplace_temp);    //如果出现半字节情况,将包的第一个半字节放在缓存数组中
                            misplace_temp[0]=0;                        //清除缓存数组中的内容
                            misplace_temp[1]=0;
                        }
                        else 
                        {
                            if((data_hex[i]==':')||(data_hex[i]==0x0d)||(data_hex[i]==0x0a))
                            {
                                hex_con[size_j++]=data_hex[i];
                            }
                            else 
                            {                       
                                    hex_con[size_j++]=Char2toByte(&data_hex[i++]);     
                            }

                            if(i>1023)                                //如果出现半字节的情况   
                            {
                                misplace_flag=1;
                                size_j=size_j-1;
                                misplace_temp[0]=data_hex[1023];        // 最后一个半字节放在缓存数组中
                                break;
                            }
                        }
                    }   

其中hex文件 格式参考:http://www.cnblogs.com/libra13179/p/5821266.html
其中介绍了 hex一行中数据的意义。

你可能感兴趣的:(日常工作记录)