During the Fab Academy, we worked with different architectures for embedded programming, and this is a very brief overview of our findings. First of all, embedded programming is a large field, and there are many different micro controller families that all use (slightly) different tool sets, compilers, and programmers. There are 8-bit micro controllers, which are widely used, especially by hobbyists and makers due to their relatively simple usage. These are often the core of Arduinos. There are more powerful, but also more complicated 32-bit micro controllers; and there are 16-bit micro controllers, which are somewhere in between. One may even use the GPIO pins of a Raspberry Pi, which may be programmed in python.
To program an 8-bit micro controller, one may choose to use the Arduino IDE, if there are board files for the target chip available; usually, this is the most convenient way, as there are tons of libraries available for virtually any functionality, and even for a lot of external sensors and devices. However, Arduino incorporates a lot of unnecessary bloat in code size, and performance is not the best. And not all chips are supported, so sometimes the only choice is to write plain C/C++ and use a compatible compiler toolchain to generate binary files which can be flashed onto the chip. Often, avr-gcc can be used to compile code for the target architecture, and avrdude is a handy tool for flashing 8-bit micro controllers. Avrdude supports many different programmers, for example the one we built during the electronics production week.
32-bit micro controllers are vastly more powerful than their 8-bit pendants, because the basic data word size is four times as large (32 instead of 8 bits). This makes them suitable to perform more and more complex calculations, since basic operations between larger data types are mapped need less instructions to be performed. Some 32-bit chips are even equipped with floating point units, which make complex calculations with real numbers efficient. For the STM32 chip family, we used the IDE provided by STM, which makes it relatively easy to develop firmware for their chips. Using an ST-Link programmer, it is even possible to perform live debugging on the chip, which is a very handy feature, since bugs on embedded systems are usually hard to find otherwise. Another advantage is that one may use the Serial Wire interface to program and debug the chips, which needs only three wires (Serial Data, Serial Clock, and Ground).
The Raspberry Pi, although it is not per se an embedded system, can be used to interact with other embedded systems via its GPIO header. There are python libraries, and a plethora of tutorials on them, available online which make it easy to develop a working program. The pi even provides a set of embedded peripherals, for example, a UART and two SPI interfaces.