# Phase 8.4 - Meaningful C Program ## Context After minimal C works, write a program large enough to exercise stack, branches, calls, arrays, strings, and UART interaction. ## Goals - Run an interactive or semi-interactive firmware. - Exercise real C control flow and memory behavior. - Build confidence before adding privilege and traps. ## New Concepts - Stack frame: per-call storage for return address, locals, and saved registers. - Recursion: function calling itself, useful for stressing stack behavior. - Jump table: compiler-generated table for some switch statements. - Serial monitor: small firmware command interface over UART. ## How To Think About It This is a system test, not a unit test. Failures can come from CPU, memory, compiler assumptions, or firmware bugs. Use it after smaller tests pass. ## Learning Tasks - Trace one function call through prologue and epilogue. - Observe stack growth and confirm it stays within data memory. - Add one feature at a time to firmware and inspect generated assembly. ## Pitfalls - Pulling in library functions accidentally. - Overflowing the tiny BRAM-backed stack. - Debugging optimized code before unoptimized code works. ## Tooling And Testing - Use map files to understand memory usage. - Add firmware-visible test results through UART. - Keep a known-good simple firmware for regression comparisons. ## References - RISC-V ELF psABI: https://github.com/riscv-non-isa/riscv-elf-psabi-doc - GNU ld map files: https://sourceware.org/binutils/docs/ld/Options.html - Embedded Artistry bare-metal articles: https://embeddedartistry.com/