File System Component  Version 6.14.1
MDK Middleware for Devices with Flash File System
 All Data Structures Files Functions Variables Enumerations Enumerator Macros Groups Pages
I/O Control Interface Routines

I/O control interface routines provide operate on FAT formatted media devices. More...

Functions

int32_t fs_ioc_get_id (const char *drive)
 Check if valid drive is specified and return its ID. More...
 
fsStatus fs_ioc_lock (int32_t drv_id)
 Lock drive and block media access to the upper layer. More...
 
fsStatus fs_ioc_unlock (int32_t drv_id)
 Unlock drive and allow media access to the upper layer. More...
 
fsStatus fs_ioc_get_cache (int32_t drv_id, fsIOC_Cache *cache_info)
 Return IOC cache buffer information. More...
 
fsStatus fs_ioc_read_sector (int32_t drv_id, uint32_t sect, uint8_t *buf, uint32_t cnt)
 Read sector from media. More...
 
fsStatus fs_ioc_write_sector (int32_t drv_id, uint32_t sect, const uint8_t *buf, uint32_t cnt)
 Write sector to media. More...
 
fsStatus fs_ioc_read_info (int32_t drv_id, fsMediaInfo *info)
 Read media configuration info. More...
 
fsStatus fs_ioc_device_ctrl (int32_t drv_id, fsDevCtrlCode code, void *p)
 IOC device control access; control code is sent directly to device driver. More...
 

Description

I/O control interface routines provide operate on FAT formatted media devices.

Function Documentation

fsStatus fs_ioc_device_ctrl ( int32_t  drv_id,
fsDevCtrlCode  code,
void *  p 
)

IOC device control access; control code is sent directly to device driver.

Parameters
[in]drv_idDrive ID obtained by fs_ioc_get_id.
[in]codeDevice control code.
[in,out]pGeneric pointer.
Returns
execution status fsStatus

The function fs_ioc_device_ctrl is used to send control code directly to the device driver, causing the device to perform a corresponding operation.

The argument drv_id identifies the drive.

The argument code is specifying the control code to be sent.

The argument p is a generic pointer and is used if the control code requires additional parameters to be passed to the driver or causes return values. The object to which pointer p points to, depends on the control code used.

Control code Generic pointerOperation description
fsDevCtrlCodeCheckMedia uint32_t Checks presence and write protection status of a removable media.
fsDevCtrlCodeControlMediauint32_t Control media device.
fsDevCtrlCodeFormat char Performs a low level format.
fsDevCtrlCodeGetCID fsCID_Register Reads memory card CID register.
fsDevCtrlCodeSerial uint32_t Reads device serial number.
fsDevCtrlCodeLockUnlock fsLockUnlock Manage memory card password protection.
fsDevCtrlCodeHealthStatusfsHealthStatus Access memory device S.M.A.R.T data.

When fsDevCtrlCodeCheckMedia is specified, argument p is used to return the bitmask of the following values:

Bit value Description
FS_MEDIA_INSERTED Media device is inserted
FS_MEDIA_PROTECTED Media device has write protection enabled
FS_MEDIA_INITIALIZED Media device is initialized
FS_MEDIA_NOCHKMEDIA Nonremovable media device or unable to detect media presence and write protection

Argument p must point to valid memory location otherwise it will be rejected.

When fsDevCtrlCodeControlMedia is specified, argument p is used to specify the following operations:

Value Operation description
FS_CONTROL_MEDIA_INIT Initialize media device
FS_CONTROL_EMMC_SLEEP Switch eMMC device to Sleep State and turn off VCC power supply.
FS_CONTROL_EMMC_AWAKE Wake-up eMMC device from Sleep State and turn on VCC power supply.

Argument p must point to valid memory location otherwise it will be rejected.

When fsDevCtrlCodeFormat is specified, argument p is used to specify low level format options. It can be NULL or point to char array containing following option:

OptionOperation description
LLEB Performs low-level formatting and erases bad block markers.

If argument p is NULL or unspecified options are specified, only low level format is performed which preserves bad block information.

When fsDevCtrlCodeGetCID is specified, argument p is used to specify the location of fsCID_Register structure where CID register values will be stored. A NULL pointer is not allowed and will be rejected.

When fsDevCtrlCodeSerial is specified, argument p is used to specify the location of 32-bit variable where device serial number will be stored. A NULL pointer is not allowed and will be rejected.

When fsDevCtrlCodeLockUnlock is specified, argument p is used to specify the location of fsLockUnlock structure. A NULL pointer is not allowed and will be rejected.
Structure fsLockUnlock consists of the following members:

Member Description
password Pointer to uint8_t buffer containing password data.
length Defines password length in bytes. The password length is up to 16 bytes.
flags Bit mask which defines set/clear password and/or device lock/erase operation.

Valid bit mask values for member flags are the following:

Value Description
FS_DEVICE_SET_PASSWORD Set new password.
FS_DEVICE_CLR_PASSWORD Clear current password.
FS_DEVICE_LOCK_UNLOCK Lock the card. Omit this flag to specify unlock operation.
FS_DEVICE_ERASE Force device erase operation.

For detailed functionality description refer to Memory Card Control Layer section Device Specific Features.

When fsDevCtrlCodeHealthStatus is specified, argument p is used to specify the location of fsHealthStatus structure. A NULL pointer is not allowed and will be rejected.
Structure fsHealthStatus consists of the following members:

Member Description
arg Argument used to control health status access behavior.
buf Defines buffer used to retrieve or to write data and must be 4 byte aligned.
buf_sz Defines buffer size in bytes.

The behavior of fsDevCtrlCodeHealthStatus is device specific and only supported for eMMC and SD devices. See Memory Card Control Layer section Device Specific Features for more information.

Code Examples

void tst_device_status (void) {
int32_t id;
uint32_t status;
id = fs_ioc_get_id ("M:");
if (status & FS_MEDIA_INSERTED) {
printf ("Removable media is present.\n");
}
if (status & FS_MEDIA_PROTECTED) {
printf ("Removable media is write protected.\n");
}
if (status & FS_MEDIA_INITIALIZED) {
printf ("Removable media is initialized.\n");
}
if (status & FS_MEDIA_NOCHKMEDIA) {
printf ("Unable to detect media presence and media write protection.\n");
}
}
}
void get_device_serial (void) {
int32_t id;
uint32_t serial;
id = fs_ioc_get_id ("M:");
if (fs_ioc_device_ctrl (id, fsDevCtrlCodeSerial, &serial) == fsOK) {
printf ("Device serial number is %d.\n", serial);
}
}
void read_cid (void) {
int32_t id;
id = fs_ioc_get_id ("M:");
printf ("Manufacturer ID: %d (0x%.2X)\n", cid.MID, cid.MID);
printf ("OEM/Application ID: %c%c\n", cid.OID >> 8, cid.OID & 0xFF);
printf ("Product name: %c%c%c%c%c\n", cid.PNM[0], cid.PNM[1], cid.PNM[2], cid.PNM[3], cid.PNM[4]);
printf ("Product revision: %d.%d\n", cid.PRV >> 4, cid.PRV & 0x0F);
printf ("Product serial number: 0x%X\n", cid.PSN);
printf ("Manufacturing date: %d/%.2d\n", cid.MDT & 0x0F, cid.MDT >> 4);
}
}
void format_nand (void) {
int32_t id;
id = fs_ioc_get_id ("N:");
printf ("Low level NAND formatting succeeded.\n");
}
}
// Memory card password
uint8_t pass[] = "12345";
// Media lock/unlock information structure
fsLockUnlock mc_lock;
// Password management function
void mc_password_manage (uint32_t operation) {
int32_t id;
fsStatus status;
// Set password data buffer and password length
mc_lock.password = pass;
mc_lock.length = 5;
switch (operation) {
case 0: // Set password and lock memory card
break;
case 1: // Set password
break;
case 2: // Clear password
break;
case 3: // Lock memory card
break;
case 4: //Unlock memory card
mc_lock.flags = 0;
break;
case 5: // Force device erase (forgotten password)
break;
}
id = fs_ioc_get_id ("M0:");
if (id < 0) {
printf ("Invalid drive specified!\n");
}
else {
// Execute memory card lock/unlock operation
status = fs_ioc_device_ctrl (id, fsDevCtrlCodeLockUnlock, &mc_lock);
if (status == fsOK) {
printf ("Operation succeeded!\n");
}
else if (status == fsAccessDenied) {
printf ("Invalid password data. Operation failed!\n");
}
else {
printf ("Operation failed! Error no.: %d\n", status);
}
}
}
#include "cmsis_compiler.h"
// 4-byte aligned buffer to store eMMC/SD card S.M.A.R.T data
uint8_t SMART_Data[512] __ALIGNED(4U);
void get_health_status (void) {
int32_t id;
id = fs_ioc_get_id ("M:");
if (id >= 0 && (fs_ioc_lock (id) == fsOK)) {
// Prepare health status access argument and buffer
cmd.arg = 1;
cmd.buf = SMART_Data;
cmd.buf_sz = sizeof(SMART_Data);
printf ("Health status was sucessfully retrieved.\n");
}
else {
printf ("Failed to access memory device health status.\n");
}
}
else printf ("Specified drive doesn't exists!");
}
fsStatus fs_ioc_get_cache ( int32_t  drv_id,
fsIOC_Cache cache_info 
)

Return IOC cache buffer information.

Parameters
[in]drv_idDrive ID obtained by fs_ioc_get_id.
[out]cache_infoIOC Cache information.
Returns
execution status fsStatus
  • fsOK = Operation successful.
  • fsInvalidParameter = Input parameters are not valid.
  • fsInvalidDrive = Nonexistent drive ID specified.
  • fsAccessDenied = IOC access not allowed for specified drive.

The function fs_ioc_get_cache is used to gain information about the file system cache buffer location and its size. The I/O Control Interface can use this buffer as a temporary storage for sector operations using fs_ioc_read_sector and fs_ioc_write_sector or for any other data storage.

The argument cache_info is a pointer to the fsIOC_Cache structure where the buffer location and its size will be stored.

Note
The buffer size is defined in the configuration file for a particular drive using File System Cache setting.

Code Example

void chk_cache_buffer (void) {
int32_t id;
id = fs_ioc_get_id ("M:");
if (fs_ioc_get_cache (id, &info) == fsOK) {
printf ("Cache buffer location: 0x%X\n", info.buffer);
printf ("Cache buffer size: %d bytes.\n", info.size);
}
}
int32_t fs_ioc_get_id ( const char *  drive)

Check if valid drive is specified and return its ID.

Parameters
[in]drivea string specifying the memory or storage device.
Returns
drive ID or execution status
  • value >= 0: drive ID as an integer when specified drive exists and allows IOC access
  • value < 0: error occurred, -value is execution status as defined with fsStatus

The function fs_ioc_get_id is used to get the drive identifier associated with the specified drive letter.

The argument drive is specifying a FAT volume drive. The Current Drive is used, if an empty string "" is provided.

fsStatus fs_ioc_lock ( int32_t  drv_id)

Lock drive and block media access to the upper layer.

Parameters
[in]drv_idDrive ID obtained by fs_ioc_get_id.
Returns
execution status fsStatus
  • fsOK = Operation successful.
  • fsInvalidDrive = Nonexistent drive ID specified.
  • fsAccessDenied = IOC access not allowed for specified drive.

The function fs_ioc_lock locks a drive in order to block media access to the file system layer while the I/O Control Interface routines are in use. The I/O Control Interface should only be used in the locked state due to possible interference with file system accesses to the media. All file operations will fail while the drive is in the locked state. The function fs_ioc_unlock is used to unlock the drive.

The argument drv_id identifies the drive and must be obtained using the fs_ioc_get_id function.

fsStatus fs_ioc_read_info ( int32_t  drv_id,
fsMediaInfo info 
)

Read media configuration info.

Parameters
[in]drv_idDrive ID obtained by fs_ioc_get_id.
[out]infoMedia information structure.
Returns
execution status fsStatus
  • fsOK = Operation successful.
  • fsInvalidDrive = Nonexistent drive ID specified.
  • fsNoMedia = Media not present.
  • fsAccessDenied = IOC access not allowed for specified drive.
  • fsError = Media information read failed.

The function fs_ioc_read_info reads the media configuration.

The argument drv_id identifies the drive.

The argument info returns the media information structure as specified in fsMediaInfo.

Code Example

void get_device_size (void) {
int32_t id;
id = fs_ioc_get_id ("M:");
if (fs_ioc_read_info (id, &info) == fsOK) {
printf ("Device size is %d bytes.\n", info.block_cnt * info.read_blen);
}
}
fsStatus fs_ioc_read_sector ( int32_t  drv_id,
uint32_t  sect,
uint8_t *  buf,
uint32_t  cnt 
)

Read sector from media.

Parameters
[in]drv_idDrive ID obtained by fs_ioc_get_id.
[in]sectSector number.
[out]bufData buffer.
[in]cntCount of sectors.
Returns
execution status fsStatus
  • fsOK = Operation successful.
  • fsInvalidDrive = Nonexistent drive ID specified.
  • fsNoMedia = Media not present.
  • fsAccessDenied = IOC access not allowed for specified drive.
  • fsError = Read sector failed.

The function fs_ioc_read_sector reads data from one or more sectors of FAT formatted media.

The argument drv_id identifies the drive.

The argument sect specifies the starting sector from where to read the data.

The argument buf is a pointer to the buffer that stores the data.

The argument cnt specifies the number of sectors to read.

Code Example

bool sector_read (uint32_t sector_addr, uint8_t *buf) {
int32_t id;
id = fs_ioc_get_id ("U:");
if (fs_ioc_lock (id) == fsOK) {
fs_ioc_read_sector (id, sector_addr, buf, 1);
return true;
}
return false;
}
fsStatus fs_ioc_unlock ( int32_t  drv_id)

Unlock drive and allow media access to the upper layer.

Parameters
[in]drv_idDrive ID obtained by fs_ioc_get_id.
Returns
execution status fsStatus
  • fsOK = Operation successful.
  • fsInvalidDrive = Nonexistent drive ID specified.
  • fsAccessDenied = IOC access not allowed for specified drive.

The function fs_ioc_unlock unlocks a drive and releases media access to the file system layer. The I/O Control Interface should only be used in the locked state due to possible interference with file system accesses to the media. The function fs_ioc_lock is used to lock the drive.

The argument drv_id identifies the drive and must be obtained using the fs_ioc_get_id function.

fsStatus fs_ioc_write_sector ( int32_t  drv_id,
uint32_t  sect,
const uint8_t *  buf,
uint32_t  cnt 
)

Write sector to media.

Parameters
[in]drv_idDrive ID obtained by fs_ioc_get_id.
[in]sectSector number.
[out]bufData buffer.
[in]cntCount of sectors.
Returns
execution status fsStatus
  • fsOK = Operation successful.
  • fsInvalidDrive = Nonexistent drive ID specified.
  • fsNoMedia = Media not present.
  • fsAccessDenied = IOC access not allowed for specified drive.
  • fsError = Read sector failed.

The function fs_ioc_write_sector writes data to one or more sectors of FAT formatted media.

The argument drv_id identifies the drive.

The argument sect specifies the starting sector to write the data.

The argument buf is a pointer to the buffer that contains the data to write.

The argument cnt specifies the number of sectors to write to.

Code Example

bool sector_write (uint32_t sector_addr, const uint8_t *buf) {
int32_t id;
id = fs_ioc_get_id ("U:");
if (fs_ioc_lock (id) == fsOK) {
fs_ioc_write_sector (id, sector_addr, buf, 1);
return true;
}
return false;
}