El ./demos/mota_basic_demo.c archivo muestra cómo un dispositivo utiliza MQTT para descargar un paquete de actualización OTA que contiene un solo archivo de actualización y ejecutar dicha actualización.
Contexto
Para obtener más información sobre la función de actualización OTA, consulte OTA update overview.
La función de actualización OTA se basa en una conexión MQTT.Para obtener más información sobre el código de una conexión MQTT, consulte MQTT connection.
no heading
Paso 1: Inicializar la función OTA
-
Agregue los archivos de encabezado.
…… …… #include "aiot_ota_api.h" #include "aiot_mqtt_download_api.h" …… -
/* A collection of system adaptation functions in the portfiles/aiot_port directory */ extern aiot_sysdep_portfile_t g_aiot_sysdep_portfile; /* TODO: To disable logs, implement this function as an empty function. To reduce logs, you can choose not to print logs based on the code. * For example: [1578463098.611][LK-0309] pub: /ota/device/upgrade/a13FN******/ota_demo * The code for the preceding log is 0309 (hexadecimal). For more information about code values, see core/aiot_state_api.h. */ /* This is a log callback function. The SDK logs are output from here. */ int32_t demo_state_logcb(int32_t code, char *message) { printf("%s", message); return 0; } -
Llame a aiot_ota_init para crear un identificador OTA.
ota_handle = aiot_ota_init(); if (NULL == ota_handle) { goto exit; }
no heading
Paso 2: Configurar la función OTA
Llame a aiot_ota_setopt para configurar las siguientes opciones.
-
Asocie el identificador de la conexión MQTT.
ImportanteAntes de configurar los parámetros OTA,
debe configurar parámetros como las credenciales del dispositivo. Para obtener más información, consulte
Configure connection parameters for MQTT
.
-
aiot_ota_setopt(ota_handle, AIOT_OTAOPT_MQTT_HANDLE, mqtt_handle); -
Elemento de configuración
Ejemplo
Descripción
AIOT_OTAOPT_MQTT_HANDLE
mqtt_handle
Las solicitudes de la función OTA se basan en conexiones MQTT. Este elemento de configuración asocia el identificador de conexión MQTT.
-
-
Configure la devolución de llamada para los mensajes de instrucción de actualización OTA.
-
aiot_ota_setopt(ota_handle, AIOT_OTAOPT_RECV_HANDLER, user_ota_recv_handler); -
Elemento de configuración
Ejemplo
Descripción
AIOT_OTAOPT_MQTT_HANDLER
user_ota_recv_handler
Cuando el dispositivo recibe una instrucción de actualización OTA desde IoT Platform, se invoca esta función de devolución de llamada.
-
Paso 3: Reportar la versión actual del dispositivo
Después de que el dispositivo establece una conexión MQTT, llame a aiot_ota_report_version para reportar el número de versión actual del dispositivo. IoT Platform determina si se requiere una actualización según el número de versión.
En el siguiente código de ejemplo, el número de versión que reporta el dispositivo antes de la actualización OTA es 1.0.0. En su aplicación, debe obtener el número de versión real del área de configuración del dispositivo y modificar el código en consecuencia.
El dispositivo debe reportar su número de versión como mínimo una vez antes de una actualización 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);
}
no heading
Paso 4: Recibir la instrucción de actualización
-
Después de agregar un paquete de actualización e iniciar una tarea de actualización en la consola de IoT Platform, IoT Platform envía una instrucción de actualización al dispositivo.
El dispositivo llama a aiot_mqtt_recv para recibir mensajes. Cuando un mensaje se identifica como una instrucción de actualización OTA, se invoca la devolución de llamada
user_ota_recv_handlerpara procesar la instrucción.-
Escriba la lógica de procesamiento para la función de devolución de llamada.
Escriba la lógica de procesamiento para la función de devolución de llamada con base en la siguiente información:
-
IoT Platform envía instrucciones de paquetes de actualización OTA al dispositivo a través del tema
/ota/device/upgrade/${ProductKey}/${DeviceName}.Para obtener más información sobre ${ProductKey} y ${DeviceName}, consulte Obtain device credentials.
-
El tipo de instrucción de actualización OTA es AIOT_OTARECV_FOTA.
void user_ota_recv_handler(void *ota_handle, aiot_ota_recv_t *ota_msg, void *userdata) { uint32_t request_size = 10 * 1024; switch (ota_msg->type) { case AIOT_OTARECV_FOTA: { if (NULL == ota_msg->task_desc || ota_msg->task_desc->protocol_type != AIOT_OTA_PROTOCOL_MQTT) { break; } …… …… } Para obtener información sobre el formato de datos Alink de los mensajes de instrucción de actualización OTA, consulte IoT Platform pushes OTA update package information.
El tipo de estructura de datos para los mensajes de instrucción de actualización OTA es aiot_ota_recv_t. Link SDK analiza sintácticamente de forma automática los mensajes de instrucción de actualización recibidos.
Para escribir la lógica de procesamiento de la función de devolución de llamada, consulteStep 5.
-
no heading
Paso 5: Descargar el paquete de actualización y ejecutar la actualización OTA
El dispositivo no descarga automáticamente el paquete de actualización después de recibir el mensaje del paquete de actualización desde IoT Platform. Debe llamar a una API de Link SDK para iniciar la descarga.
Después de que se activa user_ota_recv_handler, el descargador envía una solicitud de descarga basada en MQTT para recibir el paquete de actualización desde IoT Platform y ejecutar la actualización OTA.
-
Inicialice el descargador.
Llame a
para crear un
identificador de descarga
void user_ota_recv_handler(void *ota_handle, aiot_ota_recv_t *ota_msg, void *userdata) { …… …… printf("OTA target firmware version: %s, size: %u Bytes\r\n", ota_msg->task_desc->version, ota_msg->task_desc->size_total); void *md_handler = aiot_mqtt_download_init(); …… …… } -
Configure los parámetros de descarga.
Llame a
para configurar los parámetros de la tarea de descarga.
-
aiot_mqtt_download_setopt(md_handler, AIOT_MDOPT_TASK_DESC, ota_msg->task_desc); /* Set the size of a download package. You can adjust this value for resource-constrained devices. */ aiot_mqtt_download_setopt(md_handler, AIOT_DLOPT_DATA_REQUEST_SIZE, &request_size); /* The start and end byte numbers for each segment when you download an update package in segments or download only a fragment of the package. * If you set a range for the download, the data in a single message has a cyclic redundancy check (CRC), but the SDK does not perform a full file MD5 validation. * By default, the entire file is downloaded. The data in a single message has a CRC, and the SDK performs a full file MD5 validation. * If you uncomment the following code, the download starts from the 10th byte of the file and ends at the 10th byte of the 50th kilobyte. */ // uint32_t range_start = 10, range_end = 50 * 1024 + 10; // aiot_mqtt_download_setopt(md_handler, AIOT_MDOPT_RANGE_START, &range_start); // aiot_mqtt_download_setopt(md_handler, AIOT_MDOPT_RANGE_END, &range_end); aiot_mqtt_download_setopt(md_handler, AIOT_MDOPT_RECV_HANDLE, user_download_recv_handler); g_dl_handle = md_handler; -
Elemento de configuración Ejemplo Descripción AIOT_MDOPT_TASK_DESC ota_msg->task_desc Especifica la tarea de descarga. AIOT_DLOPT_DATA_REQUEST_SIZE request_size El tamaño de cada paquete de datos solicitado a IoT Platform. AIOT_MDOPT_RANGE_START range_start Los números de byte inicial y final para cada segmento cuando descarga un paquete de actualización por segmentos o descarga solo un fragmento del paquete. Si no se establece, se descarga todo el archivo de una sola vez.
Por ejemplo, para descargar un paquete de actualización de 1024 bytes en dos partes, puede establecer los parámetros de la siguiente manera:- Primera parte:
AIOT_DLOPT_RANGE_START=0,AIOT_DLOPT_RANGE_END=511 - Segunda parte:
AIOT_DLOPT_RANGE_START=512,AIOT_DLOPT_RANGE_END=1023
AIOT_MDOPT_RANGE_END range_end AIOT_MDOPT_RECV_HANDLE user_download_recv_handler Especifica la devolución de llamada para recibir datos del paquete de actualización OTA. Esta devolución de llamada se activa cuando IoT Platform devuelve un mensaje con el contenido del paquete de actualización después de que el dispositivo inicia una solicitud de descarga.
- Primera parte:
-
-
Llame a aiot_mqtt_download_process para enviar una solicitud de descarga a IoT Platform.
while (1) { aiot_mqtt_process(mqtt_handle); aiot_mqtt_recv(mqtt_handle); if(g_dl_handle != NULL) { int32_t res = aiot_mqtt_download_process(g_dl_handle); …… …… } } -
Después de que IoT Platform recibe la solicitud de descarga, devuelve el paquete de actualización al dispositivo. Cuando el dispositivo recibe los datos del paquete, se activa la devolución de llamada
user_download_recv_handler.Escriba la lógica de procesamiento para la función de devolución de llamada a fin de guardar los datos del paquete de actualización descargados en un archivo local.
void user_download_recv_handler(void *handle, const aiot_mqtt_download_recv_t *packet, void *userdata) { uint32_t data_buffer_len = 0; /* Currently, only the case where packet->type is AIOT_MDRECV_DATA_RESP is supported. */ if (!packet || AIOT_MDRECV_DATA_RESP != packet->type) { return; } /* The operation to persist the file locally should be implemented here. */ FILE *file = fopen("mota_demo.bin", "ab"); fwrite(packet->data.data_resp.data, packet->data.data_resp.data_size, sizeof(int8_t), file); fclose(file); data_buffer_len = packet->data.data_resp.data_size; printf("download %03d%% done, +%d bytes\r\n", packet->data.data_resp.percent, data_buffer_len); } -
Una vez descargado el paquete de actualización, llame a aiot_mqtt_download_deinit para liberar los recursos del descargador.
while (1) { aiot_mqtt_process(mqtt_handle); aiot_mqtt_recv(mqtt_handle); if(g_dl_handle != NULL) { int32_t res = aiot_mqtt_download_process(g_dl_handle); if(STATE_MQTT_DOWNLOAD_SUCCESS == res) { /* The update is successful. You can restart the device and report the new version number here. */ printf("mqtt download ota success \r\n"); aiot_mqtt_download_deinit(&g_dl_handle); break; } else if(STATE_MQTT_DOWNLOAD_FAILED_RECVERROR == res || STATE_MQTT_DOWNLOAD_FAILED_TIMEOUT == res || STATE_MQTT_DOWNLOAD_FAILED_MISMATCH == res) { printf("mqtt download ota failed \r\n"); aiot_mqtt_download_deinit(&g_dl_handle); break; } } }
no heading
Paso 6: Reportar el número de versión después de la actualización
Para ver el código de ejemplo sobre cómo reportar el número de versión, consulte Step 3: Report the current device version number.
Después de que el dispositivo completa la actualización OTA, debe reportar el número de versión más reciente. De lo contrario, IoT Platform considera que la tarea de actualización OTA ha fallado.
Si es necesario reiniciar el dispositivo después de la actualización, este debe reportar el número de versión más reciente tras el reinicio.
El código de ejemplo no incluye la lógica para reportar el número de versión una vez completada la actualización. Debe agregar esta lógica a su código.
Paso 7: Desconectarse
Puede llamar a aiot_mqtt_disconnect para enviar un mensaje de desconexión a IoT Platform y desconectarse de la red.
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;
}
Paso 8: Salir del programa OTA
Llame a aiot_ota_deinit para destruir la instancia OTA.
aiot_ota_deinit(&ota_handle);
Siguientes pasos
-
Demostración
./demos/mota-basic-demo.Para obtener más información, consulte Compile and run.