Tous les produits
Search
Centre de documentation

IoT Platform:Exemple de code de mise à jour OTA

Dernière mise à jour :Aug 10, 2026

Téléchargez un package de mise à jour sans fil (OTA) contenant un seul fichier via HTTPS et mettez à jour l'appareil., le fichier d'exemple de code ./demo/fota_posix_demo.c est utilisé.

Contexte

  • Présentation de la fonctionnalité de mise à jour OTA : Vue d'ensemble.

  • utilise des connexions MQTT. Pour des exemples de code associés, consultez Connexion MQTT.

Étape 1 : Initialiser un client

  1. Ajoutez les fichiers d'en-tête.

    ...
    ……
    #include "aiot_ota_api.h"
    ……
  2. Configurez les dépendances sous-jacentes et la sortie des journaux.

        aiot_sysdep_set_portfile(&g_aiot_sysdep_portfile);
        aiot_state_set_logcb(demo_state_logcb);
  3. Appelez l'opération aiot_ota_init pour créer un handle OTA

        ota_handle = aiot_ota_init();
        if (NULL == ota_handle) {
            printf("aiot_ota_init failed\r\n");
            aiot_mqtt_deinit(&mqtt_handle);
            return -2;
        }

Étape 2 : Configurer les fonctionnalités requises

Appelez aiot_ota_setopt pour configurer les éléments suivants.

  1. Associez un handle de connexion MQTT.

    Important

    Avant de définir les paramètres OTA, assurez-vous que l'authentification de l'appareil est configurée. Consultez l'Exemple.

    •     aiot_ota_setopt(ota_handle, AIOT_OTAOPT_MQTT_HANDLE, mqtt_handle);
    • Paramètre

      Exemple

      Description

      AIOT_OTAOPT_MQTT_HANDLE

      mqtt_handle

      Les requêtes TSL utilisent cette connexion.

  2. Configurez un rappel pour traiter les commandes de mise à jour OTA.

    •     aiot_ota_setopt(ota_handle, AIOT_OTAOPT_RECV_HANDLER, demo_ota_recv_handler);
    • Paramètre

      Exemple

      Description

      AIOT_OTAOPT_MQTT_HANDLER

      demo_ota_recv_handler

      Appelé lorsque l'appareil reçoit une commande de mise à jour OTA depuis IoT Platform.

Étape 3 : Soumettre le numéro de version de l'appareil

Une fois que l'appareil a établi une connexion MQTT, appelez aiot_ota_report_version pour soumettre le numéro de version de l'appareil. IoT Platform détermine si une mise à jour est nécessaire en fonction de ce numéro de version.

Cet exemple soumet la version 1.0.0. En production, obtenez le numéro de version à partir des paramètres de l'appareil et implémentez la logique de soumission en conséquence.

Important

Soumettez le numéro de version au moins une fois avant d'effectuer une mise à jour OTA.

    cur_version = "1.0.0";
    res = aiot_ota_report_version(ota_handle, cur_version);
    if (res < STATE_SUCCESS) {
        printf("aiot_ota_report_version failed: -0x%04X\r\n", -res);
    }

Étape 4 : Recevoir les commandes de mise à jour

  1. Après avoir ajouté un package de mise à jour et lancé une tâche de mise à jour, IoT Platform envoie une commande de mise à jour à l'appareil.

  2. L'appareil appelle l'opération aiot_mqtt_recv pour recevoir le message. Lorsque l'appareil identifie le message comme une commande de mise à jour OTA, le rappel demo_ota_recv_handler est appelé.

  3. Spécifiez la logique de traitement du rappel.

    Lorsque vous définissez la logique du rappel, tenez compte des points suivants :

Étape 5 : Télécharger le package de mise à jour et effectuer une mise à jour OTA

Important

L'appareil ne télécharge pas automatiquement le package de mise à jour après avoir reçu la commande. Vous devez appeler l'API Link SDK pour le télécharger.

Une fois que demo_ota_recv_handler est appelé, le programme de téléchargement lance une requête HTTPS pour le package de mise à jour OTA.

  1. Initialisez le programme de téléchargement.

    Appelez aiot_download_init pour créer un handle download

                dl_handle = aiot_download_init();
                if (NULL == dl_handle) {
                    break;
                }
                printf("OTA target firmware version: %s, size: %u Bytes \r\n", ota_msg->task_desc->version,
                       ota_msg->task_desc->size_total);
    
                if (NULL != ota_msg->task_desc->extra_data) {
                    printf("extra data: %s\r\n", ota_msg->task_desc->extra_data);
                }
    
                memset(&cred, 0, sizeof(aiot_sysdep_network_cred_t));
                cred.option = AIOT_SYSDEP_NETWORK_CRED_SVRCERT_CA;
                cred.max_tls_fragment = 16384;
                cred.x509_server_cert = ali_ca_cert;
                cred.x509_server_cert_len = strlen(ali_ca_cert);
  2. Définissez les paramètres.

    Appelez aiot_download_setopt pour définir les paramètres de la tâche de téléchargement.

                /* Set the TLS protocol for downloading. */
                aiot_download_setopt(dl_handle, AIOT_DLOPT_NETWORK_CRED, (void *)(&cred));
                /* Set the port number of the server to be accessed. */
                aiot_download_setopt(dl_handle, AIOT_DLOPT_NETWORK_PORT, (void *)(&port));
                /* Specify the information of the download task, which can be obtained from the task_desc member in the ota_msg input parameter. The information includes the download URL, firmware size, and firmware signature. */
                aiot_download_setopt(dl_handle, AIOT_DLOPT_TASK_DESC, (void *)(ota_msg->task_desc));
                /* Set the callback that the SDK calls when the downloaded content is received. */
                aiot_download_setopt(dl_handle, AIOT_DLOPT_RECV_HANDLER, (void *)(demo_download_recv_handler));
                /* Set the maximum buffer length for a single download. Users are notified if the limit is reached. */
                aiot_download_setopt(dl_handle, AIOT_DLOPT_BODY_BUFFER_MAX_LEN, (void *)(&max_buffer_len));
                /* Specify the information that is shared among different calls of AIOT_DLOPT_RECV_HANDLER. In this example, the progress information is stored. */
                last_percent = malloc(sizeof(uint32_t));
                if (NULL == last_percent) {
                    aiot_download_deinit(&dl_handle);
                    break;
                }
                memset(last_percent, 0, sizeof(uint32_t));
                aiot_download_setopt(dl_handle, AIOT_DLOPT_USERDATA, (void *)last_percent);
  3. Lancez une demande de téléchargement.

    1. Démarrez le thread de téléchargement demo_ota_download_thread.

                  res = pthread_create(&g_download_thread, NULL, demo_ota_download_thread, dl_handle);
                  if (res != 0) {
                      printf("pthread_create demo_ota_download_thread failed: %d\r\n", res);
                      aiot_download_deinit(&dl_handle);
                      free(last_percent);
                  } else {
                      /* Set the type of the downloading thread to detach. After the firmware is obtained, the downloading thread automatically exits. */
                      pthread_detach(g_download_thread);
                  }
    2. Une fois le thread demo_ota_download_thread activé, appelez l'opération aiot_download_send_request pour lancer une requête GET HTTPS afin de télécharger le package de mise à jour depuis le serveur de stockage.

      • void *demo_ota_download_thread(void *dl_handle)
        {
            int32_t     ret = 0;
        
            printf("starting download thread in 2 seconds ......\n");
            sleep(2);
        
            /* Initiate a request to download the update package from the storage server.  */
            /*
             * TODO: In this example, a single request is initiated to obtain all the content of the update package. 
             *       If the device has limited resources or the network connection is in poor condition, you can implement a segmented download.
             *
             *       aiot_download_setopt(dl_handle, AIOT_DLOPT_RANGE_START, ...);
             *       aiot_download_setopt(dl_handle, AIOT_DLOPT_RANGE_END, ...);
             *       aiot_download_send_request(dl_handle);
             *
             *      If you implement a segmented download, specify the preceding three statements in a loop. In this case, multiple requests are sent and multiple responses are received.
             *
             */
        
             ……
             ……
        
        }
      • Pour les téléchargements segmentés, définissez AIOT_DLOPT_RANGE_START et AIOT_DLOPT_RANGE_END.

        Exemple : pour télécharger un package de mise à jour de 1 024 octets en deux segments :

        • Premier segment : AIOT_DLOPT_RANGE_START=0, AIOT_DLOPT_RANGE_END=511

        • Deuxième segment : AIOT_DLOPT_RANGE_START=512, AIOT_DLOPT_RANGE_END=1023

  4. Recevez le package de mise à jour.

    1. Après avoir envoyé la demande de téléchargement, appelez aiot_download_recv dans le thread demo_ota_download_thread pour recevoir le package de mise à jour. Le rappel demo_download_recv_handler est déclenché lors de la réception. Enregistrez le package téléchargé dans le stockage local.

      void *demo_ota_download_thread(void *dl_handle)
      {
           ……
           ……
      
           while (1) {
              /* Receive the firmware that is sent from the server. */
              ret = aiot_download_recv(dl_handle);
      
              /* After the firmware is downloaded, the return value of aiot_download_recv() is STATE_DOWNLOAD_FINISHED. Otherwise, the value is the number of bytes that are obtained. */  */
              if (STATE_DOWNLOAD_FINISHED == ret) {
                  printf("download completed\n");
                  break;
              }
          }
           ……
           ……
      }
    2. Définissez le rappel demo_download_recv_handler pour stocker le package de mise à jour téléchargé et effectuer une mise à jour.

      Remarque

      Cet exemple se contente d'imprimer la réponse. En production, vous devez stocker le package de mise à jour et l'installer pour terminer la mise à jour OTA.

      void demo_download_recv_handler(void *handle, const aiot_download_recv_t *packet, void *userdata)
      {
          uint32_t data_buffer_len = 0;
          uint32_t last_percent = 0;
          int32_t  percent = 0;
      
          /* You can set packet->type only to AIOT_DLRECV_HTTPBODY. */
          if (!packet || AIOT_DLRECV_HTTPBODY != packet->type) {
              return;
          }
          percent = packet->data.percent;
      
          /* userdata can store the data that needs to be shared between different calls of demo_download_recv_handler(). */
          /* In this example, the percentage of the firmware download progress is stored. */
          if (userdata) {
              last_percent = *((uint32_t *)(userdata));
          }
      
          data_buffer_len = packet->data.len;
      
          /* A negative value of percent indicates that an exception occurs during data receiving or the digest authentication fails. */
          if (percent < 0) {
              printf("exception: percent = %d\r\n", percent);
              if (userdata) {
                  free(userdata);
              }
              return;
          }
           ……
           ……
      
      }
  5. Soumettez la progression du téléchargement.

    Une fois que demo_download_recv_handler est appelé, appelez aiot_download_report_progress pour soumettre la progression du téléchargement et toute erreur (comme un échec de gravure ou une déconnexion réseau) à IoT Platform.

    • Consultez la progression soumise :

      La progression s'affiche dans la console IoT Platform. Afficher l'état de la mise à jour.

    • Soumettez la progression en cas de condition normale ou anormale :

      • En cas de succès, le Link SDK calcule et soumet automatiquement la valeur percent à IoT Platform via le rappel.

      • En cas d'échec (erreur de téléchargement ou échec de gravure), signalez l'erreur à IoT Platform. Codes d'erreur : aiot_ota_protocol_errcode_t.

    void demo_download_recv_handler(void *handle, const aiot_download_recv_t *packet, void *userdata)
    {
         ……
         ……
        /*
         * TODO:
         *       After you download the update package, save the memory whose initial position is packet->data.buffer and length is packet->data.len to the local storage location or file system of the device. 
         *
         *      If the burning fails, you must call the aiot_download_report_progress(handle, -4) operation to submit the error message to IoT Platform. 
         */
        /* If the value of percent is 100, all the content of the update package is downloaded.  */
        if (percent == 100) {
            /*
             * TODO: Burn the firmware, save the configurations, restart the device, and then switch to the new firmware to boot the device. 
                     The device must submit the version number of the new firmware to IoT Platform after the update.
    
                     aiot_ota_report_version(ota_handle, new_version);
    
                     For example, if the version is updated from 1.0.0 to 1.1.0, the value of new_version is 1.1.0 must be submitted to IoT Platform. 
                     IoT Platform determines that the update is successful after it receives the version number of the new firmware. Otherwise, IoT Platform determines that the update fails. 
             */
        }
    
        /* Simplify the output. Each time the download progress increases by at least 5%, the progress is printed and submitted to IoT Platform. */
        if (percent - last_percent >= 5 || percent == 100) {
            printf("download %03d%% done, +%d bytes\n", percent, data_buffer_len);
            aiot_download_report_progress(handle, percent);
            if (userdata) {
                *((uint32_t *)(userdata)) = percent;
            }
        }
    }
  6. Quittez le programme de téléchargement.

    Une fois le téléchargement terminé, appelez aiot_download_deinit pour détruire la session download et fermer le thread de téléchargement.

        aiot_download_deinit(&dl_handle);
        printf("download thread exit\n");

Étape 6 : Soumettre le numéro de version après la mise à jour

Étape 3 : Soumettre le numéro de version de l'appareil.

Remarque
  • Après la mise à jour, soumettez le dernier numéro de version. Sinon, IoT Platform marque la tâche OTA comme ayant échoué.

  • Si l'appareil redémarre après la mise à jour, soumettez le numéro de version après le redémarrage.

  • Cet exemple n'inclut pas la logique de soumission de version. Implémentez-la selon vos besoins.

Étape 7 : Se déconnecter

Remarque

MQTT est généralement utilisé pour les appareils nécessitant une connexion persistante. Par conséquent, le programme n'atteint généralement pas ce point.

Dans le programme d'exemple, le thread principal est responsable de la configuration des paramètres et de l'établissement de la connexion. Une fois la connexion établie, le thread principal peut entrer en veille.

Vous pouvez appeler aiot_mqtt_disconnect pour envoyer un message de déconnexion à IoT Platform et vous déconnecter du réseau.

    res = aiot_mqtt_disconnect(mqtt_handle);
    if (res < STATE_SUCCESS) {
        aiot_mqtt_deinit(&mqtt_handle);
        printf("aiot_mqtt_disconnect failed: -0x%04X\n", -res);
        return -1;
    }

Étape 8 : Quitter le programme

Appelez aiot_ota_deinit pour détruire le handle OTA

    aiot_ota_deinit(&ota_handle);

Étapes suivantes