zoukankan      html  css  js  c++  java
  • W800 http完成固件OTA远程升级

    本节我们使用W800的http来完成固件OTA远程升级,由于http协议处在tcp/ip协议的应用层,tcp协议工作在传输层,只需要在tcp传输层中按照http协议中的数据格式,发送数据就可以完成http传输数据。在SDK源码中打开宏定义 DEMO_HTTP 和 DEMO_CONNECT_NET。
    在程序中编写需要传入的http ota固件地址
    int t_http_fwup(char url)
    {
    HTTPParameters httpParams;
    memset(&httpParams, 0, sizeof(HTTPParameters));
    if (url == NULL)
    {
    httpParams.Uri = "http://192.168.1.100:8080/WM_W800_SEC.img";
    }
    else
    {
    httpParams.Uri = url;
    }
    printf("Location: %s ",httpParams.Uri);
    httpParams.Verbose = TRUE;
    return http_fwup(httpParams);
    }
    接下来编写服务升级流程:
    int http_fwup(HTTPParameters ClientParams)
    {
    char
    Buffer = NULL;
    char token[32];
    char headRange[32] = {0};
    int nRetCode = 0;
    u32 content_length=0, size=32;
    u32 partLen;
    u32 totalLen = 0;
    u32 recvLen = 0;
    IMAGE_HEADER_PARAM_ST *booter;
    '#if USE_BREAK_POINT_RESUME == 0
    u32 breakFlag = 0;
    u32 breakLen = 0;
    '#endif
    struct pbuf *p;
    HTTP_SESSION_HANDLE pHTTP;
    enum ota_state now_state = PREPARE_PACKET;

    Buffer = (char*)tls_mem_alloc(HTTP_CLIENT_BUFFER_SIZE + FWUP_MSG_SIZE);
    if (!Buffer)
        return HTTP_CLIENT_ERROR_NO_MEMORY;
    memset(Buffer, 0, HTTP_CLIENT_BUFFER_SIZE + FWUP_MSG_SIZE);    
    
    while(1)
    {
        switch(now_state)
        {
            case PREPARE_PACKET:
            {
                memset(token, 0, 32);
                size = 32;
                pHTTP = HTTPClientOpenRequest(0);
    

    '#if USE_BREAK_POINT_RESUME
    HTTPClientSetVerb(pHTTP,VerbGet);
    sprintf(headRange, "bytes=%d-", recvLen);
    if((nRetCode = HTTPClientAddRequestHeaders(pHTTP,"Range", headRange, 1))!= HTTP_CLIENT_SUCCESS){
    now_state = QUIT_OTA;
    }
    '#else
    if( recvLen != 0 ){
    breakFlag = 1;
    breakLen = 0;
    }
    '#endif
    now_state = SETUP_LINK_AND_REQ;
    }
    break;

            case SETUP_LINK_AND_REQ:
            {
                if( (nRetCode = HTTPClientSendRequest(pHTTP,ClientParams.Uri,NULL,0,FALSE,0,0)) != HTTP_CLIENT_SUCCESS ){
                    tls_os_time_delay(HZ*2);
                    now_state = SHUTDOWN_LINK;
                }
                else
                    now_state = RECV_RSP;
            }
            break;
            
            case RECV_RSP:
            {
                if((nRetCode = HTTPClientRecvResponse(pHTTP, RECV_TIMEOUT)) != HTTP_CLIENT_SUCCESS)
                    now_state = SHUTDOWN_LINK;
                else
                    now_state = HANDLE_HEADER;
            }
            break;
            
            case HANDLE_HEADER:
            {
                if((nRetCode = HTTPClientFindFirstHeader(pHTTP, "content-length", (CHAR *)token, &size)) != HTTP_CLIENT_SUCCESS){
                    HTTPClientFindCloseHeader(pHTTP);
                    now_state = SHUTDOWN_LINK;
                }
                else
                {
                    HTTPClientFindCloseHeader(pHTTP);
                    content_length = atol(strstr(token,":")+1);
                    printf("content_length: %d
    ", content_length);
                    now_state = HANDLE_BODY;
                    if(recvLen == 0){
                        nRetCode = socket_fwup_accept(0, ERR_OK);
                        if(nRetCode != ERR_OK)
                            now_state = QUIT_OTA;
                    }
                }
            }
            break;
            
            case HANDLE_BODY:
            {
                partLen = 0;
                while(nRetCode != HTTP_CLIENT_EOS )
                {
                    u32 nSize = HTTP_CLIENT_BUFFER_SIZE;
                    nRetCode = HTTPClientReadData(pHTTP,Buffer+FWUP_MSG_SIZE,nSize,RECV_TIMEOUT,&nSize);
                    if( recvLen == 0 ){
             
                        booter =(IMAGE_HEADER_PARAM_ST *) (Buffer+FWUP_MSG_SIZE);
    					if (TRUE == tls_fwup_img_header_check(booter))
    					{
    						totalLen = booter->img_len + sizeof(IMAGE_HEADER_PARAM_ST);
    						if (booter->img_attr.b.signature)
    						{
    							totalLen += 128;
    						}
    					}
    					else
    					{
    						now_state = QUIT_OTA;
    						break;
    					}                        
                    }
    
                    if(nRetCode != HTTP_CLIENT_SUCCESS && nRetCode != HTTP_CLIENT_EOS){
                        now_state = SHUTDOWN_LINK;
                        break;
                    }
    

    '#if USE_BREAK_POINT_RESUME == 0
    if(breakFlag == 1){
    breakLen += nSize;
    if(breakLen <= recvLen){
    continue;
    }
    else{
    Buffer = Buffer+FWUP_MSG_SIZE+nSize-(breakLen-recvLen)-FWUP_MSG_SIZE;
    nSize = (breakLen-recvLen);
    breakFlag = 0;
    }
    }
    '#endif

                    p = pbuf_alloc(PBUF_TRANSPORT, nSize + FWUP_MSG_SIZE, PBUF_REF);
                    while( !p){
                        tls_os_time_delay(1);
                        p = pbuf_alloc(PBUF_TRANSPORT, nSize + FWUP_MSG_SIZE, PBUF_REF);
                    }
                    
                    if(recvLen == 0)
                        *(Buffer+0) = SOCKET_FWUP_START;
                    else if(nRetCode == HTTP_CLIENT_EOS && recvLen == (totalLen-nSize))
                        *(Buffer+0) = SOCKET_FWUP_END;
                    else
                        *(Buffer+0) = SOCKET_FWUP_DATA;
    
                    *(Buffer+1) = (nSize>>8) & 0xFF;
                    *(Buffer+2) = nSize & 0xFF;	
                    p->payload =  Buffer;
                    p->len = p->tot_len = nSize + FWUP_MSG_SIZE;
                    // Send received data to fwup thread and deal with socket issues.
                    s8 ret = socket_fwup_recv(0, p, ERR_OK);
                    if(ret != ERR_OK){
                        now_state = SHUTDOWN_LINK;
                        break;
                    }
                    else{
                        recvLen += nSize;
                        partLen += nSize;           
                        printf("download %d / %d
    ", recvLen, totalLen);
                        if(partLen == content_length){
                            now_state = SHUTDOWN_LINK;
                            break;
                        }
                    }
                }
    			if (now_state == QUIT_OTA);
    			else
                now_state = SHUTDOWN_LINK;
            }
            break;
            
            case SHUTDOWN_LINK:
            {
                if(pHTTP){
                    HTTPClientCloseRequest(&pHTTP);
                    (recvLen == totalLen)?(now_state = QUIT_OTA):(now_state = PREPARE_PACKET);
                }
            }
            break;
            
            default:
            break;
        }
        //printf("now_state %d
    ", now_state);
        if(now_state == QUIT_OTA)
            break;
    }
    
    tls_mem_free(Buffer);
    if(pHTTP)
        HTTPClientCloseRequest(&pHTTP);
    if(ClientParams.Verbose == TRUE)
    {
        printf("
    
    HTTP Client terminated %d (got %d kb)
    
    ",nRetCode,(recvLen/ 1024));
    }
    if(nRetCode)
        socket_fwup_err(0, nRetCode);
    return nRetCode;
    

    }
    程序的测试需要开启动一个hfs 服务器,hfs服务器下载:链接:https://pan.baidu.com/s/1N7gL9f-nj9Qr_HJv43FYAg 提取码:6666
    打开hfs服务器后端口改为8080,同时放上我们需要升级的固件,这里我们放了hello_world的img固件。

    程序编译并下载到开发板。先在串口输入配网指令联网。
    指令如:t-connect("@snail","ss559550")

    接下来输入升级指令t-httpfwup=(http://192.168.2.103:8080/w800_ota.img),串口可以看到升级进度,升级成功,自动运行新固件程序。

  • 相关阅读:
    嵌入式GUI FTK介绍(7)主题
    嵌入式GUI FTK介绍(2)两个小应用程序
    嵌入式GUI FTK介绍(8)编译/运行PC模拟版本
    嵌入式GUI FTK介绍(5)在多平台上运行
    嵌入式GUI FTK介绍(4)脚本语言绑定
    嵌入式GUI FTK介绍(3)XML界面描述语言
    活动图
    ASP.NET程序中常用的三十三种代码
    Server的Transfer和Response的Redirect (转)
    .net 点击刷新验证码问题
  • 原文地址:https://www.cnblogs.com/doiting/p/13948505.html
Copyright © 2011-2022 走看看