OTA task
This commit is contained in:
@@ -14,8 +14,10 @@ idf_component_register(
|
||||
"heartbeat_task.cpp"
|
||||
"fw_command.cpp"
|
||||
"json_utils.cpp"
|
||||
"ota.cpp"
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES nvs_flash
|
||||
REQUIRES
|
||||
nvs_flash
|
||||
esp_wifi
|
||||
esp_netif
|
||||
freertos
|
||||
@@ -25,6 +27,8 @@ idf_component_register(
|
||||
esp_websocket_client
|
||||
driver
|
||||
esp_driver_gpio
|
||||
esp_http_client
|
||||
app_update
|
||||
)
|
||||
# добавляем кастомный Kconfig
|
||||
set(COMPONENT_KCONFIG "Kconfig")
|
||||
@@ -8,13 +8,16 @@ extern "C" {
|
||||
#include <time.h>
|
||||
}
|
||||
|
||||
static const char *TAG = "heartbeat";
|
||||
static const char* TAG = "heartbeat";
|
||||
|
||||
static void heartbeat_task(void *arg)
|
||||
static TaskHandle_t heartbeat_task_handle = nullptr;
|
||||
|
||||
static void heartbeat_task(void* arg)
|
||||
{
|
||||
while (1) {
|
||||
if (protocol_is_connected()) {
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (protocol_is_connected())
|
||||
{
|
||||
time_t now;
|
||||
time(&now);
|
||||
|
||||
@@ -27,5 +30,17 @@ static void heartbeat_task(void *arg)
|
||||
|
||||
void heartbeat_task_start()
|
||||
{
|
||||
xTaskCreate(heartbeat_task, "heartbeat", 4096, NULL, 5, NULL);
|
||||
}
|
||||
if (heartbeat_task_handle == nullptr)
|
||||
{
|
||||
xTaskCreate(heartbeat_task, "heartbeat", 4096, nullptr, 5, &heartbeat_task_handle);
|
||||
}
|
||||
}
|
||||
|
||||
void heartbeat_task_stop()
|
||||
{
|
||||
if (heartbeat_task_handle != nullptr)
|
||||
{
|
||||
vTaskDelete(heartbeat_task_handle);
|
||||
heartbeat_task_handle = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
void heartbeat_task_start(void);
|
||||
void heartbeat_task_start(void);
|
||||
void heartbeat_task_stop();
|
||||
116
esp32/main/ota.cpp
Normal file
116
esp32/main/ota.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
#include "esp_http_client.h"
|
||||
#include "esp_ota_ops.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_log.h"
|
||||
#include "ota.h"
|
||||
#include "sender_task.h"
|
||||
#include "sampler_task.h"
|
||||
#include "ws.h"
|
||||
#include "heartbeat_task.h"
|
||||
#include "fw_command.h"
|
||||
|
||||
static TaskHandle_t ota_task_handle = nullptr;
|
||||
static char url_copy[256];
|
||||
static char sha256[65];
|
||||
|
||||
void perform_ota(void* par)
|
||||
{
|
||||
esp_ota_handle_t ota_handle;
|
||||
uint8_t buf[1024];
|
||||
int read_bytes;
|
||||
const esp_partition_t* partition = nullptr;
|
||||
|
||||
const char* url = static_cast<const char*>(par);
|
||||
|
||||
esp_http_client_config_t config = {};
|
||||
config.url = url;
|
||||
config.timeout_ms = 5000;
|
||||
config.buffer_size = 1024;
|
||||
|
||||
|
||||
esp_http_client_handle_t client = esp_http_client_init(&config);
|
||||
|
||||
if (esp_http_client_open(client, 0) != ESP_OK)
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
partition = esp_ota_get_next_update_partition(nullptr);
|
||||
|
||||
if (esp_ota_begin(partition, OTA_SIZE_UNKNOWN, &ota_handle) != ESP_OK)
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
while ((read_bytes = esp_http_client_read(client, (char*)buf, sizeof(buf))) > 0)
|
||||
{
|
||||
if (esp_ota_write(ota_handle, buf, read_bytes) != ESP_OK)
|
||||
{
|
||||
esp_ota_end(ota_handle);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if (esp_ota_end(ota_handle) == ESP_OK)
|
||||
{
|
||||
uint8_t hash[32];
|
||||
|
||||
if (esp_partition_get_sha256(partition, hash) != ESP_OK)
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// переводим в hex
|
||||
char hash_str[65];
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
sprintf(&hash_str[i * 2], "%02x", hash[i]);
|
||||
}
|
||||
hash_str[64] = '\0';
|
||||
|
||||
// сравнение
|
||||
if (strncmp(hash_str, sha256, 64) != 0)
|
||||
{
|
||||
printf("SHA256 mismatch!\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
esp_ota_set_boot_partition(partition);
|
||||
esp_restart();
|
||||
}
|
||||
|
||||
cleanup:
|
||||
esp_http_client_cleanup(client);
|
||||
vTaskDelete(nullptr);
|
||||
ota_task_handle = nullptr;
|
||||
}
|
||||
|
||||
void ota_task_start(const fw_cmd_t* cmd)
|
||||
{
|
||||
strncpy(url_copy, cmd->url, sizeof(url_copy));
|
||||
strncpy(sha256, cmd->sha256, sizeof(sha256));
|
||||
sampler_task_stop();
|
||||
sender_task_stop();
|
||||
heartbeat_task_stop();
|
||||
ws_disconnect();
|
||||
if (ota_task_handle == nullptr)
|
||||
{
|
||||
xTaskCreate(
|
||||
perform_ota,
|
||||
"ota",
|
||||
4096,
|
||||
url_copy,
|
||||
5,
|
||||
&ota_task_handle
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void ota_task_stop()
|
||||
{
|
||||
if (ota_task_handle != nullptr)
|
||||
{
|
||||
vTaskDelete(ota_task_handle);
|
||||
ota_task_handle = nullptr;
|
||||
}
|
||||
}
|
||||
4
esp32/main/ota.h
Normal file
4
esp32/main/ota.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
#include "fw_command.h"
|
||||
|
||||
void ota_task_start(const fw_cmd_t* cmd);
|
||||
@@ -11,35 +11,52 @@ extern "C" {
|
||||
// буфер
|
||||
static ringbuf_t rb;
|
||||
|
||||
ringbuf_t* sampler_get_buffer() {
|
||||
ringbuf_t* sampler_get_buffer()
|
||||
{
|
||||
return &rb;
|
||||
}
|
||||
|
||||
static void sampler_task(void *arg) {
|
||||
|
||||
static TaskHandle_t sampler_task_handle = nullptr;
|
||||
|
||||
static void sampler_task(void* arg)
|
||||
{
|
||||
const TickType_t period = pdMS_TO_TICKS(6000);
|
||||
TickType_t last_wake = xTaskGetTickCount();
|
||||
|
||||
while (1) {
|
||||
while (1)
|
||||
{
|
||||
int64_t now_ms = esp_timer_get_time() / 1000;
|
||||
|
||||
float temp = ds18b20_read();
|
||||
ringbuf_push(&rb, now_ms, (int)(temp * 100));
|
||||
|
||||
vTaskDelayUntil(&last_wake, period);// 6 секунд
|
||||
vTaskDelayUntil(&last_wake, period); // 6 секунд
|
||||
}
|
||||
}
|
||||
|
||||
void sampler_task_start() {
|
||||
ringbuf_init(&rb);
|
||||
ds18b20_init(GPIO_NUM_27); // новый драйвер
|
||||
void sampler_task_start()
|
||||
{
|
||||
if (sampler_task_handle == nullptr)
|
||||
{
|
||||
ringbuf_init(&rb);
|
||||
ds18b20_init(GPIO_NUM_27); // новый драйвер
|
||||
|
||||
xTaskCreate(
|
||||
sampler_task,
|
||||
"sampler",
|
||||
4096,
|
||||
NULL,
|
||||
5,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
xTaskCreate(
|
||||
sampler_task,
|
||||
"sampler",
|
||||
4096,
|
||||
nullptr,
|
||||
5,
|
||||
&sampler_task_handle
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void sampler_task_stop()
|
||||
{
|
||||
if (sampler_task_handle != nullptr)
|
||||
{
|
||||
vTaskDelete(sampler_task_handle);
|
||||
sampler_task_handle = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,4 +3,5 @@
|
||||
#include "ringbuf.h"
|
||||
|
||||
void sampler_task_start();
|
||||
ringbuf_t* sampler_get_buffer(); // ← ВОТ ЭТО
|
||||
ringbuf_t* sampler_get_buffer();
|
||||
void sampler_task_stop();
|
||||
@@ -18,11 +18,13 @@ extern "C" {
|
||||
static uint32_t last_send_ms = 0;
|
||||
static int64_t last_send_ts = 0;
|
||||
|
||||
static TaskHandle_t sender_task_handle = nullptr;
|
||||
|
||||
static void sender_task(void* arg)
|
||||
{
|
||||
ringbuf_t* rb = sampler_get_buffer();
|
||||
|
||||
last_send_ts = time(NULL);
|
||||
last_send_ts = time(nullptr);
|
||||
last_send_ms = esp_timer_get_time() / 1000;
|
||||
|
||||
while (1)
|
||||
@@ -31,7 +33,7 @@ static void sender_task(void* arg)
|
||||
|
||||
char buf[512];
|
||||
uint32_t now_ms = esp_timer_get_time() / 1000;
|
||||
time_t now_ts = time(NULL);
|
||||
time_t now_ts = time(nullptr);
|
||||
|
||||
sample_t tmp[RINGBUF_SIZE];
|
||||
ringbuf_copy(rb, tmp);
|
||||
@@ -49,6 +51,7 @@ static void sender_task(void* arg)
|
||||
out_values[count * 2 + 0] = delta;
|
||||
out_values[count * 2 + 1] = tmp[i].value;
|
||||
count++;
|
||||
if (count >= RINGBUF_SIZE) break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,12 +90,24 @@ static void sender_task(void* arg)
|
||||
|
||||
void sender_task_start()
|
||||
{
|
||||
xTaskCreate(
|
||||
sender_task,
|
||||
"sender",
|
||||
4096,
|
||||
NULL,
|
||||
5,
|
||||
NULL
|
||||
);
|
||||
if (sender_task_handle == nullptr)
|
||||
{
|
||||
xTaskCreate(
|
||||
sender_task,
|
||||
"sender",
|
||||
4096,
|
||||
nullptr,
|
||||
5,
|
||||
&sender_task_handle
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void sender_task_stop()
|
||||
{
|
||||
if (sender_task_handle != nullptr)
|
||||
{
|
||||
vTaskDelete(sender_task_handle);
|
||||
sender_task_handle = nullptr;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
// Запуск задачи отправки (1 Гц)
|
||||
void sender_task_start();
|
||||
void sender_task_start();
|
||||
void sender_task_stop();
|
||||
@@ -51,9 +51,9 @@ void init_wifi(const char* ssid, const char* pass) {
|
||||
esp_event_handler_instance_t instance_got_ip;
|
||||
|
||||
esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID,
|
||||
&wifi_event_handler, NULL, &instance_any_id);
|
||||
&wifi_event_handler, nullptr, &instance_any_id);
|
||||
esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP,
|
||||
&wifi_event_handler, NULL, &instance_got_ip);
|
||||
&wifi_event_handler, nullptr, &instance_got_ip);
|
||||
|
||||
wifi_config_t wifi_config = {};
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <string.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "fw_command.h"
|
||||
#include "ota.h"
|
||||
|
||||
static const char* TAG = "WS";
|
||||
|
||||
@@ -57,6 +58,8 @@ static void ws_event_handler(void* handler_args,
|
||||
ESP_LOGI(TAG, "URL: %s", cmd.url);
|
||||
ESP_LOGI(TAG, "SHA256: %s", cmd.sha256);
|
||||
|
||||
ota_task_start(&cmd);
|
||||
|
||||
// пока просто лог, без OTA
|
||||
}
|
||||
|
||||
@@ -73,7 +76,7 @@ void ws_init(const char* uri)
|
||||
config.network_timeout_ms = 5000;
|
||||
|
||||
client = esp_websocket_client_init(&config);
|
||||
esp_websocket_register_events(client, WEBSOCKET_EVENT_ANY, ws_event_handler, NULL);
|
||||
esp_websocket_register_events(client, WEBSOCKET_EVENT_ANY, ws_event_handler, nullptr);
|
||||
}
|
||||
|
||||
void ws_start()
|
||||
@@ -108,3 +111,8 @@ void ws_go()
|
||||
ws_init(uri);
|
||||
ws_start();
|
||||
}
|
||||
|
||||
void ws_disconnect()
|
||||
{
|
||||
esp_websocket_client_stop(client);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ void ws_go();
|
||||
void ws_start();
|
||||
bool ws_is_connected();
|
||||
void ws_send(const char* data);
|
||||
void ws_disconnect();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user