Browse Source

added OTA process mutex; progress log; reboot flag

feature/blockingOTA
Hendrik Schutter 1 year ago
parent
commit
88fd2c69a9
  1. 18
      components/mesh_ota/HTTPS_client.c
  2. 89
      components/mesh_ota/Mesh_OTA.c
  3. 12
      components/mesh_ota/include/HTTPS_client.h
  4. 4
      components/mesh_ota/include/Mesh_OTA.h
  5. 3
      components/mesh_ota/include/Mesh_network.h

18
components/mesh_ota/HTTPS_client.c

@ -12,11 +12,11 @@ static const char *REQUEST = "GET " CONFIG_OTA_HTTPS_URL " HTTP/1.1\r\n"
static HTTPS_Client_t sHTTPS_ClientConfig;
https_client_ret_t https_clientInitEmbedTLS();
https_client_ret_t https_clientConnectToServer();
https_client_ret_t https_clientValidateServer();
https_client_ret_t https_clientSendRequest();
https_client_ret_t errHTTPSClientConnectToServer();
https_client_ret_t errHTTPSClientValidateServer();
https_client_ret_t errHTTPSClientSendRequest();
https_client_ret_t https_clientInitialize()
https_client_ret_t errHTTPSClientInitialize()
{
https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK;
@ -30,7 +30,7 @@ https_client_ret_t https_clientInitialize()
return i32RetHTTPClient;
}
https_client_ret_t https_clientRetrieveData(char* pu8Data, uint32_t* pu32DataLenght, uint32_t* pu32BytesRead)
https_client_ret_t errHTTPSClientRetrieveData(char* pu8Data, uint32_t* pu32DataLenght, uint32_t* pu32BytesRead)
{
https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK;
int32_t i32RetRetrieveData = ESP_OK;
@ -85,7 +85,7 @@ https_client_ret_t https_clientRetrieveData(char* pu8Data, uint32_t* pu32DataLen
return i32RetHTTPClient;
}
https_client_ret_t https_clientReset()
https_client_ret_t errHTTPSClientReset()
{
https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK;
@ -196,7 +196,7 @@ https_client_ret_t https_clientInitEmbedTLS()
return i32RetHTTPClient;
}
https_client_ret_t https_clientConnectToServer()
https_client_ret_t errHTTPSClientConnectToServer()
{
https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK;
int32_t i32RetServerConnect = ESP_OK;
@ -229,7 +229,7 @@ https_client_ret_t https_clientConnectToServer()
return i32RetHTTPClient;
}
https_client_ret_t https_clientValidateServer()
https_client_ret_t errHTTPSClientValidateServer()
{
https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK;
int32_t i32RetValidateServer = ESP_OK;
@ -247,7 +247,7 @@ https_client_ret_t https_clientValidateServer()
return i32RetHTTPClient;
}
https_client_ret_t https_clientSendRequest()
https_client_ret_t errHTTPSClientSendRequest()
{
https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK;
int32_t i32RetSendRequest = ESP_OK;

89
components/mesh_ota/Mesh_OTA.c

@ -1,19 +1,21 @@
#include "Mesh_OTA.h"
static const char *LOG_TAG = "mesh_ota";
xQueueHandle queueNodes; //nodes that should be checked for ota update (contains children and parent)
xQueueHandle queueMessageOTA; //mesh ota controll messages like "OTA_Version_Response" "OTA_ACK"
SemaphoreHandle_t bsStartStopServerWorker; //binary semaphore
SemaphoreHandle_t bsOTAProcess; //binary semaphore
const esp_partition_t* pOTAPartition; //pointer to ota partition
bool bWantReboot; //flag to signal pending reboot
esp_err_t errMeshOTAInitialize()
{
esp_err_t err = ESP_OK;
BaseType_t xReturned;
bWantReboot = false;
//create queue to store nodes for ota worker task
queueNodes = xQueueCreate(QUEUE_NODES_SIZE, sizeof(mesh_addr_t));
@ -44,6 +46,26 @@ esp_err_t errMeshOTAInitialize()
}
}
if(err == ESP_OK)
{
bsOTAProcess = xSemaphoreCreateBinary();
if( bsOTAProcess == NULL )
{
ESP_LOGE(LOG_TAG, "Unable to create Mutex to grant access to OTA Process");
err = ESP_FAIL;
}
}
if(err == ESP_OK)
{
xSemaphoreGive(bsOTAProcess); //unlock binary semaphore
if( bsOTAProcess == NULL )
{
ESP_LOGE(LOG_TAG, "Unable to unlock Mutex to grant access to OTA Process");
err = ESP_FAIL;
}
}
ERROR_CHECK(errMeshNetworkSetChildConnectedHandle(vAddNodeToPossibleUpdatableQueue));
ERROR_CHECK(errMeshNetworkSetOTAMessageHandleHandle(vAddOTAControllMessageToQueue));
ERROR_CHECK(errMeshNetworkSetChangeStateOfServerWorkerHandle(vChangeStateOfServerWorker));
@ -72,7 +94,6 @@ esp_err_t errMeshOTAInitialize()
return err;
}
void vAddNodeToPossibleUpdatableQueue(uint8_t* pu8Data)
{
//send payload to node queue
@ -89,7 +110,6 @@ void vAddNodeToPossibleUpdatableQueue(uint8_t* pu8Data)
}
}
void vAddOTAControllMessageToQueue(MESH_PACKET_t* puMeshPacket)
{
//send ota packet to packet queue
@ -103,7 +123,6 @@ void vAddOTAControllMessageToQueue(MESH_PACKET_t* puMeshPacket)
}
}
void vChangeStateOfServerWorker(bool bState) //allow access via function ptn to networl_handler
{
static bool bLastState = false;
@ -142,38 +161,39 @@ void vTaskOTAWorker(void *arg)
void vTaskServerWorker(void *arg)
{
esp_err_t err;
bool bNewOTAImage = false; // true if a new ota image was downloaded and validated
bool bNewOTAImage; //true if a new ota image was downloaded and validated
bool bFirstRun = true;
while(true)
{
err = ESP_OK;
bNewOTAImage = false;
xSemaphoreTake(bsStartStopServerWorker, portMAX_DELAY); //wait for binary semaphore that allows to start the worker
xSemaphoreGive(bsStartStopServerWorker); //free binary semaphore, this allows the handler to change is to taken
if (esp_mesh_is_root()) //check again that this node is the root node
{
ESP_LOGI(LOG_TAG, "Checking firmware image on server");
if(bFirstRun == true)
{
ERROR_CHECK(https_clientInitialize());
ERROR_CHECK(errHTTPSClientInitialize());
bFirstRun = false;
}
ERROR_CHECK(https_clientConnectToServer());
ERROR_CHECK(https_clientValidateServer());
ERROR_CHECK(https_clientSendRequest());
ERROR_CHECK(errHTTPSClientConnectToServer());
ERROR_CHECK(errHTTPSClientValidateServer());
ERROR_CHECK(errHTTPSClientSendRequest());
ERROR_CHECK(errOTAHTTPS(&bNewOTAImage));
https_clientReset();
errHTTPSClientReset();
if(bNewOTAImage == true)
{
//set want reboot
ESP_LOGI(LOG_TAG, "Updated successfully via HTTPS, will reboot if possible");
ESP_LOGI(LOG_TAG, "Updated successfully via HTTPS, set pending reboot");
bWantReboot = true;
}
vTaskDelay( (SERVER_CHECK_INTERVAL*1000) / portTICK_PERIOD_MS); //sleep till next server check
}
}
@ -190,11 +210,12 @@ esp_err_t errOTAHTTPS(bool* pbNewOTAImage)
static esp_ota_handle_t otaHandle; //OTA process handle
uint32_t u32StartOffset = 0U; //start offset for image (exclude the http response data)
esp_app_desc_t bootPartitionDesc; //Metadate from boot partition
uint32_t u32OTABytesWritten = 0U; //counter unsed for progress log
pBootPartition = esp_ota_get_boot_partition(); //get boot partition (that will booted after reset), not the running partition
ERROR_CHECK(esp_ota_get_partition_description(pBootPartition, &bootPartitionDesc)); //get metadate of partition
ERROR_CHECK(https_clientRetrieveData(u8OTABuffer, &u32BufferLenght, &u32BytesRead)); //read first bytes if image, including the version
ERROR_CHECK(errHTTPSClientRetrieveData(u8OTABuffer, &u32BufferLenght, &u32BytesRead)); //read first bytes if image, including the version
ERROR_CHECK(errExtractVersionNumber(u8OTABuffer, &u32BytesRead, pcRemoteVersionNumber)); //extract version numbers
@ -207,23 +228,24 @@ esp_err_t errOTAHTTPS(bool* pbNewOTAImage)
ERROR_CHECK(errFindImageStart(u8OTABuffer, &u32BufferLenght, &u32StartOffset)); //get image start offset
//TODO lock ota mutex
xSemaphoreTake(bsOTAProcess, portMAX_DELAY); //wait for binary semaphore that allows to start the OTA process
ERROR_CHECK(esp_ota_begin(pOTAPartition, OTA_SIZE_UNKNOWN, &otaHandle)); //start ota update process
if(err == ESP_OK)
{
//image download and ota partition write
ESP_LOGI(LOG_TAG, "start ota https download");
ESP_LOGI(LOG_TAG, "start OTA download via HTTPS");
do
{
//TODO progress log
vPrintOTAProgress(&(pOTAPartition->size), &u32OTABytesWritten);
ERROR_CHECK(esp_ota_write(otaHandle, (const void*) u8OTABuffer+u32StartOffset, (u32BytesRead-u32StartOffset)));
if(err == ESP_OK)
{
//write was succsesfull
u32StartOffset = 0U; //reset the offset for next download
ERROR_CHECK(https_clientRetrieveData(u8OTABuffer, &u32BufferLenght, &u32BytesRead)); //download next data segment
ERROR_CHECK(errHTTPSClientRetrieveData(u8OTABuffer, &u32BufferLenght, &u32BytesRead)); //download next data segment
u32OTABytesWritten = u32OTABytesWritten + u32BytesRead; //update counter
}
}
while ((u32BytesRead > 0) && (err == ESP_OK)); //loop until error or complete image downloaded
@ -246,8 +268,12 @@ esp_err_t errOTAHTTPS(bool* pbNewOTAImage)
ERROR_CHECK(esp_ota_abort(otaHandle));
*pbNewOTAImage = false; //ota update failed
}
//TODO unlock ota mutex
} //end newer version on server
xSemaphoreGive(bsOTAProcess); //free binary semaphore, this allows other tasks to start the OTA process
}
else
{
ESP_LOGI(LOG_TAG, "server image is NOT newer --> OTA update NOT required");
}
} //end version number extracted
return err;
}
@ -378,6 +404,27 @@ esp_err_t errExtractVersionNumber(const char* pu8Data, uint32_t* pu32DataLenght,
return err;
}
inline void vPrintOTAProgress(const uint32_t* const pu32TotalImageSize, const uint32_t* const pu32BytesWritten)
{
uint32_t u32Percentage = 0U;
static uint32_t u32LastPercentage = 0U;
if((*pu32BytesWritten) >= (*pu32TotalImageSize))
{
u32Percentage = 100;
}
else
{
u32Percentage = (uint32_t) (((float) (*pu32BytesWritten)/(float) (*pu32TotalImageSize)) * 100.0);
}
if((u32Percentage-u32LastPercentage) >= OTA_PROGRESS_LOG_INTERVAL)
{
ESP_LOGI(LOG_TAG, "OTA update progress: %i %%", u32Percentage);
u32LastPercentage = u32Percentage;
}
}
/*
esp_err_t esp_mesh_ota_send(mesh_addr_t* dest)
{

12
components/mesh_ota/include/HTTPS_client.h

@ -66,12 +66,12 @@ struct HTTPS_Client
typedef int32_t https_client_ret_t;
typedef struct HTTPS_Client HTTPS_Client_t;
https_client_ret_t https_clientInitialize();
https_client_ret_t https_clientConnectToServer();
https_client_ret_t https_clientValidateServer();
https_client_ret_t https_clientSendRequest();
https_client_ret_t https_clientRetrieveData(char* pu8Data, uint32_t* pu32DataLenght, uint32_t* pu32BytesRead);
https_client_ret_t https_clientReset();
https_client_ret_t errHTTPSClientInitialize();
https_client_ret_t errHTTPSClientConnectToServer();
https_client_ret_t errHTTPSClientValidateServer();
https_client_ret_t errHTTPSClientSendRequest();
https_client_ret_t errHTTPSClientRetrieveData(char* pu8Data, uint32_t* pu32DataLenght, uint32_t* pu32BytesRead);
https_client_ret_t errHTTPSClientReset();
#endif /* H_HTTPS_CLIENT */

4
components/mesh_ota/include/Mesh_OTA.h

@ -21,6 +21,7 @@
#define QUEUE_MESSAGE_OTA_SIZE 10
#define SERVER_CHECK_INTERVAL 30 //in seconds
#define OTA_HTTPS_SEGMENT_SIZE 2048U
#define OTA_PROGRESS_LOG_INTERVAL 7U
#define ERROR_CHECK(x) if (err == ESP_OK) \
{ \
@ -39,6 +40,7 @@ esp_err_t errOTAHTTPS(bool* pbNewOTAImage);
bool bNewerVersion(const char* pu8Local, const char* pu8Remote);
esp_err_t errExtractVersionNumber(const char* pu8Data, uint32_t* pu32DataLenght, char* pc8RemoteVersionNumber);
esp_err_t errFindImageStart(const char* pu8Data, uint32_t* pu32DataLenght, uint32_t* pu32StartOffset);
void vPrintOTAProgress(const uint32_t* const pu32TotalImageSize, const uint32_t* const pu32BytesWritten);
//Handler
void vAddNodeToPossibleUpdatableQueue(uint8_t* pu8Data);
@ -46,7 +48,7 @@ void vAddOTAControllMessageToQueue(MESH_PACKET_t* puMeshPacket);
void vChangeStateOfServerWorker(bool state);
//Tasks
void vTaskServerWorker(void *arg);
inline void vTaskServerWorker(void *arg);

3
components/mesh_ota/include/Mesh_network.h

@ -95,8 +95,5 @@ void vIPEventHandler(void *arg, esp_event_base_t event_base, int32_t i32EventID,
esp_err_t errSendMeshPacket(mesh_addr_t* pAddrDest, MESH_PACKET_t* pPacket);
#endif /* H_MESH_NETWORK */

Loading…
Cancel
Save

Du besuchst diese Seite mit einem veralteten IPv4-Internetzugang. Möglicherweise treten in Zukunft Probleme mit der Erreichbarkeit und Performance auf. Bitte frage deinen Internetanbieter oder Netzwerkadministrator nach IPv6-Unterstützung.
You are visiting this site with an outdated IPv4 internet access. You may experience problems with accessibility and performance in the future. Please ask your ISP or network administrator for IPv6 support.
Weitere Infos | More Information
Klicke zum schließen | Click to close