Jump to content
Rickta59

1K serial gdb_bootloader

Recommended Posts

Inspiration:
So I'm looking at making a small msp430fr5739 based board. I was thinking that I would be able to use the msp430 launchpad to program them. However, I hit a snag in that they don't seem to recognize the msp430fr5739 as a valid device. I can use my FRAM boards to program them but not the $10 launchpad. Then there was all the hubbub about the new msp430g2955 chips and it got me thinking. Why should I let Texas Instruments determine how I program my chips?

Investigation:
I got to looking at BSL and then got discouraged trying to find a client that works on windows, linux and OSX. It mostly seemed like it was going to be a hassle. Then I got to thinking about just using GDB and its Remote Serial Protocol. If you use msp430-gdb and mspdebug, you use this interface over a local server socket. However, an often unnoticed feature of this protocol is that it can also be used with a regular serial port.

Solution:
I decided to implement a gdb stub server that you load once on your msp430 chip. You can think of it as a bootloader that happpens to use the Remote Serial Protocol. This allows you to load new programs on that chip without the need for a launchpad or an FET. All you need is a usb->serial port dongle. You can find these on ebay from $2-$10. They all go faster than the 9600 baud the virtual serial port the msp430 launchpad provides. It is likely you probably have one of these already. This scheme doesn't allow you to debug using msp430-gdb, but it does provide a way to load new code without having to deal with BSL or having to write any host side code.

How it works:

This version targets the msp430g2553 so that people can easily try it out. I'm guessing that most people don't have an msp430fr5739.  Load the attached code below to an msp430g2553 using your launchpad one time. At this point, you could remove that chip from your launchpad and throw it on a breadboard. You just need power, the caps and a pull up resistor. Then connect TX and RX to a serial to USB converter (ftdi, cp102, pl2303hx, etc..). For simplicity, we can just test with the launchpad itself and ignore the fact that there is an FET on the board and just use /dev/ttyACM0 or COM1: on windows.

At reset time, the code looks at the state of the P1.3 button on the msp430g2553. If you are holding it down, the code starts a gdb bootload/server running on the msp430g2553. On your linux box, just start up msp430-gdb to connect to the chip over a serial port. You can't debug, but what you can do is erase your flash and load a new program. The gdb server code sits at memory 0xfa00 -> 0xfdff so you do lose some of your flash. *I've done some optimization see later posts in this thread *


Loadable hex file:
The gdb_bootloader.hex file from the zip file must be loaded on an msp430g2553. I'll post code and support for other chips at a later date. I'm excited about this concept and wanted to let people try it out.

To load the gdb_stub firmware ( do this one time )

$ mspdebug rf2500 "prog gdb_bootloader.hex"
MSPDebug version 0.21 - debugging tool for MSP430 MCUs
Copyright (C) 2009-2012 Daniel Beer <dlbeer@gmail.com>
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Trying to open interface 1 on 057
rf2500: warning: can't detach kernel driver: No data available
Initializing FET...
FET protocol version is 30066536
Set Vcc: 3000 mV
Configured for Spy-Bi-Wire
fet: FET returned error code 4 (Could not find device or device not supported)
fet: command C_IDENT1 failed
fet: identify failed
Trying again...
Initializing FET...
FET protocol version is 30066536
Set Vcc: 3000 mV
Configured for Spy-Bi-Wire
Sending reset...
Device ID: 0x2553
  Code start address: 0xc000
  Code size         : 16384 byte = 16 kb
  RAM  start address: 0x200
  RAM  end   address: 0x3ff
  RAM  size         : 512 byte = 0 kb
Device: MSP430G2553/G2403
Number of breakpoints: 2
fet: FET returned NAK
warning: device does not support power profiling
Chip ID data: 25 53
Erasing...
Programming...
Writing  970 bytes at fa00...
Writing   32 bytes at ffe0...
Done, 1002 bytes total

OK. Once you have that installed, you no longer need to use your launchpad to load new code. To load programs on your chip now, just connect a usb->serial dongle up to the msp430g2553 directly and connect to that via msp430-gdb. Here are the steps to load a blink program using msp430-gdb via the serial port:

$ msp430-gdb blink.elf 
GNU gdb (GDB) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-pc-linux-gnu --target=msp430".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home2/kimballr/github/msp430_code/fabooh/examples/basic/blink/blink.elf...done.
(gdb) set remotebaud 9600
(gdb) target remote /dev/ttyACM0
Remote debugging using /dev/ttyACM0
_reset_vector__ () at ../../../gcc/gcc/config/msp430/crt0.S:103
103	../../../gcc/gcc/config/msp430/crt0.S: No such file or directory.
	in ../../../gcc/gcc/config/msp430/crt0.S
(gdb) erase
Erasing all flash memory
complete
(gdb) load
Loading section .text, size 0x96 lma 0xc000
Loading section .vectors, size 0x20 lma 0xffe0
Start address 0xc000, load size 182
Transfer rate: 264 bytes/sec, 16 bytes/write.
(gdb) quit
A debugging session is active.

	Inferior 1 [Remote target] will be killed.

Quit anyway? (y or n) y

OK, now there are two things on your msp430g2553 chip. At 0xfa00 there is the boot loader, it is run first before your blink.elf code. It checks the button to see if you are holding it down. If not, then it runs the blink.elf code. If you are holding it down, it runs the gdb server instead and allows you to reload code. So just press reset to start the blink. Press and hold the P1.3 switch down and press reset to start the gdb stub server.

Pretty simple huh? I think so.

-rick

The files in the attached zip only work with the msp430g2553 at this time:

[Edit: Updated version 04-07-2013 3:43 PM]


Source Code:
... fast track to how to get started ...

http://forum.43oh.com/topic/3661-1k-serial-gdb-bootloader/?p=33112

I'm actively optimizing this code. I only started on this project on Thursday and posted what I had late Friday. It was 1950 bytes the first pass. But I was so excited about this concept, I just had to share. Saturday, I spent the day on it and got the code size down to less than 1k.

The code is written in C++ using my fabooh framework. I've been trying to find a good app to use as the fabooh debut project. I think this will be it. This type of code needs to be small but needs the flexibility to use various UART implementations. This code personifies what fabooh does well. So expect to see it real soon now, in the fabooh source tree.

You can get yourself in a good position to use this code if you grab fabooh from github.com and take a look at it. https://github.com/RickKimball/msp430_code

Share this post


Link to post
Share on other sites

So, this must be loaded on the actual chip you want to program ? I was under the impression after talking to you on IRC that you could use one MCU ( msp430g2553 ) to program another MCU, like say the newer MSP430G2955 and what not.

 

Is this still the case, and I am missing something ? 

Share this post


Link to post
Share on other sites

Yes, this is the self licking ice cream cone version of a gdb server.

 

You load the gdb_stub code on the chip you want to program. Both the gdb_stub code and your custom code are both in flash memory on one chip. When you erase, only your code is erased, the gdb_stub code stays loaded. The gdb_stub is always ready to be called on to load another program or hide quietly in the background.

 

This image illustrates the memory layout:

 

post-190-0-77959100-1365215630_thumb.png

 

-rick

Share this post


Link to post
Share on other sites

great work.

 

not sure about the fr5739, but for g2553, there is already a factory installed BSL somewhere (0x0c00?), it should be possible to do something similar (i.e. programming via uart). i read in a TI forum thread that the tx / rx pins used for BSL is different from the usual setup and that limits usability.

 

i have not used it before so i don't know the difference between that and the solution u are presenting. i did examine the flash segment as i was trying to "claim" the space for my use. which turns out to be unsuccessful. i don't think those segments are different, but may be there is a lock somewhere. i would imagine whoever design it would leave a way to update the BSL code, or may be not.

 

anyway it would be interesting to see if it actually works or not.

Share this post


Link to post
Share on other sites

Interesting msp430-gdb commands specific to the msp430g2553:

 

erase the user code flash memory ( erased bytes are 0xFF )

examine 16 bytes of memory and display in hex (user code starts at 0xc000)

$ msp430-gdb -b 9600 -ex 'target remote /dev/ttyACM0' blink.elf
GNU gdb (GDB) 7.2(gdb) x/2xb 0x10f8
0x10f8: 0xaa 0x8f
(gdb)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-pc-linux-gnu --target=msp430".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home2/kimballr/github/msp430_code/fabooh/examples/basic/blink/blink.elf...done.
Remote debugging using /dev/ttyACM0
_reset_vector__ () at ../../../gcc/gcc/config/msp430/crt0.S:103
103 ../../../gcc/gcc/config/msp430/crt0.S: No such file or directory.
in ../../../gcc/gcc/config/msp430/crt0.S
(gdb) erase
Erasing all flash memory
complete
(gdb) x/16xb 0xc000
0xc000 <_reset_vector__>: 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
0xc008 <__init_stack+2>: 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
(gdb)

 

 

Load the blink.elf file

disassemble the code just loaded at 0xc000

(gdb) load blink.elf
Loading section .text, size 0x96 lma 0xc000
Loading section .vectors, size 0x20 lma 0xffe0
Start address 0xc000, load size 182
Transfer rate: 264 bytes/sec, 16 bytes/write.
(gdb) disassemble 0xc000,+40
Dump of assembler code from 0xc000 to 0xc028:
=> 0x0000c000 <_reset_vector__+0>: mov #23168, &0x0120 ;#0x5a80
0x0000c006 <__init_stack+0>: mov #1024, r1 ;#0x0400
0x0000c00a <__low_level_init+0>: mov #0, r15 ;#0x0000
0x0000c00e <__low_level_init+4>: tst r15
0x0000c010 <__low_level_init+6>: jz $+12 ;abs 0xc01c
0x0000c012 <__low_level_init+8>: decd r15
0x0000c014 <__low_level_init+10>: mov -16234(r15),512(r15);0xc096(r15), 0x0200(r15)
0x0000c01a <__low_level_init+16>: jnz $-8 ;abs 0xc012
0x0000c01c <__do_clear_bss+0>: mov #0, r15 ;#0x0000
0x0000c020 <__do_clear_bss+4>: tst r15
0x0000c022 <__do_clear_bss+6>: jz $+10 ;abs 0xc02c
0x0000c024 <__do_clear_bss+8>: dec r15
0x0000c026 <__do_clear_bss+10>: mov.b #0, 512(r15);r3 As==00, 0x0200(r15)
End of assembler dump.
(gdb)

 

 

Examine the interrupt vector table as 16, 16bit unsigned integers

notice, the interrupts are the user code not the gdb_stub

(gdb) x/16xh 0xffe0
0xffe0 <__ivtbl_16>: 0xc090 0xc090 0xc090 0xc090 0xc090 0xc090 0xc090 0xc090
0xfff0 <__ivtbl_16+16>: 0xc090 0xc090 0xc090 0xc090 0xc090 0xc090 0xc090 0xf600
(gdb)

 

 

Display the INFOA segment.

(gdb) x/64xb 0x10c0
0x10c0: 0x53 0x8e 0xfe 0x16 0xff 0xff 0xff 0xff
0x10c8: 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
0x10d0: 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
0x10d8: 0xff 0xff 0x10 0x10 0x05 0x80 0x00 0x00
0x10e0: 0x4e 0x7d 0xcf 0x02 0x00 0x00 0xb6 0x7d
0x10e8: 0xae 0x01 0x00 0x00 0xfe 0x08 0xff 0xff
0x10f0: 0xff 0xff 0xff 0xff 0xff 0xff 0x01 0x08
0x10f8: 0xaa 0x8f 0xb4 0x8e 0xa3 0x8d 0x62 0x87
(gdb)

 

 

Display the CALDCO_1MHZ and CALBC_1MHZ

(gdb) x/2xb 0x10f8
0x10f8: 0xaa 0x8f
(gdb)

Share this post


Link to post
Share on other sites

Connect to the gdb_stub and display help. Right now it just shows the version

In the future, it will allow for extended commands not provided by gdb. Maybe

a way to change the serial baud rate, erase the info segments, etc...

(gdb) monitor help
fabooh gdb stub version 0.0
(gdb) 

Share this post


Link to post
Share on other sites

i read in a TI forum thread that the tx / rx pins used for BSL is different from the usual setup and that limits usability.

Originally, this is what I was thinking of doing. However I'm going to target the larger chips, so the amount of memory used by this won't really be signficant.

 

The reason I decided to do this over BSL was its simplicity. With BSL you need to twiddle the Test/Reset/BSL TX/ BSL RX. That means I have to write custom host code, or find a bsl loader program. I have to figure out which pins are BSL/TX/RX, I have to make sure the usb device I'm using supports the ability to toggling the DTR/CTS pins at the right time. The other way I've seen people implement bsl loading, is with a launchpad that is acting as a bridge. I think that is TI's published solution. However you are wasting a launchpad and a chip to do this and you still have to make sure the circuit on the target device isn't affected by the BSL setup.

 

With this solution I don't need a smart dongle. In fact using the virtual serial port of the msp430 launchpad proves that point. : )

 

You can even use this with a wireless serial dongle. There is no flow control to worry about really.

 

-rick

Share this post


Link to post
Share on other sites

i would imagine whoever design it would leave a way to update the BSL code, or may be not.

On the msp430f4/5/6xxxx series you can replace the BSL code with your own. With the msp430f2xxx/gxxxx it is ROM based and there isn't a way to replace it. I think the msp430fr5xxxx can be replaced, and I'll probably look into that too. However, if that msp430fr59xx stuff appears I'll probably not bother.

 

This solution can really be thought of as a gdb bootloader. The big advantage to this solution is that you can download precompiled binaries of msp430-gdb for windows, linux and osx. Once you have downloaded a binary, you get the incredible power of gdb for free. It can examine, disassemble, write to flash, erase, save a chunk of memory to a file. Basically you get a lot of functionality without doing anything.

 

With BSL, what I found was a lot of different tools and none that work on all 3 platforms. Maybe there is a universal BSL tool, but I didnt' find it, which is how I ended up with this solution.

 

-rick

Share this post


Link to post
Share on other sites

Inspiration:

So I'm looking at making a small msp430fr5739 based board. I was thinking that I would be able to use the msp430 launchpad to program them. However, I hit a snag in that they don't seem to recognize the msp430fr5739 as a valid device. I can use my FRAM boards to program them but not the $10 launchpad. Then there was all the hubbub about the new msp430g2955 chips and it got me thinking. Why should I let Texas Instruments determine how I program my chips?

 

I've been using the msp430 launchpad to program msp430fr5739 with the usual SBW. I had to get a newer mspdebug than ubuntu has because it was trying to erase the FRAM (and failing). I wonder why it wasn't working for you.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×