USB MSC FAT FS corruption on USB power off with NRF_BLOCK_DEV_QSPI_FLAG_CACHE_WRITEBACK flag turned on

Hello,

I'm experiencing FAT FS corruption (files disappear or files disappear + "volume is full" error on any file write), when I'm unplugging my USB cable. Here is my environment:

SDK 17.1.0

nrf52840 dev kit 2.0.0

W25Q128FV flash connected to the dev-kit pins

Host OS: Mac OS 12.6

QSPI and MSC config:

#define QSPI_CONFIG                                               \
  {                                                                       \
    .xip_offset = NRFX_QSPI_CONFIG_XIP_OFFSET,                            \
    .pins =                                                               \
        {                                                                 \
            .sck_pin = QSPI_SCK_PIN,                                      \
            .csn_pin = QSPI_CS_PIN,                                       \
            .io0_pin = QSPI_MOSI_PIN,                                     \
            .io1_pin = QSPI_MISO_PIN,                                     \
            .io2_pin = NRF_QSPI_PIN_NOT_CONNECTED,                        \
            .io3_pin = NRF_QSPI_PIN_NOT_CONNECTED,                        \
        },                                                                \
    .prot_if =                                                            \
        {                                                                 \
            .readoc = NRF_QSPI_READOC_FASTREAD,                           \
            .writeoc = NRF_QSPI_WRITEOC_PP,                               \
            .addrmode = NRF_QSPI_ADDRMODE_24BIT,                          \
            .dpmconfig = false,                                           \
        },                                                                \
    .phy_if =                                                             \
        {                                                                 \
            .sck_delay = (uint8_t)2,                                      \
            .dpmen = false,                                               \
            .spi_mode = (nrf_qspi_spi_mode_t)NRF_QSPI_MODE_0,             \
            .sck_freq = (nrf_qspi_frequency_t)NRF_QSPI_FREQ_32MDIV2,      \
        },                                                                \
    .irq_priority = (uint8_t)NRFX_QSPI_CONFIG_IRQ_PRIORITY,               \
  }

NRF_BLOCK_DEV_QSPI_DEFINE(
    m_block_dev_qspi,
    NRF_BLOCK_DEV_QSPI_CONFIG(512, NRF_BLOCK_DEV_QSPI_FLAG_CACHE_WRITEBACK,
                              QSPI_CONFIG),
    NFR_BLOCK_DEV_INFO_CONFIG("Nordic", "QSPI", "1.00"));
    
#define MSC_WORKBUFFER_SIZE (1024)

#define BLOCKDEV_LIST() (                                   \
    NRF_BLOCKDEV_BASE_ADDR(m_block_dev_qspi, block_dev)     \
)

APP_USBD_MSC_GLOBAL_DEF(m_app_msc,
                        MSC_COMM_INTERFACE,
                        msc_user_ev_handler,
                        (MSC_COMM_EPIN, MSC_COMM_EPOUT),
                        BLOCKDEV_LIST(),
                        MSC_WORKBUFFER_SIZE);

Definitions:

  • USB - usb cable connected to nrf USB connector in the dev-kit and to the host PC
  • PROG - usb cable connected to JLink connector in the dev-kit and to the host PC
  • Safe\Unsafe eject - means that the flash drive was removed safely\unsafely from the host OS

Pre-condtions:

  • Flash is being pre-formatted into FAT16 in all tests
  • A random 6kb file was uploaded to flash before every test, safely ejected, plugged back again, checked it is not corrupted and safely ejected again
  • Power switch is set to VDD in all tests. Unplugging PROG cable, while USB is connected remains both SPI flash and nordic being powered on. 
  • During the tests there are no write operations performed by user (most likely the OS are doing it hidden from me, by writing .DS_Store files, etc)

Given that on my dev-kit I have performed the following tests:

1. USB powered on, PROG powered on. Turning off and turning on power switch in dev-kit.

RESULT ok: the FS keeps to be correct, despite the number of on\off attempts.

2. USB powered on, PROG powered on. Unplugging and plugging USB cable back and forth in "unsafe ejection" mode.

RESULT ok: FS keeps to be correct, despite the number of on\off attempts.

3. USB powered on, PROG powered OFF. Unplugging and plugging USB cable back and forth in safe or unsafe ejection mode (the behaviour doesn't change in both modes).

RESULT fail: FS is corrupted immediately or after 2-3-4 attempt. Empty filesystem or empty + disk is full error FS.

4. USB powered on, PROG powered on. Firstly the PROG cable is unplugged, then USB cable is unplugged both in safe\unsafe ejection modes.

RESULT fail: FS is corrupted immediately or after 2-3-4 attempt. Empty filesystem or empty + disk is full error FS.

5. USB powered on, PROG powered on. Firstly the USB cable is unplugged in safe\unsafe modes, then the PROG cable unplugged.

RESULT ok: FS keeps to be correct, despite the number of on\off attempts.

My colleague who is working on 1.0.0 dev-kit, Linux host and all the rest environment is same - also can reproduce this. May be not so frequently as I am (I can reproduce almost every 1st attempt, he can - every 3-4th attempt).

Basically, I come to a conclusion it only happens, when the USB power is removed and there are no other power sources being connected to the device. As mentioned safe or unsafe unplugging - doesn't impact on result. The most important part - if I turn off NRF_BLOCK_DEV_QSPI_FLAG_CACHE_WRITEBACK, then the FS is not being corrupted in tests 3 and 4. So I assume this is a software related bug in SDK. I've read about similar bugs in 17.0.2, but since I'm on 17.1.0 and I checked that I already have all the required fixes discussed in those topics before.

Could you please help me with that? We are in production right now and I'm worried the final product will contain this bug as well. Turning off NRF_BLOCK_DEV_QSPI_FLAG_CACHE_WRITEBACK is a possible workaround, but not sure this is a correct way to go. Thank you!

Kind regards,

Oleh Hordiichuk

Related