MSC Configuration

General Configuration

There are various configuration constants necessary to customize the MSC device. These constants are located in the usbd_cfg.h file. Table - MSC Configuration Constants shows a description of each constant.

Table - MSC Configuration Constants
ConstantDescriptionPossible Values
USBD_MSC_CFG_MAX_NBR_DEVConfigures the maximum number of class instances. Unless you plan having multiple configuration or interfaces using different class instances, this should be set to 1.From 1 to 254. Default value is 1.
USBD_MSC_CFG_MAX_NBR_CFGConfigures the maximum number of configuration in which MSC is used. Keep in mind that if you use a high-speed device, two configurations will be built, one for full-speed and another for high-speed.From 1 (low- and full-speed) or 2 (high-speed) to 254. Default value is 2.
USBD_MSC_CFG_MAX_LUNConfigures the maximum number of logical units.From 1 to 255. Default value is 1.
USBD_MSC_CFG_DATA_LENConfigures the read/write data length in octets.Higher than 0. The default value is 2048.
USBD_MSC_CFG_FS_REFRESH_TASK_ENEnables or disables the use of a task in µC/FS storage layer for removable media insertion/removal detection. If only fixed media such as RAM, NAND are used, this constant should be set to DEF_DISABLED. Otherwise, DEF_ENABLED should be set.DEF_ENABLED or  DEF_DISABLED
USBD_MSC_CFG_DEV_POLL_DLY_mSConfigures the period of the µC/FS storage layer’s task. It is expressed in milliseconds. If USBD_MSC_CFG_FS_REFRESH_TASK_EN is set to DEF_DISABLED, this constant has no effect. A faster period may improve the delay to detect the removable media insertion/removal resulting in a host computer displaying the removable media icon promptly. But the CPU will be interrupted often to check the removable media status. A slower period may result in a certain delay for the host computer to display the removable media icon. But the CPU will spend less time verifying the removable media status.The default value is 100 ms.


Since MSC device relies on a task handler to implement the MSC protocol, this OS-task’s priority and stack size constants need to be configured if µC/OS-II or µC/OS-III RTOS is used. Moreover if USBD_MSC_CFG_FS_REFRESH_TASK_EN is set to DEF_ENABLED, the µC/FS storage layer task’s priority and stack size need also to be configured. These constants are summarized in Table - MSC OS-Task Handler Configuration Constants.

Table - MSC OS-Task Handler Configuration Constants
ConstantDescriptionPossible Values
USBD_MSC_OS_CFG_TASK_PRIOMSC task handler’s priority level. The priority level must be lower (higher valued) than the start task and core task priorities.From the lowest to the highest priority supported by the OS used.
USBD_MSC_OS_CFG_TASK_STK_SIZEMSC task handler’s stack size. The required size of the stack can greatly vary depending on the OS used, the CPU architecture, the type of application, etc. Refer to the documentation of the OS for more details about tasks and stack size calculation.From the minimal to the maximal stack size supported by the OS used. Default value is set to 256.
USBD_MSC_OS_CFG_REFRESH_TASK_PRIOµC/FS storage layer task’s priority level. The priority level must be lower (higher valued) than the MSC task.From the lowest to the highest priority supported by the OS used.
USBD_MSC_OS_CFG_REFRESH_TASK_STK_SIZEµC/FS storage layer task’s stack size. The required size of the stack can greatly vary depending on the OS used, the CPU architecture, the type of application, etc. Refer to the documentation of the OS for more details about tasks and stack size calculation.From the minimal to the maximal stack size supported by the OS used. Default value is set to 256.

Class Instance Configuration

Before starting the communication phase, your application needs to initialize and configure the class to suit its needs. Table - Class Instance API Functions summarizes the initialization functions provided by the MSC implementation. Please refer to the MSC Functions reference for a full listing of the MSC API.

Table - Class Instance API Functions
Function nameOperation
USBD_MSC_Init()Initializes MSC internal structures and variables.
USBD_MSC_Add()Adds a new instance of the MSC.
USBD_MSC_CfgAdd()Adds existing MSC instance into USB device configuration.
USBD_MSC_LunAdd()Adds a LUN to the MSC interface.


To successfully initialize the MSC, you need to follow these steps:

  1. Call USBD_MSC_Init()
    This is the first function you should call, and it should be called only once regardless of the number of class instances you intend to have. This function will initialize all internal structures and variables that the class will need. It will also initialize the real-time operating system (RTOS) layer.
  2. Call USBD_MSC_Add()
    This function will add a new instance of the MSC.
  3. Call USBD_MSC_CfgAdd()
    Once the class instance is correctly configured and initialized, you will need to add it to a USB configuration. High speed devices will build two separate configurations, one for full speed and one for high speed by calling USBD_MSC_CfgAdd() for each speed configuration.
  4. Call USBD_MSC_LunAdd()

Lastly, you add a logical unit to the MSC interface by calling this function. You will specify the type and volume of the logical unit you want to add as well as device details such as vendor ID string, product ID string, product revision level and read only flag. Logical units are identified by a string name composed of the storage device driver name and the logical unit number as follows: <device_driver_name>:<logical_unit_number>:. The logical unit number starts counting from number 0. For example, if a device has only one logical unit, the <logical_unit_number> specified in this field should be 0. Examples of logical units string name are ram:0:, sdcard:0:, etc. This function is called several times when a multiple logical unit configuration is created.

Listing - MSC Initialization shows how the latter functions are called during MSC initialization and an example of multiple logical units initialization.

USBD_ERR     err;
CPU_INT08U   msc_nbr;
CPU_BOOLEAN  valid;


USBD_MSC_Init(&err);                                                          (1)
if (err != USBD_ERR_NONE){
    return (DEF_FAIL);
}
 
msc_nbr = USBD_MSC_Add(&err);                                                 (2)
if (cfg_hs != USBD_CFG_NBR_NONE){
    valid = USBD_MSC_CfgAdd(msc_nbr,                                          (3)
                            dev_nbr,
                            cfg_hs,
                           &err);
    if (valid != DEF_YES) {
        return (DEF_FAIL);
    }
}
 
if (cfg_fs != USBD_CFG_NBR_NONE){
    valid = USBD_MSC_CfgAdd(msc_nbr,                                          (4)
                            dev_nbr,
                            cfg_fs,
                           &err);
    if (valid != DEF_YES) {
        return (DEF_FAIL);
    }
}

USBD_MSC_LunAdd((void *)"ram:0:",                                             (5)
                         msc_nbr,
                        "Micrium",
                        "MSC LUN 0 RAM",
                         0x0000,
                         DEF_TRUE,
                        &err);
if (err != USBD_ERR_NONE){
    return (DEF_FAIL);
}

USBD_MSC_LunAdd((void *)"sdcard:0:",                                          (6)
                         msc_nbr,
                        "Micrium",
                        "MSC LUN 1 SD",
                         0x0000,
                         DEF_FALSE,
                        &err);
if (err != USBD_ERR_NONE){
    return (DEF_FAIL);
}

return (DEF_OK);

(1) Initialize internal structures and variables used by MSC BOT.

(2) Add a new instance of the MSC.

(3) Check if high speed configuration is active and proceed to add an existing MSC instance to the USB configuration.

(4) Check if full speed configuration is active and proceed to add an existing MSC instance to the USB configuration.

(5) Add a logical unit number to the MSC instance by specifying the type and volume. Note that in this example the <device_driver_name> string is “ram” and <logical_unit_number> string is “0” and the logical unit is read-only (DEF_TRUE specified).

(6) Add another logical unit number to the MSC instance by specifying the type and volume. Note that in this example the <device_driver_name> string is “sdcard” and <logical_unit_number> string is “0” and the logical unit is read-write (DEF_FALSE specified). When the host will enumerate the mass storage device, this one will report two logical units of different type, one RAM and one SD.