USB Mass Storage Device (MSD) Simple Example
Overview
This example demonstrates USB Mass Storage Device Host functionality on the NetBurner MOD5441X platform. The application acts as a USB host, allowing connection to external USB flash drives for file operations including reading, writing, and directory management. This provides embedded systems with the ability to interface with standard USB storage devices for data logging, file transfer, and storage expansion.
Supported Platform
- MOD5441X - MOD54415/MOD54417 core modules only
Hardware Requirements
Essential Components
- MOD5441X core module - MOD54415 or MOD54417 with USB OTG support
- NBUSB-ADPT-100R - NetBurner USB development adapter
- MOD-DEV-70CR - Development board for USB connector access
- USB flash drives - Standard USB 2.0 flash drives (FAT16/FAT32 formatted)
Hardware Assembly
Assembly Stack (bottom to top):
1. MOD-DEV-70CR development board (base)
2. MOD5441X core module (mounted on dev board)
3. NBUSB-ADPT-100R adapter (plugged into USB connector)
4. USB flash drive (plugged into adapter)
Power Requirements
- USB Host Power: 5V supply to USB port (controlled by VBUS_ENABLE)
- Flash Drive Power: Supplied through USB host port
- Current Budget: Up to 500mA for USB device power
Features
USB Host Stack Functionality
- USB 2.0 Host Support - Full-speed and high-speed device support
- Mass Storage Class - Standard USB MSD device compatibility
- Hot-plug Detection - Automatic device insertion and removal detection
- VBUS Power Control - Programmable 5V power supply to USB devices
File System Operations
- EFFS Integration - NetBurner Embedded Flash File System support
- FAT16/FAT32 Support - Standard PC-compatible file systems
- Directory Operations - File and folder listing, navigation
- File I/O Operations - Create, read, write, delete operations
- Space Management - Free space calculation and monitoring
Interactive Menu System
- Menu-driven Interface - Simple command-based operations
- Real-time Status - Device connection and operation feedback
- Error Handling - Comprehensive error reporting and recovery
- Test File Operations - Built-in test file creation and verification
Application Menu System
Menu Options (when USB drive connected)
MSD driver version: 1.0
1 = Attach file system to USB drive
2 = Display current directory
3 = Create test file: "testnb.txt"
4 = Read "testnb.txt"
5 = Delete "testnb.txt"
Menu Command Functions
Command 1: Attach File System
- Purpose: Initialize file system access to USB drive
- Operation: Mount USB drive and prepare for file operations
- Result: File system ready for read/write operations
Command 2: Display Directory
- Purpose: List all files and directories on USB drive
- Output Format: Filename and file size display
- Navigation: Recursive directory traversal and display
Command 3: Create Test File
- Purpose: Create and write test content to "testnb.txt"
- Content: Multiple test lines and character patterns
- Verification: File creation confirmation and size reporting
Command 4: Read Test File
- Purpose: Read and display contents of "testnb.txt"
- Output: Character-by-character file content display
- Validation: File integrity and readability verification
Command 5: Delete Test File
- Purpose: Remove "testnb.txt" from USB drive
- Confirmation: Delete operation success/failure reporting
- Cleanup: File system space recovery
Technical Implementation
USB Host Stack Architecture
Initialization Sequence
if (MSDOpen(&ossFileCommander, &iMSDAppVolume) == 0) {
StartMSDTask();
VBUSEnable(1);
} else {
printf("MSD initialization failed\n");
}
Device Detection and Mounting
if (device_connected) {
int result = f_chdrive(msdDriveNum);
if (result == F_NO_ERROR) {
driveOpen = true;
printf("USB drive mounted successfully\n");
}
}
File System Operations
Directory Listing Implementation
int Dir(void) {
F_FIND find;
if (result == F_NO_ERROR) {
printf("%s\n", find.filename);
while ((result =
f_findnext(&find)) == F_NO_ERROR) {
printf("%s\n", find.filename);
}
}
return result;
}
#define f_findfirst(filename, find)
Find the first file or subdirectory in a specified directory.
Definition api_f.h:458
#define f_findnext(find)
Finds the next file or subdirectory in a specified directory after a previous call to f_findfirst() o...
Definition api_f.h:474
File Writing Operations
int WriteFileTest(const char *fileName) {
F_FILE *file =
f_open(fileName,
"w+");
if (file) {
f_write(
"testline1 \r\n", 12, 1, file);
f_write(
"testline2 \r\n", 12, 1, file);
f_write(
"testline3 \r\n", 12, 1, file);
f_write(
"testline4 \r\n", 12, 1, file);
f_write(
"testline5 \r\n", 12, 1, file);
for (int i = 0; i < 40; i++) {
f_putc('\r', file);
f_putc('\n', file);
for (int j = 48; j < 91; j++) {
f_putc(j, file);
}
}
f_flush(file);
printf("Created file: %s\n", fileName);
return 0;
}
printf("Error: could not create file: %s\n", fileName);
return 1;
}
#define f_write(buf, size, size_st, filehandle)
Write data to the file at the current position.
Definition api_f.h:538
#define f_close(filehandle)
Closes an opened file.
Definition api_f.h:487
#define f_open(filename, mode)
Opens a file in the file system.
Definition api_f.h:512
File Reading Operations
int ReadFileTest(const char *fileName) {
F_FILE *file =
f_open(fileName,
"r");
char character;
if (file) {
printf("File Opened OK\n");
while (
f_read(&character, 1, 1, file) > 0) {
printf("%c", character);
}
printf("Done reading file\n");
return 0;
}
printf("Error: could not open %s\n", fileName);
return 1;
}
#define f_read(buf, size, size_st, filehandle)
Read data from the current position in a file.
Definition api_f.h:526
USB Power Management
VBUS Control
VBUSEnable(1);
VBUSEnable(0);
Power Sequencing
- System Initialization - Core module and USB stack startup
- VBUS Enable - Provide 5V power to USB connector
- Device Detection - Wait for USB device insertion
- Enumeration - USB host identifies connected device
- MSD Recognition - Verify device is Mass Storage Class
- File System Mount - Initialize EFFS access to device
Usage Instructions
Setup Process
- Hardware assembly
- Mount MOD5441X on MOD-DEV-70CR development board
- Install NBUSB-ADPT-100R USB adapter
- Prepare USB flash drive (FAT16 or FAT32 formatted)
- Build and deploy
make clean
make
make load DEVICE_IP=<your_device_ip>
- Connect terminal
- Serial terminal: 115200 baud, 8-N-1
- Connect to NetBurner debug port
Operation Procedure
Initial Startup
Application MOD54415_USB_MSD_2 started
MSD driver version: 1.0
[Menu appears when USB drive is detected]
USB Drive Connection
- Insert USB flash drive into NBUSB-ADPT-100R adapter
- Wait for detection - System will automatically detect device
- Menu activation - Interactive menu becomes available
- File system access - Ready for file operations
Testing Sequence
[Press '1'] - Attach file system to USB drive
[Press '3'] - Create test file: "testnb.txt"
[Press '2'] - Display current directory (should show testnb.txt)
[Press '4'] - Read "testnb.txt" (displays file contents)
[Press '5'] - Delete "testnb.txt"
[Press '2'] - Display directory again (file should be gone)
Expected Output Example
[Command 3] Created file: testnb.txt
[Command 4] File Opened OK
testline1
testline2
testline3
testline4
testline5
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ
[Pattern repeats 40 times]
Done reading file
[Command 5] Deleted file: testnb.txt
USB Drive Disconnection
- Safe removal - Complete all file operations before removal
- File system unmount - System automatically handles disconnection
- Menu deactivation - Menu disappears until next device insertion
- VBUS power - Remains active for next device connection
File System Utilities
Directory Display Features
Recursive Directory Traversal
uint8_t displayDirectory() {
F_FIND finder;
if (rc == F_NO_ERROR) {
do {
if (finder.attr & F_ATTR_DIR) {
printf("Directory [%s]\n", finder.filename);
if (finder.filename[0] != '.') {
displayDirectory();
}
} else {
printf("File [%s] : %lu Bytes\n",
finder.filename, finder.filesize);
}
}
return rc;
}
#define f_chdir(dirname)
Change the directory.
Definition api_f.h:413
Space Usage Reporting
uint8_t DisplayEffsSpaceStats(int32_t driveNumber) {
F_SPACE space;
if (rv == F_NO_ERROR) {
long long totalSize = ((long long)space.total_high << 32) + space.total;
long long freeSize = ((long long)space.free_high << 32) + space.free;
long long usedSize = ((long long)space.used_high << 32) + space.used;
long long badSize = ((long long)space.bad_high << 32) + space.bad;
printf("%llu total, %llu free, %llu used, %llu bad\n",
totalSize, freeSize, usedSize, badSize);
}
return rv;
}
#define f_getfreespace(drivenum, pspace)
Provides information about the drive space usage.
Definition api_f.h:400
Error Handling and Troubleshooting
Common Issues
USB Device Not Detected
Symptoms**: No menu appears, device not recognized Solutions**:
- Verify USB flash drive is functional in PC
- Check NBUSB-ADPT-100R connection to development board
- Confirm 5V power supply is adequate (>500mA capacity)
- Try different USB flash drives (some may not be compatible)
- Verify VBUS power is enabled (VBUSEnable(1))
File System Mount Failures
Symptoms**: "Attach file system" fails Solutions**:
- Reformat USB drive with standard FAT32 formatter
- Check for file system corruption on USB drive
- Verify drive is not write-protected
- Try smaller capacity drives (<32GB often more compatible)
- Check for proper USB enumeration in debug output
File Operation Errors
Symptoms**: File create, read, or write failures Solutions**:
- Verify sufficient free space on USB drive
- Check file name validity (avoid special characters)
- Ensure file system is properly mounted before operations
- Test with different file sizes and content types
- Monitor EFFS error codes for specific failure reasons
Power-Related Issues
Symptoms**: Device detected but operations fail Solutions**:
- Check development board power supply capacity
- Verify USB cable quality and connections
- Monitor current consumption during operations
- Try powered USB hub for high-current devices
- Check for voltage drop under load conditions
Debug Procedures
USB Stack Status Checking
void SeePortSC1Status() {
printf("USB Host Status: [register values]\n");
}
EFFS Error Code Translation
void DisplayEffsErrorCode(int code) {
if (code <= MAX_EFFS_ERRORCODE) {
printf("%s\n", EffsErrorCode[code]);
} else {
printf("Unknown EFFS error code [%d]\n", code);
}
}
File System Verification
int result = f_checkdisk(driveNumber);
if (result != F_NO_ERROR) {
printf("File system check failed: ");
DisplayEffsErrorCode(result);
}
Performance Characteristics
USB Transfer Rates
- USB 2.0 Full Speed: Up to 12 Mbps theoretical
- Practical throughput: 500KB/s - 2MB/s depending on device
- File system overhead: 10-20% reduction from raw transfer rates
- Small file operations: Overhead dominates transfer time
Memory Usage
- USB Host Stack: ~8KB RAM for buffers and control structures
- EFFS Buffers: ~4KB per mounted drive
- File Handles: Limited by EFFS configuration (typically 8-16)
- Application Data: <2KB for menu system and variables
Device Compatibility
- Tested Devices: Standard USB 2.0 flash drives from major manufacturers
- File System Support: FAT16, FAT32 (NTFS not supported)
- Capacity Range: 64MB to 32GB recommended
- Power Requirements: Standard USB power budget (500mA max)
Dependencies
- NetBurner NNDK - Network Development Kit with USB MSD support
- FatFile Library - EFFS FAT file system support
- USB Host Stack - Built-in USB OTG host functionality
- Hardware Adapters - NBUSB-ADPT-100R USB development adapter
Related Examples
For additional USB and file system learning, see:
- EFFS Multiple MMC example for multi-drive file systems
- USB device examples for USB device (slave) functionality
- FTP server examples for network-based file transfer
- Data logging examples for continuous file system usage