Browse Source

fixed mesh OTA process

pull/2/head
Hendrik Schutter 1 year ago
parent
commit
f74985da4c
  1. 60
      components/mesh_ota/Mesh_OTA.c
  2. 1
      components/mesh_ota/include/Mesh_OTA.h

60
components/mesh_ota/Mesh_OTA.c

@ -130,7 +130,7 @@ void vAddOTAControllMessageToQueue(MESH_PACKET_t* puMeshPacket)
}
else
{
ESP_LOGI(LOG_TAG, "added ota message to queue: %i (type)", puMeshPacket->type);
//ESP_LOGI(LOG_TAG, "added ota message to queue: %i (type)", puMeshPacket->type);
}
}
@ -216,11 +216,11 @@ void vTaskOTAWorker(void *arg)
if((uxQueueSpacesAvailable(queueNodes) - QUEUE_NODES_SIZE) == 0)
{
//nodes queue is empty
ESP_LOGI(LOG_TAG, "nodes queue is empty");
// ESP_LOGI(LOG_TAG, "nodes queue is empty");
if(bWantReboot == true)
{
ESP_LOGI(LOG_TAG, "ESP32 Reboot ...");
//ESP_LOGI(LOG_TAG, "ESP32 Reboot ...");
//vTaskDelay( (1000) / portTICK_PERIOD_MS);
//esp_restart();
}
@ -682,21 +682,22 @@ esp_err_t errOTAMeshTransmit(mesh_addr_t* pMeshNodeAddr)
esp_err_t err = ESP_OK;
const esp_partition_t* pBootPartition; //pointer to boot partition (that will booted after reset)
MESH_PACKET_t sMeshPacket; //packet for sending and receiving
uint32_t u32Index = 0U; //index for partition read offset
// uint32_t u32Index = 0U; //index for partition read offset
bool bAbort = false; //abort the OTA process
bool bNodeIsResponding = false; //remote node is still active
uint32_t u32OTABytesWritten = 0U;
uint32_t u32SegmentCounter = 0U;
pBootPartition = esp_ota_get_boot_partition(); //get boot partition (that will booted after reset), not the running partition
//loop through partition to read in segmensts until end or error or abort called
while( ((OTA_MESH_SEGMENT_SIZE * u32Index) < pBootPartition->size) && (err == ESP_OK) && (bAbort == false))
while( ((OTA_MESH_SEGMENT_SIZE * u32SegmentCounter) < pBootPartition->size) && (err == ESP_OK) && (bAbort == false))
{
bNodeIsResponding = false; //reset to default
// read partition with offset based in index
ERROR_CHECK(esp_partition_read(pBootPartition, (OTA_MESH_SEGMENT_SIZE * u32Index), sMeshPacket.au8Payload, OTA_MESH_SEGMENT_SIZE));
u32OTABytesWritten = ((u32Index+1) * OTA_MESH_SEGMENT_SIZE);
ERROR_CHECK(esp_partition_read(pBootPartition, (OTA_MESH_SEGMENT_SIZE * u32SegmentCounter), sMeshPacket.au8Payload, OTA_MESH_SEGMENT_SIZE));
u32OTABytesWritten = ((u32SegmentCounter+1) * OTA_MESH_SEGMENT_SIZE);
vPrintOTAProgress(&(pBootPartition->size), &u32OTABytesWritten, Transmitter);
if(err == ESP_OK)
@ -704,12 +705,13 @@ esp_err_t errOTAMeshTransmit(mesh_addr_t* pMeshNodeAddr)
//no error while read --> send OTA_DATA packet
sMeshPacket.type = OTA_Data;
if((OTA_MESH_SEGMENT_SIZE * (u32Index+1)) >= pBootPartition->size) //check if last segment
if((OTA_MESH_SEGMENT_SIZE * (u32SegmentCounter+1)) >= pBootPartition->size) //check if last segment
{
//last partition image segment --> send OTA_Complete
ESP_LOGI(LOG_TAG, "OTA-TX: last segment--> send Complete");
sMeshPacket.type = OTA_Complete;
}
ESP_LOGI(LOG_TAG, "OTA-TX: send packet");
err = errSendMeshPacket(pMeshNodeAddr, &sMeshPacket);
}
else
@ -717,14 +719,15 @@ esp_err_t errOTAMeshTransmit(mesh_addr_t* pMeshNodeAddr)
// error while read --> send OTA_ABORT and abort this OTA process
sMeshPacket.type = OTA_Abort;
bAbort = true;
ESP_LOGI(LOG_TAG, "OTA-TX: error while read --> send ABORT");
errSendMeshPacket(pMeshNodeAddr, &sMeshPacket);
}
// loop through all OTA messages or until abort is called or error
for (uint32_t u32Index = 0; ((u32Index < QUEUE_MESSAGE_OTA_SIZE) && (bAbort == false) && (err == ESP_OK)); u32Index++) //loop through all OTA messages
{
if(uxQueueSpacesAvailable(queueMessageOTA) < QUEUE_MESSAGE_OTA_SIZE)
{
// if(uxQueueSpacesAvailable(queueMessageOTA) < QUEUE_MESSAGE_OTA_SIZE)
// {
//queue not empty
if (xQueueReceive(queueMessageOTA, &sMeshPacket, ((3000) / portTICK_PERIOD_MS)) != pdTRUE)
{
@ -740,6 +743,7 @@ esp_err_t errOTAMeshTransmit(mesh_addr_t* pMeshNodeAddr)
case OTA_ACK: //increase index for next round
u32Index++;
bNodeIsResponding = true;
u32Index = QUEUE_MESSAGE_OTA_SIZE;//this will end the loop through all OTA messages
break;
case OTA_Abort: //abort this OTA process
bAbort = true;
@ -747,7 +751,7 @@ esp_err_t errOTAMeshTransmit(mesh_addr_t* pMeshNodeAddr)
break;
default:
//receives wrong OTA message type from node --> back to queue
vAddOTAControllMessageToQueue(&sMeshPacket);
//vAddOTAControllMessageToQueue(&sMeshPacket);
break;
}
}
@ -756,21 +760,26 @@ esp_err_t errOTAMeshTransmit(mesh_addr_t* pMeshNodeAddr)
//received from wrong node --> back to queue
vAddOTAControllMessageToQueue(&sMeshPacket);
}
/*
}
else
{
// OTA Message queue is empty --> wait some time
vTaskDelay( (1000/QUEUE_MESSAGE_OTA_SIZE) / portTICK_PERIOD_MS);
ESP_LOGI(LOG_TAG, "OTA-TX: ota message queue empty --> wait");
vTaskDelay( (OTA_MESH_TIMEOUT) / portTICK_PERIOD_MS);
}
*/
}//end OTA message loop
if(bNodeIsResponding == false)
{
//no abort was called but node didn’t responded
ESP_LOGE(LOG_TAG, "OTA-TX: no abort was called but node didn’t responded --> error");
bAbort = true;
err = ESP_FAIL; //this OTA process failed with error
}
u32SegmentCounter++;
}//end of partition segment loop
return err;
}
@ -785,6 +794,7 @@ esp_err_t errOTAMeshReceive(bool* pbNewOTAImage, mesh_addr_t* pMeshNodeAddr)
uint32_t u32OTABytesWritten = 0U; //counter unsed for progress log
static esp_ota_handle_t otaHandle; //OTA process handle
*pbNewOTAImage = false;
uint32_t u32SegmentCounter = 0U;
ERROR_CHECK(esp_ota_begin(pOTAPartition, OTA_SIZE_UNKNOWN, &otaHandle)); //start ota update process
@ -796,8 +806,8 @@ esp_err_t errOTAMeshReceive(bool* pbNewOTAImage, mesh_addr_t* pMeshNodeAddr)
// loop through all OTA messages or until abort is called
for (uint32_t u32Index = 0; ((u32Index < QUEUE_MESSAGE_OTA_SIZE) && (bAbort == false)); u32Index++) //loop through all OTA messages
{
if(uxQueueSpacesAvailable(queueMessageOTA) < QUEUE_MESSAGE_OTA_SIZE)
{
//if(uxQueueSpacesAvailable(queueMessageOTA) < QUEUE_MESSAGE_OTA_SIZE)
// {
//queue not empty
if (xQueueReceive(queueMessageOTA, &sMeshPacket, ((3000) / portTICK_PERIOD_MS)) != pdTRUE)
{
@ -812,20 +822,24 @@ esp_err_t errOTAMeshReceive(bool* pbNewOTAImage, mesh_addr_t* pMeshNodeAddr)
{
case OTA_Complete: //signal end of this OTA process, fall through because same behavior as OTA_Data
bComplete = true;
ESP_LOGI(LOG_TAG, "OTA-RX: rec Complete --> last segment");
//fall through
case OTA_Data: //data segement received
bNodeIsResponding = true;
ERROR_CHECK(esp_ota_write(otaHandle, sMeshPacket.au8Payload, OTA_MESH_SEGMENT_SIZE));
u32OTABytesWritten = ((u32Index+1) * OTA_MESH_SEGMENT_SIZE);
u32OTABytesWritten = ((u32SegmentCounter+1) * OTA_MESH_SEGMENT_SIZE);
vPrintOTAProgress(&(pOTAPartition->size), &u32OTABytesWritten, Receiver);
u32Index = QUEUE_MESSAGE_OTA_SIZE; //this will end the loop through all OTA messages
break;
case OTA_Abort: //abort this OTA process
bAbort = true;
bNodeIsResponding = true;
ESP_LOGI(LOG_TAG, "OTA-RX: rec Abort");
//this will end the loop through all OTA messages
break;
default:
//receives wrong OTA message type from node --> back to queue
vAddOTAControllMessageToQueue(&sMeshPacket);
//vAddOTAControllMessageToQueue(&sMeshPacket);
break;
}
}
@ -834,18 +848,22 @@ esp_err_t errOTAMeshReceive(bool* pbNewOTAImage, mesh_addr_t* pMeshNodeAddr)
//received from wrong node --> back to queue
vAddOTAControllMessageToQueue(&sMeshPacket);
}
}
/* }
else
{
ESP_LOGI(LOG_TAG, "OTA-RX: ota message queue empty --> wait");
// OTA Message queue is empty --> wait some time
vTaskDelay( (1000/QUEUE_MESSAGE_OTA_SIZE) / portTICK_PERIOD_MS);
vTaskDelay( (OTA_MESH_TIMEOUT) / portTICK_PERIOD_MS);
}
*/
}//end of OTA message loop
if(bNodeIsResponding == false)
{
//no abort was called but node didn’t responded --> error
ESP_LOGI(LOG_TAG, "OTA-RX: no abort was called but node didn’t responded --> error");
bAbort = true; //this will stop the partition segement loop
err = ESP_FAIL; //this OTA process failed with error
}
@ -858,6 +876,7 @@ esp_err_t errOTAMeshReceive(bool* pbNewOTAImage, mesh_addr_t* pMeshNodeAddr)
if(bAbort == false)
{
//no error while ota write --> send OTA_ACK packet
ESP_LOGI(LOG_TAG, "OTA-RX: no error while ota write --> send OTA_ACK packet");
sMeshPacket.type = OTA_ACK;
err = errSendMeshPacket(pMeshNodeAddr, &sMeshPacket);
}
@ -867,14 +886,17 @@ esp_err_t errOTAMeshReceive(bool* pbNewOTAImage, mesh_addr_t* pMeshNodeAddr)
// error while read --> send OTA_ABORT and abort this OTA process
sMeshPacket.type = OTA_Abort;
bAbort = true;
ESP_LOGI(LOG_TAG, "OTA-RX: abort --> send ABORT");
errSendMeshPacket(pMeshNodeAddr, &sMeshPacket);
}
}
u32SegmentCounter++;
}//end of partition segement loop
if(bComplete == true)
{
//all OTA segments received --> validate
ESP_LOGI(LOG_TAG, "OTA-RX: validate image ");
ERROR_CHECK(esp_ota_end(otaHandle));
ERROR_CHECK(esp_ota_set_boot_partition(pOTAPartition));
if(err == ESP_OK)

1
components/mesh_ota/include/Mesh_OTA.h

@ -23,6 +23,7 @@
#define OTA_HTTPS_SEGMENT_SIZE 2048U
#define OTA_PROGRESS_LOG_INTERVAL 7U
#define OTA_MESH_SEGMENT_SIZE MESH_NETWORK_PAYLOAD_SIZE
#define OTA_MESH_TIMEOUT 400U //in ms
#define ERROR_CHECK(x) if (err == ESP_OK) \
{ \

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