From 9521a78d13aa49d3227aa028c55d8f1672751ca6 Mon Sep 17 00:00:00 2001 From: Alexey Zholtikov Date: Sun, 16 Aug 2026 09:08:43 +0300 Subject: [PATCH] doc: updated wiki --- WIKI_EN.md | 231 +++++++++++++++++++++++++++++++++++++++++++++++++++++ WIKI_RU.md | 231 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 462 insertions(+) create mode 100644 WIKI_EN.md create mode 100644 WIKI_RU.md diff --git a/WIKI_EN.md b/WIKI_EN.md new file mode 100644 index 0000000..f06b949 --- /dev/null +++ b/WIKI_EN.md @@ -0,0 +1,231 @@ +# 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 new file mode 100644 index 0000000..897bc63 --- /dev/null +++ b/WIKI_RU.md @@ -0,0 +1,231 @@ +# 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*