Implementing a mass storage device, reading an external Image file

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Implementing a mass storage device, reading an external Image file

Jump to solution
778 Views
embedded_eng_
Contributor III

Hi, I'm using lpcxpresso55s16_dev_composite_cdc_msc_bm with a LPC55S16-EVK board.

USB HS is connected to PC A and exposes a CDC interface and a HID interface, and USB FB is connected to PC B and exposes a MSC interface.

The general purpose is that PC B will be able to mount an img file that exist in PC A.

Every read request received from PC B is read by the MCU, then the MCU issues a HID command to PC A, asking the specific block, which is sent through a CDC channel.

Since the image size is 209715200 Bytes (409600 512 blocks), the capacityInformation->totalLbaNumberSupports parameter is set to be 409600.

 

 

usb_status_t USB_DeviceMscCallback(class_handle_t handle, uint32_t event, void *param)
{
    usb_status_t error = kStatus_USB_Success;
    usb_device_lba_information_struct_t *lbaInformationStructure;
    usb_device_lba_app_struct_t *lbaData;
    usb_device_ufi_app_struct_t *ufi;
    usb_device_capacity_information_struct_t *capacityInformation;

    switch (event)
    {
        case kUSB_DeviceMscEventReadResponse:
            lbaData = (usb_device_lba_app_struct_t *)param;
            break;
        case kUSB_DeviceMscEventWriteResponse:
            lbaData = (usb_device_lba_app_struct_t *)param;
            break;
        case kUSB_DeviceMscEventWriteRequest:
            lbaData = (usb_device_lba_app_struct_t *)param;
            /*offset is the write start address get from write command, refer to class driver*/
            lbaData->buffer = g_deviceComposite_fs->mscDisk.storageDisk + lbaData->offset * LENGTH_OF_EACH_LBA;
            break;
        case kUSB_DeviceMscEventReadRequest:
            lbaData = (usb_device_lba_app_struct_t *)param;
            /*offset is the read start address get from read command, refer to class driver*/
            send_hid(lbaData->offset); //asks for the block in this offset
            lbaData->buffer = get_bulk();//get block from cdc
            break;
        case kUSB_DeviceMscEventGetLbaInformation:
            lbaInformationStructure                             = (usb_device_lba_information_struct_t *)param;
            lbaInformationStructure->logicalUnitNumberSupported = LOGICAL_UNIT_SUPPORTED;

            lbaInformationStructure->logicalUnitInformations[0].lengthOfEachLba = LENGTH_OF_EACH_LBA;
            lbaInformationStructure->logicalUnitInformations[0].totalLbaNumberSupports = 409600;
            lbaInformationStructure->logicalUnitInformations[0].bulkInBufferSize  = 512;
            lbaInformationStructure->logicalUnitInformations[0].bulkOutBufferSize = 512;
            break;
        case kUSB_DeviceMscEventTestUnitReady:
            /*change the test unit ready command's sense data if need, be careful to modify*/
            ufi = (usb_device_ufi_app_struct_t *)param;
            break;
        case kUSB_DeviceMscEventInquiry:
            ufi         = (usb_device_ufi_app_struct_t *)param;
            ufi->size   = sizeof(usb_device_inquiry_data_fromat_struct_t);
            ufi->buffer = (uint8_t *)&g_InquiryInfo;
            break;
        case kUSB_DeviceMscEventModeSense:
            ufi         = (usb_device_ufi_app_struct_t *)param;
            ufi->size   = sizeof(usb_device_mode_parameters_header_struct_t);
            ufi->buffer = (uint8_t *)&g_ModeParametersHeader;
            break;
        case kUSB_DeviceMscEventModeSelect:
        	usb_echo("kUSB_DeviceMscEventModeSelect\r\n");
            break;
        case kUSB_DeviceMscEventModeSelectResponse:
            ufi = (usb_device_ufi_app_struct_t *)param;
            break;
        case kUSB_DeviceMscEventFormatComplete:
            break;
        case kUSB_DeviceMscEventRemovalRequest:
            break;
        case kUSB_DeviceMscEventRequestSense:
            break;
        case kUSB_DeviceMscEventReadCapacity:
            capacityInformation                         = (usb_device_capacity_information_struct_t *)param;
            capacityInformation->lengthOfEachLba        = LENGTH_OF_EACH_LBA;
            capacityInformation->totalLbaNumberSupports = 409600;
            break;
        case kUSB_DeviceMscEventReadFormatCapacity:
            capacityInformation                         = (usb_device_capacity_information_struct_t *)param;
            capacityInformation->lengthOfEachLba        = LENGTH_OF_EACH_LBA;
            capacityInformation->totalLbaNumberSupports = 409600;
            break;
        default:
            break;
    }
    return error;
}

 

 

I wrote a script for PC A that listens to the relevant /dev/hidraw port, and sends the blocks through the relevant /dev/ttyACM port.

 

Now, the only issue I have seems to be with the offsets.

When the USB FS  is connected to PC B, after the following events:

kUSB_DeviceMscEventGetLbaInformation
kUSB_DeviceMscEventGetLbaInformation
kUSB_DeviceMscEventInquiry
kUSB_DeviceMscEventTestUnitReady
kUSB_DeviceMscEventReadCapacity
kUSB_DeviceMscEventModeSense
kUSB_DeviceMscEventModeSense
kUSB_DeviceMscEventTestUnitReady
kUSB_DeviceMscEventRemovalRequest
kUSB_DeviceMscEventTestUnitReady
kUSB_DeviceMscEventReadCapacity
kUSB_DeviceMscEventModeSense
kUSB_DeviceMscEventModeSense

4168 read events are received, with offsets:

0, 512, 1024, 1536, 2048, 2560, 3072, 3584

Then:

209649664, 209650176, 209650688, 209651200, 209651712, ,209652224 , 209652736...

Then: 

0, 512, 1024, 1536, 2048, 2560, 3072, 3584..

It goes like this until 4168 request were made.

 It asks for the same blocks several times.

After these events, a /dev/sdX1 partition appears on PC B.

Now, If I'm trying to mount the partition I get a filesystem error.

When I try to look at the content using  hexdump command, PC B issues some more read commands, and I see: "This is not a bootable disk. please insert a bootable floopy and..."

Maybe someone can help with that?

Tags (4)
0 Kudos
1 Solution
759 Views
embedded_eng_
Contributor III

After some digging, seems that the problem is with the cdc that received the bulk data.

Since this have nothing to do with MSC, I will create a new post with the CDC issue.

View solution in original post

0 Kudos
1 Reply
760 Views
embedded_eng_
Contributor III

After some digging, seems that the problem is with the cdc that received the bulk data.

Since this have nothing to do with MSC, I will create a new post with the CDC issue.

0 Kudos