O arquivo ./demos/mota_basic_demo.c demonstra como um dispositivo usa MQTT para baixar um pacote de atualização OTA com um único arquivo e executar a atualização.
Informações básicas
Para mais detalhes sobre o recurso de atualização OTA, consulte Visão geral da atualização OTA.
O recurso de atualização OTA baseia-se em uma conexão MQTT.Para obter mais informações sobre o código de conexão MQTT, consulte Conexão MQTT.
no heading
Etapa 1: Inicializar o recurso OTA
-
Adicione os arquivos de cabeçalho.
…… …… #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; } -
Chame aiot_ota_init para criar um handle OTA.
ota_handle = aiot_ota_init(); if (NULL == ota_handle) { goto exit; }
no heading
Etapa 2: Configurar o recurso OTA
Chame aiot_ota_setopt para definir as opções abaixo.
-
Associe o handle da conexão MQTT.
ImportanteAntes de configurar os parâmetros OTA,
defina parâmetros como as credenciais do dispositivo. Para mais informações, consulte
Configurar parâmetros de conexão para MQTT
.
-
aiot_ota_setopt(ota_handle, AIOT_OTAOPT_MQTT_HANDLE, mqtt_handle); -
Item de configuração
Exemplo
Descrição
AIOT_OTAOPT_MQTT_HANDLE
mqtt_handle
As solicitações do recurso OTA dependem de conexões MQTT. Este item associa o handle da conexão MQTT.
-
-
Configure o callback para mensagens de instrução de atualização OTA.
-
aiot_ota_setopt(ota_handle, AIOT_OTAOPT_RECV_HANDLER, user_ota_recv_handler); -
Item de configuração
Exemplo
Descrição
AIOT_OTAOPT_MQTT_HANDLER
user_ota_recv_handler
Esta função de callback é invocada quando o dispositivo recebe uma instrução de atualização OTA do IoT Platform.
-
Etapa 3: Reportar a versão atual do dispositivo
Após estabelecer a conexão MQTT, chame aiot_ota_report_version para informar o número da versão atual do dispositivo. O IoT Platform usa esse número para determinar se uma atualização é necessária.
No código de exemplo a seguir, o número da versão reportado pelo dispositivo antes da atualização OTA é 1.0.0. Na sua aplicação, obtenha o número real da versão na área de configuração do dispositivo e ajuste o código conforme necessário.
O dispositivo deve reportar seu número de versão pelo menos uma vez antes de iniciar uma atualização 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
Etapa 4: Receber a instrução de atualização
-
Depois que você adiciona um pacote de atualização e inicia uma tarefa de atualização no console do IoT Platform, a plataforma envia uma instrução de atualização ao dispositivo.
O dispositivo chama aiot_mqtt_recv para receber mensagens. Quando uma mensagem é identificada como instrução de atualização OTA, o callback
user_ota_recv_handleré invocado para processá-la.-
Implemente a lógica de processamento da função de callback.
Desenvolva a lógica de processamento do callback com base nas informações a seguir:
-
O IoT Platform envia instruções de pacotes de atualização OTA para o dispositivo por meio do tópico
/ota/device/upgrade/${ProductKey}/${DeviceName}.Para detalhes sobre ${ProductKey} e ${DeviceName}, consulte Obter credenciais do dispositivo.
-
O tipo da instrução de atualização OTA é 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; } …… …… } Sobre o formato de dados Alink das mensagens de instrução de atualização OTA, consulte IoT Platform envia informações de pacote de atualização OTA.
O tipo de estrutura de dados para mensagens de instrução de atualização OTA é aiot_ota_recv_t. O Link SDK analisa automaticamente as mensagens de instrução de atualização recebidas.
Para implementar a lógica de processamento da função de callback, consulteEtapa 5.
-
no heading
Etapa 5: Baixar o pacote de atualização e executar a atualização OTA
O dispositivo não baixa automaticamente o pacote de atualização após receber a mensagem do IoT Platform. Chame uma API do Link SDK para iniciar o download.
Quando user_ota_recv_handler é acionado, o downloader envia uma solicitação de download via MQTT para receber o pacote de atualização do IoT Platform e realizar a atualização OTA.
-
Inicialize o downloader.
Chame
para criar um
download
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(); …… …… } -
Defina os parâmetros de download.
Use
para configurar os parâmetros da tarefa de download.
-
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; -
Item de configuração Exemplo Descrição AIOT_MDOPT_TASK_DESC ota_msg->task_desc Define a tarefa de download. AIOT_DLOPT_DATA_REQUEST_SIZE request_size Tamanho de cada pacote de dados solicitado ao IoT Platform. AIOT_MDOPT_RANGE_START range_start Bytes inicial e final de cada segmento ao baixar um pacote de atualização em partes ou apenas um fragmento dele. Se não definido, o arquivo inteiro é baixado de uma só vez.
Por exemplo, para baixar um pacote de atualização de 1024 bytes em duas partes, configure os parâmetros da seguinte forma:- Primeira 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 o callback para recebimento de dados do pacote de atualização OTA. Este callback é acionado quando o IoT Platform retorna uma mensagem com o conteúdo do pacote de atualização após o dispositivo iniciar a solicitação de download.
- Primeira parte:
-
-
Chame aiot_mqtt_download_process para enviar uma solicitação de download ao 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); …… …… } } -
Ao receber a solicitação de download, o IoT Platform retorna o pacote de atualização ao dispositivo. Quando o dispositivo recebe os dados do pacote, o callback
user_download_recv_handleré acionado.Implemente a lógica de processamento da função de callback para salvar os dados do pacote de atualização baixado em um arquivo 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); } -
Após concluir o download do pacote de atualização, chame aiot_mqtt_download_deinit para liberar os recursos do downloader.
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
Etapa 6: Reportar o número da versão após a atualização
Para ver o código de exemplo sobre como reportar o número da versão, consulte Etapa 3: Reportar a versão atual do dispositivo.
Após concluir a atualização OTA, o dispositivo deve reportar o número da versão mais recente. Caso contrário, o IoT Platform considerará a tarefa de atualização OTA como falha.
Se o dispositivo precisar ser reiniciado após a atualização, ele deverá reportar o número da versão mais recente depois da reinicialização.
O código de exemplo não inclui a lógica para reportar o número da versão após a conclusão da atualização. Adicione essa lógica ao seu código.
Etapa 7: Desconectar
Chame aiot_mqtt_disconnect para enviar uma mensagem de desconexão ao IoT Platform e encerrar a conexão de rede.
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;
}
Etapa 8: Sair do programa OTA
Chame aiot_ota_deinit para destruir a instância OTA.
aiot_ota_deinit(&ota_handle);
Próximos passos
-
Demo
./demos/mota-basic-demo.Para mais informações, consulte Compilar e executar.