Browse Source

Merge pull request 'master' (#3) from master into develop

Reviewed-on: #3
develop
Hendrik Schutter 1 year ago
parent
commit
9d23788ac8
  1. 1
      .gitignore
  2. 15
      README.md
  3. 22
      components/mesh_ota/Mesh_OTA.c
  4. 1
      components/mesh_ota/Mesh_OTA_Partition_Access.c
  5. 19
      components/mesh_ota/Mesh_OTA_Util.c
  6. 6
      components/mesh_ota/include/Mesh_OTA.h
  7. 2
      components/mesh_ota/test/test_mesh_ota.c
  8. 20
      main/Blinky_LED.c
  9. 6
      main/Blinky_LED.h
  10. 1
      main/Main.c
  11. 2
      sdkconfig

1
.gitignore vendored

@ -60,3 +60,4 @@ test/build/
*.orig
Doxygen/html/

15
README.md

@ -1,19 +1,4 @@
# ESP32-Mesh-OTA
## Work in progress
<img src="https://patenschaft.bienenweide.org/img/loading.gif" alt="code_example_output" width="50"/>
## Todo for first release
### Refactoring
- architecture
- full error handling through all functions
- export as a component library
### Features
- root node: Download new Firmware from HTTPS server instead using newest ota partition
- add example main app

22
components/mesh_ota/Mesh_OTA.c

@ -114,7 +114,6 @@ esp_err_t errMeshOTAInitialize(void)
err = ESP_FAIL;
}
}
return err;
}
@ -162,7 +161,6 @@ void vMeshOtaTaskServerWorker(void *arg)
//set want reboot
ESP_LOGI(LOG_TAG, "Updated successfully via HTTPS, set pending reboot");
bWantReboot = true;
vMeshOtaUtilAddAllNeighboursToQueue(); //add all existing neighbours to queue (aparent will not be added because this node is the root)
}
vTaskDelay( (SERVER_CHECK_INTERVAL*1000) / portTICK_PERIOD_MS); //sleep till next server checks
}
@ -182,6 +180,7 @@ void vMeshOtaTaskOTAWorker(void *arg)
esp_err_t err = ESP_OK;
bool bNewOTAImage; //true if a new ota image was downloaded and validated
mesh_addr_t meshNodeAddr; //node that should be checked for ota update
BaseType_t xReturned;
while(true)
{
@ -190,25 +189,30 @@ void vMeshOtaTaskOTAWorker(void *arg)
if((uxQueueSpacesAvailable(queueNodes) - QUEUE_NODES_SIZE) == 0)
{
//nodes queue is empty
if((bWantReboot == true) && (OTA_ALLOW_REBOOT == 1))
ESP_LOGI(LOG_TAG, "//nodes queue is empty");
xReturned = xSemaphoreTake(bsOTAProcess, portMAX_DELAY); //wait for binary semaphore that allows to start the OTA process
if((xReturned == pdTRUE) && (bWantReboot == true) && (OTA_ALLOW_REBOOT == 1))
{
ESP_LOGE(LOG_TAG, "ESP32 Reboot ...");
vTaskDelay( (1000) / portTICK_PERIOD_MS);
esp_restart();
}
xSemaphoreGive(bsOTAProcess); //free binary semaphore, this allows other tasks to start the OTA process
ERROR_CHECK(errMeshOtaSlaveEndpoint(&bNewOTAImage));
}
else
{
//queue not empty
ESP_LOGI(LOG_TAG, "//queue not empty %i", (uxQueueSpacesAvailable(queueNodes) - QUEUE_NODES_SIZE));
if (xQueueReceive(queueNodes, &meshNodeAddr, ((100) / portTICK_PERIOD_MS)) != pdTRUE)
{
ESP_LOGE(LOG_TAG, "Unable to receive OTA Messages from Queue");
err = ESP_FAIL;
}
ESP_LOGI(LOG_TAG, "//handle node %x", meshNodeAddr.addr[5]);
ERROR_CHECK(errMeshOtaMasterEndpoint(&bNewOTAImage, &meshNodeAddr));
if (err != ESP_OK)
@ -275,7 +279,7 @@ esp_err_t errMeshOtaSlaveEndpoint(bool* const cpbNewOTAImage)
if((bMeshOtaUtilNewerVersion((bootPartitionDesc).version, (char*) sOTAMessage.au8Payload)) && (err == ESP_OK)) //compare local and remote version
{
//remote newer as local
ESP_LOGI(LOG_TAG, "remote image on node is newer --> OTA update required");
ESP_LOGI(LOG_TAG, "remote image on node is newer --> OTA update required from node \"%x:%x:%x:%x:%x:%x\"", sOTAMessage.meshSenderAddr.addr[0], sOTAMessage.meshSenderAddr.addr[1], sOTAMessage.meshSenderAddr.addr[2], sOTAMessage.meshSenderAddr.addr[3], sOTAMessage.meshSenderAddr.addr[4], sOTAMessage.meshSenderAddr.addr[5]);
// --> this version older --> start OTA_Rx --> set cpbNewOTAImage true
ERROR_CHECK(errMeshOtaPartitionAccessMeshReceive(cpbNewOTAImage, &sOTAMessage.meshSenderAddr));
}
@ -283,7 +287,7 @@ esp_err_t errMeshOtaSlaveEndpoint(bool* const cpbNewOTAImage)
if((bMeshOtaUtilNewerVersion((char*) sOTAMessage.au8Payload, (bootPartitionDesc).version)) && (err == ESP_OK)) //compare remote and local version
{
//local newer as remote
ESP_LOGI(LOG_TAG, "remote image on node is older --> OTA send required");
ESP_LOGI(LOG_TAG, "remote image on node is older --> OTA send required to node \"%x:%x:%x:%x:%x:%x\"", sOTAMessage.meshSenderAddr.addr[0], sOTAMessage.meshSenderAddr.addr[1], sOTAMessage.meshSenderAddr.addr[2], sOTAMessage.meshSenderAddr.addr[3], sOTAMessage.meshSenderAddr.addr[4], sOTAMessage.meshSenderAddr.addr[5]);
// --> this version newer --> start OTA_Tx
ERROR_CHECK(errMeshOtaPartitionAccessMeshTransmit(&sOTAMessage.meshSenderAddr));
}
@ -343,7 +347,7 @@ esp_err_t errMeshOtaMasterEndpoint(bool* const cpbNewOTAImage, const mesh_addr_t
if((bMeshOtaUtilNewerVersion((bootPartitionDesc).version, (char*) sOTAMessage.au8Payload)) && (err == ESP_OK)) //compare local and remote version
{
//remote newer as local
ESP_LOGI(LOG_TAG, "Mesh: remote image on node is newer --> OTA update required");
ESP_LOGI(LOG_TAG, "remote image on node is newer --> OTA update required from node \"%x:%x:%x:%x:%x:%x\"", sOTAMessage.meshSenderAddr.addr[0], sOTAMessage.meshSenderAddr.addr[1], sOTAMessage.meshSenderAddr.addr[2], sOTAMessage.meshSenderAddr.addr[3], sOTAMessage.meshSenderAddr.addr[4], sOTAMessage.meshSenderAddr.addr[5]);
// --> this version older --> start OTA_Rx --> set cpbNewOTAImage true
ERROR_CHECK(errMeshOtaPartitionAccessMeshReceive(cpbNewOTAImage, &sOTAMessage.meshSenderAddr));
}
@ -351,7 +355,7 @@ esp_err_t errMeshOtaMasterEndpoint(bool* const cpbNewOTAImage, const mesh_addr_t
if((bMeshOtaUtilNewerVersion((char*) sOTAMessage.au8Payload, (bootPartitionDesc).version)) && (err == ESP_OK)) //compare remote and local version
{
//local newer as remote
ESP_LOGI(LOG_TAG, "Mesh: remote image on node is older --> OTA send required");
ESP_LOGI(LOG_TAG, "remote image on node is older --> OTA send required to node \"%x:%x:%x:%x:%x:%x\"", sOTAMessage.meshSenderAddr.addr[0], sOTAMessage.meshSenderAddr.addr[1], sOTAMessage.meshSenderAddr.addr[2], sOTAMessage.meshSenderAddr.addr[3], sOTAMessage.meshSenderAddr.addr[4], sOTAMessage.meshSenderAddr.addr[5]);
// --> this version newer --> start OTA_Tx
ERROR_CHECK(errMeshOtaPartitionAccessMeshTransmit(&sOTAMessage.meshSenderAddr));
}

1
components/mesh_ota/Mesh_OTA_Partition_Access.c

@ -89,6 +89,7 @@ esp_err_t errMeshOtaPartitionAccessHttps(bool* const cpbNewOTAImage)
if(err == ESP_OK)
{
*cpbNewOTAImage = true; //image validated
vMeshOtaUtilAddAllNeighboursToQueue(); //add all existing neighbours to queue (aparent will not be added because this node is the root)
}
}
else

19
components/mesh_ota/Mesh_OTA_Util.c

@ -328,17 +328,24 @@ void vMeshOtaUtilClearOtaMessageQueue(const mesh_addr_t* const cpcMeshNodeAddr)
void vMeshOtaUtilClearNeighboursQueue(const mesh_addr_t* const cpcMeshNodeAddr)
{
mesh_addr_t sNode; //packet for sending and receiving
for (uint32_t u32Index = 0; (u32Index < QUEUE_MESSAGE_OTA_SIZE); u32Index++) //loop through all OTA messages
for (uint32_t u32Index = 0; (u32Index < QUEUE_NODES_SIZE); u32Index++) //loop through all node queue
{
if (xQueueReceive(queueNodes, &sNode, 0) == pdTRUE)
{
if(!(bMeshNetworkCheckMacEquality(sNode.addr, cpcMeshNodeAddr->addr)))
if((bMeshNetworkCheckMacEquality(sNode.addr, cpcMeshNodeAddr->addr)))
{
ESP_LOGI(LOG_TAG, "REMOVE_NODE: remove node %x", sNode.addr[5]);
}
else
{
//node is NOT cpcMeshNodeAddr --> keep it in queue
vMeshOtaUtilAddNodeToPossibleUpdatableQueue(cpcMeshNodeAddr->addr);
ESP_LOGI(LOG_TAG, "//node is NOT cpcMeshNodeAddr: %i --> keep it in queue", sNode.addr[5]);
vMeshOtaUtilAddNodeToPossibleUpdatableQueue(sNode.addr);
}
}else{
ESP_LOGI(LOG_TAG, "REMOVE_NODE: queue leer");
}
}//end OTA message loop
}//end nodes
}
/**
@ -361,7 +368,7 @@ void vMeshOtaUtilAddNodeToPossibleUpdatableQueue(const uint8_t* const cpcu8MAC)
}
else
{
ESP_LOGD(LOG_TAG, "added node \"%x:%x:%x:%x:%x:%x\" to possible updatable queue", addrNode.addr[0], addrNode.addr[1], addrNode.addr[2], addrNode.addr[3], addrNode.addr[4], addrNode.addr[5]);
ESP_LOGI(LOG_TAG, "added node \"%x:%x:%x:%x:%x:%x\" to possible updatable queue", addrNode.addr[0], addrNode.addr[1], addrNode.addr[2], addrNode.addr[3], addrNode.addr[4], addrNode.addr[5]);
}
}

6
components/mesh_ota/include/Mesh_OTA.h

@ -18,14 +18,14 @@
#include "HTTPS_Client.h"
#define ERASE_NVS //erase non volatile storage if full
#define QUEUE_NODES_SIZE 10
#define QUEUE_MESSAGE_OTA_SIZE 10
#define QUEUE_NODES_SIZE 20
#define QUEUE_MESSAGE_OTA_SIZE 20
#define SERVER_CHECK_INTERVAL 30 //in seconds
#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 20000U //in ms
#define OTA_ALLOW_REBOOT 0
#define OTA_ALLOW_REBOOT 1
#define ERROR_CHECK(x) if (err == ESP_OK) \
{ \

2
components/mesh_ota/test/test_mesh_ota.c

@ -1,7 +1,7 @@
#include <limits.h>
#include "unity.h"
#include "Mesh_OTA.h"
#include "Mesh_OTA_Util.h"
#include "test_image_hex.h"
// ### ### ### distinguish newer image version ### ### ###

20
main/Blinky_LED.c

@ -61,6 +61,11 @@ esp_err_t errBlinkyLEDInitialize(void)
err = ESP_FAIL;
}
}
#ifdef NEW_VERSION
gpio_set_level(GPIO_LED_GREEN, 1); //switch on
#endif
return err;
}
@ -79,8 +84,13 @@ void vGPIOInitialize(void)
gpio_config_t gpioConf;
//LED as Output
gpio_reset_pin(GPIO_LED);
gpio_set_direction(GPIO_LED, GPIO_MODE_OUTPUT);
gpio_reset_pin(GPIO_LED_BLUE);
gpio_set_direction(GPIO_LED_BLUE, GPIO_MODE_OUTPUT);
#ifdef NEW_VERSION
gpio_reset_pin(GPIO_LED_GREEN);
gpio_set_direction(GPIO_LED_GREEN, GPIO_MODE_OUTPUT);
#endif
//BTN as Input
gpioConf.intr_type = GPIO_INTR_DISABLE;
@ -212,19 +222,19 @@ void vTaskReceiveData(void *arg)
{
case LED_ON:
bLEDisOn = true;
gpio_set_level(GPIO_LED, 1); //switch on
gpio_set_level(GPIO_LED_BLUE, 1); //switch on
ESP_LOGI(LOG_TAG,"switch LED ON");
break;
case LED_OFF:
bLEDisOn = false;
gpio_set_level(GPIO_LED, 0); //switch off
gpio_set_level(GPIO_LED_BLUE, 0); //switch off
ESP_LOGI(LOG_TAG,"switch LED OFF");
break;
default:
bLEDisOn = false;
gpio_set_level(GPIO_LED, 0); //switch off
gpio_set_level(GPIO_LED_BLUE, 0); //switch off
ESP_LOGI(LOG_TAG,"switch LED OFF");
break;
}

6
main/Blinky_LED.h

@ -20,9 +20,13 @@
#include "Mesh_OTA.h"
//#define NEW_VERSION
#define GPIO_BOOT_BTN 0 //GPIO0 (Boot BTN)
#define GPIO_LED 2 //GPIO2 (internal blue LED in DevKit V1.0)
#define GPIO_LED_BLUE 2 //GPIO2 (internal blue LED in DevKit V1.0)
#ifdef NEW_VERSION
#define GPIO_LED_GREEN 13 //GPIO13
#endif
#define GPIO_INPUT_PIN_SEL (1ULL<<GPIO_BOOT_BTN)

1
main/Main.c

@ -13,7 +13,6 @@ static const char *LOG_TAG = "esp_main";
void app_main(void)
{
esp_err_t err = ESP_OK;
ESP_LOGI(LOG_TAG, "hardcoded version: 0.0.1");
ESP_LOGI(LOG_TAG, "start mesh network");
err = errMeshNetworkInitialize();

2
sdkconfig

@ -32,7 +32,7 @@ CONFIG_APP_COMPILE_TIME_DATE=y
# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set
# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set
CONFIG_APP_PROJECT_VER_FROM_CONFIG=y
CONFIG_APP_PROJECT_VER="0.0.1"
CONFIG_APP_PROJECT_VER="0.0.26"
CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16
# end of Application manager

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