Good day!
I apologize in advance for the English, I translate it through googol.
Wrote firmware for ESP32 on ESP-IDF. Since Saturday I have come across an unpleasant problem - judging by the notifications in the telegrams, TWO copies of the program are working on the controller at the same time. What happened and why - I can’t understand …
I suspect that the OTA update was not completed correctly, and now both images, which are written to FLASH, are launched at once. Can this be ???
Another sign that two copies are running is that gpio_install_isr_service (0) returns an “already installed” error. The sensors connected to the controller also work and do not work at the same time.
But if you connect a laptop to the device and look at the logs, then you can see the logs from only one copy. Can not understand…
Where to look?
kotyara12:
I suspect that the OTA update was not completed correctly, and now both images, which are written to FLASH, are launched at once. Can this be ???
I’ve never seen this happen. The bootloader decides at boot-time which is the active app partition and boots into that. Not both at the same time.
Is it possible that you provide a minimal reproducable example of this behavior? Hard to judge what’s going on otherwise.
Main firmware file:
/ *
Bathroom ventilation control + control of freezing pipes under the floor
-------------------------------------------------- -----------------------------------------------
(с) 2021 Razzhivin Alexander | Razzhivin Alexander
kotyara12@yandex.ru | https://kotyara12.ru | tg: @ kotyara1971
* /
#include "esp_log.h"
#include "project_config.h"
#include "rLog.h"
#include "rStrings.h"
#include "reLed.h"
#include "reNvs.h"
#include "reStates.h"
#include "reParams.h"
#include "reEvents.h"
#include "reEsp32.h"
#include "reWiFi.h"
#include "reSNTP.h"
#include "reMQTT.h"
#include "reSysInfo.h"
#include "reScheduler.h"
#include "reI2C.h"
#if CONFIG_PINGER_ENABLE
#include "rePinger.h"
#endif // CONFIG_PINGER_ENABLE
#if CONFIG_TELEGRAM_ENABLE
#include "reTgSend.h"
#endif // CONFIG_TELEGRAM_ENABLE
#if CONFIG_OPENMON_ENABLE
#include "reOpenMon.h"
#endif // CONFIG_OPENMON_ENABLE
#include "sensors.h"
extern "C" {
// Main function
void app_main (void)
{
// Debug messages about memory allocation errors
heap_caps_register_failed_alloc_callback (heap_caps_alloc_failed_hook);
// Suppress the output of unnecessary system messages (wifi, tcpip, ...)
esp_log_level_set ("wifi", ESP_LOG_NONE);
esp_log_level_set ("event", ESP_LOG_ERROR);
esp_log_level_set ("tcpip", ESP_LOG_ERROR);
esp_log_level_set ("tcpip_adapter", ESP_LOG_ERROR);
esp_log_level_set ("phy", ESP_LOG_ERROR);
esp_log_level_set ("phy_version", ESP_LOG_ERROR);
esp_log_level_set ("phy: phy_version", ESP_LOG_ERROR);
esp_log_level_set ("i2c", ESP_LOG_ERROR);
esp_log_level_set ("HTTP_CLIENT", ESP_LOG_NONE);
esp_log_level_set ("MQTT_CLIENT", ESP_LOG_NONE);
esp_log_level_set ("TRANS_TCP", ESP_LOG_NONE);
// Initialize "our" log and display the firmware version
rlog_empty ();
rloga_i ("Firmware initialization, version% s", APP_VERSION);
// Initialize LEDs
ledSysInit (CONFIG_GPIO_SYSTEM_LED, true, nullptr);
ledSysOn (false);
// Start the main event loop
eventLoopCreate ();
// Initialize the device tracking system
statesInit (true);
// Initialize the parameter storage system
paramsInit ();
// Initialize the I2C bus
initI2C (0, CONFIG_I2C_PORT0_SDA, CONFIG_I2C_PORT0_SCL, CONFIG_I2C_PORT0_PULLUP, CONFIG_I2C_PORT0_FREQ_HZ);
scanI2C (0);
initI2C (1, CONFIG_I2C_PORT1_SDA, CONFIG_I2C_PORT1_SCL, CONFIG_I2C_PORT1_PULLUP, CONFIG_I2C_PORT1_FREQ_HZ);
scanI2C (1);
// Register the "minute timer" and scheduling service, but don't start
schedulerEventHandlerRegister ();
#if CONFIG_PINGER_ENABLE
// Register a service for periodic checking of external servers and access to the Internet
pingerEventHandlerRegister ();
#endif // CONFIG_PINGER_ENABLE
// Start and register the time synchronization service
sntpTaskCreate (true);
// Start and register the MQTT client
mqttTaskStart (true);
// Register event handlers for parameters
paramsEventHandlerRegister ();
// Start and register the notification service in Telegram
#if CONFIG_TELEGRAM_ENABLE
tgTaskCreate (true);
#endif // CONFIG_TELEGRAM_ENABLE
// Start the service for sending data to open-monitoring.online
#if CONFIG_OPENMON_ENABLE
omTaskCreate (false);
#endif // CONFIG_OPENMON_ENABLE
// Start the service for reading data from sensors and control of ventilation and heating
sensorsTaskStart ();
// Connect to WiFi
if (wifiStartSTA ()) {
// Telegram notification about successful launch
#if CONFIG_TELEGRAM_ENABLE
// We are waiting for the WiFi connection and time synchronization
if (statesInetWait (portMAX_DELAY) && statesTimeWait (portMAX_DELAY)) {
tgSend (false, CONFIG_TELEGRAM_DEVICE, CONFIG_MESSAGE_TG_VERSION,
APP_VERSION, getResetReason (), getResetReasonRtc (0), getResetReasonRtc (1));
};
#endif // CONFIG_TELEGRAM_ENABLE
} else {
ledSysBlinkOn (1, 100, 250);
};
}
}
The most interesting thing … everything worked perfectly fine until Saturday. Of course, I will try to reflash to another crystal in the evening, but I want to understand the reason
Still, the problem was in the OTA sections. After flashing to another controller of the same type, the problem went away by itself. If you change the partition table by shifting the OTA addresses, then the problem is also solved. This means that in an exceptional case, firmwares from different partitions can still be launched simultaneously.