example_common.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /* Copyright 2020-2023 Espressif Systems (Shanghai) CO LTD
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <inttypes.h>
  19. #include <sys/param.h>
  20. #include "esp_loader_io.h"
  21. #include "esp_loader.h"
  22. #include "example_common.h"
  23. #ifndef SINGLE_TARGET_SUPPORT
  24. // For esp8266, esp32, esp32s2
  25. #define BOOTLOADER_ADDRESS_V0 0x1000
  26. // For esp32s3 and later chips
  27. #define BOOTLOADER_ADDRESS_V1 0x0
  28. #define PARTITION_ADDRESS 0x8000
  29. #define APPLICATION_ADDRESS 0x10000
  30. extern const uint8_t ESP32_bootloader_bin[];
  31. extern const uint32_t ESP32_bootloader_bin_size;
  32. extern const uint8_t ESP32_hello_world_bin[];
  33. extern const uint32_t ESP32_hello_world_bin_size;
  34. extern const uint8_t ESP32_partition_table_bin[];
  35. extern const uint32_t ESP32_partition_table_bin_size;
  36. extern const uint8_t ESP32_S2_bootloader_bin[];
  37. extern const uint32_t ESP32_S2_bootloader_bin_size;
  38. extern const uint8_t ESP32_S2_hello_world_bin[];
  39. extern const uint32_t ESP32_S2_hello_world_bin_size;
  40. extern const uint8_t ESP32_S2_partition_table_bin[];
  41. extern const uint32_t ESP32_S2_partition_table_bin_size;
  42. extern const uint8_t ESP8266_bootloader_bin[];
  43. extern const uint32_t ESP8266_bootloader_bin_size;
  44. extern const uint8_t ESP8266_hello_world_bin[];
  45. extern const uint32_t ESP8266_hello_world_bin_size;
  46. extern const uint8_t ESP8266_partition_table_bin[];
  47. extern const uint32_t ESP8266_partition_table_bin_size;
  48. extern const uint8_t ESP32_H4_bootloader_bin[];
  49. extern const uint32_t ESP32_H4_bootloader_bin_size;
  50. extern const uint8_t ESP32_H4_hello_world_bin[];
  51. extern const uint32_t ESP32_H4_hello_world_bin_size;
  52. extern const uint8_t ESP32_H4_partition_table_bin[];
  53. extern const uint32_t ESP32_H4_partition_table_bin_size;
  54. void get_example_binaries(target_chip_t target, example_binaries_t *bins)
  55. {
  56. if (target == ESP8266_CHIP) {
  57. bins->boot.data = ESP8266_bootloader_bin;
  58. bins->boot.size = ESP8266_bootloader_bin_size;
  59. bins->boot.addr = BOOTLOADER_ADDRESS_V0;
  60. bins->part.data = ESP8266_partition_table_bin;
  61. bins->part.size = ESP8266_partition_table_bin_size;
  62. bins->part.addr = PARTITION_ADDRESS;
  63. bins->app.data = ESP8266_hello_world_bin;
  64. bins->app.size = ESP8266_hello_world_bin_size;
  65. bins->app.addr = APPLICATION_ADDRESS;
  66. } else if (target == ESP32_CHIP) {
  67. bins->boot.data = ESP32_bootloader_bin;
  68. bins->boot.size = ESP32_bootloader_bin_size;
  69. bins->boot.addr = BOOTLOADER_ADDRESS_V0;
  70. bins->part.data = ESP32_partition_table_bin;
  71. bins->part.size = ESP32_partition_table_bin_size;
  72. bins->part.addr = PARTITION_ADDRESS;
  73. bins->app.data = ESP32_hello_world_bin;
  74. bins->app.size = ESP32_hello_world_bin_size;
  75. bins->app.addr = APPLICATION_ADDRESS;
  76. } else if (target == ESP32S2_CHIP) {
  77. bins->boot.data = ESP32_S2_bootloader_bin;
  78. bins->boot.size = ESP32_S2_bootloader_bin_size;
  79. bins->boot.addr = BOOTLOADER_ADDRESS_V0;
  80. bins->part.data = ESP32_S2_partition_table_bin;
  81. bins->part.size = ESP32_S2_partition_table_bin_size;
  82. bins->part.addr = PARTITION_ADDRESS;
  83. bins->app.data = ESP32_S2_hello_world_bin;
  84. bins->app.size = ESP32_S2_hello_world_bin_size;
  85. bins->app.addr = APPLICATION_ADDRESS;
  86. } else if (target == ESP32H4_CHIP){
  87. bins->boot.data = ESP32_H4_bootloader_bin;
  88. bins->boot.size = ESP32_H4_bootloader_bin_size;
  89. bins->boot.addr = BOOTLOADER_ADDRESS_V1;
  90. bins->part.data = ESP32_H4_partition_table_bin;
  91. bins->part.size = ESP32_H4_partition_table_bin_size;
  92. bins->part.addr = PARTITION_ADDRESS;
  93. bins->app.data = ESP32_H4_hello_world_bin;
  94. bins->app.size = ESP32_H4_hello_world_bin_size;
  95. bins->app.addr = APPLICATION_ADDRESS;
  96. } else {
  97. abort();
  98. }
  99. }
  100. extern const uint8_t ESP32_H4_app_bin[];
  101. extern const uint32_t ESP32_H4_app_bin_size;
  102. void get_example_ram_app_binary(target_chip_t target, example_ram_app_binary_t *bin)
  103. {
  104. if (target == ESP32H4_CHIP){
  105. bin->ram_app.data = ESP32_H4_app_bin;
  106. bin->ram_app.size = ESP32_H4_app_bin_size;
  107. } else {
  108. abort();
  109. }
  110. }
  111. #endif
  112. esp_loader_error_t connect_to_target(uint32_t higher_transmission_rate)
  113. {
  114. esp_loader_connect_args_t connect_config = ESP_LOADER_CONNECT_DEFAULT();
  115. esp_loader_error_t err = esp_loader_connect(&connect_config);
  116. if (err != ESP_LOADER_SUCCESS) {
  117. printf("Cannot connect to target. Error: %u\n", err);
  118. return err;
  119. }
  120. printf("Connected to target\n");
  121. if (higher_transmission_rate && esp_loader_get_target() != ESP8266_CHIP) {
  122. err = esp_loader_change_transmission_rate(higher_transmission_rate);
  123. if (err == ESP_LOADER_ERROR_UNSUPPORTED_FUNC) {
  124. printf("ESP8266 does not support change transmission rate command.");
  125. return err;
  126. } else if (err != ESP_LOADER_SUCCESS) {
  127. printf("Unable to change transmission rate on target.");
  128. return err;
  129. } else {
  130. err = loader_port_change_transmission_rate(higher_transmission_rate);
  131. if (err != ESP_LOADER_SUCCESS) {
  132. printf("Unable to change transmission rate.");
  133. return err;
  134. }
  135. printf("Transmission rate changed changed\n");
  136. }
  137. }
  138. return ESP_LOADER_SUCCESS;
  139. }
  140. esp_loader_error_t flash_binary(const uint8_t *bin, size_t size, size_t address)
  141. {
  142. esp_loader_error_t err;
  143. static uint8_t payload[1024];
  144. const uint8_t *bin_addr = bin;
  145. printf("Erasing flash (this may take a while)...\n");
  146. err = esp_loader_flash_start(address, size, sizeof(payload));
  147. if (err != ESP_LOADER_SUCCESS) {
  148. printf("Erasing flash failed with error %d.\n", err);
  149. return err;
  150. }
  151. printf("Start programming\n");
  152. size_t binary_size = size;
  153. size_t written = 0;
  154. while (size > 0) {
  155. size_t to_read = MIN(size, sizeof(payload));
  156. memcpy(payload, bin_addr, to_read);
  157. err = esp_loader_flash_write(payload, to_read);
  158. if (err != ESP_LOADER_SUCCESS) {
  159. printf("\nPacket could not be written! Error %d.\n", err);
  160. return err;
  161. }
  162. size -= to_read;
  163. bin_addr += to_read;
  164. written += to_read;
  165. int progress = (int)(((float)written / binary_size) * 100);
  166. printf("\rProgress: %d %%", progress);
  167. fflush(stdout);
  168. };
  169. printf("\nFinished programming\n");
  170. #if MD5_ENABLED
  171. err = esp_loader_flash_verify();
  172. if (err == ESP_LOADER_ERROR_UNSUPPORTED_FUNC) {
  173. printf("ESP8266 does not support flash verify command.");
  174. return err;
  175. } else if (err != ESP_LOADER_SUCCESS) {
  176. printf("MD5 does not match. err: %d\n", err);
  177. return err;
  178. }
  179. printf("Flash verified\n");
  180. #endif
  181. return ESP_LOADER_SUCCESS;
  182. }
  183. esp_loader_error_t load_ram_binary(const uint8_t *bin)
  184. {
  185. printf("Start loading\n");
  186. esp_loader_error_t err;
  187. const example_bin_header_t *header = (const example_bin_header_t *)bin;
  188. example_bin_segment_t segments[header->segments];
  189. // Parse segments
  190. uint32_t seg;
  191. uint32_t *cur_seg_pos;
  192. for (seg=0, cur_seg_pos = (uint32_t *)(&bin[BIN_FIRST_SEGMENT_OFFSET]);
  193. seg < header->segments;
  194. seg++) {
  195. segments[seg].addr = *cur_seg_pos++;
  196. segments[seg].size = *cur_seg_pos++;
  197. segments[seg].data = (uint8_t *)cur_seg_pos;
  198. cur_seg_pos += (segments[seg].size) / 4;
  199. }
  200. // Download segments
  201. for (seg=0; seg < header->segments; seg++) {
  202. printf("Downloading %"PRIu32" bytes at 0x%08"PRIx32"...\n", segments[seg].size, segments[seg].addr);
  203. err = esp_loader_mem_start(segments[seg].addr, segments[seg].size, ESP_RAM_BLOCK);
  204. if (err != ESP_LOADER_SUCCESS) {
  205. printf("Loading ram start with error %d.\n", err);
  206. return err;
  207. }
  208. size_t remain_size = segments[seg].size;
  209. uint8_t *data_pos = segments[seg].data;
  210. while(remain_size > 0) {
  211. size_t data_size = MIN(ESP_RAM_BLOCK, remain_size);
  212. err = esp_loader_mem_write(data_pos, data_size);
  213. if (err != ESP_LOADER_SUCCESS) {
  214. printf("\nPacket could not be written! Error %d.\n", err);
  215. return err;
  216. }
  217. data_pos += data_size;
  218. remain_size -= data_size;
  219. }
  220. }
  221. err = esp_loader_mem_finish(header->entrypoint);
  222. if (err != ESP_LOADER_SUCCESS) {
  223. printf("\nLoad ram finish with Error %d.\n", err);
  224. return err;
  225. }
  226. printf("\nFinished loading\n");
  227. return ESP_LOADER_SUCCESS;
  228. }