In the land of embedded systems development, it is broadly accepted that you should have an emulator. You do not need one with some simple systems, but you will find it hard to debug the design (hardware and software) without one. Most people often use an ICE (an in-circuit-emulator) or the debug port on a micro-controller. You can also use a simulator. In this entry, I will outline the kinds of tools available, and their distinction.
First, I suggest looking to what the vendor has to offer. If you are writing an app for a fairly well known platform, they will usually have an emulator or simulator available. This is a good place to start. You'll see emulators for the Palm Pre, iPhone, Windows CE devices, Win7phone. Older PDAs, like the Palm Pilot, had a simulator (although it was called an emulator, it put more effort in than many other emulators)
The basic difference between a simulator and an emulator is the fidelity to the "real" thing, and depth of the illusion in reproducing it. A simulator captures the same net effect. The iPhone emulator does not emulate the behaviour of the processor and boards; it compiles the app as an OS X app that uses a special set of APIs that are (largely) the same as on the iPhone.
If you are using a microcontroller, you will usually want an In-Circuit Emulator, or use an adapter that connects to the debug port on the microcontroller. This gives you the most detailed information about what is going on with the hardware, and in the microcontroller. All moderns ones work with an IDE so you can step thru your code with a symbolic debugger. In addition, most ICE's include some logic analyzer probe inputs, so you can trigger break points or trace activity. (To be honest, other people have gotten more use out of these than I have, but they are still a useful option).
The one drawback is that ICE's cannot really probe into the state of the peripherals of your system. Worse, if you are trying to debug a machine controller, hitting a break point at the wrong time could destroy things. For instance, it might keep a motor power, until it tears something apart. (In my case, the rest of the robot). In short, ICE's have the drawback that they cannot debug anything else.
Moreover, ICE's only work with real - if only prototype - hardware. If the hardware is not ready, is delay, broken, etc. an ICE will not work. (This happens a lot with embedded development too).
This leads to "software" based emulation. Sometimes a vendor will provide a software emulation of their products. (Or you might find one elsewhere.) These are less common now, although you will see a few from the microcontroller vendor. Often these are, well, useless. Like the ICE, they do not emulate the external peripherals you are using, or the analog behaviour, or the physical dynamics of your system. In addition, they usually only emulate a fraction of their product line, too often a model you are using.
That said, if you can find or create an emulator that does emulate processor you are using, a fair set of the peripherals you are using, and lets you extend it to model important features of your overall system, go for it. I would love to hear about it.
I have been mentioning emulator and simulator. Let us just take a moment to go into the distinction between these. The distinction is one of fidelity and detail to the original equipment. An emulator puts a lot of emphasis on reproducing how the target functions internally, including its limits:
For many people these distinctions are not important. They are looking to see that the basic operations are supported, and how to get their application to work with them. It can matter when they run into circumstances not simulated. The common one for PDA's and phones include video quality, memory constraints, performance characteristics, device removal, and so forth. (For example: a memory leak easily goes unnoticed with this type of simulation since the host virtual memory systems ' with its gigabytes of RAM ' is used. But a contemporary PDA may have 128MB of RAM (multiply or divide by a factor of 4). But, most application developers are willing to accept this to get the broad strokes of development and debugging done.
It is important for developers working with the deeper internals, or with systems whose operation is more than a little bit of stuff outside of the processor. And it is important for developers who working to achieve high levels of reliability, safety or other quality factors.
Now that I've advocated the use of these, I will explain in the future how I wrote my own emulators and simulators.