Combee on Palm OS

Thursday, 17 June 2004  2:53 PM

One of the harder concepts to grasp when starting to develop to the Palm OS 68K API is the idea that global variables aren't always available for your program. This is an artifact of the way Palm OS lets applications register for notifications that can occur while other programs are active on the device. Since the original devices had limited memory and processor speed, it was judged to be wasteful for the OS to go through a complex process initialization routine to deliver a notification that many applications would ignore.

However, many developers aren't quite aware of what qualifies as a global variable. This is any chunk of data that's stored in the global data section and references using an offset from the A5 register. For most purposes, this list includes:

  • global variables
  • static variables with file scope
  • static variables with function scope
  • static member variables
  • C++ virtual function tables
  • C++ RTTI information
  • C++ exception handler tables

The only exceptions are constant strings referenced directly by program code (these are allocated in the code section) and constant global variables that have no internal pointers to other data structures (when using the "PC-relative const data" code generation option in the 68K Code Gen panel in CodeWarrior). There's a caveat here too; if you use PC-relative const data, it can't be accessed directly by code in other code sections or segments.

You can tell where a symbol is allocated by using the link map feature in CW's 68K Linker panel. Look at the output MAP file and any symbol that's in the A5-relative section is global data that isn't always available.

Now, there are situations where globals are accessible even though your application is handling a system notification. This happens when your program is the active application when it gets the notification. You can tell this by looking at the launch codes passed to PilotMain; here is the text copied from SystemMgr.h:

IMPORTANT ACTION CODE CONSIDERATIONS:

Many action codes are "sent" to apps via a direct function call into the app's PilotMain() function without launching the app. For these action codes, the application's global and static variables are *not* available, unless the application is already running. Some action codes are synchronized with the currently running UI application via the event manager (alarm action codes, for example), while others, such as HotSync action codes, are sent from a background thread. To find out if your app is running (is the current UI app) when an action code is received, test the sysAppLaunchFlagSubCall flag (defined in SystemMgr.h) which is passed to your PilotMain in the launchFlags parameter (the third PilotMain parameter). If it is non-zero, you may assume that your app is currently running and the global variables are accessible. This information is useful if your app maintains an open data database (or another similar resource) when it is running. If the app receives an action code and the sysAppLaunchFlagSubCall is set in launchFlags, the handler may access global variables and use the open database handle while handling the call. On the other hand, if the sysAppLaunchFlagSubCall flag is not set (ie., zero), the handler will need to open and close the database itself and is not allowed to access global or static variables.