USB MSC host - last sector is not written to the drive
I've created two USB MSC host applications with CubeMX (1.3.1) for two STM32H743 boards. One of them is a stock Nucleo-H743ZI2 using the OTG_FS interface, the other one is a custom board with STM32H743II using OTG_HS with the internal transceiver.
Then tried it with a couple of flash drives lying around. Reading files worked well on all drives. Writing stuff worked on all of them except one, where the directory entry was apparently not updated.
I've removed the fatfs stuff to test single-sector write and got this:
(I hope it goes without saying that you don't try it on a drive with valuable data. Sector 9 was unused on my drives, it might contain the root directory on yours.)
#include "main.h"
#include "string.h"
#include "fatfs.h"
#include "usb_host.h"
extern USBH_HandleTypeDef hUsbHostFS;
#define SECTOR 9
#define BS 512
uint32_t buf2[BS/4];
void usbtest(void) {
int r;
uint32_t j;
while(1) {
setleds(5);
while(!USBH_MSC_IsReady(&hUSB_Host)) // wait until a USB drive is inserted
MX_USB_HOST_Process();
memset(buf2, 6, BS); // clear buffer
r = USBH_MSC_Read(&hUSB_Host, 0, SECTOR, (void*)buf2, 1); // read one sector
while(r != USBH_OK) {
setleds(4);
__NOP();
}
j = buf2[0];
setleds(j);
buf2[0] = (j + 1) & 3; // modify sector data
r = USBH_MSC_Write(&hUSB_Host, 0, SECTOR, (void*)buf2, 1); // write it back
while(r != USBH_OK)
__NOP();
#if 0 // workaround
r = USBH_MSC_Read(&hUSB_Host, 0, SECTOR, (void*)buf2, 1); // read the sector again
while(r != USBH_OK)
__NOP();
#endif
while(USBH_MSC_IsReady(&hUSB_Host)) // wait until the drive is removed
MX_USB_HOST_Process();
}
}Reading succeeds, writing fails silently (i.e. return value is USBH_OK, but the sector is not modified) on that one drive, succeeds on the rest. Unless I enable the workaround, reading back the sector I've just written (or any other sector).
The offending drive is a 8 to 10 years old 16 GB Intenso Business Line, which still works perfectly in my PC.
I am quite clueless about USB, so my questions are bit vague
- Have I missed something, am I doing something wrong? Where should I look?
- Is there a better way to fix it? Maybe an SCSI command to flush some cache?
- If yes, then when and how can I issue it?
