Embedded systems programming (which I have been engaged in for some 30+ years) requires a quite different mindset than most any other type of software development. The range of computing power varies widely, from 8-bit microcontrollers that cost 30 cents in quantity to 32-bit microprocessors running Linux or some other common OS. I am currently doing projects at both ends of this scale. Code memory on the smallest micros may only be a few KB, with only a few hundred bytes of RAM. A mid-range 16-bit micro costing $3 in quantity might have 256KB of program storage and 16KB of RAM.
Besides the limited memory resources, one of the aspects of embedded programming that is unlike other areas of software development is that the programmer is often dealing directly with the hardware at the register level -- either on the micro itself, or in a peripheral attached to the micro via serial busses like UART, SPI or I2C. For this reason, low-end embedded micros are usually programmed in C or assembly language.
Embedded systems are often dealing with real-time events, so an embedded firmware program usually has many interrupt routines and possible a small RTOS (real-time OS). Debugging such systems often requires hardware assistance using a couple of dedicated lines into the micro so breakpoints can be set remotely from a PC. Logic analyzers, bus analyzers and oscilloscopes are additional tools used for debugging these systems.
Because of the hardware aspects of embedded development, developers often have some electronics background. (I have degrees in both EE and CS).