Skip to main content
Topic: Linux - Bootloader-Programmer (Read 27022 times) previous topic - next topic

Linux - Bootloader-Programmer

Hi,
I'm currently trying to implement a linux - bootloader programmer for the bus pirate.
In this thead I want to report my progress - and if you would like to help, feel free to contact me.
Another reason I post my progress here is that you can tell me if I do something horribly wrong.

I checked out the svn repo and had a look at the sources.
-> The bootloader is based on the an851 - Application Note can be found here:
http://ww1.microchip.com/downloads/en/A ... 00851b.pdf
More information could be found here:
http://www.microchip.com/Stellent/idcpl ... e=en012031

I also found a linux programmer
http://cockpit.varxec.net/software/pic.html
 - but unfortunately it does not work that well - starting it without any params results in a segfault:
(gdb) r
Starting program: /data/an851/an851host
To read from flash Memory:

Program received signal SIGSEGV, Segmentation fault.
0x00007f994b1be480 in strlen () from /lib/libc.so.6

--> I will investigate these issues later on and provide a patch, but as I want to write a portable client I stick with python an pyserial, using the programms source-code as a reference.


Let's start:
* According to the source the bootloader operates at 9600 baud, 8N1  (however it should have an autobaud feature)
* According to AN p.3 the format is [...]
where STX = 0x0f , ETX=0x04 , CHECKSUM is the 2's complement of the lower byte of the sum of all data.
* On page 9 the read bootloader version information is 0x00 0x02

So my source looks like
Code: [Select]
import serial
ser = serial.Serial('/dev/ttyUSB0', 9600,bytesize=8, parity='N', stopbits=1, timeout=None, xonxoff=0, rtscts=0)

ser.write("x0Fx0Fx00x02xFEx04")

print "reading?"
print ser.read(4)

However I don't receive any data :/

Can somebody perhaps log what the original pic programmer sends over the serial line? - would be cool.

Re: Linux - Bootloader-Programmer

Reply #1
And here's the patch - but programming/erasing still not possible :/
Is there anything else I have to do than to put a jumper between PGD and PGC?
Code: [Select]
diff -uNpr an851host.c{,.orig}
--- an851host.c 2009-07-24 17:07:17.000000000 +0200
+++ an851host.c.orig    2009-07-24 17:06:23.000000000 +0200
@@ -260,7 +260,7 @@ void setline(int fd, int flags, int spee
        tcsetattr(fd, TCSANOW, &t);
 }

-void usage(char* argv0)
+void usage(argv0)
 {
        printf("To read from flash Memory: n");
        printf("tusage: %s --readflash --bytes <n> --startaddr <x>n", argv0);
@@ -280,7 +280,7 @@ void usage(char* argv0)
        printf("t  eg: %s --rows 3 --startaddr 0x01320nn", argv0);

        printf("nTo reset PIC via bootloader: n");
-       printf("tusage: %s --resetn",argv0);
+       printf("tusage: %s --resetn");
        close(fd);
        exit(-1);
 }

Re: Linux - Bootloader-Programmer

Reply #2
You should start with the auto baud byte when you open the port (0x55). I'll try to make a dump of a transaction for you. A python programmer would be great.

Here a link to AN1157, it's based on AN851 but is specific to the PIC 24F:
http://www.microchip.com/stellent/idcpl ... e=en533906

You you like SVN write access to backup your programming scripts?
Got a question? Please ask in the forum for the fastest answers.

Re: Linux - Bootloader-Programmer

Reply #3
Ok, I used Virtual Serial Ports Emulator to create a COM port pair between the FTDI driver COM port and a virtual COM port. I connected to the virtual COM port with Hercules set to display HEX output, and then connected to the virtual COM port with the Quick Programmer. Unfortunately, this doesn't tell us who said what. I can work on that if needed.

Here's the connection sequence:

Quote
{55}{55}{01}{01}{00}{00}{FF}{47}{05}{04}{00}{00}{B4}{04}{55}{55}{00}{02}{02}{01}{FB}{04}{55}{55}{01}{02}{00}{00}{00}{00}{05}{04}{05}{04}{00}{00}{00}{00}{00}{F5}{04}

I'm not fully versed on the actual protocol. I know the PIC echos a lot back to the quick programmer, but not every byte appears twice. The sequence starts with the auto baud byte (0x55), I checked without the Bus Pirate connected and the quick programmer actually sends both of the 0x55 bytes.

Here's the erase device sequence:
Quote
{55}{55}{03}{FD}{04}

This is the beginning of programming the 2.0 firmware:
Quote
{55}{55}{02}{FE}{04}{55}{55}{01}{40}{00}{00}{00}{00}{05}{04}{05}{04}{00}{00}{00}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{BE}{10}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{B3}{04}{55}{55}{02}{FE}{04}{55}{55}{01}{40}{80}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{BF}{04}{55}{55}{02}{FE}{04}{55}{55}{01}{40}{00}{01}{00}{FF}{FF}{00}{FF}{FF}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{BE}{10}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{EC}{82}{00}{00}{C0}{04}{55}{55}{02}{FE}{04}

Finally, here's the play button sequence to exit the bootloader:
Quote
{11}{0D}{0A}{48}{61}{63}{6B}{20}{61}{20}{44}{61}{79}{20}{42}{75}{73}{20}{50}{69}{72}{61}{74}{65}{20}{76}{32}{67}{6F}{0D}{0A}{68}{74}{74}{70}{3A}{2F}{2F}{77}{77}{77}{2E}{62}{75}{73}{70}{69}{72}{61}{74}{65}{2E}{63}{6F}{6D}{0D}{0A}{46}{69}{72}{6D}{77}{61}{72}{65}{20}{76}{32}{2E}{30}{0D}{0A}{48}{69}{5A}{3E}
Got a question? Please ask in the forum for the fastest answers.

Re: Linux - Bootloader-Programmer

Reply #4
Thanks ian - very nice.

Especially thanks for the link - there stx is defined in this AN as 0x55 instead of 0x02 :)
--> Now it's obvious why it didn't work :)
I'll continue hacking on the programmer and report my progress here - thanks!

Re: Linux - Bootloader-Programmer

Reply #5
hmm - I changed it - but it still does not work :/
Seems I have to read the AN more throughly  and perhaps study the code.

Do you perhaps know if the bootloader uses any hardware/software flowcontrol?

Thanks

Re: Linux - Bootloader-Programmer

Reply #6
hehe - no flowcontrol -> it works!

Code: [Select]
import serial
ser = serial.Serial('/dev/ttyUSB0', 9600,bytesize=8, parity='N', stopbits=1, timeout=None, xonxoff=0, rtscts=0)
ser.write("x55x550x02xFEx04")
#ser.write("x55x55x01x00x00xFFx47x05x04")
print "reading!"
x=ser.read(8);
for i in x:
    print hex(ord(i)),

print
Results in
[tt:]0x55 0x55 0x0 0x2 0x2 0x1 0xfb 0x4[/tt:]
-> the bootloader version is 0x1 0x2
which is defined in the config.h
Code: [Select]
//Bootloader Operation Configuration
#define MAJOR_VERSION       0x01    //Bootloader FW version
#define MINOR_VERSION       0x02

--> It works! yeah.
Now I can implement the rest of the bootloader :)

Re: Linux - Bootloader-Programmer

Reply #7
@ian:
hi - is there any posibility that I could have messed up the bootloader ?
I mean it still reports its version - however even after uploading the current firmware with windows I can't access the bus pirate's menu :/ - The update proceedure seems to work quite fine.

Are there any special values that don't get written via the programmer that are necessary? ( eeprom, flash, data memory config memory) ?

Would be nice if you/someone could give me any hints how I can revive my bus-pirate :)


Thanks,

Re: Linux - Bootloader-Programmer

Reply #8
I doubt it, the bootloader protects itself from overwriting. The worst that can probably happen is that you'll need to find a Windows PC and upload the firmware again.

Are you missing something (at the end of programming sequence) that writes the new bootloader delay value or reset vector value? At some point this is changed from 0xff (bootloader always on) to 0x00 (bootloader with pin jumper only).
Got a question? Please ask in the forum for the fastest answers.

Re: Linux - Bootloader-Programmer

Reply #9
Hey Ian,

as I said -  I already _have_ uploaded the new firmware using windows and it still does not work :/

Re: Linux - Bootloader-Programmer

Reply #10
Sorry, I missed that.

Hum, I'm not sure. I can't think of any situation that would stop the main program from executing but the bootloader will still work. If the bootloader still works then the configuration words are probably OK.

Just a few obvious thoughts, I'm sure you've already check this:
The bootloader is autobaud, runs at 9600bps, but the terminal is fixed at 115200bps.
How about the firmware version, are you using the version for hardware v2go (labeled [s:]v25-PIC Bootloader-v2.hex[/s:] edit: v25-Firmware-v2.hex)?

The only other thing I can think of is the bootloader delay or reset vector location being changed, but that should be reset when you use the known good Windows programmer.

I'll think about it some more, sorry I can pinpoint the issue.
Got a question? Please ask in the forum for the fastest answers.

Re: Linux - Bootloader-Programmer

Reply #11
no problem ian, don't worry - we'll find the solution:)
can you perhaps make a dump (i.e. read device in the windows programmer) and post it somewhere?
Then I can compare it to my dump and spot the differences and start guessing :)

Thanks,

Re: Linux - Bootloader-Programmer

Reply #12
Above I made a mistake and wrote the wrong firmware file name, it should be: v25-Firmware-v2.hex.

The program memory dump for v2 firmware on v2go hardware should be attached to this message.
Got a question? Please ask in the forum for the fastest answers.

Re: Linux - Bootloader-Programmer

Reply #13
hmm bad news - I tried flashing again and had a look at the error report :/

[tt:]Verify Error at 0x4 should be: 0x82EC but read: 0xFFFFFF
Verify Error at 0x6 should be: 0x82EC but read: 0xFFFFFF
Verify Error at 0x8 should be: 0x82EC but read: 0xFFFFFF
.....
Verify Error at 0x82E6 should be: 0x6 but read: 0xFFFFFF
Verify Error at 0x82E8 should be: 0x0 but read: 0xFFFFFF
Verify Error at 0x82EA should be: 0x0 but read: 0xFFFFFF
Verify Error at 0x82EC should be: 0xFE0000 but read: 0xFFFFFF
Verify Error at 0xABFC should be: 0xF9DF but read: 0xFFFFFF
Verify Error at 0xABFE should be: 0x3F7F but read: 0xFFFFFF[/tt:]

Re: Linux - Bootloader-Programmer

Reply #14
Is that for every address?

I've seen a few locations be wrong before when I forgot to erase the chip before reprogramming. Any chance that's the culprit?
Got a question? Please ask in the forum for the fastest answers.