ESP32 Native version of Blinky, featureful controller code for WS2811/WS2812/NeoPixels
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

149 wiersze
3.3KB

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