doc: updated readme

This commit is contained in:
aZholtikov committed 2026-08-30 16:53:29 +03:00
1 parent 03b5d12f1b
commit ae2828c6bd
3 files changed
+37 -473

No files matched your search

+37 -11
View File
@@ -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");
}
```
-231
View File
@@ -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 <http://192.168.4.1/ota>
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*
-231
View File
@@ -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. Пользователь открывает браузер и переходит по адресу <http://192.168.4.1/ota>
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*