Просмотр исходного кода

Merge branch 'examples' into 'master'

Added examples

See merge request espressif/esp-serial-flasher!2
Martin Válik 6 лет назад
Родитель
Сommit
ac4c81d654

+ 1 - 1
CMakeLists.txt

@@ -15,4 +15,4 @@ endif()
 
 
 register_component()
 register_component()
 
 
-component_compile_options(-Wstrict-prototypes)
+component_compile_options(-Wstrict-prototypes)

+ 8 - 0
example/CMakeLists.txt

@@ -0,0 +1,8 @@
+# The following lines of boilerplate have to be in your project's CMakeLists
+# in this exact order for cmake to work correctly
+cmake_minimum_required(VERSION 3.5)
+
+set(EXTRA_COMPONENT_DIRS ../)
+
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+project(esp-serial-flasher)

+ 63 - 0
example/README.md

@@ -0,0 +1,63 @@
+# Serial flash example
+
+## Overview
+
+Example demonstrates how to flash ESP32 from another (host) MCU using esp_serial_flash component API. In this case, ESP32 is also used as host MCU. Binary to be flashed from one ESP32 to another is stored in partition named `spiffs`.
+
+This example is based on spiffsgen example located in IDF. For more information how to use SPIFFS Image Generator, refer to [spiffsgen example](https://github.com/espressif/esp-idf/tree/master/examples/storage/spiffsgen)
+
+Following steps are performed in order to re-program target's memory:
+
+1. UART1 through which new binary will be transfered is initialized.
+2. Filesystem is initialized and mounted.
+3. Binary file is opened and its size is acquired, as it has to be known before flashing.
+4. Host puts slave device into boot mode tries to connect by calling `loader_connect()`.
+5. Then `loader_flash_start()` is called to enter flashing mode.
+6. `loader_flash_write()` function is called repeatedly until the whole binary image is transfered.
+
+## Hardware Required
+
+* Two development boards with ESP32 SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.).
+* A USB cable for power supply and programming.
+
+## Hardware connection
+
+Table below shows connection between two ESP32 devices.
+
+| ESP32 (host) | ESP32 (slave) |
+|:------------:|:-------------:|
+|    IO26      |      IO0      |
+|    IO25      |     RESET     |
+|    IO4       |      RX0      |
+|    IO5       |      TX0      |
+
+
+### Build and flash
+
+To run the example, type the following command:
+
+```CMake
+idf.py -p PORT flash monitor
+```
+
+(To exit the serial monitor, type ``Ctrl-]``.)
+
+See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
+
+## Example output
+
+Here is the example's console output:
+
+```
+...
+I (342) example: Initializing SPIFFS
+I (482) example: Image size: 144672
+I (902) example: Connected to target
+I (1732) example: Start programming
+I (1832) example: packet: 0  written: 1024 B
+I (1932) example: packet: 1  written: 1024 B
+...
+I (16052) example: packet: 140  written: 1024 B
+I (16152) example: packet: 141  written: 288 B
+I (16152) example: Finished programming
+```

+ 8 - 0
example/main/CMakeLists.txt

@@ -0,0 +1,8 @@
+idf_component_register(SRCS "serial_flash_example_main.c"
+                    INCLUDE_DIRS ".")
+
+# Create a SPIFFS image from the contents of the 'spiffs_image' directory
+# that fits the partition named 'storage'. FLASH_IN_PROJECT indicates that
+# the generated image should be flashed when the entire project is flashed to
+# the target with 'idf.py -p PORT flash'. 
+spiffs_create_partition_image(storage ../spiffs_image FLASH_IN_PROJECT)

+ 131 - 0
example/main/serial_flash_example_main.c

@@ -0,0 +1,131 @@
+/* Serial flasher Example
+
+   This example code is in the Public Domain (or CC0 licensed, at your option.)
+
+   Unless required by applicable law or agreed to in writing, this
+   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+   CONDITIONS OF ANY KIND, either express or implied.
+*/
+
+#include <string.h>
+#include "esp_err.h"
+#include "esp_log.h"
+#include "esp_spiffs.h"
+#include "esp_loader.h"
+#include "serial_io.h"
+#include <sys/param.h>
+
+
+static const char *TAG = "example";
+
+const uint32_t APP_START_ADDRESS = 0x10000;
+static char payload[1024];
+
+
+static void flash_binary(FILE *image, size_t image_size)
+{
+    esp_loader_error_t err;
+    int32_t packet_number = 0;
+    esp_loader_connect_args_t connect_config = ESP_LOADER_CONNECT_DEFAULT();
+
+    err = esp_loader_connect(&connect_config);
+    if (err != ESP_LOADER_SUCCESS) {
+        ESP_LOGE(TAG, "Cannot connect to target.");
+        return;
+    }
+    ESP_LOGI(TAG, "Connected to target");
+
+    err = esp_loader_flash_start(APP_START_ADDRESS, image_size, sizeof(payload));
+    if (err != ESP_LOADER_SUCCESS) {
+        ESP_LOGE(TAG, "Flash start operation failed.");
+        return;
+    }
+    ESP_LOGI(TAG, "Start programming");
+
+    while (image_size > 0) {
+        size_t to_read = MIN(image_size, sizeof(payload));
+
+        size_t read = fread(payload, 1, to_read, image);
+        if (read != to_read) {
+            ESP_LOGE(TAG, "Error occurred while reading file.");
+            return;
+        }
+
+        err = esp_loader_flash_write(payload, to_read);
+        if (err != ESP_LOADER_SUCCESS) {
+            ESP_LOGE(TAG, "Packet could not be written");
+            return;
+        }
+
+        ESP_LOGI(TAG, "packet: %d  written: %u B", packet_number++, to_read);
+
+        image_size -= to_read;
+    };
+
+    ESP_LOGI(TAG, "Finished programming");
+}
+
+
+static FILE *get_image_and_its_size(size_t *image_size)
+{
+    ESP_LOGI(TAG, "Initializing SPIFFS");
+
+    esp_vfs_spiffs_conf_t conf = {
+        .base_path = "/spiffs",
+        .partition_label = NULL,
+        .max_files = 5,
+        .format_if_mount_failed = false
+    };
+
+    // Use settings defined above to initialize and mount SPIFFS filesystem.
+    esp_err_t ret = esp_vfs_spiffs_register(&conf);
+
+    if (ret != ESP_OK) {
+        if (ret == ESP_FAIL) {
+            ESP_LOGE(TAG, "Failed to mount or format filesystem");
+        } else if (ret == ESP_ERR_NOT_FOUND) {
+            ESP_LOGE(TAG, "Failed to find SPIFFS partition");
+        } else {
+            ESP_LOGE(TAG, "Failed to initialize SPIFFS (%s)", esp_err_to_name(ret));
+        }
+        return NULL;
+    }
+
+    FILE *image = fopen("/spiffs/hello-world.bin", "r");
+    if (image == NULL) {
+        ESP_LOGE(TAG, "Failed to open file");
+        esp_vfs_spiffs_unregister(NULL);
+        return NULL;
+    }
+
+    fseek(image, 0L, SEEK_END);
+    *image_size = ftell(image);
+    rewind(image);
+
+    ESP_LOGI(TAG, "Image size: %u", *image_size);
+
+    return image;
+}
+
+
+void app_main(void)
+{
+    // Initialize UART
+    esp_loader_error_t err = loader_port_serial_init(115200);
+    if (err != ESP_LOADER_SUCCESS) {
+        ESP_LOGE(TAG, "serial initialization failed.");
+        return;
+    }
+
+    size_t image_size;
+    FILE *image = get_image_and_its_size(&image_size);
+    if (image == NULL) {
+        return;
+    }
+
+    flash_binary(image, image_size);
+
+    // All done, close file, unmount partition and disable SPIFFS
+    fclose(image);
+    esp_vfs_spiffs_unregister(NULL);
+}

+ 6 - 0
example/partitions_example.csv

@@ -0,0 +1,6 @@
+# Name,   Type, SubType, Offset,  Size, Flags
+# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
+nvs,      data, nvs,     0x9000,  0x6000,
+phy_init, data, phy,     0xf000,  0x1000,
+factory,  app,  factory, 0x10000, 1M,
+storage,  data, spiffs,  ,        0xF0000, 

+ 3 - 0
example/sdkconfig.defaults

@@ -0,0 +1,3 @@
+CONFIG_PARTITION_TABLE_CUSTOM=y
+CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_example.csv"
+CONFIG_PARTITION_TABLE_FILENAME="partitions_example.csv"

BIN
example/spiffs_image/hello-world.bin