Project 9: RP2350 RISC‑V Bare Metal Programming

Bring up the RP2350 Hazard3 cores with your own startup code and trap handler.

Quick Reference

Attribute Value
Difficulty Level 4: Expert
Time Estimate 1-2 weeks
Main Programming Language C + RISC‑V assembly
Alternative Programming Languages Rust
Coolness Level Level 4: “cross‑ISA engineer”
Business Potential 2. Portability and HAL design
Prerequisites Boot flow, linker scripts, interrupts
Key Topics RISC‑V startup, trap handling, ABI differences

1. Learning Objectives

  1. Write a RISC‑V reset handler and vector table equivalent.
  2. Configure traps and timer interrupts on Hazard3.
  3. Share peripheral drivers between Arm and RISC‑V builds.
  4. Compare binary size and performance across ISAs.

2. All Theory Needed (Per-Concept Breakdown)

2.1 RISC‑V Privilege and Trap Model

Fundamentals

RISC‑V handles interrupts and exceptions through a trap vector (mtvec) and CSRs. You must set up stack, trap handler, and enable interrupts.

Deep Dive into the concept

Unlike Cortex‑M, RISC‑V uses a single trap entry and software dispatch. The mstatus CSR controls global interrupt enable, and mie enables specific interrupts. The trap handler must save registers, inspect mcause, and branch to handlers. Hazard3 is a small core, so you should keep trap handlers minimal.


2.2 ABI and Toolchain Differences

Fundamentals

The RISC‑V calling convention differs from Arm, affecting startup code and assembly stubs.

Deep Dive into the concept

Registers a0-a7 are arguments, t0-t6 are temporaries, s0-s11 are callee‑saved. Startup code must set sp and gp, then call main. When sharing C code across ISAs, keep hardware drivers in pure C and isolate ISA‑specific startup and IRQ glue.


3. Project Specification

3.1 What You Will Build

A RISC‑V build that boots on RP2350, toggles a GPIO, and services a timer interrupt. A build system supports both Arm and RISC‑V.

3.2 Functional Requirements

  1. RISC‑V startup and vector/trap handler.
  2. Timer interrupt toggles a GPIO.
  3. Shared peripheral drivers.
  4. Build system target selection.

3.7 Real World Outcome

A board runs RISC‑V firmware, prints debug output, and toggles GPIO at 1 kHz.


4. Solution Architecture

Startup.S -> Trap Handler -> main() -> GPIO/TIMER drivers

5. Implementation Guide

5.10 Implementation Phases

  • Phase 1: Minimal startup + GPIO
  • Phase 2: Trap handler + timer interrupt
  • Phase 3: Dual‑ISA build system

6. Testing Strategy

  • Verify GPIO toggle frequency
  • Validate trap handler by forcing exception

7. Common Pitfalls & Debugging

  • Trap handler not installed (no interrupts)
  • ABI mismatch causing crashes

8. Extensions & Challenges

  • Add a small RTOS on RISC‑V
  • Benchmark vs Arm

9. Submission / Completion Criteria

Minimum Viable Completion:

  • RISC‑V firmware boots and toggles GPIO.

Full Completion:

  • Timer interrupt and shared drivers.

Excellence:

  • Side‑by‑side benchmark report.