msddrvce.h

#include <msddrvce.h>

The msddrvce library implements routines for writing and reading data to/from Mass Storage Devices (MSD). Common MSDs include flash drives, SD cards, hard drives, and similar block-level storage devices. Both synchronous and asynchronous block read/write functions are provided by this library.

Known Limitations

  • The maximum drive size is 2TiB.

  • Only drives utilizing 512 byte logical blocks are supported.

Supported Devices

The following drives have been verified to work when used with a standard OTG adapter connector. Other devices may also work but may not have been tested. The msd_bandwidth program found in the msddrvce examples directory can be used to determine if the device is suitable. This program can also be used to test the bandwidth for reading/writing blocks on the device, given in the below table:

MSD Device

USB Version

Write KiB/sec

Read KiB/sec

Kingston DataTraveler 32GB

3.2 (Gen 1)

244.25

253.84

PNY Turbo 32GB

3.0

163.12

254.56

PNY Attache 16GB

2.0

85.16

244.70

PNY Elite-X Fit 64GB

3.1

131.71

252.86

onn. USB 2.0 Flash Drive 16 GB

2.0

190.16

251.98

Sandisk Ultra 32GB

3.0

222.57

253.29

Sandisk Cruzer Glide 32GB

2.0

232.94

252.94

API Documentation

Mass Storage Device (MSD) Driver.

Author

Matt “MateoConLechuga” Waltz

Author

Jacob “jacobly” Young

Defines

MSD_BLOCK_SIZE

Block size in bytes.

Typedefs

typedef struct msd_transfer msd_transfer_t

Enums

enum msd_error_t

Mass Storage Driver return codes.

Values:

enumerator MSD_SUCCESS = 0

Operation was successful.

enumerator MSD_ERROR_INVALID_PARAM

An invalid argument was provided.

enumerator MSD_ERROR_USB_FAILED

An error occurred in usbdrvce.

enumerator MSD_ERROR_SCSI_FAILED

An error occurred in scsi transfer.

enumerator MSD_ERROR_SCSI_CHECK_CONDITION

SCSI command failed.

enumerator MSD_ERROR_NOT_SUPPORTED

The operation is not supported.

enumerator MSD_ERROR_INVALID_DEVICE

An invalid usb device was specified.

enumerator MSD_ERROR_TIMEOUT

The transfer timed out.

Functions

msd_error_t msd_Open(msd_t *msd, usb_device_t usb)

Initialize a Mass Storage Device.

Parameters
  • msd – Uninitilaized MSD device structure.

  • usb – Initialized USB device structure.

Returns

MSD_SUCCESS on success, otherwise error.

void msd_Close(msd_t *msd)

Closes and deinitializes a Mass Storage Device.

This function should also be called in the USB_DEVICE_DISCONNECTED_EVENT in the USB handler callback.

Parameters

msd – Initialized MSD device structure.

msd_error_t msd_Reset(msd_t *msd)

Attempts to reset and restore normal working order of the device.

Parameters

msd – Initialized MSD device structure.

Returns

MSD_SUCCESS on success, otherwise error.

msd_error_t msd_Info(msd_t *msd, msd_info_t *info)

Gets the number of and size of each logical block on the device.

Parameters
  • msd – Initialized MSD device structure.

  • info – Pointer to store MSD information to.

Returns

MSD_SUCCESS on success.

msd_error_t msd_ReadAsync(msd_transfer_t *xfer)

Asynchronous block read.

You must set the following xfer elements: msd, lba, buffer, count, callback. The optional element userptr can be used to store user-defined data for access in the callback. The xfer argument must remain valid (cannot be free’d or lose scope) until the callback is issued. You can free xfer inside the callback as needed.

Parameters

xfer – Initialized transaction structure.

Returns

MSD_SUCCESS if the transfer has been added to the queue.

msd_error_t msd_WriteAsync(msd_transfer_t *xfer)

Asynchronous block write.

You must set the following xfer elements: msd, lba, buffer, count, callback. The optional element userptr can be used to store user-defined data for access in the callback. The xfer argument must remain valid (cannot be free’d or lose scope) until the callback is issued. You can free xfer inside the callback as needed.

Parameters

xfer – Initialized transaction structure.

Returns

MSD_SUCCESS if the transfer has been added to the queue.

uint24_t msd_Read(msd_t *msd, uint32_t lba, uint24_t count, void *buffer)

Synchronous block read.

Parameters
  • msd – Initialized MSD structure.

  • lba – Logical Block Address (LBA) of starting block to read.

  • count – Number of blocks to read.

  • buffer – Buffer to read into. Must be at least MSD_BLOCK_SIZE * count bytes.

Returns

Number of blocks read, on success should equal count.

uint24_t msd_Write(msd_t *msd, uint32_t lba, uint24_t count, const void *buffer)

Synchronous block write.

Parameters
  • msd – Iniailized MSD structure.

  • lba – Logical Block Address (LBA) of starting block to read.

  • count – Number of blocks to write.

  • buffer – Buffer to write. Must be at least MSD_BLOCK_SIZE * count bytes.

Returns

Number of blocks written, on success should equal count.

uint8_t msd_FindPartitions(msd_t *msd, msd_partition_t *partitions, uint8_t max)

Returns a list of partitions detected on the device.

You must allocate space for partitions before calling this function, as well as passing a valid msd_t returned from msd_Open.

Note

Currently MBR (msdos) and GUID (gpt) partition tables are supported.

Parameters
  • msd – Initialized MSD structure returned from msd_Open.

  • partitions – Returned array of partitions available.

  • max – The maximum number of partitions that can be found.

Returns

Number of partitions detected; partitions will be filled with valid partition information up to the number detected.

struct msd_t
struct msd_info_t

Public Members

uint32_t bsize

Size of each block in bytes.

uint32_t bnum

Number of blocks on MSD.

struct msd_transfer

Public Members

msd_t *msd

Initialized MSD device.

uint32_t lba

Logical block address.

void *buffer

Pointer to data location to read/write.

uint24_t count

Number of blocks to transfer.

void (*callback)(msd_error_t error, struct msd_transfer *xfer)

Called when transfer completes.

void *userptr

Custom user data for callback (optional)

struct msd_partition_t

Public Members

uint32_t first_lba

First Logical Block Address (LBA) of partition.

uint32_t last_lba

Last Logical Block Address (LBA) of partition.