lz_kwok 发表于 2020-4-21 09:10:47

linux下OTA功能基于licurl使用http下载文件

本帖最后由 lz_kwok 于 2020-4-21 09:11 编辑

版权声明:本版面文章皆为原创、或参考其他技术网站、博客后自己动手做实验所得,转载请注明出处。商务合作:lz_kwok@163.com易开嵌入式工作室
嵌入式系统,OTA功能是十分重要的。linux环境下,使用libcurl,通过http可以很方便实现文件下载功能,并显示文件下载进度。实现方案如下:首先定义下载地址和下载路径#define downLoad_url         "http://xxxx/downloadExample/update.tar.gz"
#define downLoad_file         "/home/xxx/update.tar.gz"
初始化libcurl并配置CURLcode curl_base::Download(std::string strUrl,std::string filepath)
{
    CURLcode res;
    char *progress_data = "* ";
    FILE* fp = fopen(filepath.c_str(),"wb+");

    curl_handle = curl_easy_init();

    /* send all data to this function */
    curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, OnDownLoadFile);
    /* we pass our 'chunk' struct to the callback function */
    curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)fp);

    curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 0L);
    curl_easy_setopt(curl_handle, CURLOPT_PROGRESSFUNCTION, my_progress_func);
    curl_easy_setopt(curl_handle, CURLOPT_PROGRESSDATA, progress_data);

    curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
    curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L);
    curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L);

    curl_easy_setopt(curl_handle,CURLOPT_RESUME_FROM,0);//从0字节开始下载
    /* 设置连接超时,单位:毫秒 */
    curl_easy_setopt(curl_handle, CURLOPT_CONNECTTIMEOUT_MS, 10000L);
    curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT_MS, 10000L);
    curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 3);
    curl_easy_setopt(curl_handle, CURLOPT_URL, const_cast<char*>(strUrl.c_str()));


    /* get it! */
    res = curl_easy_perform(curl_handle);
    /* check for errors */
    if (res != CURLE_OK) {
      fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
    }

    fclose(fp);

    return res;
}
其中,注意要关闭CURLOPT_NOPROGRESS。看下官网解释:If onoff is to 1, it tells the library to shut off the progress meter completely for requests done with this handle. It will also prevent the CURLOPT_XFERINFOFUNCTION or CURLOPT_PROGRESSFUNCTION from getting called.回调函数如下:static size_t OnDownLoadFile(void* buffer,size_t size, size_t nmemb,void* fp)
{
   fwrite(buffer, size, nmemb, (FILE*)fp);
   fflush((FILE*)fp);

   return (size*nmemb);
}


static int my_progress_func(char *progress_data,
                     double t, /* dltotal */
                     double d, /* dlnow */
                     double ultotal,
                     double ulnow)
{
printf("%s %g / %g (%g %%)\n", progress_data, d, t, d*100.0/t);
return 0;
}
下载完成后,进行clean操作:void curl_base::DownloadFinish()
{
    curl_easy_cleanup(curl_handle);
}
主函数:void *myDownload_run(void *para){
      mycurl::my_curl::curl_base curl;

      curl.Download(downLoad_url,downLoad_file);
      curl.DownloadFinish();
      while(1){               
                sleep(2);
      }
}
编译后,查看运行效果:*271917 / 364519 (74.5961 %)*273365 / 364519 (74.9933 %)*273365 / 364519 (74.9933 %)*276261 / 364519 (75.7878 %)*276261 / 364519 (75.7878 %)*277709 / 364519 (76.1851 %)*277709 / 364519 (76.1851 %)*279157 / 364519 (76.5823 %)*279157 / 364519 (76.5823 %)*280605 / 364519 (76.9795 %)*280605 / 364519 (76.9795 %)*282053 / 364519 (77.3768 %)*282053 / 364519 (77.3768 %)*283501 / 364519 (77.774 %)*283501 / 364519 (77.774 %)*284949 / 364519 (78.1712 %)*284949 / 364519 (78.1712 %)*296533 / 364519 (81.3491 %)*296533 / 364519 (81.3491 %)*297981 / 364519 (81.7464 %)*297981 / 364519 (81.7464 %)*302325 / 364519 (82.9381 %)*302325 / 364519 (82.9381 %)*305221 / 364519 (83.7325 %)*305221 / 364519 (83.7325 %)*306669 / 364519 (84.1298 %)*306669 / 364519 (84.1298 %)*308117 / 364519 (84.527 %)*308117 / 364519 (84.527 %)*309565 / 364519 (84.9242 %)*309565 / 364519 (84.9242 %)*312461 / 364519 (85.7187 %)*312461 / 364519 (85.7187 %)*313909 / 364519 (86.116 %)*313909 / 364519 (86.116 %)*315357 / 364519 (86.5132 %)*315357 / 364519 (86.5132 %)*316805 / 364519 (86.9104 %)*316805 / 364519 (86.9104 %)*319701 / 364519 (87.7049 %)*319701 / 364519 (87.7049 %)*321149 / 364519 (88.1021 %)*321149 / 364519 (88.1021 %)*322597 / 364519 (88.4994 %)*322597 / 364519 (88.4994 %)*334181 / 364519 (91.6773 %)*334181 / 364519 (91.6773 %)*335629 / 364519 (92.0745 %)*335629 / 364519 (92.0745 %)*337077 / 364519 (92.4717 %)*337077 / 364519 (92.4717 %)*338525 / 364519 (92.869 %)*338525 / 364519 (92.869 %)*342869 / 364519 (94.0607 %)*342869 / 364519 (94.0607 %)*344317 / 364519 (94.4579 %)*344317 / 364519 (94.4579 %)*348661 / 364519 (95.6496 %)*348661 / 364519 (95.6496 %)*350109 / 364519 (96.0468 %)*350109 / 364519 (96.0468 %)*351557 / 364519 (96.4441 %)*351557 / 364519 (96.4441 %)*353005 / 364519 (96.8413 %)*353005 / 364519 (96.8413 %)*355901 / 364519 (97.6358 %)*355901 / 364519 (97.6358 %)*358797 / 364519 (98.4303 %)*358797 / 364519 (98.4303 %)*361693 / 364519 (99.2247 %)*361693 / 364519 (99.2247 %)*363141 / 364519 (99.622 %)*363141 / 364519 (99.622 %)*364519 / 364519 (100 %)

OK,完成!!!

eric2013 发表于 2020-4-21 09:16:26

就是单纯下载网址上的文件吗,这个单片机实现也很简单,给下面这个地址发送http post/get消息就行。

我之前获取百度地图就是这么干的

#define downLoad_url         "http://xxxx/downloadExample/update.tar.gz"
#define downLoad_file         "/home/xxx/update.tar.gz"

lz_kwok 发表于 2020-4-21 09:54:04

eric2013 发表于 2020-4-21 09:16
就是单纯下载网址上的文件吗,这个单片机实现也很简单,给下面这个地址发送http post/get消息就行。

我 ...

网络协议栈支持bsd也都很容易。
页: [1]
查看完整版本: linux下OTA功能基于licurl使用http下载文件