Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Data logging with serial mirroring can lose data when there is a page erase #167

Open
microbit-carlos opened this issue Feb 4, 2022 · 3 comments

Comments

@microbit-carlos
Copy link
Collaborator

microbit-carlos commented Feb 4, 2022

With the micro:bit V2.2 boards when DAPLink is erasing a flash page if the CPU tries to access flash (e.g. to fetch an instruction) it will be blocked until the erase operation is done.

This affects the processing of serial data from the target to the interface, as DAPLink can be unresponsive for the 87.5ms it takes to erase a page.

So, when using data logging in a programme like this one, with serial mirroring enabled, whenever a page erase is triggered (after logging 4096 bytes) we lose some of the serial mirrored data.
This is also replicable with smaller strings, but then things like I2C "nops" and "null transactions" (which are enabled/disabled depending on multiple factors) can somewhat mitigate this, so this longer string is easier to replicate.

#include "MicroBit.h"

MicroBit uBit;

int  main() {
    uBit.init();
    uBit.serial.setTxBufferSize(250);
    uBit.log.setSerialMirroring(true);
    uBit.log.setTimeStamp(TimeStampFormat::None);

    while (true) {
        uBit.log.beginRow();
        uBit.log.logData("I", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890");
        uBit.log.endRow();
        uBit.sleep(20);
    }
}

And in a serial console we'll see and output similar to this extract:

...
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
...

Our current theory is that when writing to a new page MicrobitLog sends the serial data to the DMA or peripheral and then it sends the "erase page" command to DAPLink before all the serial data had time to be sent out of the target.
So once DAPLink starts erasing flash any UART from the target is dropped and that's when we see those issues in the serial output.

One simple solution could be to send the serial data after the DAPLink commands are processed.
Alternatively if there was a wait for CODAL to wait until all the data is out of the target that could work as well.

@martinwork
Copy link
Collaborator

Maybe wait for serial tx buffer to empty, then pause for 1 or 2ms here?
https://github.com/lancaster-university/codal-microbit-v2/blob/master/source/MicroBitLog.cpp#L763

If the serial.send calls were after the I2C flash commands, this might not actually need to wait, unless logging very fast.

@martinwork
Copy link
Collaborator

Created lancaster-university/codal-nrf52#41 "Add NRF52Serial::pauseTx".
This doesn't delay the logging, BUT... see the comment.
I've tested it by wrapping the erase command in MicroBitLog:

            serial.pauseTx(true);
            flash.erase(nextPage);
            serial.pauseTx(false);

This will block the DMESG calls inside erase. It could also be placed down in MicroBitUSBFlashManager::_transact.

The alternative I've made is to wait for the tx buffer to empty. I'll post that next.

@martinwork
Copy link
Collaborator

Created #176.
This uses fiber_sleep or target_wait to wait for times calculated from baud rate.
I thought of waiting for CODAL_SERIAL_EVT_TX_EMPTY but wasn't sure it was better or entirely safe.

If the serial.send calls were after the I2C flash commands, this might not actually need to wait, unless logging very fast.

But sending serial while logging to flash probably increases throughput.

@JohnVidler JohnVidler added p3 and removed p2 labels Jun 16, 2022
@microbit-carlos microbit-carlos added this to the datalog milestone May 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants