ESP32 Native version of Blinky, featureful controller code for WS2811/WS2812/NeoPixels
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

170 行
3.8KB

  1. static const char *TAG = "ota";
  2. #include <esp_log.h>
  3. #include <esp_ota_ops.h>
  4. #include <lwip/apps/tftp_server.h>
  5. #include <freertos/FreeRTOS.h>
  6. #include <freertos/task.h>
  7. #include <cstring>
  8. #include "ota.hpp"
  9. // TODO: Stick this somewhere useful?
  10. static void reboot_soon_task(void*) {
  11. int delay_s = 1;
  12. ESP_LOGI(TAG, "Rebooting in %d second%s",
  13. delay_s, delay_s == 1 ? "" : "s");
  14. vTaskDelay(pdMS_TO_TICKS(delay_s * 1000));
  15. esp_restart();
  16. }
  17. static void reboot_soon() {
  18. xTaskCreate(
  19. reboot_soon_task, "reboot_task",
  20. configMINIMAL_STACK_SIZE * 2, // TODO: Choose the best size
  21. NULL, 1, NULL
  22. );
  23. }
  24. class OTA_Session {
  25. public:
  26. OTA_Session() :
  27. part(esp_ota_get_next_update_partition(NULL)),
  28. ota(0), failed(false), total_written(0)
  29. {
  30. if (!part) {
  31. ESP_LOGE(TAG, "Could not find update partition");
  32. failed = true;
  33. return;
  34. }
  35. auto err = esp_ota_begin(part, OTA_SIZE_UNKNOWN, &ota);
  36. if (err != ESP_OK) {
  37. ESP_LOGE(TAG, "esp_ota_begin: %d", err);
  38. failed = true;
  39. return;
  40. }
  41. }
  42. ~OTA_Session() {
  43. if (failed) {
  44. ESP_LOGE(TAG, "Aborting OTA due to previous failure");
  45. esp_ota_abort(ota);
  46. return;
  47. }
  48. ESP_LOGI(TAG, "Finalizing OTA (%d bytes)", total_written);
  49. auto err = esp_ota_end(ota);
  50. if (err != ESP_OK) {
  51. ESP_LOGE(TAG, "esp_ota_end: %d", err);
  52. esp_ota_abort(ota);
  53. return;
  54. }
  55. ESP_LOGI(TAG, "Setting new boot partition");
  56. err = esp_ota_set_boot_partition(part);
  57. if (err != ESP_OK) {
  58. ESP_LOGE(TAG, "esp_ota_set_boot_partition: %d", err);
  59. return;
  60. }
  61. ESP_LOGI(TAG, "OTA Successful");
  62. reboot_soon();
  63. }
  64. bool write(const void *data, int len) {
  65. if (failed) return false;
  66. auto err = esp_ota_write(ota, data, len);
  67. if (err != ESP_OK) {
  68. ESP_LOGE(TAG, "esp_ota_write(%d): %d", len, err);
  69. failed = true;
  70. return false;
  71. }
  72. total_written += len;
  73. return true;
  74. }
  75. private:
  76. const esp_partition_t* part;
  77. esp_ota_handle_t ota;
  78. bool failed;
  79. int total_written;
  80. };
  81. static void* ota_open(const char *filename, const char *mode, u8_t write) {
  82. if (strcmp(mode, "octet") != 0) {
  83. ESP_LOGE(TAG, "Unexpected mode: %s", mode);
  84. return NULL;
  85. }
  86. if (strcmp(filename, "blinky.bin") != 0) {
  87. ESP_LOGE(TAG, "Unexpected filename: %s", mode);
  88. return NULL;
  89. }
  90. if (!write) {
  91. ESP_LOGE(TAG, "Illegal read attempt");
  92. return NULL;
  93. }
  94. ESP_LOGI(TAG, "Starting OTA");
  95. return new OTA_Session();
  96. }
  97. static void ota_close(void* handle) {
  98. OTA_Session *session = (OTA_Session*)handle;
  99. if (session) delete session;
  100. else ESP_LOGE(TAG, "Attempt to close invalid session");
  101. }
  102. static int ota_read(void* handle, void* buf, int len) {
  103. ESP_LOGE(TAG, "Super illegal read of %d bytes", len);
  104. return -1;
  105. }
  106. static int ota_write(void* handle, struct pbuf* p) {
  107. OTA_Session *session = (OTA_Session*)handle;
  108. if (!session) {
  109. ESP_LOGE(TAG, "Attempt to write to invalid session");
  110. return -1;
  111. }
  112. for (; p; p = p->next) {
  113. if (!session->write(p->payload, p->len)) {
  114. ESP_LOGE(TAG, "Failed to write %d bytes", p->len);
  115. return -1;
  116. }
  117. }
  118. return 0;
  119. }
  120. static tftp_context ota_context = {
  121. .open = ota_open,
  122. .close = ota_close,
  123. .read = ota_read,
  124. .write = ota_write
  125. };
  126. int start_ota_serv() {
  127. ESP_LOGI(TAG, "Starting OTA server");
  128. ESP_ERROR_CHECK(tftp_init(&ota_context));
  129. return 0;
  130. }
  131. int stop_ota_serv() {
  132. tftp_cleanup();
  133. return 0;
  134. }