SearchA-ZB › BBC micro:bit

BBC micro:bit

2016 Open source · MIT/CC0 Online

The BBC micro:bit v1, in the browser. A from-scratch Nordic nRF51822 (a 16 MHz ARM Cortex-M0) drives the real 5x5 LED matrix, the A and B buttons and the accelerometer, decoded from the on-chip peripherals exactly as on the hardware. It runs original bare-metal programs — a flashing heart, smiley buttons, dice-on-shake and a tilt dot — and the whole Cortex-M0 plugs into this site's shared debugger to single-step real Thumb instructions and read the live nRF51 memory map.

Honest scope: this runs genuine bare-metal programs, not the full MakeCode / MicroPython runtime, which needs interrupt and SoftDevice support the core does not yet have. The micro:bit v1 has no on-board speaker, so it is naturally silent.

Visit the official micro:bit site ↗

Runs on: Web browser

BBC micro:bit Online Emulator

Play BBC micro:bit using JavaScript directly in your browser.

Configurations

ConfigurationEmulatorMachineOSLegal
MakeCode / CODAL — SoftDevice HLE bootBBC micro:bitBBC micro:bitopenOpen ⛶
MicroPython: Flashing HeartBBC micro:bitBBC micro:bitopenOpen ⛶
MicroPython: Scrolling TextBBC micro:bitBBC micro:bitopenOpen ⛶
MicroPython: Smiley ButtonsBBC micro:bitBBC micro:bitopenOpen ⛶
Interrupt HeartBBC micro:bitBBC micro:bitopenOpen ⛶
Flashing Heart (bare-metal)BBC micro:bitBBC micro:bitopenOpen ⛶
Smiley Buttons (bare-metal)BBC micro:bitBBC micro:bitopenOpen ⛶
Dice on Shake (bare-metal)BBC micro:bitBBC micro:bitopenOpen ⛶
Tilt Dot (bare-metal)BBC micro:bitBBC micro:bitopenOpen ⛶

Chips

Notes

Embedding

This is a two-layer stack: a real ARM CPU core underneath, and a from-scratch nRF51822 + micro:bit board on top. It loads real Cortex-M0 flash images and runs them on the actual on-chip peripherals — either the stock MicroPython v1.1.1 runtime (MIT) with a small appended Python program, or an original bare-metal image. Both are genuine firmware; the runtime runs on the emulated hardware, it is not a shim.

  • The CPU. cortex-m7.js executes Thumb. The real chip is a Cortex-M0 (ARMv6-M); this core is ARMv7-M, a strict superset, so it runs the M0 image unchanged. It now also implements the ARMv6-M exception model — NVIC, SysTick, SVC, PendSV, and real exception entry/return — with a host API (raiseIRQ/clearIRQ) the board drives; that is what lets an interrupt-driven runtime boot.
  • Real reset. The image is a real flash image with the ARM vector table at 0x00000000: on reset the board loads SP from word 0 and PC from word 1, exactly like the silicon.
  • Stock runtime. microbit-micropython.js carries the real MicroPython flash image; MICROBIT_MICROPYTHON.build(script) returns a 256 KB image with the chosen .py appended at 0x3E000. The runtime drives the LED matrix, timing and buttons through the new interrupts.
  • The board, in JavaScript. microbit-board.js maps FLASH/RAM/APB/GPIO at their real nRF51 addresses and decodes what the program writes to the GPIO into the 5x5 display; it feeds the buttons in on their GPIO pins and answers the accelerometer's TWI reads.
PieceKindWhat it does
Microbit.create(canvas)factoryBuild the ARM core + the nRF51 memory map + peripherals.
load(bytes) / reset()methodCopy the flat image into FLASH; reset loads SP/PC from the vector table.
runFrame()methodStep ~120k instructions; the LED matrix scan is integrated over the frame (persistence of vision) into the 25-LED image.
setButton(id,down) / setTilt(x,y) / shake()inputDrive the button GPIO levels and the accelerometer X/Y/Z.
present()methodDraw the 5x5 red-LED display to the canvas.

Debugger integration

microbit-debug.js reads window.EMU_BOOT and hands the shared debugger a genuine ARM Cortex-M0 machine — the same core the program runs on, exposed instruction-accurately.

  • Registers. registers() reads r0-r12, SP, LR, PC, xPSR and the APSR flags N/Z/C/V live each refresh; each has a set() that writes straight back into the core's register file.
  • Disassembly. FLASH is decoded with the shared cortex-m7 decoder (the Thumb-2 disassembler; ARMv6-M is a subset), so the code window shows real ARM mnemonics at the real reset address 0x00000000.
  • Single-step. Step calls transport.stepInsn, which advances the core exactly one Thumb instruction. PC and the registers update after each step. On the interrupt-driven programs you can watch a real exception entry (PC jumps to the vector's handler, xPSR/IPSR changes, the frame is stacked) and the matching return (the EXC_RETURN unstacks and resumes) as you step.
  • Breakpoints & watchpoints. Execution breakpoints are a PC set the run-loop checks before each instruction; write watchpoints wrap the board's memory-write path and pause when a watched address is written. Both are real.
  • Memory map. Four chips read the real address space side-effect-free: FLASH (program, disassembled), RAM (0x20000000), the GPIO port (0x50000000 — watch OUT/DIR/IN change as the matrix scans), and the APB peripheral block (0x40000000 — CLOCK, TWI0, TIMER0, RNG).

Architecture

The BBC micro:bit v1 is a small education board built on a Nordic nRF51822 — a 16 MHz ARM Cortex-M0 with 256 KB flash and 16 KB RAM. On board: a 5x5 LED matrix, two buttons (A and B), and an accelerometer + magnetometer on an I2C (TWI) bus. There is no speaker on v1.

  • The 5x5 display is a 3x9 multiplexed matrix. Rows ROW1..ROW3 = P0.13/14/15 (driven high, the source); columns COL1..COL9 = P0.04..P0.12 (driven low, the sink). Only 25 of the 27 crossings are wired. The board reads the GPIO the program drives, applies the real micro:bit v1 (col,row)→(x,y) map, and integrates the scan over each frame into the logical 25-LED image, so you see a steady picture even though the hardware only lights one row at a time.
  • Buttons A = P0.17, B = P0.26, active-low with a pull-up (released reads 1). The page/debugger drive those input levels; the program reads them from the GPIO IN register.
  • Accelerometer — an MMA8653FC at I2C address 0x1D on TWI0 (SDA P0.30, SCL P0.00). It is high-level-emulated: real nRF51 TWI transactions (STARTTX/TXD to set the register pointer, STARTRX/RXD to read) return WHO_AM_I = 0x5A and the settable X/Y/Z from the on-screen tilt / shake controls, so tilt and shake drive real code paths.
  • Interrupts (new). The core now has the full ARMv6-M/ARMv7-M exception model — an NVIC (pending/enable/priority + raiseIRQ/clearIRQ), the 24-bit SysTick, SVC/PendSV, and real exception entry/return (frame stacking, MSP/PSP switch, EXC_RETURN). The board wires the nRF51 interrupts into it: RTC0/RTC1 (the CODAL/MicroPython system tick), TIMER0/1/2 compares (the mbed us-ticker), and GPIOTE pin edges. It is dormant unless something pends, so the polling programs are unaffected.
  • Timing/entropy. CLOCK (HFCLK start→started), the TIMERs and RTCs, the RNG (real VALRDY/VALUE, free-running), plus FICR (CODEPAGESIZE/CODESIZE) and NVMC (flash writable) are implemented. RADIO is present but stubbed (no real RF).
  • Content. The headline is the stock MicroPython v1.1.1 runtime (MIT, the bare-metal “nosd” build) booting real Python programs on the emulated Cortex-M0 — display, animation, scrolling text and buttons all work through the interrupt-driven runtime. Also bundled: an interrupt-driven bare-metal demo (RTC ISR) and the four original CC0 polling programs. No proprietary firmware is used.
  • SoftDevice HLE (MakeCode / CODAL). A shipped MakeCode v1 .hex layers its app at flash 0x18000 over Nordic’s proprietary SoftDevice (MBR at 0, S130 at 0x1000) and reaches system/BLE services through ARM SVC traps. We do not ship Nordic’s binary: microbit-softdevice.js is a clean-room HLE of its SVC ABI (numbers/return codes from the public nrf51-sdk headers). It boots the app from the 0x18000 vector table, relocates the interrupt vectors there (the SoftDevice’s forwarding, modelled by cpu.vectorBase), forwards the nRF51 peripheral IRQs to the app, and claims the sd_softdevice_* / sd_nvic_* / sd_flash_* / clock / RNG / sd_ble_* SVCs. A real MakeCode-compiled program (built with the open MakeCode toolchain; CODAL runtime MIT) boots, renders and animates on the emulated Cortex-M0 and the debugger single-steps its real Thumb. The CODAL DAL’s LED-matrix refresh runs on the real path: TIMER1 (the mbed us-ticker, 1 MHz/16-bit; CC[0] = next event, CC[3]=0 = overflow marker) fires the COMPARE0 interrupt every ~6 ms, which ticks the DAL system timer and calls MicroBitDisplay’s systemTick to strobe a matrix row onto the ROW/COL GPIO (no SysTick or PendSV — the fiber scheduler switches in software). Honest limit: BLE and the micro:bit radio are stubbed (no real RF) — a Bluetooth-enabled app keeps running but nothing is transmitted.