Platform Limits
What are the Palm platform limits I'll likely encounter?
(Accuracy Note: Roughly every six months or so, a new Palm OS device is released that makes some item or other below inaccurate. This item was last checked for factual accuracy on 2003.03.25.)
The current Palm processor is a derivative of the Motorola 68000, a mixed 16/32 bit processor. This makes Palm devices feel like mid-80's Macintoshes in many ways. This so-called "Dragonball" processor is hobbled from that baseline by a few [reasonable] OS design decisions:
- 8 MB addressable memory - The Dragonball EZ and eariler CPUs can only address 8 MB of memory at a time. This is not a limit in the CPU's instruction set, it's a limit in the CPU's DRAM controller. This limit can be worked around by having more than one separate 8 MB chunk of memory -- you see this technique used in the original Visor and the Sony Clie, both of which have 8 MB add-on cards available. The TRG units can use even larger Compact Flash cards, but they don't directly access this memory: they move blocks of data to and from the CF card like your desktop computer uses its hard drive. The newer Dragonball VZ and SuperVZ chips support up to 32 MB of memory, but currently no released device has more than 16 MB.
- 32 KB jump size - When you do something like a function call, it resolves to a "short jump" machine language instruction. Short jumps on this processor are signed 16-bit relative jumps, you can only go a maximum of 32 KB forward or backward from the current memory location. There are also "long jumps" that have no effective limits on code distance, but they're slower and make the program bigger. So, current development systems make you jump through a few hoops (HowToWorkAroundLimits) to use these longer jumps.
- 64 KB resource size - Due to the way the current HotSync mechanism works, no one resource in a Palm database can be larger than 64 KB. Since your program's code is in a single resource by default, your PRC file can't get much bigger than 64 KB without resorting to multi-segmenting (HowToWorkAroundLimits). (If you use PRC-Tools, you can see how big your main code resource is by looking at the code0001.coffname.grc file. In my current project, for example, the PRC file is 53 KB, but the main code resource is only 33 KB. The balance is in UI and other resources.)
- 12-36 KB dynamic heap for most devices - Depending on the OS version, the dynamic heap size is quite small. OS 3.5 goes beyond the 36 KB cap in OS 3.0-3.3, allowing sizes up to 184 KB, but that's still pretty small. The dynamic heap is where dynamic variables and
malloc()'d objects are placed. Your development tool of choice may use the heap for other things, as well; CodeWarrior uses the dynamic heap for C++ exception information, for example. - Stack size - The stack size defaults to 3.25 KB on OS 3.0 and up, and it's hard-limited to 2.5 KB on older OSes. This limits how many function calls deep you can go, and how large your local variables can be. Recursive functions are almost entirely out of the question on the Palm. (You can increase the stack size in OS 3.0 and up, but be warned that the stack eats into the dynamic heap, which as we've seen is quite small already.)
- Dynamic chunk size - Due to limitations in the Memory Manager, the largest memory chunk you can dynamically allocate is a little less than 64K.
- Global variable size - Because the memory area reserved for global variables is allocated using the Memory Manager, the total space is restricted by the 64K limit. Thus, your application can have no more than 64K of global variables.
- Global variable availability - Completely starting up an application takes time. Part of this time is taken up by allocating and initializing the memory area occupied by the application's global variables. To save time and memory, this global variable allocation process is not always performed. Thus, global variables are not always available to your application when it is run (notably on "find" operations). Check the launch flags passed to PilotMain to see if the sysAppLaunchFlagNewGlobals bit is set before trying to access globals.
- Additional segment availability - When working with multi-segmented applications, calls to functions in a segment other than the current one makes use of a jump table accessed in the global variable space. Thus, to call such functions, global variables need to be available. Often, this means that when responding to launch commands like "find", you need to arrange to have all the code that handles it in the first/main code segment.
The definitive article on these issues is the Memory technical article at palmos.com.