ruuvi.firmware.c icon indicating copy to clipboard operation
ruuvi.firmware.c copied to clipboard

NFC read may cause tag to freeze (reopen)

Open mhaberler opened this issue 2 years ago • 40 comments

I frequently encounter tag freezes during NFC read with my NFC reading code

in particular this happens during an unsucessful read (UID retrieved, but not the NDEF messages - typically weak RF coupling)

disconnecting/reconnecting the battery makes the tag work again - I think this is the same as https://github.com/ruuvi/ruuvitag_fw/issues/139

this is next to a showstopper for us as diagnosis and reset of the tag in the field is cumbersome and the tag seems not to recover without help

prepared to help debugging given advice - I do have a Dev Shield at hand

mhaberler avatar Feb 03 '24 04:02 mhaberler

it seems the tag eventually reboots all by itself

I just tried a previously locked-up tag and it could be NFC-read cleanly

what is the trigger for a reboot? cyclic? if so, how long?

mhaberler avatar Feb 04 '24 14:02 mhaberler

it seems the tag recovers with a few minutes, which is good enough to live with

mhaberler avatar Feb 04 '24 21:02 mhaberler

I reopened this as this may be something that we would like to try to reproduce and fix.

laurijamsa avatar Feb 05 '24 00:02 laurijamsa

@mhaberler could you report the RuuviTag firmware version you are running in case it was not mentioned yet? Thanks!

markoaamunkajo avatar Feb 05 '24 02:02 markoaamunkajo

will do but I will have access to the debug setup only wednesday onwards

this was a custom-built version with a modified I2C address for the external TMP117, will dig up the source - should have it later today @amonvinc @alueger

mhaberler avatar Feb 05 '24 02:02 mhaberler

Thank you for the report.

We used to have problems with NFC, the problem was supposedly fixed in v3.29.0 / https://github.com/ruuvi/ruuvi.drivers.c/commit/95d621648eaa9864da3a9f773b5b3abfaa0d9018 by updating the NFC driver to use latest binary from Nordic.

What exactly "freezes" means? Data stops updating, but old data is still broadcasted or tag does not broadcast at all? In any case, if tag freezes, e.g. by looping in NFC interrupt handler the watchdog timer will reboot the tag in 6 minutes because the heartbeat() does not run https://github.com/ruuvi/ruuvi.firmware.c/blob/master/src/app_heartbeat.c. You can adjust the watchdog trigger conditions there and configure the watchdog timer interval at https://github.com/ruuvi/ruuvi.firmware.c/blob/2778a3f0fcb08f0c5f26ba6ac13b7ad691f3cbeb/src/application_config/app_config.h#L43

Reboot clears the stored data in flash because timestamps lose their accuracy on reboot.

ojousima avatar Feb 05 '24 07:02 ojousima

6 minutes is just fine.

with "freeze" I meant "no reaction to NFC reader" - not even UUID readable

I'll retry and see if sensor updates still happen in this state, will report

edit: need to replace the battery (now at 5%) and see if I can reproduce with new battery, might take till tomorrow

mhaberler avatar Feb 05 '24 08:02 mhaberler

Here is another app I sucessfuklly used to read nfc: NFC Tap https://www.st.com/en/embedded-software/stsw-st25ios001.html
or go to App Store or google play store I don't like kit as well as NRC tools as it is more tailored to ST25 tags by STMicroelectronics

DG12 avatar Feb 06 '24 00:02 DG12

To test out NFC Tap I scanned 2 different tags (ECOF and 450A) with SW:Ruuvi FW v3.31.1+default about 20 times each with no "freezing" (no partial reads since I know exactly where to place the iPhone to get a good signal.

DG12 avatar Feb 06 '24 00:02 DG12

it happens rarely, maybe one in 20-50 reads

out of 2 tags I managed to get one frozen since yesterday, put it away now for > 6 minutes and it still does not respond

a good test for a frozen tag is to put it onto the ACR122U NFC reader - a live tag will make it beep and turn the reader's led green; frozen tag: no reaction

the branch we were using at the time is a bit behind master, will rebase and see what happens

I also noticed that at least with the RFID2 reader, after a successful I need to move the reader at least 5cm, better like 10cm away to safely "NFC disconnect" (for a lack of a more exact term) the tag

I'll have a look if the MFRC522 driver can detect the "Tag leaves RF field" condition

there is also two specific things I will try in my reading code:

one of the example codes for the MFRC522v2 driver explicitly halts the tag after a successful read with reader.PICC_HaltA() operation

the other thing I'm suspicious about is this line - it might mean the PICC is left in an incommunicado state

in theory a PICC (or the tag for that matter) should be able to recover though from this state eventually

so my plan is:

  • new batteries
  • rebase code to 3.31 (or 3.32.0?) and reflash
  • add PICC_HaltA and PCD_StopCrypto1 calls in my reading code after a successful read
  • see if I still can get a tag to freeze

mhaberler avatar Feb 06 '24 04:02 mhaberler

@ojousima as for your question "does the tag still advertise values if NFC-frozen": no, it does not, updates stop

--> correction: I was wrong on that, the tag still advertises values!

edit: the tags battery was at 53% when the freeze happened, the code I use for that is:

uint8_t volt2percent(const float v) {
    // convert voltage and scale for CR2032
    float percent = (v - 2.2f) / 0.65f * 100.0f;
    if (percent < 0.0f) {
        return 0;
    }
    if (percent > 100.0f) {
        return 100;
    }
    return (uint8_t) percent;
}

mhaberler avatar Feb 06 '24 04:02 mhaberler

I now have two tags NFC-frozen

  • one is running 3.31.0-default not sending updates any more
  • the other one is running our custom firmware as linked above still sending updates

mhaberler avatar Feb 06 '24 05:02 mhaberler

@DG12 I have not yet encountered a case where I could NFC-freeze a tag with something else other than my own code

however, once the tag enters this frozen state no other utility I tried can get an NFC response

mhaberler avatar Feb 06 '24 05:02 mhaberler

Have you connected Dev Shield ? Run with j-link & RTT ? Is firmware compiled with RUUVI_NRF5_SDK15_LOG_ENABLED TRUE ?

Does the firmware have calls to ri_log , NRF_LOG...standard

Can you run with a +debug version? DO you have the symbol/address map from the loader?

DG12 avatar Feb 06 '24 12:02 DG12

Off topic : battery percent: Have you read https://github.com/ruuvi/ruuvitag_fw/wiki/FAQ:-battery

Why did you choose 2.2 as a minimum? .65 ? Do you consider once a battery appears as "low" it must always report low until reset? What kind on environment are the tags in respect to temperature changes? How important is availability of data (i.e. What is impact of tag not transmitting) How easy is its to get a tag and replace the battery?

DG12 avatar Feb 06 '24 13:02 DG12

--> correction: I was wrong on that, the tag still advertises values!

Thank you for the update. This might actually be enough to not trigger the watchdog timer, in this case the reboots would be caused by battery collapsing under load.

one is running 3.31.0-default not sending updates any more

Does this tag reboot in 6 minutes?

@DG12 I have not yet encountered a case where I could NFC-freeze a tag with something else other than my own code

NFC code or tag firmware?

We used to handle the NFC freezes by rebooting the tag after NFC read in 2.X firmwares, that approach was dropped to keep the history in 3.X. Does your application use logged history data? If not, we could program in a reboot after NFC read to avoid freezes.

ojousima avatar Feb 06 '24 18:02 ojousima

Have you tried to NFC write to a frozen tag?

DG12 avatar Feb 06 '24 19:02 DG12

Have you tried to NFC write to a frozen tag?

no, because thats not possible - as I described above, the NFC reader would not even detect the presence of a tag

mhaberler avatar Feb 06 '24 20:02 mhaberler

@ojousima after a few hours, the situation is still the same:

both tags do not react to an RFID reader - neither my RFID2 contraption nor the ACR122U reader

the Ruuvi running 3.31.0-default still sends updates the Ruuvi running our custom code with the external TMP 117 does not

I now have the DevShield at hand and will try with a logging build and the debugger

mhaberler avatar Feb 06 '24 20:02 mhaberler

I built 3.31.0 with -DDEBUG

Console log:

00> Movement 
00> Movement             

---- here I scanned with the RFID2 reader and my code, tag still NFC-sponsive:

0> app_heartbeat.c:101 WARNING: INVALID_STATE       
00> app_heartbeat.c:101 WARNING: INVALID_STATE
00> <info> app: Setting vector table to bootloader: 0x00075000
00> <info> app: Setting vector table to main app: 0x00026000
00> app_heartbeat.c:101 WARNING: INVALID_STATE
00> app_heartbeat.c:101 WARNING: INVALID_STATE
00> app_heartbeat.c:101 WARNING: INVALID_STATE
00> <info> app: Setting vector table to bootloader: 0x00075000
00> <info> app: Setting vector table to main app: 0x00026000

any compilation flag/defines suggestions?

for debugging: are you using Segger SES?

mhaberler avatar Feb 06 '24 23:02 mhaberler

I usually use Segger j-link. SES is much better and easier to work with IF you have the source files!

I am surprised to see two sets of messages "Setting Vector..." which occur when NFC receives a read with the tag being FROZEN.

Heartbeat...INVALID_STATE are unusual (for me)

DG12 avatar Feb 07 '24 00:02 DG12

00> app: Setting vector table to bootloader: 0x00075000 00> app: Setting vector table to main app: 0x00026000

I think this is related to enabling the buttonless DFU service on NFC scan.

0> app_heartbeat.c:101 WARNING: INVALID_STATE

Does this line come up reliably on frozen tags? If yes, can you try changing the line

    // Advertising should always be successful
    RD_ERROR_CHECK (err_code, ~RD_ERROR_FATAL);

to

    // Advertising should always be successful
    RD_ERROR_CHECK (err_code, RD_SUCCESS);

?

This should reboot the tag instantly after the error occurs, history is still lost but it's better than a stuck tag.

ojousima avatar Feb 07 '24 14:02 ojousima

@ojousima this particular log is from a new tag in a DevShield, separate from the (still NFC-frozen) other two tags

I built an image from 3.31.0 and flashed that then tried a couple of NFC reads I have NOT yet managed to NFC-freeze this dev setup - I will try to and keep a console log

the log you see is just from my - so far successful - NFC-reading attempts

mhaberler avatar Feb 07 '24 15:02 mhaberler

should I still try the change you suggested above?

edit: any suggestions on how to debug this setup? I have SES installed

mhaberler avatar Feb 07 '24 15:02 mhaberler

100+ tries with a build with CFLAGS+= -DDEBUG - works perfectly every time

20 or so tries with a build without -DDEBUG: NFC-frozen and stuck for > 6min

updates still sent - same symptom as the other two tags

movements are still reported with RTT Viewer so the basic functionality seems alive:

00> Movement 00> Movement 00> LOG: Storing block 00> store_block:creating new record #61441

I hope this is not a timing-dependent bug..

@ojousima do you see a way I can break into that tag post-freeze with a debugger?

mhaberler avatar Feb 07 '24 17:02 mhaberler

btw

00> app_heartbeat.c:101 WARNING: INVALID_STATE

does not come up with the non-debug build which got NFC-frozen

this looks to me as if after a NFC interaction considered finished, NFC "listening" mode is not properly reinitialized

I do not exclude this is caused by my code somehow

mhaberler avatar Feb 07 '24 17:02 mhaberler

btw 00> app_heartbeat.c:101 WARNING: INVALID_STATE does not come up with the non-debug build which got NFC-frozen should I still try the change you suggested above?

The warning about state is then probably about trying to write NFC contents while the NFC field is detected, and after the freeze the new connection does not register. In this case changing the RD_ERROR_CHECK would probably not be helpful, tag would end up resetting after every successful NFC read and possibly not after a failed read. It might make more sense to start a reboot timer instead.

100+ tries with a build with CFLAGS+= -DDEBUG - works perfectly every time 20 or so tries with a build without -DDEBUG: NFC-frozen and stuck for > 6min updates still sent - same symptom as the other two tags movements are still reported with RTT Viewer so the basic functionality seems alive: 00> Movement 00> Movement 00> LOG: Storing block 00> store_block:creating new record #61441 I hope this is not a timing-dependent bug..

The only change between the builds is -DDEBUG flag? most importantly, the debug build is not compiled with `OPT="-Og" like the official test binary?

Can you verify the power consumption of a frozen tag somehow? I'd like to understand if this issue is same as we had before, the NFC driver did not release high-frequency clock which lead to excess power consumption.

I think it would bet possible to get more information by logging the NFC events here: https://github.com/ruuvi/ruuvi.drivers.c/blob/2555fc5c9725747084b1ab7c52b29e4a4b9dedab/src/nrf5_sdk15_platform/communication/ruuvi_nrf5_sdk15_communication_nfc.c#L47

Have you made any changes to NFC interrupt handlers at https://github.com/ruuvi/ruuvi.firmware.c/blob/2778a3f0fcb08f0c5f26ba6ac13b7ad691f3cbeb/src/app_comms.c#L572?

Is this issue repeatable without your NFC hardware?

ojousima avatar Feb 07 '24 21:02 ojousima

yes, -DDEBUG added in this file for the debug build, zero changes from 2c544d with the build which NFC-freezes: https://github.com/ruuvi/ruuvi.firmware.c/blob/v3.31.0/src/targets/ruuvitag_b/armgcc/Makefile

consequently also no changes in the NFC interrupt handlers

yes, I can check the power consumption, I have that Nordic power measurement board - will do

also will add logging as suggested

yes, the issue is repeatable - I have 3 NFC-frozen tags on my desk

if you have an ESP32 (I use a S3 but really any should do) and shell out 5€ for the RFID2 reader you should be able to reproduce easily

just build https://github.com/mhaberler/MFRC522v2_t4tag.git with Platformio, adapting the ini for your board and possibly the I2C pins

later I'll do a torture-test branch in this repo which tries a read every few seconds and turns off the RF field inbetween, so the test can run automatically

mhaberler avatar Feb 07 '24 22:02 mhaberler

here's the torture-test: https://github.com/mhaberler/MFRC522v2_t4tag/tree/torture-test torturing the tag now..

mhaberler avatar Feb 08 '24 11:02 mhaberler

seems the torture test does not do its job.. 3600 successful reads in sequence will wiggle the timing and see if this helps to trigger the freeze

mhaberler avatar Feb 08 '24 15:02 mhaberler