Embedded system design, like any design task, involves making a series of tradeoffs. As software developers, we seem always to be the victim of many of these tradeoffs because we are forced to wade through a myriad of arcane kernel specifications, obscure drivers with odd semantics, fragile development tools, ad hoc techniques, and bland documentation instead of diving head first into what we enjoy most: developing solutions to the domain-specific application we're being asked to deliver.
As is the case with any operating environment (the combination of hardware; peripherals; low-level driver/boot/kernel software; application runtime, for example, C, C++, Microsoft Visual Basic, and Microsoft .NET; application APIs and frameworks; and so on)-in other words, the infrastructure necessary to support what we do best-the .NET Micro Framework aims to raise the level of abstraction at which software developers work by isolating them from the mundane and tedious details of the underlying hardware. Providing well-crafted abstractions leads to developing more reliable code that is easier to debug and profile and to creating faster-to-market products, all while providing a more enjoyable development experience. (It is, however, not a panacea and has its own tradeoffs that you need be mindful of which we'll discuss as we progress.)