From ae2828c6bdcda0d256f2e956ab34114e8f7cdd21 Mon Sep 17 00:00:00 2001 From: Alexey Zholtikov Date: Sun, 30 Aug 2026 16:53:29 +0300 Subject: [PATCH] doc: updated readme --- README.md | 48 ++++++++--- WIKI_EN.md | 231 ----------------------------------------------------- WIKI_RU.md | 231 ----------------------------------------------------- 3 files changed, 37 insertions(+), 473 deletions(-) delete mode 100644 WIKI_EN.md delete mode 100644 WIKI_RU.md diff --git a/README.md b/README.md index ec5a85b..8cde786 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,5 @@ # ESP32 ESP-IDF component for simple OTA server -## Wiki - -[EN](WIKI_EN.md) | [RU](WIKI_RU.md) - -## Tested on - -1. [ESP32 ESP-IDF v6.0.0](https://docs.espressif.com/projects/esp-idf/en/v6.0/esp32/index.html) - ## SAST Tools [PVS-Studio](https://pvs-studio.com/pvs-studio/?utm_source=website&utm_medium=github&utm_campaign=open_source) - static analyzer for C, C++, C#, and Java code. @@ -27,7 +19,7 @@ In an existing project, run the following command to install the component: -```text +```bash cd ../your_project/components git clone https://github.com/aZholtikov/zh_ota_server ``` @@ -38,6 +30,40 @@ In the application, include the header: #include "zh_ota_server.h" ``` -## Examples +## Example -See Wiki [EN](WIKI_EN.md#usage-examples) | [RU](WIKI_RU.md#примеры-использования) +```c +#include "nvs_flash.h" +#include "esp_wifi.h" +#include "zh_ota_server.h" + +#define WIFI_SSID "SSID" +#define WIFI_PASS "password" + +static httpd_handle_t http_server_handle = NULL; + +void app_main(void) +{ + esp_log_level_set("zh_ota_server", ESP_LOG_ERROR); + nvs_flash_init(); + esp_event_loop_create_default(); + esp_netif_init(); + esp_netif_create_default_wifi_ap(); + wifi_init_config_t wifi_config = WIFI_INIT_CONFIG_DEFAULT(); + esp_wifi_init(&wifi_config); + wifi_config_t ap_config = { + .ap = { + .ssid = WIFI_SSID, + .password = WIFI_PASS, + .max_connection = 4, + .authmode = WIFI_AUTH_WPA2_PSK, + }, + }; + esp_wifi_set_mode(WIFI_MODE_AP); + esp_wifi_set_config(WIFI_IF_AP, &ap_config); + esp_wifi_start(); + httpd_config_t config = HTTPD_DEFAULT_CONFIG(); + httpd_start(&http_server_handle, &config); + zh_ota_server_init(http_server_handle, "/ota"); +} +``` diff --git a/WIKI_EN.md b/WIKI_EN.md deleted file mode 100644 index f06b949..0000000 --- a/WIKI_EN.md +++ /dev/null @@ -1,231 +0,0 @@ -# zh_ota_server — OTA Firmware Update Server Component for ESP-IDF - -## Table of Contents - -- [Overview](#overview) -- [Features](#features) -- [Installation](#installation) -- [API Reference](#api-reference) -- [Usage Examples](#usage-examples) -- [Technical Specifications](#technical-specifications) -- [Error Codes](#error-codes) -- [Contributing](#contributing) -- [License](#license) - ---- - -## Overview - -`zh_ota_server` is a lightweight Over-the-Air (OTA) firmware update server component for ESP-IDF (Espressif IoT Development Framework) designed for ESP32 microcontrollers. The component provides an HTTP-based server that accepts firmware binary updates via POST requests, writes them to the next available OTA partition, and automatically activates the new firmware. - -The component handles the entire OTA workflow: receiving firmware data in chunks, flashing it to flash memory, validating the update, setting the boot partition, and rebooting the device. A web interface is embedded as a binary resource for convenient firmware uploads through a browser. - -This component is ideal for devices deployed in the field that need remote firmware updates without physical access. - ---- - -## Features - -1. **HTTP-based OTA Updates**: Firmware upload via standard HTTP POST requests -2. **Automatic Partition Management**: Automatic detection and use of the next available OTA partition -3. **Embedded Web Interface**: Built-in HTML page for browser-based firmware uploads -4. **Automatic Boot Activation**: Device reboots and boots from the new partition after successful update -5. **Chunked Data Reception**: Efficient handling of firmware data in 1000-byte chunks -6. **ESP-IDF Integration**: Seamless integration with ESP-IDF HTTP server and OTA APIs -7. **Error Handling**: Comprehensive error checking with detailed ESP_LOGE logging -8. **Low Memory Footprint**: Minimal RAM usage with local buffering - ---- - -## Installation - -Navigate to your project's components directory: - -```bash -cd ../your_project/components -``` - -Clone the repository: - -```bash -git clone https://github.com/aZholtikov/zh_ota_server -``` - -In your application, include the header: - -```c -#include "zh_ota_server.h" -``` - -The component will be automatically built with your project. - ---- - -## API Reference - -### zh_ota_server_init() - -Initializes and registers the OTA server with the ESP-IDF HTTP server instance. - -**Parameters:** - -- `server` - HTTP server handle obtained from httpd_start(). Must not be NULL -- `path` - URI path for the OTA server endpoints (e.g., "/ota"). - -**Returns:** - -- `ESP_OK` - OTA server successfully initialized and registered -- `ESP_ERR_INVALID_ARG` - Invalid server handle or path (NULL pointer) -- `ESP_ERR_NO_MEM` - Memory allocation failed for the path storage -- `ESP_FAIL` - Failed to register the URI handler with the HTTP server - -**Example:** - -```c -httpd_handle_t http_server_handle = NULL; -httpd_config_t config = HTTPD_DEFAULT_CONFIG(); -httpd_start(&http_server_handle, &config); -zh_ota_server_init(http_server_handle, "/ota"); -``` - -**Note:** The path string is copied internally and managed by the component. The caller must not free or modify the path after this function returns. - -**Warning:** Memory allocated for the path is never freed. Call this function only once during the application lifetime. - ---- - -## Usage Examples - -### Basic OTA Server Setup - -This example shows how to set up a Wi-Fi Access Point and start the OTA server: - -```c -#include "nvs_flash.h" -#include "esp_wifi.h" -#include "zh_ota_server.h" - -#define WIFI_SSID "MyDevice" -#define WIFI_PASS "secure_password" - -static httpd_handle_t http_server_handle = NULL; - -void app_main(void) -{ - esp_log_level_set("zh_ota_server", ESP_LOG_ERROR); - // Initialize NVS and Wi-Fi - nvs_flash_init(); - esp_event_loop_create_default(); - esp_netif_init(); - esp_netif_create_default_wifi_ap(); - // Configure Wi-Fi AP - wifi_init_config_t wifi_config = WIFI_INIT_CONFIG_DEFAULT(); - esp_wifi_init(&wifi_config); - wifi_config_t ap_config = { - .ap = { - .ssid = WIFI_SSID, - .password = WIFI_PASS, - .max_connection = 4, - .authmode = WIFI_AUTH_WPA2_PSK, - }, - }; - esp_wifi_set_mode(WIFI_MODE_AP); - esp_wifi_set_config(WIFI_IF_AP, &ap_config); - esp_wifi_start(); - // Start HTTP server and register OTA handler - httpd_config_t config = HTTPD_DEFAULT_CONFIG(); - httpd_start(&http_server_handle, &config); - zh_ota_server_init(http_server_handle, "/ota"); -} -``` - -### Remote Firmware Update Workflow - -The typical firmware update workflow: - -1. Device boots in Access Point mode (SSID: "MyDevice", IP: 192.168.4.1) -2. User connects via Wi-Fi to the device -3. User opens a browser and navigates to -4. User selects a firmware binary file (.bin) -5. Device receives, validates, and flashes the firmware -6. Device reboots and boots from the new partition - ---- - -## Technical Specifications - -| Parameter | Value | -| ----------- | ------- | -| **Max Firmware Size** | Limited by available OTA partition size | -| **Buffer Size** | 1000 bytes per chunk | -| **Memory Caps** | MALLOC_CAP_8BIT | -| **Thread Safety** | Not thread-safe | -| **ESP-IDF Version** | >= 5.0 | -| **Platform** | ESP32 series | -| **Language** | C (C99) | -| **Dependencies** | esp_http_server, esp_ota_ops, esp_log | - ---- - -## Error Codes - -| Error Code | Description | -| ------------ | ---------- | -| `ESP_OK` | Operation completed successfully | -| `ESP_ERR_INVALID_ARG` | Invalid argument (NULL server handle or path) | -| `ESP_ERR_NO_MEM` | Memory allocation failed (no free heap) | -| `ESP_FAIL` | General failure (URI registration, OTA operation, or HTTP response) | - ---- - -## Contributing - -Contributions are welcome! To contribute: - -1. Fork the repository -2. Create a feature branch (`git checkout -b feature/AmazingFeature`) -3. Commit your changes (`git commit -m 'Add some AmazingFeature'`) -4. Push to the branch (`git push origin feature/AmazingFeature`) -5. Open a Pull Request - -Please ensure your code follows the existing style and includes appropriate documentation. - ---- - -## License - -This project is licensed under the Apache License, Version 2.0 - see the [LICENSE](LICENSE) file for details. - -### Apache License, Version 2.0 - -Copyright (c) 2026 Alexey Zholtikov - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - ---- - -## Additional Notes - -- **Memory Management**: The URI path is allocated once during initialization and never freed. This is acceptable for embedded systems with stable memory availability -- **Security**: This component provides no authentication or encryption. Use in a trusted network environment only. For production, add HTTPS and authentication -- **Device Bricking Risk**: Flashing an invalid or corrupted firmware image will make the device unbootable until a valid image is flashed via another mechanism (e.g., UART bootloader) -- **Best Practices**: - - Always validate firmware checksums before flashing - - Implement a fallback mechanism (e.g., dual-bank OTA with backup) - - Add authentication to prevent unauthorized firmware uploads - - Consider adding a rollback feature in case of failed updates - - Monitor free heap memory before starting large OTA transfers - ---- - -*Generated for zh_ota_server v1.0.0* diff --git a/WIKI_RU.md b/WIKI_RU.md deleted file mode 100644 index 897bc63..0000000 --- a/WIKI_RU.md +++ /dev/null @@ -1,231 +0,0 @@ -# zh_ota_server — Компонент OTA-сервера для обновления прошивки в ESP-IDF - -## Содержание - -- [Обзор](#обзор) -- [Возможности](#возможности) -- [Установка](#установка) -- [Справочник API](#справочник-api) -- [Примеры использования](#примеры-использования) -- [Технические характеристики](#технические-характеристики) -- [Коды ошибок](#коды-ошибок) -- [Вклад в проект](#вклад-в-проект) -- [Лицензия](#лицензия) - ---- - -## Обзор - -`zh_ota_server` — это легковесный компонент для обновления прошивки по воздуху (OTA — Over-the-Air) для ESP-IDF (Espressif IoT Development Framework), разработанный для микроконтроллеров ESP32. Компонент предоставляет HTTP-сервер, который принимает бинарные файлы прошивки через POST-запросы, записывает их в следующий доступный OTA-раздел и автоматически активирует новую прошивку. - -Компонент обрабатывает весь процесс OTA: приём данных прошивки кусками, запись во флеш-память, валидацию обновления, установку загрузочного раздела и перезагрузку устройства. Встроенный веб-интерфейс предоставляет удобный интерфейс для загрузки прошивки через браузер. - -Этот компонент идеален для устройств, размещённых на объектах и нуждающихся в удалённом обновлении прошивки без физического доступа. - ---- - -## Возможности - -1. **OTA-обновления через HTTP**: Загрузка прошивки через стандартные HTTP POST-запросы -2. **Автоматическое управление разделами**: Автоматическое определение и использование следующего доступного OTA-раздела -3. **Встроенный веб-интерфейс**: Встроенная HTML-страница для загрузки прошивки через браузер -4. **Автоматическая активация загрузки**: Устройство перезагружается и загружается с нового раздела после успешного обновления -5. **Приём данных частями**: Эффективная обработка данных прошивки блоками по 1000 байт -6. **Интеграция с ESP-IDF**: Бесшовная интеграция с HTTP-сервером и OTA-API ESP-IDF -7. **Обработка ошибок**: Комплексная проверка ошибок с детальным логированием через ESP_LOGE -8. **Минимальное потребление памяти**: Низкое использование ОЗУ с локальным буферизированием - ---- - -## Установка - -Перейдите в каталог компонентов вашего проекта: - -```bash -cd ../ваш_проект/components -``` - -Клонируйте репозиторий: - -```bash -git clone https://github.com/aZholtikov/zh_ota_server -``` - -В вашем приложении подключите заголовочный файл: - -```c -#include "zh_ota_server.h" -``` - -Компонент будет автоматически собран вместе с вашим проектом. - ---- - -## Справочник API - -### zh_ota_server_init() - -Инициализирует и регистрирует OTA-сервер в экземпляре HTTP-сервера ESP-IDF. - -**Параметры:** - -- `server` — дескриптор HTTP-сервера, полученный из httpd_start(). Не должен быть NULL -- `path` — URI-путь для endpoints OTA-сервера (например, "/ota") - -**Возвращает:** - -- `ESP_OK` — OTA-сервер успешно инициализирован и зарегистрирован -- `ESP_ERR_INVALID_ARG` — Неверный дескриптор или путь (NULL-указатель) -- `ESP_ERR_NO_MEM` — Не удалось выделить память для хранения пути -- `ESP_FAIL` — Не удалось зарегистрировать URI-обработчик в HTTP-сервере - -**Пример:** - -```c -httpd_handle_t http_server_handle = NULL; -httpd_config_t config = HTTPD_DEFAULT_CONFIG(); -httpd_start(&http_server_handle, &config); -zh_ota_server_init(http_server_handle, "/ota"); -``` - -**Примечание:** Строка пути копируется внутри компонента и управляется им. Вызывающая сторона не должна освобождать или изменять путь после возвращения этой функции. - -**Предупреждение:** Память, выделенная для пути, никогда не освобождается. Вызывайте эту функцию только один раз за время работы приложения. - ---- - -## Примеры использования - -### Базовая настройка OTA-сервера - -Этот пример показывает, как настроить точку доступа Wi-Fi и запустить OTA-сервер: - -```c -#include "nvs_flash.h" -#include "esp_wifi.h" -#include "zh_ota_server.h" - -#define WIFI_SSID "MyDevice" -#define WIFI_PASS "secure_password" - -static httpd_handle_t http_server_handle = NULL; - -void app_main(void) -{ - esp_log_level_set("zh_ota_server", ESP_LOG_ERROR); - // Инициализация NVS и Wi-Fi - nvs_flash_init(); - esp_event_loop_create_default(); - esp_netif_init(); - esp_netif_create_default_wifi_ap(); - // Настройка Wi-Fi AP - wifi_init_config_t wifi_config = WIFI_INIT_CONFIG_DEFAULT(); - esp_wifi_init(&wifi_config); - wifi_config_t ap_config = { - .ap = { - .ssid = WIFI_SSID, - .password = WIFI_PASS, - .max_connection = 4, - .authmode = WIFI_AUTH_WPA2_PSK, - }, - }; - esp_wifi_set_mode(WIFI_MODE_AP); - esp_wifi_set_config(WIFI_IF_AP, &ap_config); - esp_wifi_start(); - // Запуск HTTP-сервера и регистрация OTA-обработчика - httpd_config_t config = HTTPD_DEFAULT_CONFIG(); - httpd_start(&http_server_handle, &config); - zh_ota_server_init(http_server_handle, "/ota"); -} -``` - -### Рабочий процесс обновления прошивки - -Типичный рабочий процесс обновления: - -1. Устройство запускается в режиме точки доступа (SSID: "MyDevice", IP: 192.168.4.1) -2. Пользователь подключается по Wi-Fi к устройству -3. Пользователь открывает браузер и переходит по адресу -4. Пользователь выбирает бинарный файл прошивки (.bin) -5. Устройство получает, проверяет и записывает прошивку -6. Устройство перезагружается и загружается с нового раздела - ---- - -## Технические характеристики - -| Параметр | Значение | -| ---------- | ---------- | -| **Макс. размер прошивки** | Ограничивается размером доступного OTA-раздела | -| **Размер буфера** | 1000 байт на часть | -| **Параметры памяти** | MALLOC_CAP_8BIT | -| **Потокобезопасность** | Не является потокобезопасным | -| **Версия ESP-IDF** | >= 5.0 | -| **Платформа** | Серия ESP32 | -| **Язык** | C (C99) | -| **Зависимости** | esp_http_server, esp_ota_ops, esp_log | - ---- - -## Коды ошибок - -| Код ошибки | Описание | -| ------------ | ---------- | -| `ESP_OK` | Операция выполнена успешно | -| `ESP_ERR_INVALID_ARG` | Неверный аргумент (NULL-дескриптор или путь) | -| `ESP_ERR_NO_MEM` | Не удалось выделить память (не хватает свободной памяти) | -| `ESP_FAIL` | Общая ошибка (регистрация URI, операция OTA или HTTP-ответ) | - ---- - -## Вклад в проект - -Вклад приветствуется! Чтобы внести свой вклад: - -1. Сделайте форк репозитория -2. Создайте ветку функции (`git checkout -b feature/AmazingFeature`) -3. Закоммитьте ваши изменения (`git commit -m 'Add some AmazingFeature'`) -4. Отправьте в ветку (`git push origin feature/AmazingFeature`) -5. Откройте Pull Request - -Пожалуйста, убедитесь, что ваш код следует существующему стилю и включает соответствующую документацию. - ---- - -## Лицензия - -Этот проект лицензирован по лицензии Apache, версия 2.0 — см. файл [LICENSE](LICENSE) для подробной информации. - -### Apache License, Version 2.0 - -Авторское право (c) 2026 Алексей Жолтиков - -Лицензировано по лицензии Apache License, Version 2.0 (далее — "Лицензия"); -вы не можете использовать этот файл, кроме случаев, предусмотренных Лицензией. -Копию Лицензии можно получить по адресу: - - http://www.apache.org/licenses/LICENSE-2.0 - -Если иное не требуется действующим законодательством или не согласовано в письменном виде, -программное обеспечение, распространяемое по Лицензии, распространяется на условиях "КАК ЕСТЬ", -БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, явных или подразумеваемых, включая, но не ограничиваясь, гарантии -ТОВАРНОГО СОСТОЯНИЯ, ПРИГОДНОСТИ ДЛЯ КОНКРЕТНОЙ ЦЕЛИ И НЕНАРУШЕНИЯ ПРАВ. -Смотрите Лицензию для получения конкретных прав и ограничений. - ---- - -## Дополнительные заметки - -- **Управление памятью**: Путь URI выделяется один раз при инициализации и никогда не освобождается. Это приемлемо для встраиваемых систем со стабильным объёмом доступной памяти -- **Безопасность**: Этот компонент не предоставляет аутентификацию или шифрование. Используйте только в доверенной сети. Для продакшена добавьте HTTPS и аутентификацию -- **Риск блокировки устройства**: Загрузка недействительной или повреждённой прошивки сделает устройство незагружаемым, пока не будет загружена валидная образ через другой механизм (например, через UART bootloader) -- **Лучшие практики**: - - Всегда проверяйте контрольные суммы прошивки перед записью - - Реализуйте механизм отката (например, dual-bank OTA с резервным разделом) - - Добавьте аутентификацию для предотвращения несанкционированной загрузки прошивки - - Рассмотрите возможность добавления функции отката в случае неудачного обновления - - Контролируйте свободную память перед началом больших OTA-передач - ---- - -*Сгенерировано для zh_ota_server v1.0.0*