My first PBP bootloader (almost) working .. help


Closed Thread
Results 1 to 5 of 5
  1. #1
    Join Date
    Oct 2005
    Location
    Italy
    Posts
    81

    Default My first PBP bootloader (almost) working .. help

    Hi all,
    here I'm with my first PBP bootloader that unfortunately doesn't work properly....
    The main program jumps to bootloader, flash the new code, come back to main, do something expected at beginning
    then starts to behave "funny", resets chips, etc.
    I describe everything as if it were a tutorial so some expert maybe can see where is the weak area.


    The bootloader is intended for a PIC18F67k22 that has a blocksize of 128 bytes and Int_Vector at 08h and 18h.
    I leave free the first block 0-127 to remap Reset_Vector and Int_Vectors.
    The bootloader code starts at 80h after the first block and has available all memory to 2FFFh, it's about 12k.
    The main program starts at 3000h and have avaliable the remaining about 120k.


    The bootloader has a complex UART communication with a GSM module and I need interrupt to manage properly
    a 1k serial buffer. It works fine in other applications of mine, no problem at all that side.
    Please note, I have found in this forum some other interesting solutions, like keeping the bootloader in the
    high memory, retrieve code from I2C EEprom etc. But for several reasons they doesn't fit my needings.
    I just would like to discover why my code fails and let it works properly, hope to find help :-)


    This is the bootloader code:


    Code:
        DEFINE RESET_ORG 80h
        BlockSize    CON 128
        UpperLimit    CON $1FFFF-BlockSize
        @ nop
        STKPTR=0
        CLEAR
        ' initialize your stuff, declare VAR, etc
        Goto BootLoaderStart
        
            INCLUDE "DT_INTS-18.bas"       ; Base Interrupt System
            INCLUDE "ReEnterPBP-18.bas"    ; Include if using PBP interrupts
    ASM              
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler     RX1_INT,  _Rx1INT,             PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
        INCLUDE "interrupt.inc"                ; here I manage the serial buffer, it works perfect
    
    
    BootLoaderStart:
        ' remap Reset_Vector and INT_Vectors for bootloader
        EraseCode 0                ' erase first block
        WriteCode $00,$EF40        ' --> put a GoTo $80 at address $00    
        WriteCode $02,$F000        
        WriteCode $08,$EF44        ' --> put a GoTo $88 at address $08
        WriteCode $0A,$F000
        WriteCode $18,$EF4C        ' --> put a GoTo $98 at address $18
        WriteCode $1A,$F000    
        WriteCode $7F,$FF        ' write the last byte of the block to allow WriteCode
        Pause 500
    
    
        ' erase memory from $3000 to end
           FOR Adr=$3000 to UpperLimit STEP BlockSize                 
               ERASECODE Adr
           NEXT Adr
    
    
        ' enable UART
        RCSTA1.4=0                        ' Reset Overrun flag
        RCSTA1.4=1
        @    INT_ENABLE  RX1_INT         ; enable RS232 interrupts
        INTCON.7=1                        ; enable global int
        INTCON.6=1                        
    
    
        ' here i scan the new HEX file that has been already downloaded via FTP and stored in the GSM module memory
    ScanLoop:
        ' read a line, example :1000A0000BE0060604C0E9FF05C0EAFFEE50E9CF09
        ' decode address, check crc, etc
        '  be careful to skip addresses from 0 to 2FFFh, not to overwrite the bootloader we are executing
        ' WRITECODE Adr, FlashByte
        ' when fnished, exit loop
        goto ScanLoop
        
    ExitBootLoader:
        ' remap Reset_Vector and INT_Vectors before jumping back to main program
        @    INT_DISABLE  RX1_INT         ; disable RS232 interrupts
        INTCON=0                        ; disable INT        
        EraseCode 0                        ; erase first block 0-127
        WriteCode $00,$EF00                ; --> put a GoTo $3000 at address 0h
        WriteCode $02,$F018        
        WriteCode $08,$EF04                ; --> put a GoTo $3008 at address 8h
        WriteCode $0A,$F018
        WriteCode $18,$EF0C                ; --> put a GoTo $3018 aat address 18h
        WriteCode $1A,$F018        
        WriteCode $7F,$FF                ; write the last byte of the block to allow WriteCode
        Pause 500
        @ RESET
    
    
    @ ORG 0h
        @ GOTO 80h        ' Reset Vector
    @ ORG 8h
        @ GOTO 88h        ' High priority Int_Vector
    @ ORG 18h
        @ GOTO 98h        ' Low priority Int_Vector PIC18F67K22
    
    
    @ ORG 3000h
    BootLoaderEnd:

    Now build the program. I'm using PBP Long option here to be able to WriteCode at address > 64k
    I'm in MPLAB IDE 8.92, open "Program memory" view, then in the "Opcode HEX" tab right click "Export Table"
    Put 0x80 as start Address and 0x2FFF as End Address, check "Single column output" and save.
    Now you need to write a tool (I have used B4J) to read this file and obtain this format


    Code:
    ASM
        dw 0x0EFA1, 0x0F002, 0x0FFFF, 0x0FFFF, 0x0EF4D, 0x0F004, 0x0FFFF
        dw 0x0E00B, 0x00606, 0x0C004, 0x0FFE9, 0x0C005, 0x0FFEA, 0x050EE
        .....
        .....
    ENDASM

    Let's jump now to our main program. This (and all updates) needs to work starting at 3000h so it will have
    the structure as below. When you want to trigger an update you can simpy call @ GOTO 80h


    Code:
        DEFINE RESET_ORG 3000h
        @ nop
        STKPTR=0
        CLEAR
        ' initialize your stuff, declare VAR, etc
        goto Start
         
            INCLUDE "DT_INTS-18.bas"       ; Base Interrupt System
            INCLUDE "ReEnterPBP-18.bas"    ; Include if using PBP interrupts
    ASM              
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR1_INT,  _Timer1_250mS_INT,   PBP,  yes
            INT_Handler     RX1_INT,  _Rx1INT,             PBP,  yes
            INT_Handler     RX2_INT,  _Rx2INT,             PBP,  yes
            INT_Handler   TMR0_INT,  _Timer0_8000mS_INT,  PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
        INCLUDE "interrupt.inc"                ; here I manage all the interrupt, it works perfect (before an update)
    
    
    
    
    Start:
        ; do your main program stuff
        ; When you want to trigger an update you can simpy call @ GOTO 80h
    
    
        if Update_Needed = true then
            ; download the new HEX file via FTP and store in the GSM module memory
            ; so that it will be available for the BootLoader code, then
            @ INT_DISABLE TMR1_INT
            @ INT_DISABLE TMR0_INT
            @ INT_DISABLE RX1_INT
            @ INT_DISABLE RX2_INT
            INTCON.7=0
            @ goto 80h
        endif
        goto start
    
    
    @ ORG 0h
        @ GOTO 3000h
    @ ORG 8h
        @ GOTO 3008h
    @ ORG 18h
        @ GOTO 3018h
    
    
    
    
    ' here you have to copy the file generated before
    @ ORG 80h
    BootLoader:
    ASM
        dw 0x0EFA1, 0x0F002, 0x0FFFF, 0x0FFFF, 0x0EF4D, 0x0F004, 0x0FFFF
        dw 0x0E00B, 0x00606, 0x0C004, 0x0FFE9, 0x0C005, 0x0FFEA, 0x050EE
        .....
        .....
    ENDASM

    The main program above works normally as expected. When I want to publish an update, I send the new HEX file
    to the FTP server then send a message to the main program to inform that a new update is available.


    As I told at beginning, everything works, but when the BootLoader jump back to the new main program, it starts
    to do something correctly then behave funny and reset the chip.
    Can you see some concept errors ? Besides disabling interrupt before enetering bootloader and remapping the vectors
    is there any other register to take care ?
    Thanks in advance. Hope that (once fixed) this stuff can be useful to other in the forum.
    Cheers

  2. #2
    Join Date
    Oct 2005
    Location
    Italy
    Posts
    81


    Did you find this post helpful? Yes | No

    Default Re: My first PBP bootloader (almost) working .. help

    Found the bug !
    There was an error in the flash procedure so that the last block was lost. Remember when using WriteCode:

    "Note that block writes are not actually executed until the end location of the block is written to. If you write to random addresses within a block and neglect to write to the end location, the previously buffered data will not be written and will be lost."

    So, I cant' modify the title but I say here that now everything works perfect and I'm reaaly happy and satisfied.
    I want to tanks Pedja and Richard that helped me during these last days. I wouldn't be able to arrive here if alone.
    Cheers.

  3. #3
    Join Date
    Sep 2009
    Posts
    737


    Did you find this post helpful? Yes | No

    Default Re: My first PBP bootloader (almost) working .. help

    Just spent half an hour reading your first post

    You can get block size from ASM.
    Code:
        BlockSize VAR BYTE BANKA SYSTEM
        @ MovLW BLOCK_SIZE
        @ MovWF BlockSize

  4. #4
    Join Date
    Feb 2013
    Posts
    1,078


    Did you find this post helpful? Yes | No

    Default Re: My first PBP bootloader (almost) working .. help

    A little off-topic question.

    Say I've built something using PIC, and want it's firmware to be user upgradeable without specific hardware, such as pickit or standalone programmer.
    As I know, some PICs have native USB interface, and there are some examples about updating the firmware via USB.
    Can we do same trick with PBP? I mean, flash some bootloader, and then user, via USB, updates only "main" code area?

  5. #5
    Join Date
    Oct 2005
    Location
    Italy
    Posts
    81


    Did you find this post helpful? Yes | No

    Default Re: My first PBP bootloader (almost) working .. help

    No problem at all. You just have to remap Reset and Int vector and you can jump to another program and back and do what you want of the PIC memory.
    I've never played with built-in USB but I see there are specific instructions in PBP so you shouldn't have problems.

Similar Threads

  1. Tiny bootloader and pbp
    By longpole001 in forum PBP3
    Replies: 26
    Last Post: - 30th May 2020, 16:42
  2. Open source PBP bootloader
    By cncmachineguy in forum PBP Wish List
    Replies: 40
    Last Post: - 22nd March 2014, 19:34
  3. Working bootloader hex on 18f2550
    By f_lez in forum USB
    Replies: 21
    Last Post: - 19th March 2010, 18:23
  4. Replies: 6
    Last Post: - 5th November 2008, 12:30
  5. can someone post example to code a bootloader using pbp?
    By nimonia in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 9th May 2005, 17:28

Members who have read this thread : 2

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts