From d0fccbce15360ff520bc1133f311592895c1e024 Mon Sep 17 00:00:00 2001 From: Chen Wu Date: Mon, 19 Dec 2016 15:40:21 +0800 Subject: [PATCH] examples: Add OTA demo --- components/app_update/esp_ota_ops.c | 2 +- examples/18_ota/Makefile | 9 + examples/18_ota/OTA_workflow.png | Bin 0 -> 58211 bytes examples/18_ota/README.md | 101 ++++++++ examples/18_ota/main/Kconfig.projbuild | 40 ++++ examples/18_ota/main/component.mk | 4 + examples/18_ota/main/ota.c | 318 +++++++++++++++++++++++++ examples/18_ota/sdkconfig | 5 + 8 files changed, 478 insertions(+), 1 deletion(-) create mode 100644 examples/18_ota/Makefile create mode 100644 examples/18_ota/OTA_workflow.png create mode 100644 examples/18_ota/README.md create mode 100644 examples/18_ota/main/Kconfig.projbuild create mode 100644 examples/18_ota/main/component.mk create mode 100644 examples/18_ota/main/ota.c create mode 100644 examples/18_ota/sdkconfig diff --git a/components/app_update/esp_ota_ops.c b/components/app_update/esp_ota_ops.c index e95937256f..439117b596 100644 --- a/components/app_update/esp_ota_ops.c +++ b/components/app_update/esp_ota_ops.c @@ -378,4 +378,4 @@ const esp_partition_t *esp_ota_get_boot_partition(void) ESP_LOGE(TAG, "not found current bin"); return NULL; } -} \ No newline at end of file +} diff --git a/examples/18_ota/Makefile b/examples/18_ota/Makefile new file mode 100644 index 0000000000..7ffb10234f --- /dev/null +++ b/examples/18_ota/Makefile @@ -0,0 +1,9 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := ota + +include $(IDF_PATH)/make/project.mk + diff --git a/examples/18_ota/OTA_workflow.png b/examples/18_ota/OTA_workflow.png new file mode 100644 index 0000000000000000000000000000000000000000..3e91dafb3801df54ddd86cceb069d6ecf9bae75f GIT binary patch literal 58211 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 +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" + +#include "esp_system.h" +#include "esp_wifi.h" +#include "esp_event_loop.h" +#include "esp_log.h" +#include "esp_ota_ops.h" +#include "esp_partition.h" + +#include "nvs_flash.h" +#include "lwip/err.h" +#include "lwip/sockets.h" +#include "lwip/sys.h" +#include "lwip/netdb.h" +#include "lwip/dns.h" + +#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID +#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD +#define EXAMPLE_SERVER_IP CONFIG_SERVER_IP +#define EXAMPLE_SERVER_PORT CONFIG_SERVER_PORT +#define EXAMPLE_FILENAME CONFIG_EXAMPLE_FILENAME +#define BUFFSIZE 1024 +#define TEXT_BUFFSIZE 1024 + +static const char *TAG = "ota"; +/*an ota data write buffer ready to write to the flash*/ +char ota_write_data[BUFFSIZE + 1] = { 0 }; +/*an packet receive buffer*/ +char text[BUFFSIZE + 1] = { 0 }; +/* an image total length*/ +int binary_file_length = 0; +/*socket id*/ +int socket_id = -1; +char http_request[64] = {0}; +/* operate handle : uninitialized value is zero ,every ota begin would exponential growth*/ +esp_ota_handle_t out_handle = 0; +esp_partition_t operate_partition; + +/* FreeRTOS event group to signal when we are connected & ready to make a request */ +static EventGroupHandle_t wifi_event_group; + +/* The event group allows multiple bits for each event, + but we only care about one event - are we connected + to the AP with an IP? */ +const int CONNECTED_BIT = BIT0; + +static esp_err_t event_handler(void *ctx, system_event_t *event) +{ + switch (event->event_id) { + case SYSTEM_EVENT_STA_START: + esp_wifi_connect(); + break; + case SYSTEM_EVENT_STA_GOT_IP: + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + /* This is a workaround as ESP32 WiFi libs don't currently + auto-reassociate. */ + esp_wifi_connect(); + xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); + break; + default: + break; + } + return ESP_OK; +} + +static void initialise_wifi(void) +{ + tcpip_adapter_init(); + wifi_event_group = xEventGroupCreate(); + ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); + ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); + wifi_config_t wifi_config = { + .sta = { + .ssid = EXAMPLE_WIFI_SSID, + .password = EXAMPLE_WIFI_PASS, + }, + }; + ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); + ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); + ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); + ESP_ERROR_CHECK( esp_wifi_start() ); +} + +/*read buffer by byte still delim ,return read bytes counts*/ +int read_until(char *buffer, char delim, int len) +{ +// /*TODO: delim check,buffer check,further: do an buffer length limited*/ + int i = 0; + while (buffer[i] != delim && i < len) { + ++i; + } + return i + 1; +} + +/* resolve a packet from http socket + * return true if packet including \r\n\r\n that means http packet header finished,start to receive packet body + * otherwise return false + * */ +bool resolve_pkg(char text[], int total_len, esp_ota_handle_t out_handle) +{ + /* i means current position */ + int i = 0, i_read_len = 0; + while (text[i] != 0 && i < total_len) { + i_read_len = read_until(&text[i], '\n', total_len); + // if we resolve \r\n line,we think packet header is finished + if (i_read_len == 2) { + int i_write_len = total_len - (i + 2); + memset(ota_write_data, 0, BUFFSIZE); + /*copy first http packet body to write buffer*/ + memcpy(ota_write_data, &(text[i + 2]), i_write_len); + /*check write packet header first byte:0xE9 second byte:0x09 */ + if (ota_write_data[0] == 0xE9 && i_write_len >= 2 && ota_write_data[1] == 0x09) { + ESP_LOGI(TAG, "OTA Write Header format Check OK. first byte is %02x ,second byte is %02x", ota_write_data[0], ota_write_data[1]); + } else { + ESP_LOGE(TAG, "OTA Write Header format Check Failed! first byte is %02x ,second byte is %02x", ota_write_data[0], ota_write_data[1]); + return false; + } + + esp_err_t err = esp_ota_write( out_handle, (const void *)ota_write_data, i_write_len); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Error: esp_ota_write failed! err=%x", err); + return false; + } else { + ESP_LOGI(TAG, "esp_ota_write header OK"); + binary_file_length += i_write_len; + } + return true; + } + i += i_read_len; + } + return false; +} + +bool connect_to_http_server() +{ + ESP_LOGI(TAG, "Server IP: %s Server Port:%s", EXAMPLE_SERVER_IP, EXAMPLE_SERVER_PORT); + sprintf(http_request, "GET %s HTTP/1.1\r\nHost: %s:%s \r\n\r\n", EXAMPLE_FILENAME, EXAMPLE_SERVER_IP, EXAMPLE_SERVER_PORT); + + int http_connect_flag = -1; + struct sockaddr_in sock_info; + + socket_id = socket(AF_INET, SOCK_STREAM, 0); + if (socket_id == -1) { + ESP_LOGE(TAG, "Create socket failed!"); + return false; + } + + // set connect info + memset(&sock_info, 0, sizeof(struct sockaddr_in)); + sock_info.sin_family = AF_INET; + sock_info.sin_addr.s_addr = inet_addr(EXAMPLE_SERVER_IP); + sock_info.sin_port = htons(atoi(EXAMPLE_SERVER_PORT)); + + // connect to http server + http_connect_flag = connect(socket_id, (struct sockaddr *)&sock_info, sizeof(sock_info)); + if (http_connect_flag == -1) { + ESP_LOGE(TAG, "Connect to server failed! errno=%d", errno); + close(socket_id); + return false; + } else { + ESP_LOGI(TAG, "Connected to server"); + return true; + } + return false; +} + +bool ota_init() +{ + esp_err_t err; + const esp_partition_t *esp_current_partition = esp_ota_get_boot_partition(); + if (esp_current_partition->type != ESP_PARTITION_TYPE_APP) { + ESP_LOGE(TAG, "Error: esp_current_partition->type != ESP_PARTITION_TYPE_APP"); + return false; + } + + esp_partition_t find_partition; + memset(&operate_partition, 0, sizeof(esp_partition_t)); + /*choose which OTA image should we write to*/ + switch (esp_current_partition->subtype) { + case ESP_PARTITION_SUBTYPE_APP_FACTORY: + find_partition.subtype = ESP_PARTITION_SUBTYPE_APP_OTA_0; + break; + case ESP_PARTITION_SUBTYPE_APP_OTA_0: + find_partition.subtype = ESP_PARTITION_SUBTYPE_APP_OTA_1; + break; + case ESP_PARTITION_SUBTYPE_APP_OTA_1: + find_partition.subtype = ESP_PARTITION_SUBTYPE_APP_OTA_0; + break; + default: + break; + } + find_partition.type = ESP_PARTITION_TYPE_APP; + + const esp_partition_t *partition = esp_partition_find_first(find_partition.type, find_partition.subtype, NULL); + assert(partition != NULL); + memset(&operate_partition, 0, sizeof(esp_partition_t)); + err = esp_ota_begin( partition, OTA_SIZE_UNKNOWN, &out_handle); + if (err != ESP_OK) { + ESP_LOGE(TAG, "esp_ota_begin failed err=0x%x!", err); + return false; + } else { + memcpy(&operate_partition, partition, sizeof(esp_partition_t)); + ESP_LOGI(TAG, "esp_ota_begin init OK"); + return true; + } + return false; +} + +void __attribute__((noreturn)) task_fatal_error() +{ + ESP_LOGE(TAG, "Exiting task due to fatal error..."); + close(socket_id); + (void)vTaskDelete(NULL); +} + +void main_task(void *pvParameter) +{ + esp_err_t err; + ESP_LOGI(TAG, "Starting OTA example..."); + /* Wait for the callback to set the CONNECTED_BIT in the + event group. + */ + xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, + false, true, portMAX_DELAY); + ESP_LOGI(TAG, "Connect to Wifi ! Start to Connect to Server...."); + + /*connect to http server*/ + if (connect_to_http_server()) { + ESP_LOGI(TAG, "Connected to http server"); + } else { + ESP_LOGE(TAG, "Connect to http server failed!"); + task_fatal_error(); + } + + int res = -1; + /*send GET request to http server*/ + res = send(socket_id, http_request, strlen(http_request), 0); + if (res == -1) { + ESP_LOGE(TAG, "Send GET request to server failed"); + task_fatal_error(); + } else { + ESP_LOGI(TAG, "Send GET request to server succeeded"); + } + + if ( ota_init() ) { + ESP_LOGI(TAG, "OTA Init succeeded"); + } else { + ESP_LOGE(TAG, "OTA Init failed"); + task_fatal_error(); + } + + bool pkg_body_start = false, flag = true; + /*deal with all receive packet*/ + while (flag) { + memset(text, 0, TEXT_BUFFSIZE); + memset(ota_write_data, 0, BUFFSIZE); + int buff_len = recv(socket_id, text, TEXT_BUFFSIZE, 0); + if (buff_len < 0) { /*receive error*/ + ESP_LOGE(TAG, "Error: receive data error! errno=%d", errno); + task_fatal_error(); + } else if (buff_len > 0 && !pkg_body_start) { /*deal with packet header*/ + memcpy(ota_write_data, text, buff_len); + pkg_body_start = resolve_pkg(text, buff_len, out_handle); + } else if (buff_len > 0 && pkg_body_start) { /*deal with packet body*/ + memcpy(ota_write_data, text, buff_len); + err = esp_ota_write( out_handle, (const void *)ota_write_data, buff_len); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Error: esp_ota_write failed! err=%x", err); + task_fatal_error(); + } + binary_file_length += buff_len; + ESP_LOGI(TAG, "Have written image length %d", binary_file_length); + } else if (buff_len == 0) { /*packet over*/ + flag = false; + ESP_LOGI(TAG, "Connection closed, all packets received"); + close(socket_id); + } else { + ESP_LOGE(TAG, "Unexpected recv result"); + } + } + + ESP_LOGI(TAG, "Total Write binary data length : %d", binary_file_length); + + if (esp_ota_end(out_handle) != ESP_OK) { + ESP_LOGE(TAG, "esp_ota_end failed!"); + task_fatal_error(); + } + err = esp_ota_set_boot_partition(&operate_partition); + if (err != ESP_OK) { + ESP_LOGE(TAG, "esp_ota_set_boot_partition failed! err=0x%x", err); + task_fatal_error(); + } + ESP_LOGI(TAG, "Prepare to restart system!"); + esp_restart(); + return ; +} + +void app_main() +{ + nvs_flash_init(); + initialise_wifi(); + xTaskCreate(&main_task, "main_task", 8192, NULL, 5, NULL); +} diff --git a/examples/18_ota/sdkconfig b/examples/18_ota/sdkconfig new file mode 100644 index 0000000000..070b529a05 --- /dev/null +++ b/examples/18_ota/sdkconfig @@ -0,0 +1,5 @@ +# Some sdkconfig parameters overriden from the defaults for this example, +# This file is in git but will be overwritten with the autogenerated file +# the first time "menuconfig" is run (changes ignored by git). +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_PARTITION_TABLE_TWO_OTA=y -- 2.40.0