
Semi-hosting on ARM with Rust - _mbr
http://embed.rs/articles/2016/semi-hosting-rust/
======
pm215
Ah, semihosting; a bit unloved but very useful in some circumstances.
Emulators like QEMU also support this interface, which makes it handy for
random debug if you're using them as your test/development environment. The
Linux kernel has a configuration option to use semihosting for its console
output too.

PS: the article is not quite correct about when to use which trap instruction.
Cortex-M profile CPUs should use BKPT; all other 32-bit code should use SVC
(with an immediate value varying depending on whether the instruction is Thumb
or ARM). 64-bit code uses a HLT insn. If you care at that level of detail
you'll be looking at the documentation for the ABI anyway though...

~~~
_mbr
I'll admit, I wasn't as accurate as I should have been. I've corrected the
part, but left out the long treatise about 2 and 4 byte instructions.
Hopefully no one will miss it.

------
brandmeyer
Semihosting does more than just emulate the standard I/O streams. It also
emulates the filesystem. I've used this feature to get gcov-based coverage
analysis out of an embedded target. You see, gcov normally expects to be able
to write its statistics out to files which are named after the object files.
Of course, those don't exist on a cross target. But with semihosting, you can
fake it well enough to work.

This also works for getting rich unit testing frameworks to work, too. Not
only do they expect the standard streams to be available, you can also store a
bunch of data-parameterized test cases for the unit under test in a file.

------
AceJohnny2
> _println!-style (or printf-style for more C-affine readers) debugging can be
> immensely useful, a quick-fix that can save a lot of time that would
> otherwise be spent setting breakpoints or single-stepping through a
> program._

Funny, the very reason I use a debugger is that it provides a faster
turnaround than modifying the code, compiling, flashing, and hoping I printed
the right thing...

~~~
Manishearth
For me, the main advantage of printf debugging is that it gives a lot of
output at once. With a debugger, you have to stop at each breakpoint, print
something, and go on. In case the breakpoint is in a hot path, this takes
forever. With printf I can get a nice text file to skim through.

This doesn't mean I use printf debugging often, just that it makes sense in
some cases and I use it then :)

~~~
Jtsummers
With gdb, at least, you can set up breakpoints like this:

    
    
      break file.c:200
      commands
      silent
      printf "x is %d\n",x
      cont
      end
    

(NB: _silent_ prevents gdb from announcing that it's stopping at the
breakpoint, reducing the output noise.)

Now with gdb running the program, every time we hit that line we can get this
output. With logging ( _set logging file <filename>_, _set logging on_ ) you
can get the output from the run's execution stored to a file.

Conditionals are also possible, so we only print out the results of every 10th
iteration through a loop, for instance.

    
    
      br file.c:200 if (i % 10) == 9
      commands
      silent
      printf "Iteration: %d, X: %x\n",i,x
      end
    

(NB: Not at a computer with gdb, apologies if I miswrote something in the
examples.)

~~~
monocasa
Over JTAG, you're looking at ~200ms for each break which makes it untenable
for a lot of embedded use-cases.

~~~
Jtsummers
That's fair, I'm not using that for my work, however. Once you start getting
into different extremes you have to choose the appropriate tool.

EDIT: We also have a system where we were running on embedded linux, but due
to constraints simply couldn't get gdb involved. printf-style, implemented by
way of a logging function where we could specify logging levels, was the
effective solution for us.

------
kukx
Please consider using a thicker font. This one is not very readable on my
device (Windows 10 + Chrome + 17" 100PPI display). I can read it, but it's not
a pleasant experience. [edited]

~~~
lnanek2
That font is really thin and weird looking here on OSX too. I can read it,
just not sure I want to.

~~~
_mbr
Is it also unreadable at
[https://fonts.google.com/specimen/Lato](https://fonts.google.com/specimen/Lato)
? (Try "Thin" at 18 px size)?

~~~
usea
I'm not parent, but experiencing the same problem. Yes, it's also very thin at
the google font site, on 18 px Thin. Here is a screenshot:
[http://i.imgur.com/bUe7gNs.png](http://i.imgur.com/bUe7gNs.png) The arrow
points to the "Thin" line.

Windows 10, Firefox 49.0.1

FWIW, I think it's a pretty common problem with many web fonts on certain
platforms (windows?). I see it all the time.

Also, thanks for the post!

------
comex

        bkpt_n = int(raw, 16 if raw.startswith('0x') else 10)
    

Tip: you can accomplish something similar with 'int(raw, 0)'.

~~~
_mbr
That's a neat feature I'll remember. Fixed as well.

------
xxr
Haven't read the article yet, but the coauthor Philipp Oppermann has a really
enjoyable guide I've been following on building an OS in Rust:
[http://os.phil-opp.com/](http://os.phil-opp.com/)

------
hornetblack
> The "volatile" option indicates that the code has side-effects and should
> not be by removed by optimizations.

I think volatile also means don't change the order with respect to other
volatile operations.

