merged dev branch: TaskFactory is now TaskMgr, OTA is using HTTPS
This commit is contained in:
parent
bf29ccda08
commit
51e0c72c04
@ -11,3 +11,5 @@ MQTT server:
|
|||||||
This produces eventgrid.azure.pem certificate file.
|
This produces eventgrid.azure.pem certificate file.
|
||||||
|
|
||||||
|
|
||||||
|
openssl s_client -showcerts -connect www.bigfoot-inc.com:443
|
||||||
|
|
||||||
|
|||||||
31
certs/bigfoot-inc.pem
Executable file
31
certs/bigfoot-inc.pem
Executable file
@ -0,0 +1,31 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
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
|
||||||
|
nLRbwHOoq7hHwg==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
@ -72,16 +72,13 @@ void App::init()
|
|||||||
|
|
||||||
void App::otaCheck()
|
void App::otaCheck()
|
||||||
{
|
{
|
||||||
ota_update::OTA ota(*this);
|
OTA ota(*this);
|
||||||
ota.start();
|
ota.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::start()
|
void App::start()
|
||||||
{
|
{
|
||||||
// while(true)
|
|
||||||
// {
|
|
||||||
// vTaskDelay(pdMS_TO_TICKS(10020));
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::readSensors()
|
void App::readSensors()
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
idf_component_register(SRCS main.cpp App.cpp Settings.cpp Led.cpp TaskFactory.cpp Wifi.cpp utilities.cpp
|
idf_component_register(SRCS main.cpp App.cpp Settings.cpp Led.cpp TaskMgr.cpp Wifi.cpp utilities.cpp
|
||||||
ProvisionSoftAP.cpp ReaderWriter.cpp OTA.cpp Mqtt.cpp
|
ProvisionSoftAP.cpp ReaderWriter.cpp OTA.cpp Mqtt.cpp
|
||||||
INCLUDE_DIRS "."
|
INCLUDE_DIRS "."
|
||||||
EMBED_TXTFILES ../html/logo.png ../html/provision.html
|
EMBED_TXTFILES ../html/logo.png ../html/provision.html
|
||||||
EMBED_TXTFILES ../certs/eventgrid.azure.pem ../certs/client1-authn-ID.key ../certs/client1-authn-ID.pem
|
EMBED_TXTFILES ../certs/eventgrid.azure.pem ../certs/client1-authn-ID.key ../certs/client1-authn-ID.pem ../certs/bigfoot-inc.pem
|
||||||
)
|
)
|
||||||
|
|
||||||
#message(FATAL_ERROR "error ${ROLE}")
|
#message(FATAL_ERROR "error ${ROLE}")
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
/// © MiroZ 2024
|
/// © MiroZ 2024
|
||||||
|
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
#include "app_config.h"
|
||||||
|
|
||||||
#include "Led.h"
|
#include "Led.h"
|
||||||
|
|
||||||
@ -106,7 +107,7 @@ Led::Led(uint32_t pin)
|
|||||||
assert(m_queue = xQueueCreate(5, sizeof(struct LED_QUEUE)));
|
assert(m_queue = xQueueCreate(5, sizeof(struct LED_QUEUE)));
|
||||||
|
|
||||||
// create the led task
|
// create the led task
|
||||||
m_task = TASK_FACTORY.createTask(std::bind(&Led::run, this), "led task", 2096, 5, 0);
|
m_task = TaskMgr::getInstance().createTask(std::bind(&Led::run, this), LED_TASK_NAME, LED_TASK_STACK_SIZE, LED_TASK_PRIORITY, LED_TASK_CORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
Led::~Led()
|
Led::~Led()
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <Adafruit_NeoPixel.h>
|
#include <Adafruit_NeoPixel.h>
|
||||||
#include "TaskFactory.h"
|
#include "TaskMgr.h"
|
||||||
|
|
||||||
class Led
|
class Led
|
||||||
{
|
{
|
||||||
|
|||||||
@ -3,7 +3,8 @@
|
|||||||
#include "Mqtt.h"
|
#include "Mqtt.h"
|
||||||
|
|
||||||
#include <esp_log.h>
|
#include <esp_log.h>
|
||||||
#include "TaskFactory.h"
|
#include "TaskMgr.h"
|
||||||
|
#include "app_config.h"
|
||||||
|
|
||||||
static const char * mqtt_broker = "mqtt-dev-server.westus2-1.ts.eventgrid.azure.net";
|
static const char * mqtt_broker = "mqtt-dev-server.westus2-1.ts.eventgrid.azure.net";
|
||||||
static const char * topic = "wellnuotopics/topic1";
|
static const char * topic = "wellnuotopics/topic1";
|
||||||
@ -51,9 +52,7 @@ void Mqtt::task()
|
|||||||
else
|
else
|
||||||
ESP_LOGE(TAG, "%d publish failed", n);
|
ESP_LOGE(TAG, "%d publish failed", n);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "%d", TaskFactory::getStackHighWaterMark());
|
delay(20000);
|
||||||
|
|
||||||
delay(50000);
|
|
||||||
|
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
@ -70,9 +69,11 @@ void Mqtt::start()
|
|||||||
m_esp_client->setCACert((const char*)server_cert);
|
m_esp_client->setCACert((const char*)server_cert);
|
||||||
m_esp_client->setCertificate((const char *)client_cert); // for client verification
|
m_esp_client->setCertificate((const char *)client_cert); // for client verification
|
||||||
m_esp_client->setPrivateKey((const char *)client_key); // for client verification
|
m_esp_client->setPrivateKey((const char *)client_key); // for client verification
|
||||||
|
|
||||||
m_mqtt_client->setServer(mqtt_broker, mqtt_port);
|
m_mqtt_client->setServer(mqtt_broker, mqtt_port);
|
||||||
m_mqtt_client->setCallback(std::bind(&Mqtt::callback, this, _1, _2, _3));
|
m_mqtt_client->setCallback(std::bind(&Mqtt::callback, this, _1, _2, _3));
|
||||||
|
m_mqtt_client->setKeepAlive(30);
|
||||||
|
m_mqtt_client->setSocketTimeout(30);
|
||||||
|
|
||||||
m_task = TASK_FACTORY.createTask(std::bind(&Mqtt::task, this), "mqtt task", 6144, 5, 0);
|
m_task = TaskMgr::getInstance().createTask(std::bind(&Mqtt::task, this), MQTT_TASK_NAME, MQTT_TASK_STACK_SIZE, MQTT_TASK_PRIORITY, MQTT_TASK_CORE);
|
||||||
}
|
}
|
||||||
82
main/OTA.cpp
82
main/OTA.cpp
@ -18,25 +18,21 @@
|
|||||||
|
|
||||||
#include "OTA.h"
|
#include "OTA.h"
|
||||||
|
|
||||||
|
#include <HTTPClient.h>
|
||||||
|
|
||||||
|
#define OTA_URL "https://bigfoot-inc.com/fw/wellhub.bin"
|
||||||
|
|
||||||
|
extern const uint8_t server_cert[] asm("_binary_bigfoot_inc_pem_start");
|
||||||
|
|
||||||
#define OTA_URL "http://192.168.1.131/wellhub.bin"
|
|
||||||
|
|
||||||
static const char *TAG = "OTA";
|
static const char *TAG = "OTA";
|
||||||
|
|
||||||
namespace ota_update
|
|
||||||
{
|
|
||||||
|
|
||||||
OTA::OTA(App & app) : m_app(app)
|
OTA::OTA(App & app) : m_app(app)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OTA::httpCleanup(esp_http_client_handle_t client)
|
|
||||||
{
|
|
||||||
esp_http_client_close(client);
|
|
||||||
esp_http_client_cleanup(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OTA::taskFatalError()
|
void OTA::taskFatalError()
|
||||||
{
|
{
|
||||||
ESP_LOGE(TAG, "Exiting task due to fatal error...");
|
ESP_LOGE(TAG, "Exiting task due to fatal error...");
|
||||||
@ -57,6 +53,25 @@ void OTA::start()
|
|||||||
|
|
||||||
ESP_LOGW(TAG, "Starting OTA check...");
|
ESP_LOGW(TAG, "Starting OTA check...");
|
||||||
|
|
||||||
|
HTTPClient client;
|
||||||
|
|
||||||
|
client.begin(OTA_URL, (const char *)server_cert);
|
||||||
|
int http_code = client.GET();
|
||||||
|
|
||||||
|
if(http_code != HTTP_CODE_OK)
|
||||||
|
{
|
||||||
|
ESP_LOGE(TAG, "Server error %d", http_code);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int remote_len = client.getSize();
|
||||||
|
ESP_LOGI(TAG, "remote file len %d", remote_len);
|
||||||
|
|
||||||
|
if(remote_len < 4096)
|
||||||
|
return;
|
||||||
|
|
||||||
|
WiFiClient* stream = client.getStreamPtr();
|
||||||
|
|
||||||
const esp_partition_t *configured = esp_ota_get_boot_partition();
|
const esp_partition_t *configured = esp_ota_get_boot_partition();
|
||||||
const esp_partition_t *running = esp_ota_get_running_partition();
|
const esp_partition_t *running = esp_ota_get_running_partition();
|
||||||
|
|
||||||
@ -70,27 +85,6 @@ void OTA::start()
|
|||||||
ESP_LOGI(TAG, "Running partition type %d subtype %d (offset 0x%08x)", running->type, running->subtype,
|
ESP_LOGI(TAG, "Running partition type %d subtype %d (offset 0x%08x)", running->type, running->subtype,
|
||||||
running->address);
|
running->address);
|
||||||
|
|
||||||
esp_http_client_config_t config = { };
|
|
||||||
config.url = OTA_URL;
|
|
||||||
|
|
||||||
esp_http_client_handle_t client = esp_http_client_init(&config);
|
|
||||||
if (client == NULL)
|
|
||||||
{
|
|
||||||
ESP_LOGE(TAG, "Failed to initialize HTTP connection");
|
|
||||||
}
|
|
||||||
err = esp_http_client_open(client, 0);
|
|
||||||
if (err != ESP_OK)
|
|
||||||
{
|
|
||||||
ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err));
|
|
||||||
esp_http_client_cleanup(client);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
esp_http_client_fetch_headers(client);
|
|
||||||
|
|
||||||
int remote_len = esp_http_client_get_content_length(client);
|
|
||||||
|
|
||||||
ESP_LOGI(TAG,"remote len %d", remote_len);
|
|
||||||
|
|
||||||
update_partition = esp_ota_get_next_update_partition(NULL);
|
update_partition = esp_ota_get_next_update_partition(NULL);
|
||||||
ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x", update_partition->subtype,
|
ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x", update_partition->subtype,
|
||||||
update_partition->address);
|
update_partition->address);
|
||||||
@ -101,17 +95,15 @@ void OTA::start()
|
|||||||
bool image_header_was_checked = false;
|
bool image_header_was_checked = false;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
int data_read = esp_http_client_read(client, otaWriteData, BUFFSIZE);
|
// int len = stream->available();
|
||||||
|
int data_read = stream->readBytes(otaWriteData, BUFFSIZE);
|
||||||
if (data_read < 0)
|
if (data_read < 0)
|
||||||
{
|
{
|
||||||
ESP_LOGE(TAG, "Error: SSL data read error");
|
ESP_LOGE(TAG, "Error: SSL data read error");
|
||||||
esp_http_client_close(client);
|
return;
|
||||||
esp_http_client_cleanup(client);
|
|
||||||
taskFatalError();
|
|
||||||
}
|
}
|
||||||
else if (data_read > 0)
|
else if (data_read > 0)
|
||||||
{
|
{
|
||||||
//printf(".");
|
|
||||||
if (image_header_was_checked == false)
|
if (image_header_was_checked == false)
|
||||||
{
|
{
|
||||||
// this is the first 1k of received image
|
// this is the first 1k of received image
|
||||||
@ -159,15 +151,15 @@ void OTA::start()
|
|||||||
ESP_LOGW(TAG, "Previously, there was an attempt to launch the firmware with %s version, but it failed.",
|
ESP_LOGW(TAG, "Previously, there was an attempt to launch the firmware with %s version, but it failed.",
|
||||||
invalid_app_info.version);
|
invalid_app_info.version);
|
||||||
ESP_LOGW(TAG, "The firmware has been rolled back to the previous version.");
|
ESP_LOGW(TAG, "The firmware has been rolled back to the previous version.");
|
||||||
httpCleanup(client);
|
// httpCleanup(client);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: add date/time check
|
||||||
if (memcmp(new_app_info.version, running_app_info.version, sizeof(new_app_info.version) + sizeof(new_app_info.project_name) + sizeof(new_app_info.time) + sizeof(new_app_info.date)) == 0)
|
if (memcmp(new_app_info.version, running_app_info.version, sizeof(new_app_info.version) + sizeof(new_app_info.project_name) + sizeof(new_app_info.time) + sizeof(new_app_info.date)) == 0)
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG, "Current running version is the same as a remote. No need for update.");
|
ESP_LOGI(TAG, "Current running version is the same as a remote. No need for update.");
|
||||||
httpCleanup(client);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,22 +172,22 @@ void OTA::start()
|
|||||||
if (err != ESP_OK)
|
if (err != ESP_OK)
|
||||||
{
|
{
|
||||||
ESP_LOGE(TAG, "esp_ota_begin failed (%s)", esp_err_to_name(err));
|
ESP_LOGE(TAG, "esp_ota_begin failed (%s)", esp_err_to_name(err));
|
||||||
httpCleanup(client);
|
// httpCleanup(client);
|
||||||
taskFatalError();
|
taskFatalError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ESP_LOGE(TAG, "received package does not fit len");
|
ESP_LOGE(TAG, "received package does not fit len");
|
||||||
httpCleanup(client);
|
return;
|
||||||
taskFatalError();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = esp_ota_write(update_handle, (const void *) otaWriteData, data_read);
|
err = esp_ota_write(update_handle, (const void *) otaWriteData, data_read);
|
||||||
|
|
||||||
if (err != ESP_OK)
|
if (err != ESP_OK)
|
||||||
{
|
{
|
||||||
httpCleanup(client);
|
ESP_LOGE(TAG, "Error: esp_ota_write error");
|
||||||
taskFatalError();
|
taskFatalError();
|
||||||
}
|
}
|
||||||
binary_file_length += data_read;
|
binary_file_length += data_read;
|
||||||
@ -208,11 +200,10 @@ void OTA::start()
|
|||||||
last_reported = progress;
|
last_reported = progress;
|
||||||
ESP_LOGI(TAG, "%d%%", last_reported);
|
ESP_LOGI(TAG, "%d%%", last_reported);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (data_read == 0)
|
else if (data_read == 0)
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG, "Connection closed,all data received");
|
ESP_LOGI(TAG, "All data received");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -222,7 +213,7 @@ void OTA::start()
|
|||||||
if (esp_ota_end(update_handle) != ESP_OK)
|
if (esp_ota_end(update_handle) != ESP_OK)
|
||||||
{
|
{
|
||||||
ESP_LOGE(TAG, "esp_ota_end failed!");
|
ESP_LOGE(TAG, "esp_ota_end failed!");
|
||||||
httpCleanup(client);
|
// httpCleanup(client);
|
||||||
taskFatalError();
|
taskFatalError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,7 +223,7 @@ void OTA::start()
|
|||||||
if (err != ESP_OK)
|
if (err != ESP_OK)
|
||||||
{
|
{
|
||||||
ESP_LOGE(TAG, "esp_ota_set_boot_partition failed (%s)!", esp_err_to_name(err));
|
ESP_LOGE(TAG, "esp_ota_set_boot_partition failed (%s)!", esp_err_to_name(err));
|
||||||
httpCleanup(client);
|
// httpCleanup(client);
|
||||||
taskFatalError();
|
taskFatalError();
|
||||||
}
|
}
|
||||||
ESP_LOGI(TAG, "Prepare to restart system!");
|
ESP_LOGI(TAG, "Prepare to restart system!");
|
||||||
@ -242,5 +233,4 @@ void OTA::start()
|
|||||||
|
|
||||||
OTA::~OTA()
|
OTA::~OTA()
|
||||||
{
|
{
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -12,10 +12,7 @@
|
|||||||
#define BUFFSIZE 1024
|
#define BUFFSIZE 1024
|
||||||
#define HASH_LEN 32 /* SHA-256 digest length */
|
#define HASH_LEN 32 /* SHA-256 digest length */
|
||||||
|
|
||||||
namespace ota_update
|
|
||||||
{
|
|
||||||
#include "App.h"
|
#include "App.h"
|
||||||
#include "esp_http_client.h"
|
|
||||||
|
|
||||||
|
|
||||||
class OTA
|
class OTA
|
||||||
@ -25,7 +22,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
char otaWriteData[BUFFSIZE + 1] = { 0 };
|
char otaWriteData[BUFFSIZE + 1] = { 0 };
|
||||||
void httpCleanup(esp_http_client_handle_t client);
|
|
||||||
App & m_app;
|
App & m_app;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -35,6 +31,5 @@ public:
|
|||||||
OTA(App & app);
|
OTA(App & app);
|
||||||
virtual ~OTA();
|
virtual ~OTA();
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __OTA_H__ */
|
#endif /* __OTA_H__ */
|
||||||
@ -121,6 +121,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Settings();
|
Settings();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Settings & getInstance();
|
static Settings & getInstance();
|
||||||
|
|
||||||
|
|||||||
@ -1,38 +0,0 @@
|
|||||||
/// © MiroZ 2024
|
|
||||||
|
|
||||||
#include "TaskFactory.h"
|
|
||||||
|
|
||||||
TaskFactory::TaskFactory()
|
|
||||||
{
|
|
||||||
#ifdef USE_MUTEX
|
|
||||||
m_xMutex = xSemaphoreCreateMutex();
|
|
||||||
assert(m_xMutex);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
TaskFactory::~TaskFactory()
|
|
||||||
{
|
|
||||||
#ifdef USE_MUTEX
|
|
||||||
if(m_xMutex != NULL)
|
|
||||||
vSemaphoreDelete(m_xMutex);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
TaskHandle_t TaskFactory::createTask(TASK_FUNCTION task_function, const char *name, uint32_t stack_size, UBaseType_t priority, BaseType_t core)
|
|
||||||
{
|
|
||||||
TaskHandle_t task_handle = nullptr;
|
|
||||||
|
|
||||||
#ifdef USE_MUTEX
|
|
||||||
if (xSemaphoreTake(m_xMutex, portMAX_DELAY))
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
m_task_function = task_function;
|
|
||||||
xTaskCreatePinnedToCore(taskStarter, name, stack_size, this, priority, &task_handle, core);
|
|
||||||
#ifdef USE_MUTEX
|
|
||||||
xSemaphoreGive(m_xMutex);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return task_handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
TaskFactory TASK_FACTORY;
|
|
||||||
88
main/TaskMgr.cpp
Normal file
88
main/TaskMgr.cpp
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/// © MiroZ 2024
|
||||||
|
|
||||||
|
#include "TaskMgr.h"
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <esp_log.h>
|
||||||
|
|
||||||
|
static const char * TAG = "taskmgr";
|
||||||
|
|
||||||
|
TaskMgr::TaskMgr()
|
||||||
|
{
|
||||||
|
m_xMutex = xSemaphoreCreateMutex();
|
||||||
|
assert(m_xMutex);
|
||||||
|
#ifdef TASKMGR_TASK_NAME
|
||||||
|
createTask(std::bind(&TaskMgr::task, this), TASKMGR_TASK_NAME, TASKMGR_TASK_STACK_SIZE, TASKMGR_TASK_PRIORITY, TASKMGR_TASK_CORE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskMgr::~TaskMgr()
|
||||||
|
{
|
||||||
|
if(m_xMutex != NULL)
|
||||||
|
vSemaphoreDelete(m_xMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TASKMGR_TASK_NAME
|
||||||
|
void TaskMgr::task()
|
||||||
|
{
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
delay(TASKMGR_TASK_DELAY);
|
||||||
|
getInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TaskMgr & TaskMgr::getInstance()
|
||||||
|
{
|
||||||
|
static TaskMgr taskmgr;
|
||||||
|
return taskmgr;
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskHandle_t TaskMgr::createTask(TASK_FUNCTION task_function, const char *name, uint32_t stack_size, UBaseType_t priority, BaseType_t core)
|
||||||
|
{
|
||||||
|
TaskHandle_t task_handle = nullptr;
|
||||||
|
|
||||||
|
if (xSemaphoreTake(m_xMutex, portMAX_DELAY))
|
||||||
|
{
|
||||||
|
m_task_function = task_function;
|
||||||
|
xTaskCreatePinnedToCore(taskStarter, name, stack_size, this, priority, &task_handle, core);
|
||||||
|
m_tasks.push_back(task_handle);
|
||||||
|
|
||||||
|
xSemaphoreGive(m_xMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return task_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskMgr::deleteTask(TaskHandle_t task)
|
||||||
|
{
|
||||||
|
if(task == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (xSemaphoreTake(m_xMutex, portMAX_DELAY))
|
||||||
|
{
|
||||||
|
vTaskDelete(task);
|
||||||
|
m_tasks.remove(task);
|
||||||
|
|
||||||
|
xSemaphoreGive(m_xMutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskMgr::getInfo()
|
||||||
|
{
|
||||||
|
if (xSemaphoreTake(m_xMutex, portMAX_DELAY))
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG, "Current running tasks:");
|
||||||
|
for(auto i : m_tasks)
|
||||||
|
{
|
||||||
|
const char * name = pcTaskGetName(i);
|
||||||
|
uint32_t hwm = (uint32_t)uxTaskGetStackHighWaterMark(i);
|
||||||
|
if(hwm < 256)
|
||||||
|
ESP_LOGW(TAG, "%10s (%d)", name, hwm);
|
||||||
|
else
|
||||||
|
ESP_LOGI(TAG, "%10s (%d)", name, hwm);
|
||||||
|
}
|
||||||
|
xSemaphoreGive(m_xMutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,39 +3,43 @@
|
|||||||
#ifndef __TASK_FACTORY_H__
|
#ifndef __TASK_FACTORY_H__
|
||||||
#define __TASK_FACTORY_H__
|
#define __TASK_FACTORY_H__
|
||||||
|
|
||||||
|
#include "app_config.h"
|
||||||
#include <freertos/FreeRTOS.h>
|
#include <freertos/FreeRTOS.h>
|
||||||
#include <freertos/task.h>
|
#include <freertos/task.h>
|
||||||
#include <freertos/semphr.h>
|
#include <freertos/semphr.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <esp_err.h>
|
#include <esp_err.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
typedef std::function<void()> TASK_FUNCTION;
|
typedef std::function<void()> TASK_FUNCTION;
|
||||||
|
|
||||||
// no need for mutex here
|
class TaskMgr
|
||||||
#define _USE_MUTEX
|
|
||||||
|
|
||||||
class TaskFactory
|
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
#ifdef USE_MUTEX
|
|
||||||
SemaphoreHandle_t m_xMutex = NULL;
|
SemaphoreHandle_t m_xMutex = NULL;
|
||||||
#endif
|
|
||||||
TASK_FUNCTION m_task_function = nullptr;
|
TASK_FUNCTION m_task_function = nullptr;
|
||||||
|
std::list<TaskHandle_t> m_tasks;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void taskStarter(void * ptr) { (static_cast<TaskFactory*>(ptr)->run()); }
|
static void taskStarter(void * ptr) { (static_cast<TaskMgr*>(ptr)->run()); }
|
||||||
void run(){ m_task_function(); }
|
void run(){ m_task_function(); }
|
||||||
|
|
||||||
public:
|
#ifdef TASKMGR_TASK_NAME
|
||||||
TaskHandle_t createTask(TASK_FUNCTION task_function, const char *name, uint32_t stack_size, UBaseType_t priority, BaseType_t core);
|
void task();
|
||||||
static uint32_t getStackHighWaterMark(TaskHandle_t task = NULL){ return (uint32_t)uxTaskGetStackHighWaterMark(task); }
|
#endif
|
||||||
static void deleteTask(TaskHandle_t task = NULL){ vTaskDelete(task); }
|
|
||||||
|
|
||||||
TaskFactory();
|
private:
|
||||||
~TaskFactory();
|
TaskMgr();
|
||||||
|
|
||||||
|
public:
|
||||||
|
static TaskMgr & getInstance();
|
||||||
|
|
||||||
|
TaskHandle_t createTask(TASK_FUNCTION task_function, const char *name, uint32_t stack_size, UBaseType_t priority, BaseType_t core);
|
||||||
|
void deleteTask(TaskHandle_t task = NULL);
|
||||||
|
void getInfo();
|
||||||
|
|
||||||
|
~TaskMgr();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern TaskFactory TASK_FACTORY;
|
|
||||||
|
|
||||||
#endif /* __TASK_FACTORY_H__ */
|
#endif /* __TASK_FACTORY_H__ */
|
||||||
@ -6,6 +6,7 @@
|
|||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
#include "app_config.h"
|
||||||
|
|
||||||
static const char *TAG = "Wifi";
|
static const char *TAG = "Wifi";
|
||||||
#define IGNORE_SSID_MINS 20
|
#define IGNORE_SSID_MINS 20
|
||||||
@ -101,7 +102,7 @@ int Wifi::start()
|
|||||||
if(m_task == nullptr)
|
if(m_task == nullptr)
|
||||||
{
|
{
|
||||||
ESP_LOGW(TAG, "Starting wifi");
|
ESP_LOGW(TAG, "Starting wifi");
|
||||||
m_task = TASK_FACTORY.createTask(std::bind(&Wifi::task, this), "wifi task", 4096, 5, 0);
|
m_task = TaskMgr::getInstance().createTask(std::bind(&Wifi::task, this), WIFI_TASK_NAME, WIFI_TASK_STACK_SIZE, WIFI_TASK_PRIORITY, WIFI_TASK_CORE);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <esp_timer.h>
|
#include <esp_timer.h>
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "TaskFactory.h"
|
#include "TaskMgr.h"
|
||||||
|
|
||||||
#define _USE_TIMER
|
#define _USE_TIMER
|
||||||
|
|
||||||
|
|||||||
31
main/app_config.h
Normal file
31
main/app_config.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/// © MiroZ 2024
|
||||||
|
|
||||||
|
#ifndef __APP_CONFIG_H__
|
||||||
|
#define __APP_CONFIG_H__
|
||||||
|
|
||||||
|
// LED task
|
||||||
|
#define LED_TASK_NAME "led"
|
||||||
|
#define LED_TASK_STACK_SIZE 2096
|
||||||
|
#define LED_TASK_PRIORITY 5
|
||||||
|
#define LED_TASK_CORE 0
|
||||||
|
|
||||||
|
// WIFI task
|
||||||
|
#define WIFI_TASK_NAME "wifi"
|
||||||
|
#define WIFI_TASK_STACK_SIZE 4096
|
||||||
|
#define WIFI_TASK_PRIORITY 5
|
||||||
|
#define WIFI_TASK_CORE 0
|
||||||
|
|
||||||
|
// MQTT task
|
||||||
|
#define MQTT_TASK_NAME "mqtt"
|
||||||
|
#define MQTT_TASK_STACK_SIZE 6144
|
||||||
|
#define MQTT_TASK_PRIORITY 5
|
||||||
|
#define MQTT_TASK_CORE 0
|
||||||
|
|
||||||
|
// task mgr task
|
||||||
|
#define TASKMGR_TASK_NAME "task mgr"
|
||||||
|
#define TASKMGR_TASK_STACK_SIZE 2048
|
||||||
|
#define TASKMGR_TASK_PRIORITY 5
|
||||||
|
#define TASKMGR_TASK_CORE 0
|
||||||
|
#define TASKMGR_TASK_DELAY 60000
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -6,7 +6,7 @@
|
|||||||
#include <esp_log.h>
|
#include <esp_log.h>
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "TaskFactory.h"
|
#include "TaskMgr.h"
|
||||||
#include "esp_task_wdt.h"
|
#include "esp_task_wdt.h"
|
||||||
|
|
||||||
#include "App.h"
|
#include "App.h"
|
||||||
@ -25,8 +25,7 @@ extern "C" void app_main(void)
|
|||||||
App * app = new App();
|
App * app = new App();
|
||||||
app->init();
|
app->init();
|
||||||
app->start();
|
app->start();
|
||||||
ESP_LOGI(TAG, "stack high water mark %d", TaskFactory::getStackHighWaterMark());
|
|
||||||
|
|
||||||
// we're no longer needed
|
// we're no longer needed
|
||||||
TaskFactory::deleteTask();
|
vTaskDelete(NULL);
|
||||||
}
|
}
|
||||||
3
ota.sh
3
ota.sh
@ -12,6 +12,5 @@ if (($ret_val != 0)); then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
cp build/wellhub.bin /var/www/esp_ota
|
cp build/wellhub.bin /var/www/esp_ota
|
||||||
|
lftp -c "open -u mirozmrzli@bigfoot-inc.com,3445trGGDSa9 ftp.bigfoot-inc.com; put build/wellhub.bin"
|
||||||
idf.py -p /dev/ttyUSB1 monitor -B 450000
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user