Running Contiki examples on your linux system

Contiki has a bunch of examples, and most of it can be compiled to run on your local system, “native” and also in a special platform called “minimal-net”

So, let’s go and try and build one, say, [contiki-root]/examples/webserver That should be nice and easy.

contiki-minimal-net.a(contiki-main.o): In function `main':
/home/karlp/src/contiki-locm3/examples/webserver/../../platform/minimal-net/./contiki-main.c:298: undefined reference to `uip_ds6_if'
/home/karlp/src/contiki-locm3/examples/webserver/../../platform/minimal-net/./contiki-main.c:304: undefined reference to `uip_ds6_if'
contiki-minimal-net.a(tcpip.o): In function `tcpip_input':
/home/karlp/src/contiki-locm3/examples/webserver/../../core/net/tcpip.c:532: undefined reference to `uip_ext_len'
contiki-minimal-net.a(tcpip.o): In function `tcpip_ipv6_output':
/home/karlp/src/contiki-locm3/examples/webserver/../../core/net/tcpip.c:562: undefined reference to `uip_ds6_is_addr_onlink'
/home/karlp/src/contiki-locm3/examples/webserver/../../core/net/tcpip.c:566: undefined reference to `uip_ds6_route_lookup'
/home/karlp/src/contiki-locm3/examples/webserver/../../core/net/tcpip.c:568: undefined reference to `uip_ds6_defrt_choose'
/home/karlp/src/contiki-locm3/examples/webserver/../../core/net/tcpip.c:597: undefined reference to `rpl_update_header_final'
/home/karlp/src/contiki-locm3/examples/webserver/../../core/net/tcpip.c:602: undefined reference to `uip_ds6_nbr_lookup'
/home/karlp/src/contiki-locm3/examples/webserver/../../core/net/tcpip.c:603: undefined reference to `uip_ds6_nbr_add'
/home/karlp/src/contiki-locm3/examples/webserver/../../core/net/tcpip.c:620: undefined reference to `uip_ds6_addr_lookup'
/home/karlp/src/contiki-locm3/examples/webserver/../../core/net/tcpip.c:621: undefined reference to `uip_nd6_ns_output'
/home/karlp/src/contiki-locm3/examples/webserver/../../core/net/tcpip.c:623: undefined reference to `uip_nd6_ns_output'
/home/karlp/src/contiki-locm3/examples/webserver/../../core/net/tcpip.c:626: undefined reference to `uip_ds6_if'
/home/karlp/src/contiki-locm3/examples/webserver/../../core/net/tcpip.c:677: undefined reference to `uip_ext_len'
contiki-minimal-net.a(tcpip.o): In function `process_thread_tcpip_process':
/home/karlp/src/contiki-locm3/examples/webserver/../../core/net/tcpip.c:769: undefined reference to `rpl_init'
contiki-minimal-net.a(tcpip.o): In function `eventhandler':
/home/karlp/src/contiki-locm3/examples/webserver/../../core/net/tcpip.c:479: undefined reference to `uip_ds6_timer_periodic'
/home/karlp/src/contiki-locm3/examples/webserver/../../core/net/tcpip.c:480: undefined reference to `uip_ds6_timer_periodic'
/home/karlp/src/contiki-locm3/examples/webserver/../../core/net/tcpip.c:481: undefined reference to `uip_ds6_periodic'
collect2: error: ld returned 1 exit status
make: *** [webserver-example.minimal-net] Error 1

Oops. In commit 2d50a406 IPv6 was turned on by default, but the minimal-net platform doesn’t seem to support ipv6 (yet) I fully believe this to be a short term problem, but it’s extremely disheartening when you see it straight away.

So, to work around this, you can edit [contiki-root]/core/contiki-default-conf.h. About line 100, comment out the line #define UIP_CONF_IPV6 1. (I would not have found this myself, but one of the users of #contiki-os helped me out)

Ok, so you build. And you run. And… it fails again.

~/src/contiki-locm3/examples/webserver $ ./webserver-example.minimal-net 
RPL enabled
ioctl(TUNSETIFF): Operation not permitted
~/src/contiki-locm3/examples/webserver $

This time, it’s because the minimal-net platform actually makes some tricks. It tries to create and set up a tun/tap interface, creating a virtual network cable to your application. Remember, your application is a complete operating system with a full networking stack. But regular users can go doing that sort of thing, so… let’s run it with sudo…

~/src/contiki-locm3/examples/webserver $ sudo ./webserver-example.minimal-net 
[sudo] password for karlp: 
RPL enabled
ifconfig tap0 inet 172.18.0.1/16
route add -net 172.18.0.0/16 dev tap0
IP Address:  172.18.0.2
Subnet Mask: 255.255.0.0
Def. Router: 172.18.0.1

*******Contiki-2.6-487-g96e85cc online*******

Cool! That looks better! I can ping 172.18.0.2, and ifconfig shows me this virtual network. (At this point nmap should be able to fingerprint the OS (according to the contiki docs) but it totally fails for me at least.) Anyway, we built a webserver! Let’s check it out!

So that failed hard. Curl/wget doesn’t work either. And there was nothing on the console log, even after turning on logging. (A story in it’s own right, why would that not be on by default for the example running on the native host?)

I went down a rabbit hole here trying to work out what was going on. I got into gdb and could see action when I made a webrequest, but couldn’t follow the code well enough through Contiki’s protothreads to see what happened next. Still suspecting some ipv6 difficulties, I went and had a look through the [contiki-root]/core/contiki-default-conf.h file again. And found this gem…

/* UIP_CONF_BUFFER_SIZE specifies how much memory should be reserved
   for the uIP packet buffer. This sets an upper bound on the largest
   IP packet that can be received by the system. */
#ifndef UIP_CONF_BUFFER_SIZE
#define UIP_CONF_BUFFER_SIZE 128
#endif /* UIP_CONF_BUFFER_SIZE */

Now, that’s pretty small. It doesn’t say what happens when it gets a bigger packet, but I’m guessing it’s not pretty, and from the behaviour, it’s probably just terminating the connection if it runs out of buffer space. (“The connection was interrupted” in chrome and “* Recv failure: Connection reset by peer” from curl)

Ok, let’s change that to something bigger, 512 for starters. And…..

We’re finally working! Whee!

It turns out, you can get this to respond properly from curl by setting the useragent to something much smaller, but that’s not really all that helpful is it? So, in my mind, this is something that needs to be updated for contiki for the minimal-net platform. It’s totally reasonable to have a limit on the IP packet size for the final sensor nodes, when you know what you’re doing, but the example code, which is meant to run on your host system by default, using the minimal-net platform, should just work!. I’m trying to work up a clean pull request for this. (I can’t seem to get “project-conf.h” based overrides to work, and it’s late, so it will be another day)

Porting Contiki on STM32 (libopencm3) continued – timers and clocks and uarts

When I fixed my stupid error earlier, I got stdout/printf working. I then poked a lot of simple examples and started to understand how to write simple contiki apps using protothreads. It’s really pretty simple, as long as you remember that it’s all done with switch/case magic, so you can’t use stack variables the way you might expect. This is ok. This makes you think more about where you data lives and what you’re passing around. With stdout working though, I started to go through what else was needed.

Contiki offers ~4 different apis for doing things at some point in time. ctimers, etimers, stimers and rtimers. (And also with the clock_* api, which are for when you reallllllly want to do some busy waiting. Don’t do that!) This wiki page was very helpful in understanding the differences, and even having some “porting guide” information. This is an area I feel contiki is very weak in, the almost complete lack (to my eyes) of a porting guide. There’s quite a few different ports in the tree, but they’re often implemented in quite radically different ways, and some of them appear to be unmaintained.

But, the good thing about all these timers, is that’s all core. Your port only needs to implement clock.c, and it’s basically all taken care of! Neat! Except rtimers. rtimers are the realtime timers, used for turning radios on and off at the right times to synchronize. When I get to the radio (soon) I’ll be looking at other implementations and seeing what’s best.

As it stands though, ctimers, etimers, timers and the clock routines are all working in my port, and I’d played with some simple play applications to test out how they worked. I then tried to get the shell working. So, this is an app. So you need to put APPS+=serial-shell into your makefile. (Remember, this is the makefile for your final application) Then, because the AUTOSTART_PROCESSES() macro can only be used once in an application, the apps you can include can’t use that macro. You need to start them yourself. Here’s what my “demo” playground main application process looked like:

PROCESS_THREAD(foo_process, ev, data)
{
  PROCESS_BEGIN();
 
  printf("Hello foo world\n");
  leds_blink();  // oh yeah, the leds api works for the stm32l discovery board too ;)
  serial_shell_init();  // starts the serial shell process
 
  // these are all commands the shell can run.  
  shell_ps_init();
  shell_blink_init();
  shell_powertrace_init();
 
  // these are experiments with my own applications
  static struct blipper_info bl1 = { CLOCK_SECOND * 2, 'a' };
  static struct blipper_info bl2 = { CLOCK_SECOND * 5, 'b' };
  process_start(&blipper_process, (void*)&bl1);
  process_start(&blipper2_process, (void*)&bl2);
 
  PROCESS_END();
}

Note that serial-shell is actually just a wrapper around the shell app.
Note that you need to call a shell_XXXXX routine for each command you need to add. Note well that that is not documented anywhere. You actually have to look in [contiki-root]/apps/shell for all the shell-xxx.c files that call shell_register_command() Or, have a look at [contiki-root]/examples/example-shell/example-shell.c

Ok, so you got a shell application built and flashed. But… it doesn’t work! I ran into two problems here. One of them was very well documented, I just didn’t read it. I was used to having to implement newlib syscalls like _read() and _write(), but you actually need to not implement _read(), and make sure you just follow the directions!.

Unfortunately, in my case, this wasn’t enough. I could run my application with the native target, but not on my stm32. Again, reading the documentation, contiki processes serial input line by line, looking for a line feed (hex 0xa) to mark the end of line, and completely ignoring carriage return characters (hex 0xd) With gdb I could see that on the native platform, entering a command and pressing “enter” sent only a LF character, and it worked. With picocom and a USB-serial adapter to my board, I was seeing only a CR character, which was ignored. Wikipedia has a lot to say about this, and some of the helpful people on ##stm32 pointed out that this was because my serial device was in “cooked” mode, and I could put it back to raw mode to send the “right” characters. Turns out lots of terminal software has to deal with this, and miniterm.py (Something I just happened to have installed anyway) by default does the “right thing” (or the other thing) There were some suggestions that contiki should probably be more flexible in it’s input, and deal with both either, or, and both, but not require a specific one. That’s a future debate, but not one I’m battling now.

With a different serial terminal program, all of a sudden I had a console, and a shell. Here’s a full log of my app running, and me typing, “ps” and “help”

--- Miniterm on /dev/ttyUSB2: 115200,8,N,1 ---
--- Quit: Ctrl+]  |  Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
Platform init complete
Hello foo world
Hello blipper id: a!
Started timer
Hello blipper2 id: b!
Started timer
Should get printed after any event, even if it wasn't ours....
callback about to be set...
Should get printed after any event, even if it wasn't ours....
0.0: Contiki> 
Should get printed after any event, even if it wasn't ours....
Processes:
ps
periodic blipper2 process
periodic blipper process
Shell server
Shell
Contiki serial shell
Ctimer process
Event timer
Serial driver
Should get printed after any event, even if it wasn't ours....
0.0: Contiki> 
a hit timer expiry tick: 0 at clock time: 2
Should get printed after any event, even if it wasn't ours....
In the callback!
Should get printed after any event, even if it wasn't ours....
Available commands:
?: shows this help
blink [num]: blink LEDs ([num] times)
exit: exit shell
help: shows this help
kill : stop a specific command
killall: stop all running commands
null: discard input
powertrace [interval]: turn powertracing on or off, with reporting interval 
ps: list all running processes
quit: exit shell
Should get printed after any event, even if it wasn't ours....
0.0: Contiki> 
a hit timer expiry tick: 1 at clock time: 4
Should get printed after any event, even if it wasn't ours....
b hit timer expiry tick: 0 at clock time: 5
b Should only print after our event....

--- exit ---

Note that there is no local echo of commands! (Again, this can be turned on by the terminal program, but often it’s handled by the far side’s shell implementation)

But, all’s well that ends well. At this point I have what’s a pretty complete port of the core of contiki to the STM32L discovery board, and all the code that is common for any stm32 (and mostly, any chip using libopencm3) is in the cpu section of contiki, rather than the platform code.

Now, it’s just time to start the radio drivers, and work out the best way of implementing the rtimers!

My Platform port: https://github.com/karlp/contiki-outoftree This is all you need to target the STM32L discovery, it includes my changes to Contiki, as well as libopencm3 as git submodules.
Contiki port: https://github.com/karlp/contiki-locm3/tree/locm3 You’ll need this if you want to make another platform port based on libopencm3

libopencm3 with Contiki on STM32L part 2 – it’s alive, and a stupid error

In a previous post I got to a compiling and linking build for the STM32L Discovery board, but it didn’t actually print anything. Turns out I’d made one of the classically common mistakes with STM32 development, and one of the weakpoints in libopencm3’s api for the RCC module.

rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB2ENR_USART1EN);

The API unfortunately needs both the register, and the bit, and if you can’t see the problem, don’t worry, you’re not alone. The problem is that I was turning on a feature in APB1 (ONE) with a bit definition designed for APB2 (TWO)

When I actually turned on the USART peripheral, everything started working as I expected. I can’t believe how often I’ve done something like this. Or how often I’ve simply not turned on what I needed. Later, I added code to support USART2 and USART3, but…. didn’t turn on those peripherals. Silly me.

But, that does mean that my Contiki port to the STM32L Discovery board is alive: https://github.com/karlp/contiki-outoftree

Much more to come! Radio drivers and more examples and onwards!

Revised MRF24J40 driver code for STM32 and AVR

I meant to post this a while ago, but oh well :) A long time ago I made a basic driver for AVR, then I hacked it up a bit to make it run on the STM32L discovery board. None of the code was common, and the STM32 code was some of my earliest steps in that world. Last summer I started trying to put this all together, but I got busy with other things, and more particularly, I ditched the ST Standard Peripheral Lib and started actively working on libopencm3. Anyway, I eventually got back into project mode, and decided it was time to tidy this all up.

So, here it is. The 3rd edition of my MRF24J40 code. This one should be somewhat more portable to other platforms, as it uses function pointers to set up all the spi and interrupts. (As if anyone else is using this stuff anyway!)

https://github.com/karlp/simrf

There’s still plenty of tidying up that could be done, there always is, but it’s more going to be a base for further work on Contiki, so it’s probably about as good as it’s getting for now.

sshfs hangs: culprit? __git_ps1 and bash completion

Weird one. Not sure who to report it to even. On my Fedora 17 development machine, I have the following in my ~/.bashrc

GIT_PS1_SHOWDIRTYSTATE=true
PS1='\u@\h:\w$(__git_ps1 " (%s)")\$ '

This makes a very nice bash shell with git status. Except, something odd happened when I tried to use sshfs. I could “ls” the newly mounted directory, but I couldn’t “cd” into it. It just hung. Dead in the water, control-c, control-z, kill and kill -9, nothing. WIth some sshfs debug options turned on, I saw that it was failing like this. (Whatever it means)

unique: 535, opcode: GETATTR (3), nodeid: 1, insize: 56
getattr /
   unique: 535, success, outsize: 120
unique: 536, opcode: ACCESS (34), nodeid: 1, insize: 48
   unique: 536, error: -38 (Function not implemented), outsize: 16
unique: 537, opcode: LOOKUP (1), nodeid: 1, insize: 45
LOOKUP /.git
getattr /.git
[00343] STAT

For reference, my sshfs command line is like so: karlp@pojak:~/src$ sshfs root@192.168.255.29:/ oroot -odebug,sshfs_debug,loglevel=debug -o no_remote_lock -o follow_symlinks -o workaround=rename But I tried with a lot less options and a lot more too.

The console hangs like this:

karlp@pojak:~/src$ ls oroot/
bin  etc  lost+found  overlay  rme_post_fresh_install.log  root  sys  usr  www
dev  lib  mnt         proc     rom                         sbin  tmp  var
karlp@pojak:~/src$ cd oroot

^C
^C
^Z
~.

Now, seeing that getattr /.git there made me think, and indeed, disabling the git bash extension and using a new shell works just fine. It makes no sense, but it works ok.

Update
Even “git status” hangs, so this really isn’t fixed at all. :(

802.15.4 export controls

Export controls. Woo, yeah! The USA classed various encryption as a weapon for a while, and tried to prevent it from being “exported” This was relaxed 10-15 years ago, when they realised how absurd it all was. Now, you can buy microelectronics with encryption built in, for instance, and what i’m talking about here, 802.15.4 transceivers have AES encryption built in. It’s a required part of 802.15.4 support after all. However, the way the export controls were relaxed required lots of paperwork, and there’s still some restrictions in place. And the big electronics distributors like digikey and mouser have interesting approaches to following these rules.

Here’s a quick roundup of what I tried to buy today on digikey. Note that all of these parts include AES encryption, as they are all 802.15.4 devices. In some cases, these aren’t even made in the US, they’re made in europe, shipped to distributers in the US, then not allowed out again because of these awesome “export controls”

Note: I live in Iceland, which seems to have fallen into a paperwork crack at some time, most of europe can buy these devices, but not me :(

Microchip’s MRF24J40 modules

Digikey will not sell the MRF24J40MA module by itself, DK partno: MRF24J40MA-I/RM-ND
Digikey will sell the ZENA usb dongle, which is a MRF24J40 radio + USB interface, DK partno: AC182015-1-ND

Mouser will sell the modules.

Farnell said they would sell the modules, then asked me to fill out export restrictions forms (from the UK, not the US!) and has since not replied. (This was about 6 months ago)

ST’s STM32W parts

Digikey will not sell me the STM32W-RFCKIT, DK partno: 497-11406-ND
Digikey will sell me the STEVAL-IDZ401V1, an STM32W based USB dongle. DK partno: 497-12887-ND

Mouser wouldn’t sell me the STM32W-RFCKIT either

TI’s CC2531 parts

Digikey will sell me the TI CC2531 usb dongle, DK partno: 296-28921-ND
Digikey will also sell me CC2531 chips themselves

Freescale’s MC1322x parts

Digikey will not sell me the usb dongle, DK partno: 1322XUSB-ND
I didn’t try buying the parts themselves

Atmel’s range

Digikey will sell me the Raven RZ USB stick, DK partno: ATAVRRZUSBSTICK-ND
Digikey will not sell me the development kit, DK partno: ATAVR128RFA1-EK1-ND

So, awesome job there. I can still buy “restricted” encryption hardware, but only some of it, and only in certain shapes. Fucking ballsup. I’ve spoken to Digikey, (though not with such a list of contradictions) and they brushed me off with, “we just follow the export restrictions guidance from the DOJ” They might bend a bit more if I was ordering 10k units of course, and actually go and check the paperwork, but that’s no help for me today.

make vim always start git commits on the first line

Vim has a (oftentimes) nice feature of remembering where in a file you were when you open it again. Which is all well and good, but it’s based on filenames, and git commit messages are always the same. So it remembers the line number where I finished my last commit message. I always want git commit messages to open up on the first line. Here’s some vimrc magic to make it Do The Right Thing™

" don't remember the cursor position in git commits
au FileType gitcommit au! BufEnter COMMIT_EDITMSG call setpos('.', [0, 1, 1, 0])

Porting Contiki to the STM32L

WARNING – rambling diatribe that might help me….

This is mostly a notepad of what I did, why I think I did it, and what I couldn’t find documented anywhere obvious at the time of writing

Motivation: I am interested in low power wireless sensor nodes. Most of the commonly used MCU operating systems I had looked at treated power usage as a second class citizen at best (if at all) Contiki builds all that in, it’s a primary concern. I abhor the idea of custom wireless protocols (even though I hacked one up for the current nodes in my house) Contiki builds in IPv6 (amongst other protocols) and knows explicitly about 802.15.4 (what I like to use) IP all the way sounds like a pretty smart bet.

So, I want to use contiki on my devices.

Right, big blob of unknown new code. What do I need, where does it need to go…. There’s a rather ugly blob of code in the repository that supports the STM32W series (a rather awkward part to use. No reference manual, binary blobs of radio drivers, the complete inability to order them to Iceland thanks to arbitrary export encryptions, etc) so maybe it would be easy. The code makes no real sense, and seems to be completely abandoned. There’s meant to be ARM support though, so shouldn’t be too hard.

Hrmm. code is split between “cpu” and “platform” Hard to know what should be where.
Oh! Someone just added support for the stm32F1, a chip I know well, no radio driver yet, but that’s ok, I know the MRF24J40 radio well, and would be using that anyway.

Oh, that code got reverted due to (to me) a fairly arbitrary lpgl vs bsd arguments (despite the stm32w code having a binary blob radio driver, let’s not start in there)

Ok, so, nothing says I can’t have my own fork, at least while licensing is worked out. https://github.com/contiki-os/contiki/wiki/Out-of-Tree-Development is the best reference I’ve found for getting started so far.

Now, I’ve got the hello world “app” copied into my tree as “foo” and I can do “make” and then ./foo.native and it works.

 karlp@tera:~/src/kcontiki (master *)$ ./foo.native 
Contiki 2.6 started
Rime started with address 2.1
MAC nullmac RDC nullrdc NETWORK Rime
Hello foo world
^C

Excellent, now what? Now I start to leave the comfort of the directions. I decide to copy the reverted stm32f107_basic platform into my tree, still following the Out of Tree Development guide

I’ve added libopencm3 as a git submodule too now. I can do “make TARGET=stm32ldiscovery” and it sort of works, in that it finds platforms/stm32ldiscovery/Makefile.stm32ldiscovery. Now I just need to know what _else_ is needed to go into that makefile. What’s in it now? MCK=72000000, do I really need that? I’d like to not have to care in a makefile. Hrmm. I guess what is really next is sorting out what is part of cpu/arm/xxx and what goes into platform/stm32ldiscovery.

CONTIKI_TARGET_MAIN. What’s that for? why do I need that? grepping the source shows totally inconsistent usages of it. Let’s ignore that for now.

Ok, the libopencm3 based stm32f107basic tree has a uart driver and some newlib stubs. Let’s keep as much of that as possible, and just hack the uart driver to be L1 based rather than F1 based. (This is actually just a difference in gpio AF function settings, the uart code is all identical)

That seems to get a little further, but now we need to get the cpu/arm/stm32f1x_cl code to work out somehow. let’s see how much of that is really “platform” Ok clock.c is opencm3 specific, but not f1x specific. OH! Here’s the MCK setting being used. ok, we’ll set that. rtimer* and mtarch* are all stubs, so that’s ok for now too.

So, a bit more hacking on the cpu/arm/stm32f1x_cl makefile to make it a little more of a “stm32 libopencm3” makefile, and we have a build!

But… does it work? No. setvbuf goes straight into the blocking handler, and puts does too. I guess something didn’t get linked or built properly. But we’re getting somewhere. I’ll look at the backtrace a bit later on, but it’s late.

Code so far in

Esoteric python of the day: * and **

I was hacking up a grotty (but neat!) python plugin for gdb last night, and ran into a quirk I didn’t really understand. I had a list of numbers, and was using struct to make a suitable memory buffer for gdb.selected_inferior().write_memory. Except, it wasn’t quite working….

import struct
q = [1,2,3,4]
x = struct.pack("<4H", q)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
struct.error: pack requires exactly 4 arguments

I wasn’t really expecting this, normally things “just work” and python “does the right thing” (Computer! Do as I want, not as I say!) StackOverflow gave me the gem of using the * operator.

import struct
q = [1,2,3,4]
struct.pack("<4H", *q)
'\x01\x00\x02\x00\x03\x00\x04\x00'

OK, well and good, but WTF?! Where did that come from? Turns out it’s not an operator per se, but part of the call syntax. So * turns a list into a string of positional arguments, and ** turns a dict into a set of keyword arguments, like so.

def gofish(where, when):
     print(where, when)
 
gofish("lake", "tomorrow")
('lake', 'tomorrow')
gofish({"where" : "a river", "when": "next weekend"})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: gofish() takes exactly 2 arguments (1 given)
gofish(**{"where" : "a river", "when": "next weekend"})
('a river', 'next weekend')

So there, a rather esoteric corner of python I’d never seen before.

arm-none-eabi-gdb with python support on linux (Fedora 17)

I’ve been using the GCC ARM Embedded toolchain for STM32 development on linux for a while now. It’s maintained by ARM, it’s available for linux, windows and osx, and it’s just a zip of binaries. Untar, add to your path, and you’re golden. With the new 4.7 release (2012q4) it includes some decent code size improvements, and is generally just a one stop shop for getting a toolchain.

However, the linux builds don’t have python support in GDB. This isn’t necessarily a bad thing, but people are starting to put together some nice tools that plugin to GDB that rely on python support. There’s some experimental SWV/SWO support, there’s some neat support for printf without printf and, what I’m trying to do, dump a lot of data buffers straight out of ram on the target device for analysis in python.

So, I tried building it myself. I first tried just downloading recent gdb sources and adding python support, after setting the target to arm-none-eabi. but….. that didn’t play well with openocd, so I went back to trying to build the G-A-E provided sources instead.

Here’s what I needed on Fedora 17 x64

  • libmpc-devel
  • expat-devel
  • ncurses-devel
  • python-devel
  • bison

This then replaces step 5 from the provided instructions…

$ cd [extracteddir]/src
[dir]/src$ tar -xf gdb.tar.gz
[dir]/src$ cd gdb
./configure --with-expat --with-python --target=arm-none-eabi
make -j5

That got me a working gdb with python support…