Skip to main content
Topic: Bootloader v4 (ds30 Loader) (Read 57253 times) previous topic - next topic

Bootloader v4 (ds30 Loader)

Reply #45
No thanks, like to help.

[quote author="ian"]
>mixed together with some UART and mode LED debugging. If I implement initialize() from main.c and BpInit() from base.c I should be OK?
[/quote]

This is for the installer. I need to initialize everything the same way as BP it is in HiZ-mode. To provide the users some visual feedback (like mode led on and some kind of progress bar on the terminal)

Bootloader v4 (ds30 Loader)

Reply #46
Ah, you mean an internal installer? A firmware that you upload and then it writes the new bootloader? I thought you meant an upgrade script for the PC. That would make a lot more sense.

Yes, those are the setup functions you'd need. baseio or baseui has the actual UART functions, and the macros for LEDs are defined in the hardwarevx.h files.

I really like your ASM, it's a lot less 'mov-je' (mov-ie?) than my solution. I'm curious though, why did you & with f800 and not a800? Anything over a800 should be an invalid write.

I'm torn on failing silently. On one hand, a verification error could provide feedback if there's an incorrect setting in the loader app or the wrong firmware was used, on the other hand it might make people think the chip is broken when it isn't. Silent is probably OK because the loader app is the primary line of defense against overwrites.

Is the sneeuw ever going away? I want to go to the market but the streets are pure ice, I'm not crazy enough to ride my bike on that!
Got a question? Please ask in the forum for the fastest answers.

Bootloader v4 (ds30 Loader)

Reply #47
It is difficult to explain, but i try anyway:

Code: [Select]

begin of page

A800 = 1010 1000 0000 0000
F800 = 1111 1000 0000 0000
       =================== &
A800 = 1010 1000 0000 0000

end of page

ABFF = 1010 1011 1111 1111
F800 = 1111 1000 0000 0000
       =================== &
A800 = 1010 1000 0000 0000


This only matches the range we need.

If you and it with 0xA800 the following statemant is  true:

Code: [Select]

8800 = 1000 1000 0000 0000
A800 = 1010 1000 0000 0000
       =================== &
8800 = 1000 1000 0000 0000


BTW you don;t receive an verification error if you fail silently (bra main), it never reaches the verify subs.

Not much snow here ;) besides when using a car it prevents you from falling :P

Bootloader v4 (ds30 Loader)

Reply #48
Thanks for the explanation. I had the order of the SUB instruction backwards. That makes more sense, it's OP2-OP1, so 8800-A800 would be negative. I think the status Z flag (Z test) would be false if it's negative though, and the N flag is set.

The literal (#0xa800) with SUB can only be 10bits maximum. I think this will give unexpected results because it does not treat it as a 16bit unsigned number. The easy solution is to mov 0xa800 (also defined as #STARTADDR) to an unused W register. This is from the table on page 218 of the 24Fj64GA002 manual.

I imagine two bootloader problem scenarios:
1. User checks 'overwrite bootloader' and uploads firmware that includes new config words.
2. Runaway data, accidental reset, garbage data, etc. The checksum is only one byte, so 1 in 256 runaway situations could result in loss of bootloader (less because it would also have to be correct instruction to erase the correct page etc, but it's possible).

Here is a working solution that's a bit more involved that I'd like, but it also catches cases where write or erase address is 0xa7C1 and higher. This goes before check command:
      ;----------------------------------------------------------------------
      ; Check address
      ;----------------------------------------------------------------------   
      ;check that write and erase range does not overlap the bootloader
      ;if(TBLPAG=0){ ;always 0 on this PIC (?)
      ;check the start address
      ;if write start address (WADDR) >= bl start address (WCNT) then error
      mov    #STARTADDR, WCNT;reuse WCNT to hold start address
      cp      WADDR, WCNT    ;compare the start address, does it overlap?
      bra      GEU, bladdrerror   ;yes, then branch to error handler
      ;check the end address
      ;write row size is fixed, add rowsize to starting postion
      mov      #ROWSIZE, W0   ;hold row size in W0
      add    WADDR, W0, W0   ;find the end write address W0=(WADDR+ #ROWSIZE)
      ;if write end address (W0) is <= bl start address (WCNT) then OK
      ;= is ok because we don't DEC after adding, write 10 bytes to 10 = end at 19
      cp      W0, WCNT      ;compare end address, does it overlap?
      bra    LEU, bladdrok      ;continue to erase and program if no error
       ;handle the address error
bladdrerror:clr   DOERASE          ;clear, just in case
      bra vfail ;Main            ;fail silently

I've been testing this, so I had it fail with a verify error. This shows up in the ds30 Loader app, it tries three times then quits. I'm leaning towards keeping the error because it is accurate: that part of memory was not erased or written correctly.


Here is the ASM guide I've been using. This is for my own reference because it's really hard to find again:
http://ww1.microchip.com/downloads/en/D ... 70157C.pdf

--------------------
Upgrades are pretty stable at this point. If you don't have any garbage in the upper page (no translated firmware, no nightly compiles used) then you can upgrade without erasing the config words. To verify, click the read chip button in the PIC24F quick programmer utility. Open the PROGMEM.TXT file that is created, scroll to the bottom and check the lines from 15000, they should be blank (except the last line):

015000 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00
...a bunch more lines...
0157E0 FF FF FF 00 FF FF FF 00 FF FF FF 00 FF FF FF 00
0157F0 FF FF FF 00 FF FF FF 00 DF F9 00 00 7F 3F 00 00

If you have a clean upper page, erase the chip and upload the new bootloader with leave 'preserve flash configuration works on erase" checked. The upper page will be written correctly with no risk of losing the configuration. If it isn't blank, uncheck the box, erase the chip, then upload the v4 bootloader. Follow my previous post to access the new bootloader and upload the bus pirate firmware to erase the old bootloader.

This is pretty stable. I haven't had a single problem. It's also possible to revert to the old bootloader with the new one (uncheck the preserve config bits box to erase the v4 from v2 or the upper page won't get erased correctly). I wouldn't recommend it for everyone yet, but it works great.

-----------------

The only thing currently holding up testing and deployment is the bootloader application. The author added configurable bootloader placement for us, but it's still a little flakey. It doesn't recognize the updated bootloader placement setting without a bit of trickery, and there's a ton of settings that have to be configured each time.

To use the new app, grab the latest compile from our SVN:
http://code.google.com/p/the-bus-pirate ... tly/loader
(no install required if you keep all the .dlls in the same folder as the application)

Open it.
Open the HEX file to program.
Configure it as shown in the attached image.
Go to View->advanced mode
Click on the advanced tab
Check custom bootloader placement and set it to 1 (see other image).
Go back to the basic tab

At this point, you still can't program because the application needs to parse the HEX file again according to the new bootloader placement. This is a bug I think the author will fix soon. To get it to reparse, you can close and open the app again, or just go to options->debug mode (the parse progress will display in the box).

Now check the Write Program box on the basic tab
click the download button

As you can see, this is a whole bunch of configuration that will have to be done by every user for every upgrade. This is why I want to add a distribution config file that sets as many defaults as possible. The program does store settings on a per-file basis, but each upgrade is a new file.
Got a question? Please ask in the forum for the fastest answers.

Bootloader v4 (ds30 Loader)

Reply #49
NOT FOR GENERAL USE!!! TESTING ONLY!!!

Here's a package with the bootloader upgrade, compatible firmware, and ds30 Loader application:

http://code.google.com/p/the-bus-pirate ... 4.test.zip

NOT FOR GENERAL USE!!! TESTING ONLY!!!
Got a question? Please ask in the forum for the fastest answers.

Bootloader v4 (ds30 Loader)

Reply #50
Hopefully one of my final posts on this topic :) Requested changes for ds 30 Loader application:

Goal: preconfigure the GUI for quick updates from a distribution archive.

The application stores some settings in a settings.xml file. In the most recent update the author added a feature that remembers the settings for each firmware file the app loads in a recentfileX.xml. The settings in recentfileX.xml are matched on the full file path, so it's not helpful in our situation.

I think the easiest thing is to add a 'distribution' tag to the settings.xml file which causes settings to be loaded directly from settings.xml instead of the recentfileX.xml. These are the values (tags currently stored in recentfileX.xml) that I need to set:


 115200
  PIC24FJ
  64GA002
  true
  1


If we wrap the settings in a tag then we probably don't need an additional tag.

Optionally, it would be nice to include a file name based on a relative path (current directory). Currently it's stored like this:
E:Workbus-piratetrunkfirmwarev4-nightlyBPv3&v2goBPv3-Firmware-v4.hex

It might be nice to do something like this that would load a firmware from the current directory automatically:
BPv3-Firmware-v4.hex

I'm not sure if it's possible for anyone but Mikael to make the changes at the moment because there doesn't appear to be a source repository for the project. I've asked about it though, and will let you know what I hear. He usually writes after work northern EU time.
Got a question? Please ask in the forum for the fastest answers.

Bootloader v4 (ds30 Loader)

Reply #51
One minor change. Precalculated the end position so there's no need to do it on the chip every time:

      .equ   BLCHECKST,  ( STARTADDR - (ROWSIZE) )         /*precalculate the first row write position that would overwrite the bootloader*/

That eliminates the need to add row size and compare to STARTADDR every time:


      ;check the start address
      ;if write start address (WADDR) >= bl start address (WCNT) then error
      mov    #STARTADDR, WCNT;reuse WCNT to hold start address
      cp      WADDR, WCNT    ;compare the start address, does it overlap?
      bra      GEU, bladdrerror   ;yes, then branch to error handler
      ;check the end address
      ;write row size is fixed, any writes at (bootloader start-63) are an error
      ;if write end address (W0) is <= bl start address (WCNT) then OK
      ;= is ok because we don't DEC after adding, write 10 bytes to 10 = end at 19
      mov      #BLCHECKST, WCNT   ;first row write postion that would overwrite the bootloader
      cp      WADDR, WCNT      ;compare end address, does it overlap?
      bra    LEU, bladdrok      ;continue to erase and program if no error
       ;handle the address error
bladdrerror:clr   DOERASE          ;clear, just in case
      bra vfail ;Main            ;fail silently
Got a question? Please ask in the forum for the fastest answers.

Bootloader v4 (ds30 Loader)

Reply #52
Here's the latest C# source from the ds30 Loader author:
http://www.whereisian.com/files/ds30_loader.zip

I'd like to add a section to settings.xml that will be used if there's no recentfileX.xml present. That's not as specialized as a distribution mode, it just defines the default startup settings. Since most users unzip the upgrade archive to a folder, there won't be an existing recentfileX.xml and the defaults will be used.
Got a question? Please ask in the forum for the fastest answers.

Bootloader v4 (ds30 Loader)

Reply #53
How about storing an recentfilex.xml in the archive? :D

Bootloader v4 (ds30 Loader)

Reply #54
The recentfile.xml is full-path qualified, so the file would have to match the same drive letter and location stored in the XML.
Got a question? Please ask in the forum for the fastest answers.

Re: Bootloader v4 (ds30 Loader)

Reply #55
I'll make the changes to the GUI this weekend.

Re: Bootloader v4 (ds30 Loader)

Reply #56
I almost finished the installer, but I came to a point where it is not safe for me to further test it (writing the real bootloader to the correct location and alter the reset vector)

The current build writes a test pattern (from firmware.h) to a 'safe' location (0x9000). I saw it erases the page (or perhaps the other bootloader did it?) and write the test pattern correctly (read it back with the old bootloader). for the final build firmware.h should be altered with the correct firmware and load adress and the commented-out code should be enabled. And perhaps some bugs fixed ;)

I already put it under the same license as the buspirate and gave credit for the pieces I did use (mostly from the buspirate project and some asm lines from the C30 loader).

everything should be in de archive.

Re: Bootloader v4 (ds30 Loader)

Reply #57
Thanks Alex & Sjaak
Got a question? Please ask in the forum for the fastest answers.

Re: Bootloader v4 (ds30 Loader)

Reply #58
No problem! Even got some more ideas to implement!

I forgot to mention is it lighting fast. Programming is done in a blink of an eye. So it is as safe as i can be...

Re: Bootloader v4 (ds30 Loader)

Reply #59
Hi,
I was looking at the bootloader protection, you don't need that 2nd check. The first one catches both erase and write operations in the bootloader area.

Instead of bra vfail you could add a new response:
Code: [Select]
		.equ	BLPROT,		'P'										/*bl protection tripped*/

;bra vfail ;Main ;fail silently
SendL BLPROT
bra main1

Here's the changed code that goes into c# engine to handle the new bl protection response. I will include this in the next official release.
Code: [Select]
        public const char cBlProtTrip = 'P';

//---------------------------------------------------------------------
// ProcessWriteResponse()
//---------------------------------------------------------------------
static private void ProcessWriteResponse( clsSerialPort pobjPort, ref int piRetries, int piTabLevel, string pstrWriteType, ref bool pbRetry, ref bool pbResult )
{
            int iResponse = -1;
            pbResult = false;

            // Get response
            bool bGetResponseResult = false;
            iResponse = GetResponse( pobjPort, ref bGetResponseResult );
            if ( bGetResponseResult == false ) {
                return;
            }

            // Check response
    if ( iResponse != cOK ) {
    if ( ++piRetries == 3 ) {
                    OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.error, "download failed", -1) );
    return;
    } else {
    if ( iResponse == cChecksumErr ) {
                        OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.error, "checksum error," + piRetries.ToString() + " try", -1) );
                        pbRetry = true;
                    } else if ( iResponse == cVerifyErr ) {
                        OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.error, "verify error," + piRetries.ToString() + " try", -1) );
                        pbRetry = true;
                    } else if ( iResponse == cBlProtTrip ) {
                        OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.error, "bl protection tripped", -1) );
                        pbRetry = false;
                        return;
                    } else {
                        OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.error, "unknown response," + piRetries.ToString() + " try", -1) );
                        pbRetry = true;
                    }
                   
    OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.info, "Writing flash...", piTabLevel) );
    }
    } else {
                pbRetry = false;
            }

            pbResult = true;
}// ProcessWriteResponse()