Assembler für den Raspberry Pi Pico und Pico 2

Arm und RISC-V schreiben, auf das Board bringen und Schritt für Schritt debuggen – ohne OpenOCD, ohne SDK.

Mit .target pico oder .target pico2 sagt ein Programm, für welches Board es ist. Asmonite assembliert es, prüft es gegen das Board, schreibt es über eine Debug-Probe ins RAM oder in den Flash und hält bei _start. Danach gehst du Befehl für Befehl hindurch und siehst Register, Stack und Speicher. Die Probe steuert Asmonite selbst über USB an; OpenOCD, GDB oder das Pico-SDK brauchst du nicht.

Die Beispiele sind in den Ordnern examples\pico und examples\pico2 des ZIPs. Die ausführliche Anleitung steht im Quelltext-Repository unter docs/de/riscv-pico2.md.

Zwei Boards, drei Kerne

Der Pico hat Arm-Kerne, der Pico 2 zwei Sorten von Kernen; welche läuft, entscheidet das Boot-ROM nach dem Programm im Flash. Asmonite schreibt Programme für alle drei und debuggt jeweils Kern 0.

PicoPico 2, ArmPico 2, RISC-V
Chip, KernRP2040, Cortex-M0+RP2350, Cortex-M33RP2350, Hazard3
Direktiven.target pico
.arch thumb
.target pico2
.arch thumb
.target pico2
.arch riscv32
BefehleThumb (ARMv6-M)Thumb-2 (ARMv8-M)RV32IMA, Zicsr, Zifencei, Zba, Zbb, Zbs, Zbc, Zbkb
RAM, Flash264 KB, 2 MB520 KB ab 0x20000000, 4 MB ab 0x10000000
Start aus dem Flashboot2-Block (.boot2) + VektortabelleVektortabelle + IMAGE_DEF (0x1021)IMAGE_DEF-Block (0x1101)
Hardware-Breakpoints4 im Flash, im RAM beliebig viele84
Register im DebuggerR0…R12, SP, LR, PC, XPSR, Flags N Z C Vx0…x31, pc

Der Pico (RP2040)

Der Cortex-M0+ kennt die Befehle des ARMv6-M, und ein Flash-Programm beginnt mit einem boot2-Block. Datei: examples\pico\blink_flash.asm.

.target pico
.arch thumb
.imagebase 0x10000000   ; flash

    .boot2                 ; 256 bytes that set up the flash chip
vectors:                   ; at 0x10000100
    dd 0x20042000          ; stack pointer
    dd _start + 1          ; start address (+1: Thumb code)
_start:
    ldr  r0, resets_clr    ; a 32-bit constant from a word behind the code
    ...

Mit .target pico lässt der Assembler nur die Befehle des ARMv6-M zu: Thumb mit 16 Bit, von den 32-Bit-Befehlen nur bl, msr, mrs und die Barrieren. Es gibt kein movw/movt, kein cbz und kein it; jeder andere Befehl ist ein Fehler mit seiner Zeile. .boot2 setzt den boot2-Block des Pico-SDK ein (BSD-3-Clause, im ZIP und in Asmonite eingebaut), mit seiner CRC-32, die das Boot-ROM prüft. Für ein Board mit einem anderen Flash-Chip nimmt .boot2 datei.bin einen eigenen Block.

Anschließen und debuggen

  1. Die Debug-Probe anschließen. Die Raspberry Pi Debug Probe oder ein zweiter Pico mit der Firmware debugprobe (CMSIS-DAP). Drei Drähte an die Debug-Pins: SWCLK, GND, SWDIO. Das Board bekommt Strom über sein eigenes USB-Kabel. Windows braucht keinen Treiber.
  2. Das Ziel wählen. Unter Debug > Debug targets Raspberry Pi Pico (RP2040) oder Raspberry Pi Pico 2 (RP2350) wählen und Test the connection drücken. Es sagt, ob das Board antwortet und welche Kerne laufen.
  3. Starten. Ein Beispiel öffnen und F7 drücken: Asmonite assembliert, liest die Chip-ID des Boards, schreibt das Programm und hält bei _start. F7 und F8 gehen einen Schritt, F9 lässt laufen, F4 läuft bis zum Cursor, F5 setzt einen Breakpoint, Debug > Pause hält an.
  4. Ansehen und ändern. Rechts stehen die Register (Doppelklick ändert einen Wert) und der Stack mit Notizen, wo ein Wert in dein Programm zeigt. Die Speicheransicht zeigt Bytes oder, umgeschaltet auf Code, die Befehle ab einer Adresse mit deinen Labels.

Passt das Programm nicht zum Board an der Probe (ein Pico-Programm am Pico 2 oder umgekehrt), lehnt Asmonite es mit dem Namen des Boards ab und schreibt nichts.

RAM, Flash und UF2

.imagebase 0x20000000Das Programm kommt ins RAM. Schnell zum Ausprobieren; nach dem Ausschalten ist es weg.
.imagebase 0x10000000Asmonite schreibt das Programm über die Funktionen des Boot-ROM in den Flash, nur die 4-KB-Sektoren, die sich unterscheiden, und liest sie zurück. Es wird dort debuggt und startet nach dem Einschalten von selbst.
Project > Save as UF2 fileEine Datei für das BOOTSEL-Laufwerk, mit der Familie des Chips (RP2040, Arm oder RISC-V). Ohne Debug-Probe: BOOTSEL gedrückt halten, einstecken, Datei auf das Laufwerk ziehen.

Der Wechsel zwischen RISC-V und Arm. Der RP2350 lässt immer nur eine Sorte von Kernen laufen. Startest du ein Flash-Programm für die andere Sorte, schreibt Asmonite es mit den gerade laufenden Kernen in den Flash, setzt den Chip zurück, und das Boot-ROM startet die Kerne, für die das Programm ist. Das dauert etwa zwei Sekunden. Ein RAM-Programm kann nicht umschalten; Asmonite sagt dann, welches Flash-Programm zuerst zu starten ist.

Ohne OpenOCD. Asmonite spricht CMSIS-DAP über USB und darüber SWD mit dem Chip: das Debug-Modul der RISC-V-Kerne, die Debug-Register der Arm-Kerne, beim RP2040 den Multidrop-Bus. Wer OpenOCD trotzdem nutzen will, kann es für die RISC-V-Kerne als Ausweichweg wählen (Host und Port seines GDB-Servers).

Was es (noch) nicht gibt

Weiter

Syntax

Labels, Konstanten mit equ, Ausdrücke und Direktiven.

Die Syntax-Seite →

Befehlsreferenz

Jeder Befehl mit Bitkodierung und Pseudocode, für die Arm- und die RISC-V-Kerne.

Thumb / Thumb-2 →
RISC-V (RV32) →

Herunterladen

Ein ZIP mit allem; entpacken, starten, fertig.

Zum Download →