Power over power, speed over speed

Property MCU (microcontroller) MPU (microprocessor)
Example (brands) ARM Cortex-M series (STM32)
AVR (Arduino)
Xtensa (ESP32) ARM Cortex-A series (Snapdragon, Tegra)
”x86” architectures (Intel Core, AMD Ryzen)
ARM-based (Apple Silicon, Nuvia)
Price ✅ ($0.30 - $50+) ❌ ($100 - $600+)
Processing power ❌ (≳ 500 MHz) ✅ (≳ 5.5 GHz)
Cache/memory ❌ (≳ 5 MiB RAM + ROM) ✅ (> 80 MiB cache)
Manufacturing node ❌ (40 nm) ✅ (4 nm)
Multithreading ❌ (Single core, single thread) ✅ (4+ cores, incl. virtual threads)
Power consumption ✅ (nA- to mA-scale) ❌ (10’s to 100’s of amps)
Physical size = (varies) = (varies)
Extreme environments ✅ (more validation/hardening time & heritage usage) ❌ (state-of-the art, relatively unproven or optimized for extremes)
Analog and custom peripherals ✅ (analog components, specialized protocols, etc.) ❌ (purely digital, focus on digital processing)

Binary operations and registers

This is a more detailed explanation of what was covered in the meeting

Binary numbers

Binary numbers are base 2 - the only valid digits are 0 (”setting” a bit) and 1(”clearing” a bit). Computers operate in binary, using a high and low voltage to represent each value; this makes it less likely that a fluctuation will be read as the wrong value.

Also used often in computing are hexadecimal numbers (base 16), ranging from 0 to 9, and then continuing with the first 6 letters (A through F) before restarting. Computers still convert these values to binary, but “hex” is a more compact way to represent it. 1 hex digit = 4 binary digits (C == 1100)

Some common written formats for the decimal number 29, and how to calculate them:

Negative numbers can also be represented in binary, but there are a few different way to do it. The most common is two’s complement, which uses the most significant bit (see right) to indicate positive (0) or negative (1). Here’s two ways to calculate the two’s complement of 30, which equals $\text{-30}$:

Also abbreviated to MSB and LSB, respectively.

Also abbreviated to MSB and LSB, respectively.

0b011110 --> 0b100001 // Flip all bits

  0b100001
+ 0b000001 // Notice the inclusion of the extra MSB to indicate a positive number
----------
  0b100010

// Adding both numbers should equal 0
  0b011110 // positive
+ 0b100010 // negative
----------
  0b000000

// The sign bit can be extended, so the carry over continues infinitely, and is ignored
0b011101 == 0b0000000000011101
0b100010 == 0b1111111111100010
0b011110 // The least significant one is in the 2nd spot from the right
// Flip all bits to the left of it

0b0111 10 -> 0b1000 10 -> 0b100010

// Check
  0b011110
+ 0b100010
----------
  0b000000

And lastly, a useful tip: 0x5 == 0b0101 and 0xA == 0b1010

Bitwise operations

You can also perform bitwise (logical) operations. These are similar to operations performed in if() or for() statements, but they operate on a bit-by-bit basis. You can use binary numbers as bitmasks to perform operations on many bits at the same time

Operator (symbol, boolean symbols) Explanation Single bit examples Bitmask examples
AND (&, ×, ∧) Returns 1 if both bits are 1, else 0 1 & 1 == 1
1 & 0 == 0
0 & 0 ==0 0b11010 & 0b01001 == 0b01000
OR (` `, +, ∨) Returns 1 if either bit is 1, else 0 `1
`1 0 == 1`
`0 0 == 0` `0b11010 0b01001 == 0b11011`
XOR (^, ⊕) Stands for eXclusive OR; returns 1 if one and only one of the bits is 1. In other words, returns 1 if the bits are opposites. 1 ^ 1 == 0
1 ^ 0 == 1
0 ^ 0 == 0 0b11010 ^ 0b01001 == 0b10011
Negation/NOT (~, $\overline{\text{line over var}}$, ¬) Inverts each bit. Operates on one number at a time, but can be combined with other operators ~1 == 0
~0 == 1
~(~1) == 1 0b11010 & ~0b01001 == 0b10010
Left shift/LSH (<<) Shift all bits x places to the left. Effectively $\mathrm{var} \times 2^x$ 0b1 << 1 == 0b10
0b110 << 3 == 0b110000 0b11010 << 0b11 == 0b11010000
Right shift/RSH (>>) Shift all bits x places to the right. Effectively $\text{floor}(\mathrm{var} \div 2^x)$. 0b10 >> 1 == 0b1
0b11101 >> 3 == 0b11 0b11010 >> 0b11 == 0b11