Anomalous RTC2_IRQn generated after DFU

EDIT: the IRQ is always generated by the RTC2, the Radio is not involved

Hello,
we are facing a strange issue with the FW development on nRF52832.
Suddendly after a FW update OTA via BLE (using a slighly changed version of Secure BLE DFU Bootloader) the MCU starts consuming a lot (about 3.3mA) but keeps working as expected for the remaining functionalities.

Here is the conditions generating the issue:

HW: nRF52832

FW: SDK 16, sd132 6.1.1

BLE Role: Single connection as Peripheral

  1. Update only the Main App using OTA update via BLE, bootloader is the one present in ..\examples\dfu\secure_bootloader\pca10040_s132_ble with minor changes into the user init of dfu;
  2. At restart, clear the whitelist deleting the previous peer if present;
  3. Bond with the Central, bonding procedure is started by the Central with pm_conn_secure(...);
  4. Disconnection and reconnection of the Central randomly generated;

As a consequence of the above steps the MCU after a short time (seconds to minutes) starts consuming around 3.3mA.
Not sure that step 4 is affecting the phenomenon since it occurs both during the connected and disconnected status.

Debugging we managed to retrieve the cause of the anomalous consumption by printing in the nrf_pwr_mgmt_run the wake up source from idle.
The RTC2_IRQn  is continuosly generated (I suppose from the Softdevice since there is no use of RTC2 in the code) with a frequency of about 7350 Hz, therefore continusly waking up the MCU from the sd_app_evt_wait().
The MCU continues working but with a usage percentage around 75% (all due to the interrupts) and therefore an high power consumption.

This strange behaviour occurs only after a FW update via OTA, I couldn't reproduce it differently.

As a workaround at the moment we are counting the number of interrupts per second in the nrf_pwr_mgmt_run , in case it exceeds a reasonable threshold (2k events) we reset the MCU, therefore we avoid the anomalous consumption from draining the battery. However this is not a solution but just a workaround.

Suggestion on the reasons behind these strange triggers and how to avoid them?

In case you need more details or info please let me know.
I will share what we possibily could share.

Parents
  • Hi,

    1) Are you seeing this on custom HW, or the nRF52832 DK? 

    ->If you are using custom HW, are you able to reproduce it on the nRF52832-DK?

    2) Are you able to reproduce this with the latest nRF5-SDK version ,and SoftDevice version ?

  • Hi Sigurd,
    tentatively I created a fork project of the one described above using SDK 17 and softdevice sd132 - 7.2.0

    The problem of the anomalous power consumption due to continuous interrupts persists, nothing changed.
    Did you find something?

  • Hi,

    campy_electronics said:
    As you can see from the log, in this case the trigger is generated by the RTC2 instead of the RADIO, however, the RTC2 is not even initialize in our code.

    The RTC2 timer is used in the bootloader project. So could be that it's somehow still running after your application is booted.

    Suddendly after a FW update OTA via BLE (using a slighly changed version of Secure BLE DFU Bootloader)

    What was slighly changed?

  • Hi,

    The RTC2 timer is used in the bootloader project. So could be that it's somehow still running after your application is booted.

    I noticed that but we did not change the code regarding the RTC2 used by the watchdog and timeout timers. And if the RTC2 was still enabled, it should trigger the interrupt regularly from the restart of the code in the main app. Instead, the time it takes to manifest the anomalous triggers is variable.

    What was slighly changed?

    We replaced the "nrf_bootloader.c" with a custom_nrf_bootloader.c, which is almost the same but differs in  the "loop_forever" function where we added a function that changes the advertising name with a runtime built one and manages the switches and leds of the custom board.
    The functions for managing the leds use the apptimer from nordic though. I will try to remove these functions and run the test once again.

  • I will try to remove these functions and run the test once again.

    I tried this out, the problem is still there even with standard bootloader without any customization.

    My guess is that it is related to the writing in flash with FDS using SD, since the problem occurs when we bond to the central and write the peer info in flash, however it is unknown why it manifests only after OTA update.

    On the PCA10040 the time it takes to enter the continuous trigger is around 150s, however we have no timer set to this extent in the code. Is there anything in the sd?

Reply
  • I will try to remove these functions and run the test once again.

    I tried this out, the problem is still there even with standard bootloader without any customization.

    My guess is that it is related to the writing in flash with FDS using SD, since the problem occurs when we bond to the central and write the peer info in flash, however it is unknown why it manifests only after OTA update.

    On the PCA10040 the time it takes to enter the continuous trigger is around 150s, however we have no timer set to this extent in the code. Is there anything in the sd?

Children
  • campy_electronics said:
    however it is unknown why it manifests only after OTA update.

    If you after the OTA update, turn the device off, and on again, do you still see the issue?

  • do you still see the issue?

    Turning OFF and ON the board the issue never occurs.

    The problem is only at the reset after the bootloader OTA.

  • Hi Sigurd,
    attached is the debug window with RTC2 registers after the DFU.

    Unfortunately the issue doesn't occur with the debugger connected, therefore I am not sure that such a test is representative of the real problem occurring only when there is no debugger or RTT viewer session ongoing.

    EDIT: I tried to enter debug mode without reset and code loading after that the issue occurs.

    As you can see in the picture below, there actually is the timer COMPARE0 enabled and the counter is running as if the bootloader initialized the RTC2 without resetting.

    Hoping it is not an artifact due to the debug mode I setup, there actually is the RTC2 set with the EVENTS_COMPARE[0] triggered.

    I also halted the MCU in the normal reset conditions (without passing through DFU update) and as you can see the RTC2 is not even enabled in this case.

    On the other hand, halting the MCU after a DFU but before the issue you can see that the RTC is still enabled but there is no EVENT_COMPARE[0] generated

    Therefore my guess is:
    the DFU initialize the RTC2 to use timers during DFU, however after the RESET the RTC2 registers are not reset properly. On the other hand, with Hardware Reset the registers from RTC2 are cleared and therefore there is no event generated at the compare of the RTC2 counter.
    Since there is no handling of the RTC2 events, the MainApp doesn't handle the RTC event and therefore it keeps triggering without clearing the flag.

    Now, the question is:

    1) Why is the RTC2 not uninitialized by the bootloader before jumping to the app?

    2) How is it possible to reset "like" hardware reset after DFU?

  • Hi,

    campy_electronics said:
    Unfortunately the issue doesn't occur with the debugger connected

    You can also read and print the register values with nrf_log/printk.

    campy_electronics said:

    Now, the question is:

    1) Why is the RTC2 not uninitialized by the bootloader before jumping to the app?

    2) How is it possible to reset "like" hardware reset after DFU?

    After a DFU is completed, the device will do a system/hardware reset. When it boot up again, It will enter the bootloader, and determine if it should either enter DFU mode, or boot the app. Only when it enters DFU mode, RTC 2 started. If it's booting the app, the RTC2 is not started, and there is no reason to uninitialize it. Most likely you are somehow starting RTC2 in your app.

    Maybe you can print the RTC2 values early in your app main()

Related