This chapter describes how to work with expansion cards and add-on devices using the Palm OS® Expansion and Virtual File System (VFS) Managers.
- Expansion Support introduces basic terminology and discusses the hardware and file systems supported by the Expansion and VFS Managers.
- Architectural Overview illustrates the Palm OS expansion architecture and discusses the differences between primary and secondary storage.
- Applications on Cards covers the various implications of running Palm OS applications from an expansion card.
- Card Insertion and Removal covers, in detail, the sequence of events that occur when an expansion card is inserted into or removed from an expansion slot.
- Checking for Expansion Cards shows you how to verify that the handheld supports expansion, how to check each of the handheld's slots for expansion cards, and how to determine the capabilities of a card in a given slot.
Expansion Support
The Palm OS Expansion and VFS Managers are optional system extensions that provide a standard mechanism by which Palm OS applications can take advantage of the expansion capabilities of various Palm Powered™ handhelds. This capability not only augments the memory and I/O of the handheld, but facilitates data interchange with other Palm Powered handhelds and with devices that aren't running the Palm OS. These other devices include digital cameras, digital audio players, desktop or laptop computers, and the like.
Primary vs. Secondary Storage
All Palm Powered handhelds contain primary storage—directly addressable memory that is used for both long-term and temporary storage. This includes storage RAM, used to hold nonvolatile user data and applications; and dynamic RAM, which is used as working space for temporary allocations.
On most handhelds, primary storage is contained entirely within the device itself. The Palm OS memory architecture doesn't limit devices to this, however; devices can be designed to accept additional storage RAM. The products developed by Handspring™ work this way; memory modules plugged into the Springboard slot are fully-addressable and appear to a Palm OS application as additional storage RAM.
Secondary storage, by contrast, is designed primarily to be add-on nonvolatile storage. Although not limited to any particular implementation, most secondary storage media:
- can be inserted and removed from the expansion slot at will
- are based upon a third-party standard, such as Secure Digital (SD) memory cards, MultiMedia (MMC) cards, CompactFlash, Sony's Memory Stick™, and others
- present a serial interface, accessing data one bit, byte, or block at a time
Applications access primary storage either directly, in the case of most dynamic RAM, or through the Database and Resource Managers. To access secondary storage, however, applications use the Expansion and VFS Managers. These have been designed to support as broad a range of serial expansion architectures as possible.
Expansion Slot
The expansion slots found on many Palm Powered handhelds vary depending on the manufacturer. While some may accept SD and MMC cards, others may accept Memory Stick or CompactFlash. Note that there is no restriction on the number of expansion slots that a given handheld can have.
Depending on the expansion technology used, there can be a wide variety of expansion cards usable with a given handheld:
- Storage cards provide secondary storage and can either be used to hold additional applications and data, or can be used for a specific purpose, for instance as a backup mechanism.
- ROM cards hold dedicated applications and data.
- I/O cards extend the handheld's I/O capabilities. A modem, for instance, could provide wired access, while a Bluetooth™ transceiver could add wireless capability.
- "Combo" cards provide both additional storage or ROM along with some I/O capability.
Universal Connector
Certain Palm Powered handhelds may be equipped with a universal connector that connects the handheld to a HotSync® cradle. This connector can be used to connect the handheld to snap-on I/O devices as well. A special device driver dedicated to this connector allows handheld-to-accessory communication using the serial portion of the connector. This "plug and play" driver presents the peripheral as a card in a slot, even to the extent of providing the card insertion notification when the peripheral is attached.
Because the universal connector's driver makes a snap-on peripheral appear to be a card in a slot, such peripherals can be treated as expansion cards, at least from an application developer's perspective. For the remainder of this chapter, wherever an I/O card could be used, the phrase "expansion card" can be taken to mean both "expansion card" and "plug and play peripheral."
Architectural Overview
Figure 5.1 illustrates the Palm OS expansion architecture. It is designed to be flexible enough to support multiple file systems and diverse physical expansion mechanisms while still presenting a consistent set of APIs to applications and to other parts of the Palm OS. The following sections describe the major components of the Palm OS expansion architecture. Working from the bottom up, those components are: block device drivers, file systems, the VFS Manager, and the Expansion Manager.
Figure 5.1 Palm OS expansion architecture

Block Device Drivers
A block device driver is a standard Palm OS shared library that encapsulates direct access to the hardware and provides a standard set of services to the Expansion Manager (and optionally to file system libraries). Adding support for a new type of hardware expansion is usually simply a matter of writing a block device driver for it. As illustrated in Figure 5.1, applications don't normally interact directly with device drivers.
Each expansion slot has a block device driver associated with it. Slots are identified by a unique slot reference number, which is assigned by the Expansion Manager. Expansion cards themselves are not numbered individually; applications typically reference the slot into which a card is inserted. Note, however, that a slot may or may not have a card in it at any given time, and that a card can be inserted and removed while an application is running.
The current implementation only supports one volume per slot.
File Systems
The Palm OS expansion architecture defines a common interface for all file system implementations on the Palm OS. This interface consists of a complete set of APIs for interacting with the file system, including the ability to open, close, read, write, and delete both files and directories on named volumes.
File system implementations are packaged as shared libraries of type sysFileTFileSystem
('libf'
). They are modular plug-ins that add support for a particular type of file system, such as VFAT, HFS, or NFS. The Palm OS expansion architecture allows multiple file system libraries to be installed at any given time. Typically, an implementation of the VFAT file system is present.
VFAT is the industry standard for flash memory cards of all types. It enables easy transfer of data and or applications to desktops and other devices. The VFAT file system library natively supports VFAT file systems on secondary storage media. It is able to recognize and mount FAT and VFAT file systems, and offers to reformat unrecognizable or corrupted media.
Because the VFAT file system requires long filenames to be stored in Unicode/UCS2 format, the standard VFAT file system library supports conversion between UCS2 and Shift-JIS (the standard Palm OS multi-byte character encoding), and the Palm/Latin encoding.
The FAT filesystem component in Palm OS Cobalt supports FAT12/16 and VFAT as well as FAT32. Volumes greater than 512 MB are implicitly formatted as FAT32. However, the system recognizes volumes of any size that are formatted as FAT12 or FAT16.
VFS Manager
The VFS (Virtual File System) Manager provides a unified API that gives applications access to many different file systems on many different media types. It abstracts the underlying file systems so that applications can be written without regard to the actual file system in use. The VFS Manager includes APIs for manipulating files, directories, and volumes.
NOTE: Although the great majority of the functions in the VFS Manager can be used by any application, some are intended only for use by drivers and file systems. Others are not intended for use by third-party applications but are designed primarily for system use.
The VFS Manager, the Data Manager, and File Streaming APIs
With the addition of the VFS Manager to the Palm OS, there are now three distinct ways applications can store and retrieve Palm OS user data:
- The Data Manager manages user data in the storage heap. It was specifically designed to make the most of the limited dynamic RAM and the nonvolatile RAM used instead of disk storage on most handhelds. Use the Data Manager to store and retrieve Palm OS user data when storage on the handheld is all that is needed, or when efficient access to data is paramount.
- The File Streaming API is a layer on top of the Data Manager that provides file functionality with all data being read from or written to a database in the storage heap. Most applications have no need for the File Streaming APIs; they are primarily used by applications that need to work with large blocks of data.
- The VFS and Expansion Managers were designed specifically to support many types of expansion memory as secondary storage. The VFS Manager APIs present a consistent interface to many different types of file systems on many types of external media. Applications that use the VFS APIs can support the widest variety of file systems. Use the VFS Manager when your application needs to read and write data stored on external media.
Palm OS applications should use the appropriate APIs for each given situation. The Data Manager, being an efficient manager of storage in the storage heap, should be used whenever access to external media is not absolutely needed. Use the VFS API when interoperability and file system access is needed. Note, however, that the VFS Manager adds the extra overhead of buffering all reads and writes in memory when accessing data, so only applications that specifically need this functionality should use the VFS Manager.
For more information on the Data and Resource Managers, as well as on the File Streaming APIs and the VFS Manager, see Exploring Palm OS: Memory, Databases, and Files.
Expansion Manager
The Expansion Manager is a software layer that manages block device drivers on Palm OS handhelds. Supported expansion card types include, but are not limited to, Memory Stick and SD cards. The Expansion Manager does not support these expansion cards directly; rather, it provides an architecture and higher level set of APIs that, with the help of low level block device drivers and file system libraries, support these types of media.
- broadcasts notification of card insertion and removal
- plays sounds to signify card insertion and removal
- mounts and unmounts card-resident volumes
NOTE: Some of the other functions provided by the Expansion Manager are for use by drivers and file systems and are not generally used by their-party applications.
For details of the APIs presented by the VFS Manager, see Exploring Palm OS: Memory, Databases, and Files.
Applications on Cards
Palm OS applications located in the /PALM/Launcher
directory of an expansion card volume appear in a separate Launcher category when the card is inserted into the handheld's expansion slot. If you tap the icon for one of these applications, it is copied to main memory and then launched.
Applications launched from a card ("card-launched" applications) are first sent a sysAppLaunchCmdCardLaunch
launch code, along with a parameter block that includes the reference number of the volume on which the application resides and the complete path to the application. When processing this launch code, the application shouldn't interact with the user or access globals. Unless the application sets the sysAppLaunchStartFlagNoUISwitch
bit in the start
flags (which are part of the parameter block), the application is then sent a sysAppLaunchCmdNormalLaunch
launch code. This is when the application should, if it needs to, interact with user. Applications may want to save some state when sysAppLaunchCmdCardLaunch
is received, then act upon that state information when sysAppLaunchCmdNormalLaunch
is received.
When the user switches to a new application, the card-launched application is removed from main memory. Note, however, that any databases created by the card-launched application remain.
There are certain implications to this "copy and run" process.
- There must be sufficient memory for the application. If the handheld doesn't have enough memory to receive the application, it isn't copied from the expansion card and it isn't launched.
- The copying process takes time. For large applications, this can cause a noticeable delay before the application is actually launched.
- If some version of the application on the card is already present in main memory, the Launcher puts up a dialog that requires the user to choose whether or not to overwrite the in-memory version.
- Card-launched applications have a limited lifetime: applications reside in main memory only while they are running. When the user switches to a different application, the card-launched application that was just running is removed from main memory. If the card-launched application is then re-launched, it is once again copied into the handheld's memory.
- "Legacy" applications—those that are unaware that they are being launched from a card—only work with databases in main memory. Associated databases aren't copied to main memory along with the application unless the database is bundled with the application. Databases created by card-launched applications are not removed along with the application, however, so this data is available to the application when it is subsequently run. Applications that are written to take advantage of the VFS Manager can read and write data on the expansion card, so this limitation generally only applies to legacy applications.
Bundled databases, although copied to main memory along with their associated application, are meant for static data that doesn't change, such as a game level database. Bundled databases are not copied back to the card; they are simply deleted from memory when the user chooses another application. To bundle a database with an application, give it the same creator ID as the owning application, set the
dmHdrAttrBundle
bit, and place it in the/PALM/Launcher
directory along with the application. - Unless a card-launched application is running, it doesn't receive notifications or launch codes since it isn't present on the handheld. In particular, these applications don't receive notifications and aren't informed when an alarm is triggered.
Card Insertion and Removal
The Expansion Manager supports the insertion and removal of expansion media at any time. The handheld continues to run as before, though an application switch may occur upon card insertion. The handheld need not be reset or otherwise explicitly informed that a card has been inserted or removed.
WARNING! Due to the way certain expansion cards are constructed, if the user removes an expansion card while it is being written to, in certain rare circumstances it is possible for the card to become damaged to the point where either it can no longer be used or it must be reformatted. To the greatest extent possible, applications should only write to the card at well-defined points, and the application should warn the user—perhaps with a "Please Wait" or progress dialog—at that time not to remove the expansion card. The card can be removed while an application is reading from it without fear of damage.
The Palm OS uses a series of notifications to indicate that a card has been inserted or removed, or that a volume has been mounted or unmounted. The following table lists these notifications, and the priority for which they have been registered by the Expansion and VFS Managers. Note that the priorities may change in a future release, so applications shouldn't depend on these precise values. Applications that register for these using normal priority get the correct behavior.
Table 5.1 Expansion card notifications
The following diagram shows the sequence of events that occur when an expansion card is inserted into a Palm Powered handheld's expansion slot. For clarity, it assumes that no errors occur. If the card doesn't contain a mountable volume, and if the card cannot be formatted and then mounted, this sequence is aborted and the card remains unmounted, although the card insertion notification is still broadcast.
Figure 5.2 Sequence of events upon card insertion

The Expansion Manager registers for sysNotifyCardInsertedEvent
with a priority of 20, ensuring that it is notified after other handlers that may have registered with normal priority. To override the Expansion Manager's default handler, register your handler to receive sysNotifyCardInsertedEvent
with normal priority, and have it set the appropriate bits in the handled
member of the SysNotifyParamType
structure:
-
expHandledVolume
indicates that any volumes associated with the card have been dealt with, and prevents the Expansion Manager from mounting or unmounting the card's volumes. -
expHandledSound
indicates that your application has handled the playing of an appropriate sound, and prevents the Expansion Manager from playing a sound when the card is inserted or removed.
Note that the number of the slot into which the card was inserted is passed to your handler using the notifyDetailsP
member—which is a UInt16
, cast to a void *
—of the SysNotifyParamType
structure.
Although most applications only register for volume mount and unmount notifications, if you need to receive notifications when the user removes a card from a slot managed by the Expansion Manager, have your application register to receive sysNotifyCardRemovedEvent
. Unlike with sysNotifyCardInsertedEvent
, the Expansion Manager registers for sysNotifyCardRemovedEvent
with a priority of -20, ensuring that it receives the notification before other handlers that are registered for it with normal priority. This notification, too, passes the number of the slot from which the card was removed to your handler using the notifyDetailsP
member—which is a UInt16
, cast to a void *
—of the SysNotifyParamType
structure.
The VFS Manager registers for sysNotifyVolumeMountedEvent
with a priority of 10. To override the VFS Manager's default handler, register your handler to receive sysNotifyVolumeMountedEvent
with normal priority, and have it set the appropriate bits in the handled
member of the SysNotifyParamType
structure:
-
vfsHandledUIAppSwitch
indicates that your application has handledSysUIAppSwitch
tostart.prc
. This bit prevents the VFS Manager from performing its ownSysUIAppSwitch
tostart.prc
(althoughstart.prc
is still loaded and aSysAppLaunch
is performed), and also prevents the launcher from switching to itself. -
vfsHandledStartPrc
indicates that your handler has dealt with the automatic running ofstart.prc
. The VFS Manager won't load it and won't call eitherSysAppLaunch
orSysUIAppSwitch
.
Note that if your application handles the running of start.prc
, you need to keep security in mind. If the handheld is locked when an expansion card is inserted, the VFS Manager's own handler defers the execution of start.prc
until the user unlocks the handheld.
Card removal follows a similar sequence, although there is no equivalent to start.prc
that is automatically run. This sequence is illustrated in the following diagram.
Figure 5.3 Sequence of events upon card removal

Upon card removal, the Expansion Manager broadcasts a notification to all applications that have registered to receive card removal notifications and unmounts any mounted volumes on the card. This causes the VFS Manager to issue a card unmounted notification. Each application must register for the card unmounted notification and provide the necessary error handling code if card removal at any time will cause a problem for the application.
Note that the card insertion and removal notifications are intended primarily for system use, although they can be registered for by applications that need them. Applications that deal only with file systems and the VFS Manager should confine themselves to the volume mounted and unmounted notifications.
Start.prc
Upon receipt of a sysNotifyVolumeMountedEvent
that hasn't already been handled (as indicated by the state of the vfsHandledStartPrc
bit, as described in the previous section), the VFS Manager copies /Palm/start.prc
—and its overlay, if there is one—to the storage heap and launches it. This process enables "application cards"—single-function cards that execute automatically upon card insertion. It also allows for combo cards that automatically load any necessary drivers and applications to support card I/O.
To launch start.prc
, the VFS Manager first sends it a special launch code, sysAppLaunchCmdCardLaunch
. If the application only needs to do a bit of work and return, it should do it here and then set the sysAppLaunchStartFlagNoUISwitch
bit in the start flags, which are part of the sysAppLaunchCmdCardLaunch
parameter block. Note that the application doesn't have access to globals and it shouldn't interact with the user here. If the sysAppLaunchStartFlagNoUISwitch
bit is not set, as it isn't if the application ignores the sysAppLaunchCmdCardLaunch
launch code, the VFS Manager then sends it a sysAppLaunchCmdNormalLaunch
launch code to run the application normally. This ensures backwards compatibility with applications that do not understand the sysAppLaunchCmdCardLaunch
launch code. This is where the application can interact with the user; an application may want to save state when it receives sysAppLaunchCmdCardLaunch
, and then act upon that state when it receives sysAppLaunchCmdNormalLaunch
.
To avoid running out of stack space, the VFS Manager sets the "new stack" bit when launching start.prc
. The start.prc
application remains in system memory until the volume from which it was copied is removed. start.prc
is deleted before VFSVolumeUnmount
broadcasts sysNotifyVolumeUnmountedEvent
but after the Expansion Manager broadcasts sysNotifyCardRemovedEvent
. By registering for sysNotifyCardRemovedEvent
, start.prc
can react to the volume being removed before it is deleted.
NOTE: If an expansion card is inserted while the handheld is locked,
start.prc
is not executed until the user unlocks the handheld.
Checking for Expansion Cards
Before looking for an expansion card, your program should first make sure that the handheld supports expansion by verifying the presence of the Expansion and VFS Managers. It can then query for mounted volumes. Finally, your program may want to ascertain the capabilities of the card; whether it has memory, whether it does I/O, and so on. The following sections describe each of these steps.
Verifying Handheld Compatibility
There are many different Palm OS handhelds, and in the future there will be many more. Some will have expansion slots to support secondary storage, and some will not. Hardware to support secondary storage is optional, and may or may not be present on a given handheld. Since the Expansion and VFS Managers are of no use on a handheld that has no physical expansion capability, they are optional system extensions that are not present on every Palm Powered handheld.
Due to the great variability both in handheld configuration and in the modules which can be plugged into or snapped onto the handheld, applications shouldn't attempt to detect the manufacturer or model of a specific handheld when determining if it supports secondary storage. Instead, check for the presence and capabilities of the underlying operating system.
Checking for Mounted Volumes
Many applications rely on the handheld's expansion capabilities for additional storage. Applications that don't care about the physical characteristics of the secondary storage module, and that don't need to know the slot into which the module is inserted, can rely on the fact that the Palm OS automatically mounts any recognized volumes inserted into or snapped onto the handheld. Thus, many applications can simply enumerate the mounted volumes and select one as appropriate. The following code illustrates how to do this:
Listing 5.1 Enumerating mounted volumes
UInt16 volRefNum; UInt32 volIterator = vfsIteratorStart; while (volIterator != vfsIteratorStop) { err = VFSVolumeEnumerate(&volRefNum, &volIterator); if (err == errNone) { // Do something with the volRefNum } else { // handle error... possibly by // breaking out of the loop } }
The volume reference number obtained from VFSVolumeEnumerate()
can then be used with many of the volume, directory, and file operations that are described later in this chapter.
Occasionally an application needs to know more than that there is secondary storage available for use. Those applications likely need to take a few extra steps, beginning with checking each of the handheld's slots.
Enumerating Slots
Before you can determine which expansion modules are attached to a Palm OS handheld, you must first determine how those modules could be attached. Expansion cards and some I/O devices could be plugged into physical slots, and snap-on modules could be connected through the handheld's universal connector. Irrespective of how they're physically connected, the Expansion Manager presents these to the developer as slots. Enumerating these slots is made simple due to the presence of the ExpSlotEnumerate()
function. The use of this function is illustrated here:
Listing 5.2 Iterating through a handheld's expansion slots
UInt16 slotRefNum; UInt32 slotIterator = expIteratorStart; while (slotIterator != expIteratorStop) { // Get the slotRefNum for the next slot err = ExpSlotEnumerate(&slotRefNum, &slotIterator); if(err == errNone) { // perform slot-specific processing here } else { // handle error... possibly by // breaking out of the loop }
The slot reference number returned by ExpSlotEnumerate
uniquely identifies a given slot. This can be supplied to various Expansion Manager functions to obtain information about the slot, such as whether there is a card or other expansion module present in the slot.
Checking a Slot for the Presence of a Card
Use the ExpCardPresent
function to determine if a card is present in a given slot. Given the slot reference number, this function returns errNone
if there is a card in the slot, or an error if either there is no card in the slot or there is a problem with the specified slot.
Determining a Card's Capabilities
Just knowing that an expansion card is inserted into a slot or connected to the handheld isn't enough; your application needs to know something about the card to ensure that the operations it needs to perform are compatible with the card. For instance, if your application needs to write data to the card, its important to know if writing is permitted.
The capabilities available to your application depend not only on the card but on the block device driver as well. Handheld manufacturers will provide one or more block device drivers that define standard interfaces to certain classes of expansion hardware. Card and device manufacturers may also choose to provide card-specific block device drivers, or they may require that applications use the slot custom control function and a registered creator code to access and control certain cards.
The block device driver is responsible for querying expansion cards for a standard set of capabilities. When a block device driver is present for a given expansion card, you can use the ExpCardInfo
function to determine the following:
- the name of the expansion card's manufacturer
- the name of the expansion card
- the "device class," or type of expansion card. Values returned here might include "Ethernet" or "Backup"
- a unique identifier for the device, such as a serial number
- whether the card supports both reading and writing, or whether it is read-only
- whether the card supports a simple serial interface
Note that the existence of the ExpCardInfo
function does not imply that all expansion cards support these capabilities. It only means that the block device driver is able to assess a card and report its findings up to the Expansion Manager.
Summary of Expansion Manager
|