This article may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. To maintain the flow of the article, we've left these URLs in the text, but disabled the links.


May 1998

Microsoft Systems Journal Homepage

Microsoft Windows CE 2.0: It’s Not Just for Handheld PCs Any More

Paul Yao

If there is confusion about the role for Windows CE, it is due to the fact that until recently there was only one product that used Windows CE: the Handheld PC. In January of this year, Microsoft announced two more Windows CE-powered devices: the Auto PC and the Palm-size PC (P/PC).

This article assumes you're familiar with Win32

Paul Yao has spent the last decade writing books and training corporate clients on Windows programming topics. He’s now created the first workshops available on Windows CE. He can be reached at 1-800-942-3535, or on email at 73717.3041@compuserve.com.

If your impression of Windows® CE is that it's a pared-down version of Windows 95, or that, like its first incarnation, it can be used only on the Handheld PCs, you should take a closer look at version 2.0. Designed from scratch to be small, portable, fast, and scalable, Windows CE 2.0 is far more comprehensive than you may imagine.
      Before diving too deep into the technical details, it is worthwhile to examine the motivations behind the design of Windows CE. Three emerging trends represent massive opportunity for the software industry and direct applicability for Windows CE.
      First, very fast, low-cost, low-power, 32-bit microprocessors are becoming ubiquitous. Everywhere you look (industrial monitoring, medical equipment, point of sale terminals, multimedia consumer appliances, smart phones, customer kiosks, and even cars), an intelligent device is making our work and home lives easier and more efficient.
      Second, mobile computing is becoming the modus operandi of the modern worker. Millions of traveling professionals, telecommuters, and field representatives (real-estate agents, car appraisal experts, and sales reps to name a few) are demanding more powerful, longer lasting computing power in ultra portable forms.
      Finally, the convergence of entertainment, information, and technology in the home will fundamentally change the way millions of people spend their leisure time. While digital convergence has been hyped for years, products such as DSS receivers, high-definition digital TV, and DVD players have already started to work their way into millions of homes.
      All this technology is rendered pretty useless if it can't communicate and exchange information with one another. Clearly, the importance of the Internet as a communications and information delivery infrastructure almost goes without saying. As you might expect, support for standard protocols (TCP/IP) and formats (HTML) is a fundamental requirement for any device powered by Windows CE.
      So let's explore the details of each of the Se from the developer's perspective.

Publicly Announced Devices
      If there is confusion about the intended role for Windows CE, it is due in no small part to the fact that until recently there was only one product available that used Windows CE: the Handheld PC. At the Consumer Electronic Show in January of this year, Microsoft announced two more Windows CE-powered devices: the Auto PC and the P/PC.

Figure 1 A Handheld PC
Figure 1 A Handheld PC


      Figure 1 shows a Handheld PC device from Sharp Electronics Corporation, the Mobilon HC-4500. Powered by a MIPS R4000 RISC processor, it has one of the larger display screens of any available Handheld PC, 640X240 (more typical sizes are 480X240). A touch screen serves as the pointing device instead of a mouse. Its ROM holds the Windows CE operating system and several applications like Pocket Word and Microsoft® Pocket Excel. It also has 16MB of RAM for use both as conventional RAM to run programs and hold data, and also for the Object Store, where a user stores files. It comes with a PC card slot, a serial port, and an infrared (IrDA) port. Its user interface resembles Windows 95, although it's a scaled down version that focuses on Pocket Explorer.

Figure 2 A Palm-size PC
Figure 2 A Palm-size PC


      Figure 2 shows a typical P/PC device. To get an idea of what such a unit might consist of, I checked out the Casio Computer Company Web site (http://www.casiohpc.com) and got the following details on the Cassiopeia E-10. Powered by an NEC VR4111 MIPS RISC processor, the E-10 has a 240X320 four-level grayscale touch screen. The touch screen and a few buttons on its side serve as the input devices, as it lacks both a mouse and a keyboard. It has 4MB of RAM and, like the Handheld PC, both a serial port and an IrDA port. It has built-in support for handwriting recognition, although as on earlier handwriting recognition systems, you have to learn a particular style of writing to get good results. This is a replaceable module, however, so presumably as the technology gets better, you'll see better and better solutions provided.

Figure 3 An Auto PC
Figure 3 An Auto PC


      Figure 3 shows an Auto PC. Created as an upgrade replacement for the car radio, it has its own AM/FM radio and CD player that can be used both for audio as well as for CD-ROM disks. Its display screen is 256X64. Its user interface is primarily audio-oriented instead of visually-oriented (like desktop and laptop systems). Unlike other PC companion products, it does not have a touch screen. Voice input (using voice recognition technology) is used to receive commands from a user, and a synthe Sized voice "talks" back to the driver. Like the Handheld PC and the P/PC, this device has an IrDA port and a serial port. In addition, it has a Universal Serial Bus (USB) for connections to other devices such as CD changers and cell phone cradles.
      So what are the key characteristics of Windows CE? Here are the highlights: small, modular, portable, connected, compatible, and real-time. Let's cover the Se one at a time.

Small
      The current size of the Windows CE core libraries is less than 500KB, but varies with each particular system. A Windows CE-based device with the kernel, the file system, and the registry could fit into 256KB of ROM. While a Handheld PC-like device (which includes the kernel, drivers, communications, the file system, a database, GDI, and the shell) requires 1.5–2.5MB of ROM and 600KB of RAM, still other configurations may command even more resources. Binaries—including both operating system libraries and other included programs—sit in ROM, and run in place so as to not take up any system RAM. This tiny footprint makes Windows CE a candidate for small to medium-sized embedded systems, whose low per-unit cost allowances make larger systems like Windows 95 or Windows NT® unfeasible. (It might surprise you to learn that some companies do use Windows NT in embedded systems, although obviously the hardware requirements are significantly more than for a Windows CE-powered system.)
      This run-in-place ROM means that Windows CE is more similar to other embedded operating systems than it is to desktop and laptop systems. On a PC, the Operating system is read from disk as part of a (sometimes too-long) boot process. Windows CE runs with no boot process, aside from when power is first turned on, and stays on even after the user turns the power off in a state known as suspend mode. (All Windows CE-based devices will have a suspend mode, but this is OEM selectable.) In this mode, only a tiny amount of power is needed, and it allows the system to "wake up" to notify the user of things like upcoming appointments or other significant events. On the unit that I experimented with, I was delighted to find that the power-on cycle time was more like that of a calculator or telephone instead of the lengthy startup time required for PCs.

Modular and Configurable
      Microsoft Windows 98 and Microsoft Windows NT are, more or less, monolithic operating systems built with a specific set of features and a specific set of API functions. Unlike the M, Windows CE was created as a modular operating system that different customers could configure to meet specific needs. At present, OEM customers can choose from among 60 or so different components.
      The modularity of Windows CE is crucial to allowing flexibility in configuring custom embedded systems for applications as diverse as home appliances, office equipment, and industrial controllers. Within this wide playing field, choice among the components helps keep the price down for simpler devices, yet allows more sophisticated devices access to greater capabilities.
      Consider two different devices: a Handheld PC and an office printer, both running Windows CE. Clearly, the Handheld PC unit needs good graphical output ability to allow display of rich text and complex graphics. An office printer, on the Other hand, might need only support for a simple text display window or LED indicators. (While lower-priced inkjet and laser printers probably won't ever use Windows CE, higher-end laser printers have surprisingly sophisticated CPUs and real-time operating systems that could be replaced by Windows CE, assuming that Microsoft can convince printer manufacturers to license it.) Windows CE is sufficiently configurable so that the builder of each type of device can get the Operating system components needed without paying for more than what is needed.
      Other examples showing the benefits of modularity are clearest by pointing out what is excluded from a class of devices. For example, a module excluded from the Windows CE on the current crop of Handheld PCs is hard-drive support (data is stored in RAM, in a software emulation of a file system). The versions of Windows CE on the P/PC and the Auto PC don't have the keyboard module, since both units lack a keyboard. The P/PC has handwriting recognition support, something the Auto PC lacks. And the Auto PC supports voice recognition, lacking in the P/PC.
      A development team that chooses Windows CE for an embedded system can incorporate as much or as little of the OS into their system based on their needs.

Portable
      Microsoft broke away from a long-standing tradition of building Intel-only operating systems with the release of Windows NT in 1992. In addition to 32-bit Intel processors, Microsoft built Windows NT for the Alpha, MIPS, and PowerPC processors. (Today only the Intel x86 and Alpha CPUs are still supported.)
      The range of processors for which Windows CE has been built include those shown in Figure 4. Windows CE is even more portable than Windows NT, since it isn't dependent on a particular bus architecture nor is it dependent on a specific system interrupt structure. This makes sense, since to be a viable embedded operating system, Windows CE had to be flexible enough to meet the needs of a wide range of embedded systems.

Connected
      Connectivity was a key design goal of Windows CE. This makes sense given the extent to which we live in a "wired" world where few devices don't connect to some other device. Embedded systems routinely connect to other systems via network or serial link. A water pumping station up the street from my home is controlled by an embedded system that communicates to a central office via a dial-up phone line. On the factory floor, programmable logic controllers—the vast array of "switches" that control devices on assembly lines—are networked to allow for coordination between different events that affect the flow of manufactured goods. For Windows CE to become a viable player in the embedded system market, an ability to connect to other computer systems is vital.
      Windows CE support for connectivity is also evident in currently shipping Handheld PC units, all of which have an infrared (IrDA) port, a serial port, and a type-II PC card slot. The IrDA port can be used for computer-to-computer data sharing (for example, two Handheld PC units can talk to each other for sharing name and address information). Printing is possible from an IrDA port to printers similarly equipped. The serial port allows connections between a Handheld PC and a desktop machine for synchronizing of files, such as personal schedules, address books, and for uploading email. And, of course, the PC slot allows a user of a Handheld PC unit to stay connected when in the Office (via a network PC card) and, thanks to the built-in Remote Access Service (RAS) client support, when out of the Office as well (via a modem card). Some Handheld PC units even come with built-in modems.
      The connectivity of Windows CE is also evident in support for both TAPI and Windows sockets. TAPI, the Telephony API, is a high-level API for controlling communications over telephone networks. Windows 9x and Windows NT provide TAPI support that includes a wide range of sophisticated features, including managing conference calls, handling caller ID, and managing voice mail. On Windows CE, support for TAPI is limited to handling outgoing calls—specifically, outbound modem calls.
      Windows sockets is a high-level network communications API, based on Unix sockets. As with TAPI, Windows CE support for sockets does not include the complete implementation found on desktop systems. Instead, the focus is on a lean-and-mean core set of services. In particular, the message-based asynchronous socket services are not supported (functions like WSAAsyncSelect, WSASend and WSARecv). The biggest concern this should raise is if you are porting existing Windows sockets code from Windows 9x or Windows NT. If you're writing new code, you will have to rely on the standard "blocking" functions like send, recv, and select. Unix sockets programmers tell me they feel right at home with this subset of the Windows sockets API.

Compatible
      Another important design goal for Windows CE is compatibility. In particular, the programming interface is a subset of the Win32® API. For programmers, this is a big win, since much that you know about programming for Windows 95 and Windows NT can be directly translated into Win32 programming on Windows CE. And for programmers who haven't learned Win32 API, Windows CE could represent your chance to broaden your skillset to include this important API.
      Perhaps one of the more interesting aspects of Windows CE is support—or lack of same—for legacy applications. By this, of course, I mean MS-DOS® programs and 16-bit Windows-based programs, both of which are not supported. By not supporting legacy applications, the Windows CE development team saved significant memory and, more importantly, saved the testing and debugging time that inevitably must be spent to allow such applications to run. Legacy application testing has always been a major cost to Microsoft when preparing to ship a new operating system.
      Another obvious way that Windows CE 2.0 meets the criteria of compatibility is in compatibility with Windows CE 1.0. As Microsoft has done with its desktop Windows-based systems, the planned additions to Windows CE are built to maintain compatibility with previous versions. (See "Feature Highlights of Windows CE 2.0".)
      Another way that the compatibility goal has been served is represented by the array of development choices available. You can compile applications in assembler, C, or C++ to take full advantage of performance and memory. With Windows CE 2.0, Microsoft has introduced MFC and ATL support, along with a Visual Basic® runtime for Windows CE and Microsoft VMs for Java. When used with the corresponding developer toolkits, developers can apply their knowledge of Visual Basic and the Java language to build applications for Windows CE. At this point, the Visual Basic and Java language support may only be found on Handheld PCs. Microsoft plans to migrate the support for the Visual Basic and Java programming languages to embedded systems applications in the future.

Real Time
       For many years, the words "Microsoft Windows" and "real time" were rarely used in the same sentence, and then only as an apology. With the introduction of Windows NT in 1992, things got more real—that is, you could more deterministically predict the responsiveness of the Operating system to external events. The multithreaded, preemptive nature of Windows NT helped make it a reasonable target for real-time systems. However, it must be kept in mind that Windows NT was built as a general purpose operating system, and the adequacy of its real-time support is something that you'll have to decide based on your system requirements.
      So how real is the real time in Windows CE? Several factors need to be taken into account to answer this question. With embedded products, Microsoft knows that real-time support is key. For that reason, the Windows CE Embedded Toolkit has tools to help measure response time.
      An article at the Microsoft Web site describes some of the details of the Se tools, and some of the issues to consider (see http://www.microsoft.com/windowsce/embedded/techpapers/realtimesys.htm). This article provides some algorithms and hard numbers for the ODO reference platform, which is based on a 60MHz Hitachi SH3 processor. I'll summarize some of the details here, but real time aficionados should check out the Original article.
      With real time processing, latency is an important consideration. Latency refers to the amount of time that elapses after an event occurs and before the software responds. Three different latency numbers are of interest: maximum ISR start time, median IST latency, and worst case IST start time.
      The maximum time to respond to an interrupt, based on 1000 tests on the previously mentioned reference platform, was 7.5 microseconds. In the article, this is referred to as the Start of ISR time. ISR stands for interrupt service routine, which is kernel-mode code that gets called when a specific hardware interrupt occurs. Very little "real" work is done in an ISR, except perhaps to copy data from a port to a buffer; it then triggers an event (via the Win32 PulseEvent function) that notifies a user-mode thread, known as the IST or interrupt service thread, that there is work to do. For real time applications that need single-digit microsecond response time, the good news is that your code has a chance to respond to the interrupt and do some work on the fly. the Obvious downside is that such behavior increases systemwide ISR latency, since interrupt handling isn't nested on Windows CE. In a closed system, such robbing Peter to pay Paul strategies are justifiable only when undertaken with both eyes wide open. On open systems—that is, when you're writing a device driver for one of the PC companion platforms like the Handheld PC or the P/PC—such an approach can create timing problems for other device drivers.
      The median IST latency refers to the median time to start the IST. An IST is a user-mode thread that runs in the address space of DEVICE.EXE, the process that handles all installable device drivers. Such threads typically run at the highest thread priority, time critical. Devices are loaded into memory using a call to LoadDevice (called from the RegisterDevice function), a substitute for the LoadLibrary function that loads and locks all of the pages of a DLL into memory. (On Windows CE 2.0, DLL pages are not locked into memory by LoadLibrary.) The behavior of LoadDevice eliminates the latency that can otherwise occur when pages must be read from the Object store.
      The role of the IST is to do all of the "real" work associated with handling an interrupt (aside from what the ISR has done). The Web article suggests a median latency of less than 100 microseconds (actually, 90 percent of the cases reported 102 microseconds or less). The median time is helpful when handling real time situations that can tolerate some amount of failure. For example, some network protocols will retry when a packet has been lost. In such cases, the median latency (or a derivative) provides a starting point for deciding what response time is acceptable.
      The worst case IST start time—which the article calls the "conservative upper bound that is higher than the actual worst case time"—is 500 microseconds. The article goes into great detail describing how this number was derived, based on the longest time in various kernel routines. Such a number is important when building a real-time system for which there is no recovery from a failure to act on the interrupt. In particular, this takes into account all of the worst case paths through the kernel and through other interrupts.
      So is this real-time response good enough for your needs? Experienced real-time programmers know that the Only way to know for sure is to do your own benchmarks on hardware that you anticipate using. You'll want to measure, measure, measure—and the tools in the embedded toolkit will help you do exactly that.

Hardware
      the Only hardware required to run Windows CE is some RAM, some ROM, a 32-bit processor, and an internal timer for scheduling (and, of course, a power supply). A minimum Windows CE system requires less than 256KB of ROM and 350KB of RAM. The Windows CE libraries sit uncompressed in ROM, and they run in-place. Of course, very few systems will run a minimal configuration, as most systems need a way to get commands and data from users, and some means to show the results of work done. A Windows CE system with all available components requires 1.5–2.5MB of ROM.
      I have broken down the supported types of hardware for Windows CE systems into four parts: input devices, output devices, communication devices, and storage devices.

Input Devices
      A typical Microsoft Windows desktop system has a mouse and a keyboard for input. On Windows CE-powered systems, possible input devices include keyboards, touch screens, voice input, and handwriting recognition. It's easy to imagine other input devices, such as magnetic card-readers, barcode readers, or even (to borrow from the movies) retinal scanners (as in "Tomorrow Never Dies") and breath scanners (as in "Alien Resurrection").
      The keyboard on a typical Handheld PC device includes a standard alphanumeric set of keys, with many standard desktop keys designated as optional. On the Casio Cassiopeia system that I tested, there weren't any function keys. That's perhaps not a big deal for some users, but I missed hitting Alt+F4 to close running programs. I look forward to some type of standard to replace this old favorite—perhaps Ctrl+Q for Quit. Some newer machines with larger keyboards may have a more complete set of keys to reduce the difference between handheld and desktop devices.
      A standard input device on P/PC and Handheld PC devices is a microphone for recording personal messages, interviews, and telephone conversations. With the standard compression used, an hour of recording can be stored in just 1MB. In occupations such as journalism, social work, and the legal profession, the ability to record and play back is critical. Why carry a tape recorder and a computer, when one device can do both?
      It's one thing for a computer to record speech, and quite another thing for a computer to understand speech. As an indication of how important this type of input is to Microsoft, a recent Fortune magazine article revealed that half of Microsoft's Research group is working on speech recognition. To keyboard-oriented users like software developers, such a deployment of resources might seem like overkill on a marginal input media, or even simple infatuation with a hopelessly complex engineering problem. But voice input offers certain users the best way to interact with a computer.
      Take drivers. How many hours a week do you spend driving? One source suggests seven hours per week on average. The Auto PC has interactive speech technology to allow drivers to keep eyes on the road and hands on the wheel. Along with an AM/FM radio and CD player, an Auto PC can give a driver access to personal contacts and driving instructions, and allow use of email, paging, and cellular phone service. The voice recognition capability allows for input of simple spoken commands. In addition, it uses a voice synthe Sizer to "talk" to the driver.
      Another input style that Microsoft is pioneering with Windows CE is handwriting recognition. This isn't a new idea, but the Apple Newton and Windows for Pen Computing both produced fairly marginal results, since the recognition software wasn't able to produce the consistency that users wanted. Today's handwriting recognition software is better, owing to more finely tuned algorithms and faster processors.
      A Windows CE-based device that uses handwriting recognition—and which has no keyboard!—is the P/PC. As shown in Figure 2, a P/PC has a graphical display screen that has suggestions of the Windows user-interface standard. A plastic-coated touchscreen serves as the pointing device. The touchscreen also provides the input device for handwriting recognition. If you prefer, you can also summon a keyboard display for tapping individual keystrokes onscreen.

Output Devices
      One possible configuration for Windows CE systems is no output devices! That's right, it's possible to have Windows CE embedded in a device with no means of communicating directly with users, except perhaps through another computer. I told you Windows CE is not like desktop systems. Windows CE doesn't require the same I/O devices, the same form factor, and it doesn't need to look (or smell) like a computer. It's difficult to think of Windows 98 or Windows NT systems running without a mouse, keyboard, display screen, and the collection of whirring fans and spinning motors (except perhaps for "headless" network servers). Consider an array of Windows CE devices embedded on a factory floor. Rather than having a bunch of display screens, status information from individual devices could be sent via network to a central control system that displays the collective results. For troubleshooting, an operator could perhaps zoom onto a particular controller.
      Well, suppose an OEM does want an output device. Possible output devices for Windows CE systems include synthe Sized voice, text-only display screens, as well as display screens as small or as large as the target application requires.
      The Auto PC has a small (256X64 pixel) conventional display screen that supports eight colors. In addition, a voice synthe Sizer talks to a driver to give directions, read email, and provide a notification when a pager message arrives to the car. This device will have great appeal for individuals who like voice mail. A preference for aural or visual communication is a well-documented psychological trait.
      Another output device for Windows CE-based systems is, of course, the display screen. The range of available display screens on currently shipping Windows CE-based systems extends from the tiny 256X64 on the Auto PC up to 640X240 on some of the more recently created Handheld PC units.
      the Operating system ships with the driver source code so that OEMs can support their particular video hardware. Writers of Windows CE device drivers should note that there aren't many pixels on a typical system. To a user of a desktop system with resolutions like 1024X768, 1280X1024, and 1600X1200, the Se are tiny spaces to work with. However, the larger display resolutions of Windows CE units overlap with the lowest resolutions of laptop and desktop systems. Programmers should make sure they follow the rules of Windows programming. In particular, avoid hard coding for a specific device resolution. Among seasoned programmers, this goes without saying, yet some newer software has shipped with hard-coded window sizes.
      Windows CE-based systems do provide a high level of integration to desktop and laptop systems running Windows 95, Windows 98, or Windows NT. That is the next area of hardware devices that I plan to discuss, namely Windows CE-supported communication devices.
      

Communication Devices
      As I mentioned, connectivity is a key design goal of Windows CE. It's not surprising, therefore, that there are many ways to connect a Windows CE-powered device to other devices.
      Before getting into the communication specifics, it might be worthwhile to discuss exactly what devices a Windows CE device might connect to. Four scenarios make the most sense. First, some Windows CE units will connect to Windows 95, Windows 98, and Windows NT desktop systems. Second, some Windows CE units will connect to other Windows CE units. Third, Windows CE units will be made to connect to the Internet for simple Web browsing and channel surfing (the P/PC, with its small screen, is intended more as a recipient of the push model). Finally, Windows CE-based devices can connect to printers. Let's take a closer look at each of the Se four uses.
      Every P/PC and Handheld PC comes equipped with a serial port to allow connection to a Windows 95, Windows 98, or Windows NT system. On the desktop side, the RAS support must be installed. In addition, some special software (Microsoft Windows CE Services) must be installed to do the necessary handshaking with the Windows CE unit. Incidentally, this same software is necessary to enable remote debugging from Visual C++ 5.0, and that is why this software comes with the Windows CE Toolkit.
      There are several reasons why a user might connect a Windows CE unit to a desktop Windows system. One reason is simply to load application software, since the amount of local storage is in the range of tens of megabytes.
      Another reason is to move data between a desktop system and a Windows CE unit. For example, after building a contact database on the desktop, a salesperson could download a list of clients to a Windows CE unit and have all the data needed for a weeks worth of sales calls. While in the field, the salesperson would run a scaled down version of the desktop product specially designed for the small memory and limited user interface of the Windows CE unit. After visiting clients, the salesperson would connect to the desktop to automatically update the contact database with all the details collected in the sales calls.
      The second type of connection that can be made from a Windows CE unit is to another Windows CE unit. Three of the four publicly announced classes of devices—the Handheld PC, the P/PC, and the Auto PC—come equipped with an infrared port that appears on some systems as COM3:. (This is configurable by the OEM.) Using that port, two Windows CE units can communicate and share data. Imagine, then, that you know you are going on a long trip. On your desktop, after printing out the map, you download the addresses and contact information to your Handheld PC unit, and in the car download that data from the Handheld PC to your Auto PC. It's this second connection, from Handheld PC to Auto PC, that is made using the infrared port. The wireless connection between your Handheld PC and your Auto PC doesn't involve any messy cables or tiny connectors (which might be hard to find in a dark car). On your trip, you talk to your Auto PC and have it read the directions as you need the M. What could be simpler?
      The third type of Windows CE connection is to the Internet. The Handheld PCs on the market all ship with a scaled down version of Microsoft Internet Explorer. The P/PC, with its smaller screen, is able to connect to individual Internet channels that you set up and download from a desktop Windows system. But then how does either type of Windows CE unit connect to the Internet itself? One way is to use a built-in modem—the Ones I've heard about use a software modem, which uses the CPU for its brains and in general requires less power than a PC card modem. Another way is to use a PC card modem, which can cause a severe drain on available power on a battery-operated Windows CE unit. A third alternative is to use a wireless modem. Motorola has announced just such a modem, to allow you to browse the Web, connect to your email, and maybe even play an Internet-based game or two. A fourth possible connection to the Internet is through a PCMCIA network card.
      Finally, Windows CE-based devices can connect to printers. There are three ways such a connection can take place. One way is through the serial port, which appears as COM1:, standard on Handheld PC units. A second way is through the infrared port to printers that are similarly equipped. A third way is using the USB, a port that is not standard on Handheld PCs, but an option for OEM customers to add to Windows CE-powered devices.

Storage Devices
      The final category of Windows CE-based hardware devices that I'll cover is storage devices. A typical Handheld PC device comes equipped with 8MB of ROM, 8MB of RAM, and no hard drive. That isn't because Windows CE cannot support hard drives, since an optional ATA drive module is available for embedded systems designers who require one. In the new classes of devices that are made possible by Windows CE, a hard-disk drive would be too severe a drain on the batteries. So, the basic form of storage is RAM. Then again, many Windows CE-based devices are not going to be battery powered.
      It's said that if you live long enough, you'll see old-fashioned things come back into style. In the heyday of MS-DOS, when the address space of an IBM-PC compatible was 1MB, it was possible to purchase memory boards to be used as RAM drives. the Se were software emulations of disk drives that used memory to store code and data. RAM drives made disk-bound applications run faster, since RAM is generally faster than magnetic media.
      In Windows CE, the same concept exists in what is known as the Object store. There are in fact three types of objects in the Object store: a file system, Windows CE databases, and the system registry. The file system provides support for long file names, which in itself was a surprise to me given the Windows CE goal to run small. But Windows CE, just like its desktop cousins, allows file names up to 255 characters long, and fully qualified paths up to 260 characters long. While long file names and long file paths are supported, rest assured that the design goal of running small has been achieved: there is no wasted space in the Object store for shorter file names.
      The Windows CE database support really means flat-file, simple record storage. You can assign up to four keys for each database, and you can have as many databases in memory as the Object store allows. There is no support for the more sophisticated relational operators, hierarchical relationships between databases, or SQL. It provides just the thing you need to store simple data in an efficient manner, with little if any parsing required. Small and simple, that's the credo of the Windows CE database.
      The final type of object store entry is the registry. Just like Windows NT, Windows CE has a registry for storing system configuration information and for storing things like COM object class IDs. And you use the same Win32 APIs to create, read, write, and close registry entries. One difference between the desktop registry and the Windows CE registry is in the size of registry key names and in the size of registry key values. On the desktop, both can be up to 4096 bytes, while on Windows CE key names can be up to 255 bytes and nested to 16 levels in depth. Values can be a maximum of 4096 bytes.
      Having covered the range of hardware for which Windows CE-based systems can be built, let's return to the star of the show, the Windows CE operating system itself.

Windows CE Operating System Features
      In a Wall Street Journal review of Windows CE Handheld PC devices, the writer called Windows CE the "younger sibling of Windows 95." This reflects the perception that given the price point and the machine size, Windows CE is more closely related to Windows 95 than to Windows NT. I think of Windows CE as being closer to Windows NT, a kind of Lite version of Windows NT. Unlike Windows 95, which is at least half 16-bit segmented code, Windows CE is 100 percent 32-bit code. Windows CE leaves behind the legacy 16-bit Windows and MS-DOS tradition on which Windows 95 was built. To me, it's a child of the 90s and is at best a distant relation of Windows 95.
      Microsoft reported that 500,000 Windows CE-based units have shipped to date. Programmers who helped build software for Windows CE version 1.0 might only want to know about the "delta," the differences between the first version and version 2.0. If you're one, see the sidebar titled "Feature Highlights of Windows CE 2.0". For programmers without prior knowledge of Windows CE, the rest of the article focuses on what I consider to be the core operating system features.
      I'll start with a discussion of the key components of Windows CE 2.0. Next, I'll cover the supported subset of the Win32 API. I deliberately do not discuss two key features: memory and networks, since both topics are covered in the Other two articles in this issue of MSJ. Windows CE is a multithreaded, preemptively scheduled operating system, and I'll discuss what exactly this means. Next, I'll touch on ActiveX® support, and conclude with a look at the Remote API (RAPI).

System Components
      Unlike Windows 9x and Windows NT, Windows CE is a configurable operating system that individual OEM customers can tailor to the needs of a given platform. The pieces from which a Windows CE system can be built are divided into roughly a dozen modules (see Figure 5), which are the Mselves built from 60 or so components. It's important to note that the modules the Mselves are not monolithic entities, but can be further refined by the exclusion of various pieces. For example, the Graphics, Windowing, and Events Subsystem (GWES) can be shrunk down by excluding mouse cursor support, keyboard caret support, clipboard support, and the dialog box support.
      Of the modules in Figure 5, only NK, the Operating system kernel, is required. Among the core system features it provides are thread scheduling and synchronization, program and DLL loading, paged memory management (but not heap management, that's separate), and exception handling.
      When present in a Windows CE system, each of the first four modules in the module list run in their own processes. In other words, on a typical Handheld PC or P/PC device, you'll find the Se four executable files: NK.EXE, DEVICE.EXE, GWES.EXE, and FILESYS.EXE. At system startup, each gets started in their own process address space. Applications access the services of each using a mechanism that is reminiscent of the local procedure call (LPC): the call to the system service involves a context switch of sorts from the application's address space to the subsystem address space for a single function call. The key benefit this provides is operating system robustness, since applications are prevented from having direct access to operating system code and data. As all things in life, there is a cost, which—just like on Windows NT—is the time it takes to transition between the different address spaces.

The Win32 API
      After many years of driving a car, getting back on a bicycle can be a bit frustrating, and that is what Windows CE programming is like to those used to programming for a desktop version of Windows. In a car, you have a roof over your head, a sound system, layers of chrome and steel, and four huge tires, so you feel pretty safe. On a bicycle, you have none of the comforts and all of the risk: it's you against the weather, the road, and the cars. And yet, there is a freedom and self-sufficiency on a bike that car drivers never get. There is some frustration with the lack of certain favorite Win32 functions when you start writing code for Windows CE, but there's also a certain thrill with seeing your own code running on a featherweight handheld unit. Like you're gazing at the future of computing or something.
      To help get a sense for the differences between Win32 on Windows NT and on Windows CE, I had a project to port close to 100 programs originally written for Windows NT. They were sample programs and lab solutions for a programming class on Windows NT that I had created several years ago. A client was asking me to teach the same material with a focus on Windows CE instead. The nice thing about this set of programs is that the range of issues and APIs that I had to deal with spanned a wide range of Win32 programming topics. There were only a few "gotchas" that slowed me down, although each of the programs seemed to require some change. Nothing too major, but a major point worth making is that quite a number of Win32 functions that you might be used to are not implemented in the subset that was created for Windows CE. Often, there is still a function available to do what you want done, but sometimes you have to look around a bit when a favorite Win32 function wasn't included. It struck me that about 80 percent of things don't change from the desktop to the Handheld PC unit, but you do have to deal with the lack of support for certain things.
      The general principle of the team that designed the Win32 API for Windows CE seemed to be this: conserve memory by making the API as small as possible. Where there are two or more ways to do something on the desktop, leave only one (and occasionally two) on Windows CE. For example, for drawing text, the Win32 API on desktop systems has the following functions: TextOut, ExtTextOut, TabbedTextOut, and, of course, DrawText. On Windows CE, there are only two: ExtTextOut and DrawText. (I miss TextOut, and would like the CE team to add it back as a macro that calls ExtTextOut. I'll even volunteer to write it for the M!) If you are an experienced programmer, you will find that lots of your old favorite functions are missing. While it's an inconvenience to look for replacements, you have to keep repeating to yourself the benefits that are derived from the smaller, simpler API: Windows CE was kept small, which lowers the memory requirements, which lowers the cost of Windows CE-based devices. In a sense, it's the classic software trade-off: memory saved for processing time spent.
      Another important feature of the Win32 API on Windows CE is that only Unicode functions and data structures are supported. As you may know, when Microsoft created the Win32 API, for every function (or data structure) that deals with any character strings as parameters, two functions (or data structures) were defined. For example, the function to query the text of a window is GetWindowText, declared as follows:


 int GetWindowText(HWND hWnd, LPTSTR lpString, 
                  int nMaxCount);
      The Unicode version of this function is called GetWindowTextW, and the multibyte version (ANSI version) is called GetWindowTextA. Although you can explicitly call the functions with the W and the A prefixes, most programmers rely on a layer of macros to resolve to one or the Other (the default is ANSI). An example of this applied to data structures can be seen with the LOGFONT structure. The Unicode name is LOGFONTW and the ANSI name is LOGFONTA. Only Unicode versions of functions and data structures that contain character strings exist on Windows CE.
      While the change of function names and data structures is somewhat transparent to programmers, there are other issues that you must deal with when writing Unicode-compatible code. The most obvious is in the way that constants, both character strings and single character values, are defined. Here is an ANSI string and an ANSI character:

 CHAR ch = 'H';
 LPSTR p = "Hello World";
An equivalent Unicode string follows. Note the use of L before both the string and the character constants:

 WCHAR wch = L'H';
 LPWSTR pw = L"Hello World";
      Other issues include different C runtime functions: wcscpy copies a Unicode string, while strcpy copies an ANSI string. There are still more issues you'll need to contend with, however; more complete information can be found in Nadine Kano's book Developing International Software (Microsoft Press, 1995).
      A key selling feature of Windows NT is security, and the Win32 API itself exposes quite a few mechanisms for controlling the security of objects created. When starting processes (CreateProcess), opening files (CreateFile), or creating file mapping objects (CreateFileMapping), you encounter a reference to security attributes (LPSECURITY_ ATTRIBUTES). When programming for Windows CE, which does not have any support for security, you set such parameters to NULL.
      The UI API is significantly stripped down from what you find on a desktop API. Only a subset of menuing calls are supported, and some old favorites, like GetMenu to query the menu handle from a window handle, have not been implemented on Windows CE. There is, however, reasonable dialog box, dialog box control, and property sheet support. Windowing support is substantially pared down, with fewer window and class styles, and no support for the MDI.
      Of all the parts of Windows, GDI seems to have been pared down the most. The list of features not supported includes metafiles, coordinate mapping, rotation, and bezier drawing. You can still draw text with TrueType fonts; the Handheld PC ships with seven TrueType fonts. You can draw lines, but the available functions have been pared down so you must call Polyline, and don't have the Option of using MoveToEx/LineTo, PolyPolyline, or even PolylineTo. You can draw raster graphics, since support for all raster operators (ROP2, ROP3, and ROP4) is included. Starting with Windows CE 2.0, printing is supported, through either serial link or infrared port. While becoming small and fast, GDI still retains enough functionality to run Microsoft Internet Explorer 4.0.
      DLLs on Windows CE seem to have all the features of DLLs on the desktop. That includes the ability to create global variables that are visible in all processes that use a DLL (by default, global variables in a DLL are private to the process address space in which a DLL runs). To define shared global variables, you bracket the variables to be shared between two #pragma statements:

 #pragma data_seg(".shared")
 char achPublic[BUFSIZE] = "";
 #pragma data_seg()
The global variable must be initialized for this to work. the Only other thing you need to do is to create an entry in your DLL's .DEF file, like the following:

 SECTIONS
     .shared READ WRITE SHARED
It's worth pointing out that the name of the shared section created is ".shared", but there's nothing special about this name. I use the leading period since this seems to be the convention for section names. But you could just as well create a shared section named SweeneyTodd. Also, the size of the shared section you create can be as large as you'd like it to be.
      The final note I'd like to make on the API has to do with the memory API. Support for global atoms doesn't exist in Windows CE, which mostly were used for the DDE, which is also not supported. The GlobalAlloc function, a decorated hero of the segmented programming wars, has been officially retired. Its younger cousin LocalAlloc is alive and well on Windows CE. Just like on Windows NT, this function allocates from the process heap (that is, it basically calls GetProcessHeap and HeapAlloc). One type of memory that is supported is thread local storage, which includes the type you request by calling TlsAlloc, as well as the kind you declare using the __declspec(thread) keyword. Both appear to work just fine on Windows CE.

Multithreading
      Windows CE is a preemptively scheduled, multithreaded operating system, just like Windows 95, Windows 98, and every version of Windows NT. One difference is in the maximum number of processes that the Operating system can support. On the desktop, the limit is system memory. On Windows CE, the maximum number of processes at any one moment is 32. On a Handheld PC, the shell and bundled applications create 10 processes, leaving room for 22 user processes. The limit on the number of threads in the system is much higher and is only limited by available system memory.
      On Windows CE, as on desktop versions of Windows, threads are the unit of scheduling and every thread has a stack and a priority. Every process that starts running gets one thread, and from there processes can create more threads. If you want to port an application to Windows CE that uses a large number of processes on another OS, one way around the maximum process limit involves using threads. Combine two or more processes into one process, with each subprocess having its own thread. Obviously, this requires having a reasonable way to combine processes. Work will start to pile up if, for example, two processes to be combined had a lot of global variables with the same names, or if the same function names were used.
      Another difference between Windows CE and desktop Windows is in how execution priority is assigned. On the desktop, each process has a priority class—real time, high, normal, or idle. Individual threads get their priority as a delta of the process priority class, which means that on the desktop you cannot have a single process that has a thread with idle priority and a thread with real-time priority. On Windows CE, execution priority is a thread attribute. There are eight thread priorities defined, from real time through normal to idle (and several in between). With this arrangement, unlike on the desktop, it is possible for a single process to have both idle and real-time threads.
      To help coordinate the activities of threads, the Win32 API provides four types of synchronization objects: critical sections, mutexes, semaphores, and events. All of the Se except semaphores are supported on Windows CE, which underscores how important synchronization objects are in a multithreading environment. On the Other hand, memory is still tight so that—in spite of the importance of the Se objects—not all of the M made the cut for the supported Win32 functions on Windows CE.

Exception Handling
      Win32 exception handling is supported on Windows CE, including both the __try and __except clauses, as well as its close cousin, the termination handler, __try and __finally. If you are unfamiliar with this programming technique, it allows you to create protected blocks of code. You can catch invalid memory access (bad pointers) and divide-by-zero errors. You can also define your own software exceptions, for recovering from unexpected situations in a crash-free manner with a fairly small amount of code.
      In the current version of the Windows CE Toolkit for Visual C++ 5.0, C++ exception handling is not supported. To some extent, you can substitute Win32 exception handling. But without special care, it doesn't do proper stack unwinding that users of C++ exception handling have come to expect. In other words, local objects on the stack frame won't necessarily have their destructors called unless you set your Win32 termination handling up properly. Hopefully, C++ exception support will be in a future release of the Windows CE development tools.

ActiveX Support
      There was no ActiveX support on Windows CE 1.0. There is some on Windows CE 2.0—but not complete support. In a nutshell, you can have in-process COM objects, but there is no interprocess (local server) support for COM, and no intermachine (remote server) support. This limited support is due, no doubt, to memory constraints; that is, to the need to keep Windows CE small.
      With the importance of the Internet, one thing this support does provide for is ActiveX controls. ActiveX automation is supported, but here again only via in-process servers. The importance of this depends on how an application uses automation. Obviously, automation servers that run as standalone applications on the desktop must be rewritten to run in a DLL, something that might not make sense for every automation controller. In this case, some subset of the automation support might be appropriate.
      For automation clients, the same problem has to be viewed from a different angle. While automation clients traditionally don't care whether the automation server is in-process or not, a lack of local server support on Windows CE might mean your favorite automation server is not available on Windows CE or is not available when you need it.
      Support is also provided for structured storage. This is good news for desktop application writers whose applications rely on compound files, since desktop data files can be directly copied to a Windows CE-based device. Once there, a Windows CE version of the application can modify the file's contents. The files can be copied back to the desktop at any time, without any special intervention from a file filter on the desktop side.
      There is no support for compound documents, which means that embedding of editable objects and linking to objects is not supported. Whether you can view the contents of a file that contains embedded objects depends on the way the Object is stored in the file. In particular, objects that are embedded with bitmaps are viewable, since Windows CE supports bitmaps. On the Other hand, objects embedded with metafiles are not viewable, since there is no metafile support on Windows CE.

RAPI Support
      The Remote API (RAPI) provides the ability to access a Windows CE-based device from the desktop. The core portion of this API allows access to the Object store, which means access to Windows CE databases, registry entries, and the file system. Using the set of functions with names that start with Ce you can do things like create a database (CeCreateDatabase), create a file (CeCreateFile), and access the registry (CeOpenKeyEx).

Windows, Windows Everywhere
      Windows CE 2.0, the newest member of the Microsoft Windows family of operating systems, is here. It's built to be small, modular, configurable, portable, compatible, and real time. With the bevy of desktop development tools that can be used to build Windows CE-based software, and an army of experienced Win32 programmers who can quickly and easily become productive with it, it has a good chance of making inroads.

From the May 1998 issue of Microsoft Systems Journal.