serial_flash_example_main.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /* Serial flasher Example
  2. This example code is in the Public Domain (or CC0 licensed, at your option.)
  3. Unless required by applicable law or agreed to in writing, this
  4. software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  5. CONDITIONS OF ANY KIND, either express or implied.
  6. */
  7. #include <string.h>
  8. #include "esp_err.h"
  9. #include "esp_log.h"
  10. #include "esp_spiffs.h"
  11. #include "esp_loader.h"
  12. #include "serial_io.h"
  13. #include "driver/gpio.h"
  14. #include "driver/uart.h"
  15. #include <sys/param.h>
  16. static const char *TAG = "example";
  17. #ifndef TARGET_ESP8266
  18. const uint32_t BOOTLOADER_ADDRESS = 0x1000;
  19. #else
  20. const uint32_t BOOTLOADER_ADDRESS = 0x0;
  21. #endif
  22. const uint32_t PARTITION_ADDRESS = 0x8000;
  23. const uint32_t APPLICATION_ADDRESS = 0x10000;
  24. const uint32_t HIGHER_BAUD_RATE = 230400;
  25. static uint8_t payload[1024];
  26. #if defined TARGET_ESP8266
  27. #define PARTITION_FILE "/spiffs/ESP8266/partition-table.bin"
  28. #define BOOTLOADER_FILE "/spiffs/ESP8266/bootloader.bin"
  29. #define APPLICATION_FILE "/spiffs/ESP8266/hello-world.bin"
  30. #elif defined TARGET_ESP32
  31. #define PARTITION_FILE "/spiffs/ESP32/partition-table.bin"
  32. #define BOOTLOADER_FILE "/spiffs/ESP32/bootloader.bin"
  33. #define APPLICATION_FILE "/spiffs/ESP32/hello-world.bin"
  34. #elif defined TARGET_ESP32_S2
  35. #define PARTITION_FILE "/spiffs/ESP32_S2/partition-table.bin"
  36. #define BOOTLOADER_FILE "/spiffs/ESP32_S2/bootloader.bin"
  37. #define APPLICATION_FILE "/spiffs/ESP32_S2/hello-world.bin"
  38. #endif
  39. static void flash_binary(FILE *image, size_t image_size, size_t address)
  40. {
  41. esp_loader_error_t err;
  42. int32_t packet_number = 0;
  43. err = esp_loader_flash_start(address, image_size, sizeof(payload));
  44. if (err != ESP_LOADER_SUCCESS) {
  45. ESP_LOGE(TAG, "Flash start operation failed with error %d.", err);
  46. return;
  47. }
  48. ESP_LOGI(TAG, "Start programming");
  49. while (image_size > 0) {
  50. size_t to_read = MIN(image_size, sizeof(payload));
  51. size_t read = fread(payload, 1, to_read, image);
  52. if (read != to_read) {
  53. ESP_LOGE(TAG, "Error occurred while reading file.");
  54. return;
  55. }
  56. err = esp_loader_flash_write(payload, to_read);
  57. if (err != ESP_LOADER_SUCCESS) {
  58. ESP_LOGE(TAG, "Packet could not be written");
  59. return;
  60. }
  61. ESP_LOGI(TAG, "packet: %d written: %u B", packet_number++, to_read);
  62. image_size -= to_read;
  63. };
  64. ESP_LOGI(TAG, "Finished programming");
  65. #ifndef TARGET_ESP8266
  66. err = esp_loader_flash_verify();
  67. if (err != ESP_LOADER_SUCCESS) {
  68. ESP_LOGE(TAG, "MD5 does not match. err: %d", err);
  69. return;
  70. }
  71. #endif
  72. ESP_LOGI(TAG, "Flash verified");
  73. }
  74. static FILE *get_image_and_its_size(const char *path, size_t *image_size)
  75. {
  76. FILE *image = fopen(path, "r");
  77. if (image == NULL) {
  78. ESP_LOGE(TAG, "Failed to open file %s", path);
  79. esp_vfs_spiffs_unregister(NULL);
  80. return NULL;
  81. }
  82. fseek(image, 0L, SEEK_END);
  83. *image_size = ftell(image);
  84. rewind(image);
  85. ESP_LOGW(TAG, "File %s opened. Size: %u bytes", path, *image_size);
  86. return image;
  87. }
  88. static void upload_file(const char *path, size_t address)
  89. {
  90. size_t image_size;
  91. FILE *image = get_image_and_its_size(path, &image_size);
  92. if (image != NULL) {
  93. flash_binary(image, image_size, address);
  94. fclose(image);
  95. }
  96. }
  97. static esp_err_t connect_to_target()
  98. {
  99. const loader_serial_config_t config = {
  100. .baud_rate = 115200,
  101. .uart_port = UART_NUM_1,
  102. .uart_rx_pin = GPIO_NUM_5,
  103. .uart_tx_pin = GPIO_NUM_4,
  104. .reset_trigger_pin = GPIO_NUM_25,
  105. .gpio0_trigger_pin = GPIO_NUM_26,
  106. };
  107. // Initialize UART
  108. esp_loader_error_t err = loader_port_serial_init(&config);
  109. if (err != ESP_LOADER_SUCCESS) {
  110. ESP_LOGE(TAG, "serial initialization failed.");
  111. return err;
  112. }
  113. esp_loader_connect_args_t connect_config = ESP_LOADER_CONNECT_DEFAULT();
  114. err = esp_loader_connect(&connect_config);
  115. if (err != ESP_LOADER_SUCCESS) {
  116. ESP_LOGE(TAG, "Cannot connect to target. Error: %u", err);
  117. return err;
  118. }
  119. ESP_LOGI(TAG, "Connected to target");
  120. #ifndef TARGET_ESP8266
  121. err = esp_loader_change_baudrate(HIGHER_BAUD_RATE);
  122. if (err != ESP_LOADER_SUCCESS) {
  123. ESP_LOGE(TAG, "Unable to change baud rate on target.");
  124. return err;
  125. }
  126. err = loader_port_change_baudrate(HIGHER_BAUD_RATE);
  127. if (err != ESP_LOADER_SUCCESS) {
  128. ESP_LOGE(TAG, "Unable to change baud rate.");
  129. return err;
  130. }
  131. #endif
  132. return ESP_OK;
  133. }
  134. static esp_err_t register_vfs()
  135. {
  136. ESP_LOGI(TAG, "Initializing SPIFFS");
  137. esp_vfs_spiffs_conf_t conf = {
  138. .base_path = "/spiffs",
  139. .partition_label = NULL,
  140. .max_files = 5,
  141. .format_if_mount_failed = false
  142. };
  143. // Use settings defined above to initialize and mount SPIFFS filesystem.
  144. esp_err_t ret = esp_vfs_spiffs_register(&conf);
  145. if (ret != ESP_OK) {
  146. if (ret == ESP_FAIL) {
  147. ESP_LOGE(TAG, "Failed to mount or format filesystem");
  148. } else if (ret == ESP_ERR_NOT_FOUND) {
  149. ESP_LOGE(TAG, "Failed to find SPIFFS partition");
  150. } else {
  151. ESP_LOGE(TAG, "Failed to initialize SPIFFS (%s)", esp_err_to_name(ret));
  152. }
  153. }
  154. return ret;
  155. }
  156. void app_main(void)
  157. {
  158. if ( register_vfs() == ESP_OK ) {
  159. if ( connect_to_target() == ESP_OK) {
  160. upload_file(PARTITION_FILE, PARTITION_ADDRESS);
  161. upload_file(BOOTLOADER_FILE, BOOTLOADER_ADDRESS);
  162. upload_file(APPLICATION_FILE, APPLICATION_ADDRESS);
  163. }
  164. esp_vfs_spiffs_unregister(NULL);
  165. }
  166. }