UNIT 02 · FOUNDATIONS

Programming Close to Hardware

Where the C compiler meets the silicon.

6 lessons21 guided experiments62 min full read

A microcontroller does not know what a variable is. It knows addresses, bytes and a handful of instructions that move and combine them. C is the thin layer that lets you write timer->CTRL |= EN and get exactly the store instruction you meant, and the same thinness is why an off-by-one shift or a forgotten volatile produces code that is silently wrong rather than an error. This unit builds the mental model of memory and integers that the rest of the curriculum assumes.

Start with lesson 1 →

The unit in six ideas

  1. 1A byte is eight bits with weights 202^0 to 272^7; hexadecimal writes every four bits as one digit, so register values can be read field by field.
  2. 2Fixed-width integers form a ring of 2n2^n values; unsigned arithmetic wraps modulo 2n2^n by definition.
  3. 3Memory is byte cells with addresses; a variable is a named run of cells; & yields the address and * goes through one.
  4. 4Struct members keep declaration order; each starts at an offset that is a multiple of its alignment; the total is rounded up to the largest alignment.
  5. 5A peripheral is a block of registers at fixed addresses; C reaches them through a cast volatile pointer or a volatile-qualified struct overlay whose layout matches the register map.
  6. 6Implementation-defined behaviour is documented and usable per target; undefined behaviour removes the program’s meaning, and optimisers assume it never occurs.

Lessons

  1. LESSON 01 · 4 EXPERIMENTS · 10 MIN

    Binary, Hexadecimal, and Bit Operations

    Why does hardware documentation prefer the strange middle spelling, and how does one line of C turn on bit 3 of a register without disturbing the seven bits that some other part of the program relies on?

  2. LESSON 02 · 4 EXPERIMENTS · 9 MIN

    Integer Types, Signedness, and Overflow

    What is the contract, and where is it written down?

  3. LESSON 03 · 4 EXPERIMENTS · 9 MIN

    Pointers, Arrays, and Addresses

    What is actually stored in p, and why does adding 1 to it sometimes move it 4 bytes?

  4. LESSON 04 · 4 EXPERIMENTS · 10 MIN

    Structures, Alignment, and Data Layout

    Where did five bytes come from, and why did the timestamp arrive backwards?

  5. LESSON 05 · 3 EXPERIMENTS · 12 MIN

    Memory-Mapped Registers and Volatile

    What does the keyword tell it, and why is that not the same as making the code correct?

  6. LESSON 06 · 2 EXPERIMENTS · 12 MIN

    Undefined Behavior and Safe Register Access

    What is the compiler allowed to assume, where does firmware most often trip over it, and what does that have to do with the fact that a one-line REG |= BIT can lose an interrupt?