日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

設備OTA開發

OTA(Over-the-Air Technology)即空中下載技術,物聯網平臺支持通過OTA方式進行設備固件升級。

背景信息

基于MQTT協議下固件升級流程如下。

OTA例程講解

  • 過OTA的API可以實現設備端固件下載。但是如何存儲/使用下載到的固件,需要用戶實現。

  • 存儲固件是指將下載到的固件存儲到FLASH等介質上。

  • 使用固件,包括加載新下載的固件,需要用戶根據業務的具體需求(例如需要用戶單擊升級按鈕)來實現。

說明

OTA整體流程請見OTA服務

下面用兩個例子分別說明如何用基礎版接口和高級版接口來實現OTA功能。

用基礎版接口實現的OTA例程

現對照 src/ota/examples/ota_example_mqtt.c 例程分步驟講解如何使用基礎版的接口實現OTA的功能。

  1. OTA業務建立前的準備:導入設備證書,初始化連接信息。

    int main(int argc, char *argv[]) {
        ...
        /**< get device info*/
        HAL_SetProductKey(PRODUCT_KEY);
        HAL_SetDeviceName(DEVICE_NAME);
        HAL_SetDeviceSecret(DEVICE_SECRET);
        /**< end*/
        _ota_mqtt_client()
    }
  2. 在_ota_mqtt_client函數完成建連和OTA的主要配置邏輯。

        /* Device AUTH */
        if (0 != IOT_SetupConnInfo(g_product_key, g_device_name, g_device_secret, (void **)&pconn_info)) {
            EXAMPLE_TRACE("AUTH request failed!");
            rc = -1;
            goto do_exit;
        }
    
        /* Initialize MQTT parameter */
        memset(&mqtt_params, 0x0, sizeof(mqtt_params));
        mqtt_params.port = pconn_info->port;
        mqtt_params.host = pconn_info->host_name;
        mqtt_params.client_id = pconn_info->client_id;
        mqtt_params.username = pconn_info->username;
        mqtt_params.password = pconn_info->password;
        mqtt_params.pub_key = pconn_info->pub_key;
    
        mqtt_params.request_timeout_ms = 2000;
        mqtt_params.clean_session = 0;
        mqtt_params.keepalive_interval_ms = 60000;
        mqtt_params.read_buf_size = OTA_MQTT_MSGLEN;
        mqtt_params.write_buf_size = OTA_MQTT_MSGLEN;
    
        mqtt_params.handle_event.h_fp = event_handle;
        mqtt_params.handle_event.pcontext = NULL;
    
        /* Construct a MQTT client with specify parameter */
        pclient = IOT_MQTT_Construct(&mqtt_params);
        if (NULL == pclient) {
            EXAMPLE_TRACE("MQTT construct failed");
            rc = -1;
            goto do_exit;
        }
  3. _ota_mqtt_client函數進行OTA有關的初始化工作(主要是訂閱跟這個設備有關的固件升級信息)。

        h_ota = IOT_OTA_Init(PRODUCT_KEY, DEVICE_NAME, pclient);
        if (NULL == h_ota) {
            rc = -1;
            EXAMPLE_TRACE("initialize OTA failed");
            goto do_exit;
        }
  4. 建立一個循環,一直去嘗試接收OTA升級的消息。

        int ota_over = 0;
        do {
            uint32_t firmware_valid;
            EXAMPLE_TRACE("wait ota upgrade command....");
    
            /* 接收MQTT消息 */
            IOT_MQTT_Yield(pclient, 200);
    
            /* 判斷接收到的消息中是否有固件升級的消息 */
            if (IOT_OTA_IsFetching(h_ota)) {
             /* 下載OTA內容, 上報下載進度,見章節 "5. 下載OTA內容, 上報下載進度" */
             /* 校驗固件的md5, 見章節 "6. 校驗md5的值" */
            }
    
            } while (!ota_over);

    需要到服務端推送一個固件升級事件下去,IOT_OTA_IsFetching返回才能結果為1,才能走入固件升級的邏輯。推送固件升級事件的具體步驟如下。

    1. 到IoT控制臺的 OTA服務頁面,單擊新增固件

    2. 單擊創建固件驗證固件

    3. 單擊這個新增固件的批量升級按鈕,從中選擇設備所屬產品為examples/ota/ota_mqtt-example.c中設備證書對應的產品。

    4. 待升級版本號點開下拉框選當前版本號,升級范圍定向升級,再從設備范圍中選當前的設備證書對應的設備,單擊確定即可。

  5. 下載OTA內容,上報下載進度。

        do {
    
            /* 下載OTA固件 */
            len = IOT_OTA_FetchYield(h_ota, buf_ota, OTA_BUF_LEN, 1);
            if (len > 0) {
                if (1 != fwrite(buf_ota, len, 1, fp)) {
                    EXAMPLE_TRACE("write data to file failed");
                    rc = -1;
                    break;
                }
            } else {
    
                /* 上報已下載進度 */
                IOT_OTA_ReportProgress(h_ota, IOT_OTAP_FETCH_FAILED, NULL);
                EXAMPLE_TRACE("ota fetch fail");
            }
    
            /* get OTA information */
            /* 獲取已下載到的數據量, 文件總大小, md5信息, 版本號等信息 */
            IOT_OTA_Ioctl(h_ota, IOT_OTAG_FETCHED_SIZE, &size_downloaded, 4);
            IOT_OTA_Ioctl(h_ota, IOT_OTAG_FILE_SIZE, &size_file, 4);
            IOT_OTA_Ioctl(h_ota, IOT_OTAG_MD5SUM, md5sum, 33);
            IOT_OTA_Ioctl(h_ota, IOT_OTAG_VERSION, version, 128);
    
            last_percent = percent;
            percent = (size_downloaded * 100) / size_file;
            if (percent - last_percent > 0) {
    
                /* 上報已下載進度 */
                IOT_OTA_ReportProgress(h_ota, percent, NULL);
                IOT_OTA_ReportProgress(h_ota, percent, "hello");
            }        IOT_MQTT_Yield(pclient, 100);
    
            /* 判斷下載是否結束 */
        } while (!IOT_OTA_IsFetchFinish(h_ota));
  6. 校驗md5的值。

        IOT_OTA_Ioctl(h_ota, IOT_OTAG_CHECK_FIRMWARE, &firmware_valid, 4);
        if (0 == firmware_valid) {
            EXAMPLE_TRACE("The firmware is invalid");
        } else {
            EXAMPLE_TRACE("The firmware is valid");
        }
    
        ota_over = 1;
  7. 用戶通過IOT_OTA_Deinit釋放所有資源。

        if (NULL != h_ota) {
            IOT_OTA_Deinit(h_ota);
        }
    
        if (NULL != pclient) {
            IOT_MQTT_Destroy(&pclient);
        }
    
        if (NULL != msg_buf) {
            HAL_Free(msg_buf);
        }
    
        if (NULL != msg_readbuf) {
            HAL_Free(msg_readbuf);
        }
    
        if (NULL != fp) {
            fclose(fp);
        }
    
        return rc;
  8. 固件的存儲。

    _ota_mqtt_client函數中通過下述方式打開,寫入和關閉一個文件。

    fp = fopen("ota.bin", "wb+")
    ...
    if (1 != fwrite(buf_ota, len, 1, fp)) {
        EXAMPLE_TRACE("write data to file failed");
        rc = -1;
        break;
    }
    ...
    if (NULL != fp) {
        fclose(fp);
    }

用高級版接口實現的OTA例程

現對照src/dev_model/examples/linkkit_example_solo.c分步驟講解如何使用高級版的接口實現OTA的功能。

  1. 初始化主設備,注冊FOTA的回調函數,建立與云端的連接。

    int res = 0;
    int domain_type = 0, dynamic_register = 0, post_reply_need = 0;
    iotx_linkkit_dev_meta_info_t master_meta_info;
    
    memset(&g_user_example_ctx, 0, sizeof(user_example_ctx_t));
    
    memset(&master_meta_info, 0, sizeof(iotx_linkkit_dev_meta_info_t));
    memcpy(master_meta_info.product_key, PRODUCT_KEY, strlen(PRODUCT_KEY));
    memcpy(master_meta_info.product_secret, PRODUCT_SECRET, strlen(PRODUCT_SECRET));
    memcpy(master_meta_info.device_name, DEVICE_NAME, strlen(DEVICE_NAME));
    memcpy(master_meta_info.device_secret, DEVICE_SECRET, strlen(DEVICE_SECRET));
    
    /* Register Callback */
    ...
    ...
    IOT_RegisterCallback(ITE_FOTA, user_fota_event_handler);
    
    domain_type = IOTX_CLOUD_REGION_SHANGHAI;
    IOT_Ioctl(IOTX_IOCTL_SET_DOMAIN, (void *)&domain_type);
    
    /* Choose Login Method */
    dynamic_register = 0;
    IOT_Ioctl(IOTX_IOCTL_SET_DYNAMIC_REGISTER, (void *)&dynamic_register);
    
    /* post reply doesn't need */
    post_reply_need = 1;IOT_Ioctl(IOTX_IOCTL_RECV_EVENT_REPLY, (void *)&post_reply_need);
    
    /* Create Master Device Resources */
    g_user_example_ctx.master_devid = IOT_Linkkit_Open(IOTX_LINKKIT_DEV_TYPE_MASTER, &master_meta_info);
    if (g_user_example_ctx.master_devid < 0) {
        EXAMPLE_TRACE("IOT_Linkkit_Open Failed\n");
        return -1;}
    
    /* Start Connect Aliyun Server */
    res = IOT_Linkkit_Connect(g_user_example_ctx.master_devid);
    if (res < 0) {
        EXAMPLE_TRACE("IOT_Linkkit_Connect Failed\n");
        return -1;
    }
  2. 實現上述代碼中的回調函數user_fota_event_handler

    該回調函數在如下兩種情況下會被觸發:

    • 直接收到云端下發的新固件通知時。

    • 由設備端主動發起新固件查詢,云端返回新固件通知時。

    在收到新固件通知后,可調用IOT_Linkkit_Query進行固件下載。

    int user_fota_event_handler(int type, const char *version){
        char buffer[128] = {0};
        int buffer_length = 128;
    
        /* 0 - new firmware exist, query the new firmware */
        if (type == 0) {
            EXAMPLE_TRACE("New Firmware Version: %s", version);
    
            IOT_Linkkit_Query(EXAMPLE_MASTER_DEVID, ITM_MSG_QUERY_FOTA_DATA, (unsigned char *)buffer, buffer_length);
        }
    
        return 0;
    }
  3. 固件的存儲。

    用戶需要實現如下3個HAL接口來實現固件的存儲。

    /* SDK在開始下載固件之前進行調用 */
    void HAL_Firmware_Persistence_Start(void);
    
    /* SDK在接收到固件數據時進行調用 */
    int HAL_Firmware_Persistence_Write(char *buffer, uint32_t length);
    
    /* SDK在固件下載結束時進行調用 */
    int HAL_Firmware_Persistence_Stop(void);
  4. 用戶主動發起新固件查詢。

    IOT_Linkkit_Query(user_example_ctx->master_devid, ITM_MSG_REQUEST_FOTA_IMAGE,
                          (unsigned char *)("app-1.0.0-20180101.1001"), 30);

OTA支持多模塊

OTA除了可以升級設備固件外,還可以下載并升級設備的軟件模塊,客戶需要在物聯網平臺的控制臺上創建模塊,如下圖所示:

OTA module

設備端開發時, 需要將module設置為與控制臺的模塊名一致:

char* module = "mcu";
IOT_Ioctl(IOTX_IOCTL_SET_MODULE, (void *)module);

其他流程如正常的ota測試流程,在云端控制臺部署任務后, 設備端會有如下日志, 具體見其中的module字段:

[dbg] otamqtt_UpgrageCb(111): topic=/ota/device/upgrade/a1******PjW/foDzDj*******3PDJ9d
[dbg] otamqtt_UpgrageCb(112): len=431, topic_msg={"code":"1000","data":{"size":143360,"module":"mcu","sign":"867f1536fb********a2205436252","version":"111","url":"https://iotx-******ily.oss-cn-shanghai.aliyuncs.com/ota/338ac9db05545dcab9*********52/ck75mi***********5xbgz61vl.tar?Expires=1582951757&OSSAccessKeyId=aS4***********j6Gy&Signature=urw%2F9WAlizQui*************0A%3D","signMethod":"Md5","md5":"867f1536fb*********436252"},"id":1582865357795,"message":"success"}
[dbg] otamqtt_UpgrageCb(129): receive device upgrade
[inf] ofc_Init(47): protocol: https
received state: -0x092C(msg queue size: 0, max size: 50)
received state: -0x092C(msg enqueue w/ message type: 43)
received state: -0x092C(msg dequeue)
received state: -0x0938(alink event type: 43)
received state: -0x0938(new fota information received, 111)
user_fota_module_event_handler.219: New Firmware Version: 111, module: mcu