The world of embedded systems is an interesting one. It's not a field which gets a whole lot of attention from people who don't deal directly with it. Many programmers are under the impression that they have to learn Windows if they want to get a real programming job; after all, that's what 95% of the world's PCs run, right? They don't stop to consider that the processor sitting in their Playstation 2 isn't one that appears in any personal computer, and its operating system likely isn't either.
Embedded systems are typically resource-constrained computers, designed to do a specific job, running custom software. In many cases, the computer is just some 8-bit microprocessor that the company can buy cheaply in bulk, and the software runs right on the metal, with a very simple custom "OS". In others, an off-the-shelf RTOS (Real-Time Operating System), like QNX, VxWorks, or even Linux (with Real Time patches and usually using the uClinux tools instead of GNU tools), is used.
One constraint that most embedded systems have is that they have to be real-time. In a nutshell, this means that they absolutely must respond to events within a given time frame. A process with a lower priority (for example, garbage collection) cannot be allowed to make another process miss its deadlines. Most RTOSes are designed so that every system call takes a deterministic amount of time, and only processes of a higher priority can pre-empt the process that is currently running. This is a far cry from the desktop world, where pre-emptive multitasking ensures that everyone gets a crack at the CPU, and a simple memory access might require the system to load a page into memory from a swap partition on the hard drive. In a time-critical section of your system, where a response time in nanoseconds counts, that sort of behaviour would wreak havoc.
