
Rust on BBC micro:bit - robin_reala
https://github.com/SimonSapin/rust-on-bbc-microbit/blob/master/README.md
======
eggy
Very cool, and very persistent. Good job!

I can see myself losing a month on something like this.

<rant> Now, I like the tech and hacker side of it, but it made me think again
of how complicated modern hardware and software have become compared to
staying with plain C, not even C++. This is not wholly due to more complicated
hardware, but so many people building stuff without going back to first
principles. I think the Rust crowd are doing their homework here though.

I understand the benefits of Rust, since I am learning it at the moment, but I
guess at my age it is a harder sell for something like this micro. It is so
easy to just drop into C for small micros. The BBC micro:bit has a C/C++
interface, of which I bet the C interface is cake. It's small enought that all
a good programmer has to do is dot their 'i's and cross their 't's anyway (or
they should). </rant>

~~~
StavrosK
It's become more complicated because C is _much_ more cumbersome to write than
a higher-level language, so everyone prefers the latter. If I'm working on a
project for fun on my spare time, I don't want to spend an hour fighting the
compiler figuring out why array bounds are being weird, or why the compiler is
complaining about the type, or whatever.

Python is much more do-what-I-mean, for example, and it's much more appealing
to me when I want to write something quickly. I've tried other languages and,
with the exception of Rust, I always feel like development shouldn't have to
be this yak-shavy.

~~~
eggy
I used to think similarly to you about C, or even Python for that matter, but
after years of leaving C, I am back at it. This is while also learning Rust.
Why? Because the easy languages are never self-contained to perform a
specialized task, and you wind up going through dependency hell, or rolling
your own libraries. C takes work, but you stay in the same arena while sussing
it out. And, in the end, it is truly portable and usually the fastest of any
other implementation. Horses for courses I guess.

~~~
moosingin3space
I don't understand how using C lets you avoid dependency hell or rolling your
own libraries. This comment doesn't make sense to me - dependency
management/rolling your own libraries seems to be there in all languages.

~~~
eggy
I am specifically referring to it in the context of the OP about an embedded
device. For general computing, your objections may hold. In all my years of
doing small devices, Python's libs wouldn't fit in the space of the unit if
you could find the exact library to run on different architectures.

The only other languages I have used aside from C for the small devices is
Forth or assembler. There are usually ready-made libs or interfaces from the
manufacturer. I haven't seem much provided in Python or other high-level
languages. The NodeLua project is an exception, and it is promising. I have
already began work on a Lisp of mine (written in C) for this device. Others
have done so too.

I guess if you have a Raspberry Pi or other, you can afford the space, and it
is basically a small Linux box, so you can run anything you like. I was
sticking to a discussion of small, embedded devices where those are not yet
options. In the future, I am sure they will be big enough to fit high-level
languages.

------
Ericson2314
This was quite entertaining! Having worked through many such build systems
adventures myself, it's a genre I do appreciate. As always, the story is more
captivating than the end result.

\--

Also, yay! a shout out to my RFC 1133.

~~~
m_eiman
NB, Rust RFC 1133 "Make Cargo aware of standard library dependencies" isn't
the same as IETF RFC 1133 "Routing between the NSFNET and the DDN".

I first searched for just "rfc 1133" and the matches didn't really make much
sense :]

Rust RFC 1133: [https://github.com/rust-
lang/rfcs/pull/1133](https://github.com/rust-lang/rfcs/pull/1133)

~~~
Ericson2314
Hmm, I feel obligated to read up on routing between the NSFNET and the DDN
now.

------
twic
This is by now a familiar sight:

    
    
      #[lang = "eh_personality"] extern fn eh_personality() {}
      #[lang = "panic_fmt"] extern fn panic_fmt() -> ! { loop {} }
    

But it's a little unsatisfying.

What does eh_personality actually do, and how would you write a 'real'
implementation?

I can guess what panic_fmt is for, but exactly what is it supposed to do, and
how would you write a 'real' implementation?

~~~
SimonSapin
I now have a "more real" panic_fmt in the repository:

    
    
        #[lang = "panic_fmt"]
        extern fn panic_fmt(details: ::core::fmt::Arguments, file: &'static str, line: u32) -> ! {
            println!("Panic at {}:{}, {}", file, line, details);
            let row_2 = ::gpio::Pin::output(::pins::ROW_2);
            let col_3 = ::gpio::Pin::output(::pins::COL_3);
            row_2.set_high();
            loop {
                col_3.set_low();
                ::busy_loop::wait_approx_ms(5);
                col_3.set_high();
                ::busy_loop::wait_approx_ms(200);
            }
        }
    

Note that println! is a macro I defined myself, it writes to the serial port.

I still don’t know about eh_personality, though.

~~~
jdub
wrt eh_personality, there's a good short answer with a link to a good (very!)
long answer here:

[http://stackoverflow.com/questions/16597350/what-is-an-
excep...](http://stackoverflow.com/questions/16597350/what-is-an-exception-
handling-personality-function)

~~~
zokier
So basically if I got it right, non-terminating panic_fmt and empty
eh_personality means that we don't get stack unwinding at all, which also
means that destructors don't get called. That could be fairly important for
RAII heavy code.

~~~
SimonSapin
Is it important, when there is no other thread or process that could use any
resource you're holding?

~~~
zokier
Resource wouldn't necessary be something internal in the application, it could
be also some external system or something like that. You might want to close
TCP connections cleanly in destructors, or maybe more relevantly for embedded
systems the resource might be some actual physical gadget that is
activated/deactivated.

Of course this is all hypotheticals and it could very well be argued that
relying on destructors to do something actually critical would be a bad
design.

~~~
monocasa
> Of course this is all hypotheticals and it could very well be argued that
> relying on destructors to do something actually critical would be a bad
> design.

Eh, I'd only argue that in the case of garbage collected languages. In RAII
languages like Rust and C++, it's the preferred way.

~~~
twic
There's a classic interview question about RAII along the lines of "in what
situation can a RAII resource be acquired, but not released?". The key answer
is "if someone turns the power off".

panic_fmt entering an infinite loop leads to pretty similar results as someone
turning the power off. The stack will not be unwound, destructors will not be
run, and bad designs will leave external resources in an inconsistent state.

~~~
monocasa
I mean, sure.

loop {}

^--- That'll also cause destructors to not be run.

------
tdicola
Would xargo help with the cross compiler setup?
[https://github.com/japaric/xargo](https://github.com/japaric/xargo) I've been
meaning to look more at rust on ARM Cortex-M chips and recently saw tools like
xargo that appear to make it a bit less tedious to setup.

~~~
SimonSapin
Looks like it would help get libcore for your target more easily, yes.

Still, I'd like similar functionality to get in standard Cargo eventually.

------
eyan
As a Rust fan and electronics enthusiast, I find these kinds of projects
awesome. Thank you for the write up and keep on hacking!

------
clort
These micro:bit look pretty interesting from an embedded controller
perspective - does anybody have any useful comparisons between them and
others, eg Arduino etc?

I've been working on a project where I will end up having to make a simple
stepper motor to drive an analogue clock and I think I can use this to control
it (advance x% of turn every minute, currently x=50) though I was initially
thinking of a small PICAXE circuit as we have some equipment at the school I
work at. I like the thought that I could access it over BLE though, and that
it could be programmed to handle DST automatically and even drive a few LEDs
for good measure

Also, what is the power consumption? As my project involves a clock, I'm
thinking it needs to last a while on some batteries, though at least its big
enough that I can pack a few in.

~~~
TickleSteve
Just get a bog-standard STM32 board for very-cheap.... don't bother with one
of these.

e.g. A standard STM32F103 board can be had for around $3.

~~~
clort
Hm, thanks.. I will look closer at this kind of thing over my holidays. That
looks like I can program it over RS-232 and operates at battery voltages,
which is really what I require.

------
petra
Did he mention he integrated this with the mbed ? i though that was hard,
because of c++.

But if he did so, that would be really valuable - it's a good solution for the
problems of portability and software support , mnajor issues for embedded
developers.

~~~
SimonSapin
Yes, I've had Rust code and C++/mbed code in the same program. But C++ is
still an issue, I wrote a C wrapper for the one C++ method I was using. Doing
so for all of mbed would be very tedious and fragile.

Servo's fork of rust-bindgen [https://github.com/servo/rust-
bindgen](https://github.com/servo/rust-bindgen) has some C++ support and might
be able to generate bindings for all(?) of mbed (at least for a given hardware
configuration), but I haven't tried.

------
SeanDav
> _" Rust on BBC micro:bit"_

OT: I just did a double-take. For a moment there, when I saw the title, I
thought of a rusty computer part.

~~~
lathiat
glad I wasn't the only one.

