Programming
Embedded
Assembly
The series of instructions to be performed, represented as plain binary. In the end, this is always what gets sent to the chip’s flash, usually stored in a .bin
or .elf
file.
Compiled languages
The most popular option for embedded programming. The code (usually C/C++) is compiled by the host PC thanks to a cross-compiling toolchain. This level of abstraction allows code to remain compatible under different microcontrollers, as long as the adequate register definitions are made in a separate header file.
Interpreted languages
This option is increasingly popular for computers, but the extreme overhead makes it impractical for most microcontrollers. The interpreter makes these languages significantly slower than compiled languages, but they offer great flexibility and are usually easier to get started with. The main philosophy is to keep the code easy to read and write (and maintain!), while transferring the underlying complexity to the interpreter.
One notable example is Python, which was ported to microcontrollers as MicroPython and CircuitPython.
Flashing protocols
JTAG
SAM microcontrollers are based on this synchronous, half-duplex protocol with realtime debugging capabilities. It includes a data-line, a clock and a reset line which must be driven low to enter debug mode.
EDBG is an open-source tool for interfacing with a CMSIS-DAP debugger such as Atmel ICE or free-DAP.
UPDI
The protocol used for flashing the new AVR 0,1 and 2-series. It’s extremely simple as it requires only 1 communication wire (+common ground), and is simply based on UART, as long as your serial adapter supports 2 stop bits and even parity bits.
The debug mode of an AVR is initialized by driving its UPDI pin to LOW for an abnormally long duration (=break condition). For this reason, the UPDI pin should always be configured as an input. If it’s not the case, a special high-voltage (12V) re-programming can be performed with the adequate equipment.
pymcuprog can be used to flash a new AVR using a simple serial adapter.
Bootloaders
Flashing microcontrollers with a bootloader
Hardware Description Languages (HDL)
Describes physical logic circuits, not a sequential program. The result can be implemented by an FPGA, or turned into an ASIC design without additional effort. The most common HDLs are Verilog, System-Verilog, and VHDL. Increasingly popular alternatives include nMigen and Chisel, among many others.
Since the description of physical circuits ultimately boils down to geometry, there’s a blurry boundary between programming and CAD as you work your way toward the bottom of the stack. Some frameworks embrace this whole-heartedly, such as CBA’s Asynchronous Logic Automata.
Parallel Computing on HPC Systems
Parallelization on CPU used to require manual management of subprocesses and threads but is now easier thanks to improved libraries and tooling. Notably, in many cases OpenMP can parallelize your C/C++ code with the addition of a single line preprocessor pragma.
- basic threading in C++
- CUDA hello world
- Satori hello world (including CUDA aware MPI)
Genetic algorithms
Genetic or evolutionary algorithms is an intriguing field in which parameters to solve a given problem are treated as a genome, and undergo some form of mutation and natural selection. This can be applied to any problem in which a score (reward) is easily computed, while the problem itself can be arbitrarily complex. The term “evolutionary algorithm” remains, but newer methods make use of optimization to prune the search space significantly.
Machine Learning
The closest thing we have to a general A.I., and by far the hottest topic in that field.
Backpropagation is the backbone of modern machine learning: it allows gradient evaluation on arbitrarily complex combination of trainable functions, as long as each of them has a defined gradient function. For signal with time or spatial dimensions, convolutions are an efficient implementation for the trainable function, as they require less parameters to train.
- supervised: input/output pairs are available as training datasets. There is a danger of overfitting if the dataset is too small, not representative or has high redundancy.
- unsupervised: no input/output pair available
- Classification:
- reinforcement learning: reward-based, we let the system learn by trial and error. Amazingly, this requires no dataset at all, only rules describing the problem and a well-crafted reward function. This is how Deepmind trained AlphaZero to master Go and chess from the game’s rules only. A new variant can even play Starcraft II.
- Generative Adversarial Networks (GAN): two sub-systems take turns refining their