The MSP430 LLVM backend has been enabled in the latest nightly, please test it!


(MSP430 is a family of 16-bit microcontrollers)

Disclaimer: This target is not ready for prime time. This is a call for participation to get it in better shape.

If you have the right hardware, please test it and report your findings in this issue. That issue is where we are discussing support for this target and the next steps to take.

Minimal, non-working (*) example

(*) won’t work (will probably crash) if actually flashed on a device

There’s no “in tree” target for this architecture so you’ll have to use a custom target specified by a JSON file.

$ cat msp430.json
  "arch": "msp430",
  "data-layout": "e-m:e-p:16:16-i32:16:32-a:16-n8:16",
  "executables": true,
  "linker": "msp430-elf-gcc",
  "llvm-target": "msp430",
  "max-atomic-width": 0,
  "no-integrated-as": true,
  "os": "none",
  "panic-strategy": "abort",
  "relocation-model": "static",
  "target-endian": "little",
  "target-pointer-width": "16"

$ cat

pub fn main() -> ! {
    loop {}

#[lang = "copy"]
trait Copy {}

#[lang = "sized"]
trait Sized {}

$ rustc --target msp430 --emit=obj

$ msp430-elf-objdump -Cd foo.o
foo.o:     file format elf32-msp430

Disassembly of section .text.main:

00000000 <main>:
   0:   21 83           decd    r1              ;
   2:   00 3c           jmp     $+2             ;abs 0x4

00000004 <.LBB0_1>:
   4:   00 3c           jmp     $+2             ;abs 0x6

00000006 <.LBB0_2>:
   6:   00 3c           jmp     $+2             ;abs 0x8

Compiling core

In theory, you can build a no_std program with these commands:

$ cargo new --bin app && cd $_

# NOTE you have to manually expand the `$(rustc --print sysroot)` command
$ edit Cargo.toml && tail -n2 $_
path = "$(rustc --print sysroot)/lib/rustlib/src/rust/src/libcore"

$ cat src/

pub fn main() -> ! {
    loop {}

$ rustup component add rust-src

$ ls msp430.json

$ cargo build --target msp430

But this fails to compile due to a LLVM assertion triggered by some code in the core crate. Would be great if someone manages to pinpoint the problematic code.


Are there any examples of how to register and service ISRs in rust? I have some old MSP430 C I could try porting for grins.


Are there any examples of how to register and service ISRs in rust?

None yet. There’s not even a blinky example right now.

We’ll have to add a “new ABI” to support interrupts. I’d expect the actual isr will look like this:

#[export_name = "some_symbol_name_that_the_linker_knows_about"]
pub extern "msp430-interrupt" fn isr() {
    // ...

But first we have to teach rustc about "msp430-interrupt".


I might have to hold off on porting that then, but I do have a few MSP430 boards in my garage. If someone sends code and clear detailed steps on how to build and run it I’ll be happy to test it. Also if anyone is in the Boulder area and wants to borrow them for testing, they are welcome to them.


Just a fun note: the MSP430 is the same microprocessor used in Matasano’s capture-the-flag game. You had to analyze MPS430 programs and figure out how to break into them. It was a blast.