Device Driver for MMC MultiMedia Cards


CYGPKG_DEVS_DISK_MMC -- eCos Support for MMC MultiMedia Cards


This package provides a disk device driver for MultiMediaCards (MMC). A MultiMediaCard provides non-volatile storage in a small footprint (24mm * 32mm * 1.4mm), and weighing less than 2 grams. Typical card sizes are 16MB to 128MB, with an upper limit of 4GB. It should be noted that these sizes are measured in millions of bytes, not 2^20. The MultiMediaCard Association defines the standard for these cards.

At the hardware level there are two ways of accessing an MMC card, either using a custom interface or via an SPI bus. A card will detect the interface in use at run-time. The custom interface allows for better performance but requires additional hardware. Currently only SPI mode is supported by this package.

Theoretically an MMC card can be used with any file system. In practice all cards are formatted for PC compatibility, with a partition table in the first block and a single FAT file system on the rest of the card. Currently this package checks the format of the MMC card and will only allow access to a card if it is formatted this way.

An MMC socket allows cards to be removed and inserted at any time. The device driver will detect removal events when the next I/O operation happens and will report them to higher-level code via an error code ENODEV. However there are no guarantees that the higher-level code will be able to recover from this error. The expected usage is that application code will explicitly mount the card before attempting any file I/O, and will umount the card before it is removed. Between these operations the system is likely to keep some disk blocks cached, for performance reasons. If the card is removed before the umount then it may end up with a corrupted file system, and the disk subsystem may be left in an inconsistent state. Regular uses of sync will reduce the risk of file system corruption.

Configuration Options

CYGPKG_DEVS_DISK_MMC is a hardware package which should get loaded automatically when you configure for a suitable eCos target platform. In this case suitable means that the hardware has an MMC socket connected to an SPI bus, that an SPI bus driver package exists and is also automatically loaded, and that the platform HAL provides information on how the card is connected to the SPI bus.

The package depends on support from the generic disk package CYGPKG_IO_DISK. That will not be loaded automatically: the presence of an MMC socket on the board does not mean that the application has any need for a file system. Hence by default CYGPKG_DEVS_DISK_MMC will be inactive and will not contribute any code or data to the application's memory footprint. To activate the driver it will be necessary to add one or more packages to the configuration using ecosconfig add or the graphical configuration tool: the generic disk support CYGPKG_IO_DISK; usually a file system, CYGPKG_FS_FAT; support for the file I/O API CYGPKG_IO_FILEIO; and possibly additional support packages that may be needed by the file system, for example CYGPKG_LINUX_COMPAT. Depending on the template used to create the initial configuration some of these may be loaded already.

The package provides two main configuration options. CYGDAT_DEVS_DISK_MMC_SPI_DISK0_NAME specifies the name of the raw disk device, for example /dev/hd0. Allowing for partition tables that makes /dev/hd0/1 the first argument that shoul be passed to a mount call. If the hardware has multiple disk devices then each one will need a unique name. CYGIMP_DEVS_DISK_MMC_SPI_POLLED controls whether the SPI bus will be accessed in interrupt-driven or polled mode. It will default to interrupt-driven if the application is multi-threaded, which is assumed to be the case if the kernel is present. If the kernel is absent, for example in a RedBoot configuration, then the driver will default to polled mode. With some hardware polled mode may significantly increase disk throughput even in a multi-threaded application, but will consume cpu cycles that could be used by other threads.

Additional Functionality

The disk driver package exports a variable cyg_mmc_spi_polled. This defaults to true or false depending on the configuration option CYGIMP_DEVS_DISK_MMC_SPI_POLLED. If the default mode is interrupt-driven then file I/O, including mount operations, are only allowed when the scheduler has started and interrupts have been enabled. Any attempts at file I/O earlier during system initialization, for example inside a C++ static constructor, will lock up. If it is necessary to perform file I/O at this time then the driver can be temporarily switched to polling mode before the I/O operation by setting cyg_mmc_spi_polled, and clearing it again after the I/O. Alternatively the default mode can be changed to polling by editing the configuration, and then the main() thread can change the mode to interrupt-driven once the scheduler has started.

Porting to New Hardware

Assuming that the MMC connector is hooked up to a standard SPI bus and that there is already an eCos SPI bus driver, porting the MMC disk driver package should be straightforward. Some other package, usually the platform HAL, should provide a cyg_spi_device structure cyg_spi_mmc_dev0. That structure contains the information needed by this package to interact with the MMC card via the usual SPI interface, for example how to activate the appropriate chip select. The platform HAL should also implement the CDL interface CYGINT_DEVS_DISK_MMC_SPI_CONNECTORS.

When defining cyg_spi_mmc_dev0 special care must be taken with the chip select. The MMC protocol is transaction-oriented. For example a read operation involves an initial command sent to the card, then a reply, then the actual data, and finally a checksum. The card's chip select must be kept asserted for the entire operation, and there can be no interactions with other devices on the same SPI bus during this time.

Optionally the platform HAL may define a macro HAL_MMC_SPI_INIT which will be invoked during a mount operation. This can take any hardware-specific actions that may be necessary, for example manipulating GPIO pins. Usually no such macro is needed because the hardware is set up during platform initialization.

Currently the package does not provide any support for accessing MMC cards using an interface other than SPI. On some targets there may be additional hardware to detect events such as card insertion or removal, but there is no support for exploiting such hardware at present.

Only a single MMC socket is supported. Extending the package to support multiple sockets would be straightforward but it seems unlikely that any hardware would come with multiple MMC sockets. Given the nature of SPI buses there is a problem if the MMC socket is hooked up via an expansion connector rather than being attached to the main board. The platform HAL would not know about the socket so would not implement the CDL interface CYGINT_DEVS_DISK_MMC_SPI_CONNECTORS, and the ecos.db target entry would not include CYGPKG_DEVS_DISK_MMC. Because this is a hardware package it cannot easily be added by hand. Instead this scenario would require some editing of the existing platform HAL and target entry.