8051 microcontroller 8051 microcontroller
Forums

Rickey's World of Microcontrollers & Microprocessors :: Forums :: Discuss and Learn :: PIC Microcontroller Discussion
 
<< Previous thread | Next thread >>
How to validate/verify user code from Bootloader code
Moderators: Ajay Bhargav, Arun Kumar V, pdi33, Shailesh NAYAK, ۞ TPS ۞, shyam, sashijoseph, ExperimenterUK, DavesGarage, majoka
Author Post
Emb_cool
Fri May 18 2012, 05:19AM
Registered Member #38588
Joined: Fri May 18 2012, 05:09AM
Location (Home Town): India
Posts: 16
hi ,
i m trying to write boot loader code for Pic Micro 18F series , i completed finished boot loading concepts.

1. Before entering into the user code from Bootloader code ,i need to verify whether user code is valid or not. My Question is how to verify /validate the user code presence.
Back to top
Ajay Bhargav
Fri May 18 2012, 12:38PM
Rickey's World Admin


Registered Member #1
Joined: Fri Feb 24 2006, 07:56AM
Location (Home Town): Punjab, India
Posts: 12665
are you programming user code directly to code memory? if not then you can write and then compare.
Back to top
Emb_cool
Sat May 19 2012, 01:45AM
Registered Member #38588
Joined: Fri May 18 2012, 05:09AM
Location (Home Town): India
Posts: 16
Through Boot code only i m writing the user code, so i ill try what you have mentioned sir
Back to top
mangesh.ghugal
Thu Aug 09 2012, 10:35AM
Registered Member #7657
Joined: Mon May 05 2008, 06:27PM
Location (Home Town): mumbai
Posts: 27
hey guys!!!!!!
I am also trying to write a bootloader for pic18f6722 controller but but able to write it

CODE:
/******************** *******************
* File Name          : Main.c
* Author             :
* Date First Issued  : xx/07/2012
* Description        : This file has all the main related functions
* History                        : 07 May 2012: Started
*******************************************************************************/

#include <p18f6722.h>#include <delays.h>#include <flash.h>#include "bootloader.h"
extern void _startup(void);
void            start(void);
void            interrupt_at_user_high_vector(void);
void            interrupt_at_user_low_vector(void);

/*******************************************************************************
CODEPAGE    NAME=BResetVector   START=0x00000           END=0x00007     PROTECTED               // Boot Reset Vectors
CODEPAGE    NAME=BHighISR               START=0x00008           END=0x00017     PROTECTED       // Boot High ISR
CODEPAGE    NAME=BLowISR                START=0x00018           END=0x00029     PROTECTED               // Boot Low ISR
CODEPAGE    NAME=BootCode               START=0x0002A           END=0x00FFF     PROTECTED       // Bootloader Code

CODEPAGE    NAME=AResetVector   START=0x01000           END=0x01007     PROTECTED               // Application Reset Vectors
CODEPAGE    NAME=AHighISR               START=0x01008           END=0x01017     PROTECTED       // Application High ISR
CODEPAGE    NAME=ALowISR                START=0x01018           END=0x01029     PROTECTED               // Application Low ISR
CODEPAGE    NAME=AppCode                START=0x0102A           END=0x1FFFF     PROTECTED       // Application Code
********************************************************************************/


#pragma config OSC=HS,IESO = OFF  
#pragma config WDT=ON, WDTPS = 16384
#pragma config BORV=2
#pragma config PWRT=OFF
#pragma config LVP=OFF
#pragma config STVREN = ON
#pragma config XINST = OFF

#pragma code BHighISR   = 0x00008                               // Start of High ISR           
void interrupt_at_high_vector(void)
{
        _asm goto High_ISR _endasm
}
#pragma code                                                                    // End of High ISR

#pragma code BLowISR    = 0x00018                               // Start of Low ISR
void interrupt_at_low_vector(void)
{
        _asm goto Low_ISR _endasm
}
#pragma code                                                                    // End of Low ISR

//      High Priority interrupt routine  
#pragma interrupt High_ISR
void High_ISR(void)
{
        ;
}

// Low Priority interrupt routine
#pragma interrupt Low_ISR
void Low_ISR(void)
{
        ;
}

#pragma code BootCode = BOOTLOADER_START

/*******************************************************************************
* Function Name         :       main(void)
* Parameter                     :
* Returns                       :
* Created by            :
* Created date          :
* Last Modified by      :
* Last Modified on      :
* Decription            :
* Notes                         :
*******************************************************************************/

void main(void)
{
        u8 i,Data;
        Init_Ports();

        Inptr = 0;

        for (i=0; i<7; i++)
                Tx_String (BLString[i]);

        TimeOut(BOOT_TIMEOUT); 

        if (RCREG1 == 'D'){                                                             // Ready to Download

                TBLPTRU = 0;
                erase   = APPLICATION_START;                            // Clear program memory prior to program download
                while(1)
                {
                        TBLPTRL = (u8)erase;
                        TBLPTRH = (u8)(erase >> 8);
                        EECON1  = 0x90;                                                 // set up for flash erase
                        zap();
                        erase += 64;
                        //if (CARRY)
                        //      TBLPTRU++;
                        //if (TBLPTRU == UPPER_ADDRESS_BYTE)
                        if (erase == MEM_TOP)
                                break; 
                }      
                //Tx_Char ('>');
                Tx_String (Ready);
                RxData = 0x00;
                TimeOut(BOOT_TIMEOUT);

                if (!RxData)                                                            // if no hex file to download, resume normal program
                {
                        Tx_String(TimeOutMSG);
                        Tx_Char('E');
                        start();//(*((void(*)(void))PROG_START))();
                }
       
                TBLPTRU=0;
                for(;;)                                                                         // loop until end of file
                {
                        while (RCREG1!=':');                                    // wait for start of hex file line
                        cksum   = bcount = g2x();                               // get the byte count
                        TBLPTRH = EEADRH = g2x();                               // get the address
                        TBLPTRL = EEADR  = g2x();
       
                        DO_NOT_INCREMENT = 1;
                        rectype = g2x();                                                // get the record type
       
                        switch(rectype)
                        {
                                case HEX_DATA_REC:                                                                                      // data record
                                        if ((FLASH)&&(TBLPTRU==0)&&(TBLPTRH<10))                // to protect bootloader from being overwritten
                                                break;
                                        clear_buffer();
                                        while(bcount--)
                                        {
                                                TABLAT = EEDATA = buff[(EEADR&7)] = g2x();      // get the data
                                                if((CONFIG)||(EEPROM))
                                                {
                                                        if(CONFIG)                                                              // EEPROM/config. bytes are written one byte at a time
                                                                table_write();
                                                        zap();
                                                }
                                                else
                                                        if ((EEADR&7) == 7)                                             // program/IDLOCs are flashed 8 bytes at a time
                                                        {
                                                                flash8();
                                                                clear_buffer();
                                                        }
                                                EEADR++;
                                        }
                                        if (((EEADR&7) != 0) && (FLASH))
                                flash8();
       
                                        checksum();
                                        break;
       
                                case HEX_EOF_REC:                                                                                       // End of hex file
                                        checksum();
                                        Tx_String(DownloadSucc);
                                        start();//(*((void(*)(void))PROG_START))();                             // Jump to new program
                                        break;
       
                                case HEX_EXTADDR_REC:                                                           // Extended address record
                                        while (bcount--)
                                        {
                                                EEADR=g2x();                                                            // This byte determines whether EE, Config or ID data
                                        }
       
                                        EECON1bits.EEPGD = 1;
                                        if (EEADR == 0xF0)
                                                EECON1bits.EEPGD = 0;                                           // select for EEPROM
       
                                        EECON1bits.CFGS=0;
                                        if ((EEADR & 0xF0) == 0x30)
                                                EECON1bits.CFGS = 1;                                            // select for config write
       
                                        TBLPTRU=EEADR;
                                        checksum();
                                        break;
                        }
                }
        }

        while(1)
        {
                if (INTCONbits.TMR0IF){                
       
                        OneSecFlg                 = TRUE;
                        TMR0L                     = 0xF6;                               // 1 sec
                        TMR0H                     = 0xC2;
                        INTCONbits.TMR0IF = FALSE;
                }

                if (OneSecFlg){
                        OneSecFlg = FALSE;     
                        if (RxData == FALSE){                                   // Execute application firmware if empty then reboot.
                                Nop();
                                Tx_Char('E');
                                start();//(*((void(*)(void))PROG_START))();
                        }
                        else{                                                                   // Reboot from bootloader
                                Tx_Char('I');
                                Reset();
                        }                      
                }
        }
}

/*******************************************************************************
* Function Name         :       Init_Ports(void)
* Parameter                     :
* Returns                       :
* Created by            :
* Created date          :
* Last Modified by      :
* Last Modified on      :
* Decription            :
* Notes                         :
*******************************************************************************/


void Init_Ports(void)
{

        TRISA = TRISA | 0b00101111;                             // Configure ADC pins as i/p

        //////////// INIT for USART0 Channel 1 /////////////////
        PIE1bits.CCP1IE         = 0;
        RCONbits.IPEN           = 0;                            // Turn OFF Interrupt priority
    INTCONbits.GIEH     = 0;                            // Turn OFF High priority interrupts depends OFF RCONbits.IPEN
    INTCONbits.GIEL     = 0;                            // Turn OFF Low priority interrupts depends OFF RCONbits.IPEN
        INTCONbits.RBIE         = 0;
        TRISC                      &= 0b11011000;               // GPS SHDN and 4052 configuration pins as output leaving UART and I2C unaffected
        TRISCbits.TRISC6        = 0;                            // Uart 1 rx tx direction
        TRISCbits.TRISC7        = 1;
        RCSTA1bits.SPEN         = 1;
        TXSTA1bits.TXEN         = 1;
        TXSTA1bits.SYNC         = 0;
        BAUDCONbits.BRG16       = 0;
        RCSTA1bits.CREN         = 1;
        SPBRG1                          = 25;
        SPBRGH1                         = 0;
        TXSTA1bits.BRGH         = 0;

        PIE1bits.RC1IE          = 1;                            // EUSART1 Receive Interrupt Enable bit.
//////////////// for testing
//      RCONbits.IPEN           = 1;                            // Turn ON Interrupt priority
//      INTCONbits.GIEH         = 1;                            // Turn ON High priority interrupts depends on RCONbits.IPEN
//      INTCONbits.GIEL         = 1;                            // Turn ON Low priority interrupts depends on RCONbits.IPEN
////


        INTCONbits.RBIF         = 0;
        INTCONbits.RBIE         = 0;
        Select_CH_UART1(1);                                             // Select config port for configuration

        //////////// END OF USART0 with channel 1 /////////////////////

        //////////// TIMER0 INIT ///////////////

        INTCONbits.TMR0IF       = 0x00;
        INTCONbits.TMR0IE       = 0x01;
        INTCON2bits.TMR0IP      = 0x00;
        T0CON                           = 0x87;
        TMR0L                           = 0xF6;
        TMR0H                           = 0xC2;
        Timer0ON                        = TRUE;
        /////////// TIMER0 INIT ENDS ///////////
}


/*******************************************************************************
* Function Name         :       void TimeOut(u8 tmr)
* Parameter                     :
* Returns                       :
* Created by            :
* Created date          :
* Last Modified by      :
* Last Modified on      :
* Decription            :
* Notes                         :
*******************************************************************************/


void TimeOut(u8 tmr)
{
        delay_time = tmr;
        Timer0ON   = TRUE;
        do
        {
                if(PIR1bits.RC1IF)              //Flag for UART1 Reciever if something has arrived at UART 1
                {
                        if((RCSTA1bits.OERR1) || (RCSTA1bits.FERR1))
                        {
                                RCSTA1 = 0x00;
                                Nop();
                                RCSTA1 = 0x90;
                                return;
                        }
                        RxData                  = RCREG1;
                        PIR1bits.RC1IF  = FALSE;
                        delay_time      = FALSE;               
                }

                if (INTCONbits.TMR0IF){                
       
                        OneSecFlg                 = TRUE;
                        TMR0L                     = 0xF6;                               // 1 sec
                        TMR0H                     = 0xC2;
                        INTCONbits.TMR0IF = FALSE;
                }


                if (OneSecFlg){
                        OneSecFlg = FALSE;     
                        if (delay_time){
                                delay_time--;
                                if(delay_time > 9)
                                        Tx_Char('.');
                                else   
                                        Tx_Char(delay_time + 0x30);
                        }
                }      
        }while(delay_time != FALSE);
       
        Tx_Char('\r');
        Tx_Char('\n');

}

/*******************************************************************************
* Function Name         :       void Tx_Char(u8 Data)
* Parameter                     :
* Returns                       :
* Created by            :
* Created date          :
* Last Modified by      :
* Last Modified on      :
* Decription            :
* Notes                         :
*******************************************************************************/


void Tx_Char(u8 Data)
{
        TXREG1 = Data;
        while(!TXSTA1bits.TRMT);
}

/*******************************************************************************
* Function Name         :       void Tx_String(const rom u8 *src)
* Parameter                     :
* Returns                       :
* Created by            :
* Created date          :
* Last Modified by      :
* Last Modified on      :
* Decription            :
* Notes                         :
*******************************************************************************/


void Tx_String(const rom u8 *src)
{
        while (*src)
                Tx_Char(*src++);
}

/*******************************************************************************
* Function Name         :       void Select_CH_UART1(u8 ch_no)
* Parameter                     :
* Returns                       :
* Created by            :
* Created date          :
* Last Modified by      :
* Last Modified on      :
* Decription            :
* Notes                         :
*******************************************************************************/


void Select_CH_UART1(u8 ch_no)
{
        INH = TRUE;

        switch (ch_no){
                case 0:
                        PORTC &= 0b11111100;
                        PORTC |= 0b00000000;
                        break;

                case 1:
                        PORTC &= 0b11111100;
                        PORTC |= 0b00000010;
                        break;

                /*
                case 2:
                        PORTC &= 0b11111100;
                        PORTC |= 0b00000001;
                        break;

                case 3:
                        PORTC &= 0b11111100;
                        PORTC |= 0b00000011;
                        break;
                */

        }
        INH = FALSE;
}

/*******************************************************************************
* Function Name         :       u8 Read_Char(void)
* Parameter                     :
* Returns                       :
* Created by            :
* Created date          :
* Last Modified by      :
* Last Modified on      :
* Decription            :       High Interupt Declaration
* Notes                         :
*******************************************************************************/


u8 Read_Char(void)
{
        u8 RxData;     
        while(!PIR1bits.RC1IF);
        RxData            = RCREG;
        PIR1bits.RCIF = FALSE;
        return RxData;
}


/*******************************************************************************
* Function Name         :       void zap(void)
* Parameter                     :
* Returns                       :
* Created by            :
* Created date          :
* Last Modified by      :
* Last Modified on      :
* Decription            :       Initiate a write to memory
* Notes                         :
*******************************************************************************/

 
void zap(void)
{
        EECON1bits.WREN = 0x01;
        EECON2                  = 0x55;
        EECON2                  = 0xAA;
        EECON1bits.WR   = 0x01;
        Nop();
        while(EECON1bits.WR);
        EECON1bits.WREN = 0x00;
}
/*******************************************************************************
* Function Name         :       u8 gx(void)
* Parameter                     :
* Returns                       :
* Created by            :
* Created date          :
* Last Modified by      :
* Last Modified on      :
* Decription            :       Get a 4 bit HEX number from the serial port
* Notes                         :
*******************************************************************************/


u8 gx(void)
{
        while(!PIR1bits.RC1IF);
        EEDATA = RCREG1;
        Inptr++;
        //#ifdef VERBOSE
        //      if(TRMT)                // Echo RX nibbles to output. If high speed RX, some
        //              TXREG=EEDATA;   // nibbles mightn't be TXed but will still be programmed.
        //#endif
        if (EEDATA >= 'A')
                return ((EEDATA - (u8)'A') + 10);
        return (EEDATA - '0');
}

/*******************************************************************************
* Function Name         :       u8 g2x(void)
* Parameter                     :
* Returns                       :
* Created by            :
* Created date          :
* Last Modified by      :
* Last Modified on      :
* Decription            :       Recieve a hexadecimal byte, add it to the checksum
* Notes                         :
*******************************************************************************/

 
u8 g2x(void)
{
        u8 temp = (gx()<<4);
        temp   +=  gx();
        cksum  +=  temp;
        return temp;
}

/*******************************************************************************
* Function Name         :       void table_write(void)
* Parameter                     :
* Returns                       :
* Created by            :
* Created date          :
* Last Modified by      :
* Last Modified on      :
* Decription            :       Transfer a byte from RAM to internal flash register(s)
* Notes                         :
*******************************************************************************/

 
void table_write(void)
{
       
        if(DO_NOT_INCREMENT){                                           // address is already loaded in TBLPTR, no pre-increment needed
                _asm TBLWT _endasm;
        }
        else{
                _asm TBLWTPOSTINC _endasm;                              // otherwise TBLPTR must be pre-incremented    
        }
        DO_NOT_INCREMENT=0;
}

/*******************************************************************************
* Function Name         :       void flash8(void)
* Parameter                     :
* Returns                       :
* Created by            :
* Created date          :
* Last Modified by      :
* Last Modified on      :
* Decription            :       Write the 8 byte buffer to flash
* Notes                         :
*******************************************************************************/

 
void flash8(void)
{
        if (DO_NOT_INCREMENT){
                TBLPTRL &= 0xF8;                        // point to start of 8 byte panel
        }
        for (index = 0; index < 8; ){  
                TABLAT = buff[index++];
                table_write();
        }
        zap();
}

/*******************************************************************************
* Function Name         :       void clear_buffer(void)
* Parameter                     :
* Returns                       :
* Created by            :
* Created date          :
* Last Modified by      :
* Last Modified on      :
* Decription            :      
* Notes                         :
*******************************************************************************/

 
void clear_buffer(void)
{
        buff[0] = buff[1] = buff[2] = FILL_BYTE;        // 8 byte buffer initialised with      
        buff[3] = buff[4] = buff[5] = FILL_BYTE;        // known data
        buff[6] = buff[7] = FILL_BYTE;
}


/*******************************************************************************
* Function Name         :       void checksum(void)
* Parameter                     :
* Returns                       :
* Created by            :
* Created date          :
* Last Modified by      :
* Last Modified on      :
* Decription            :      
* Notes                         :
*******************************************************************************/

 
void checksum(void)
{
        g2x();
        if (cksum)                              // if checksum does not add to zero, bad check, reset
                Reset();
        Tx_Char('\r');                  // echo each hex record on a new line
}



void start(void)                                                               
{
    _asm GOTO RESET_VECTOR _endasm
}



// bootloader header file

/* ------------------------------------------------------------------------- */
/* Data Types                                                                            */
/* ------------------------------------------------------------------------- */
typedef unsigned char                   u8;
typedef char                                    s8;
typedef unsigned int                    u16;
typedef int                                     s16;
typedef unsigned long                   u32;

/* ------------------------------------------------------------------------- */
/* Boolean                                                                                       */
/* ------------------------------------------------------------------------- */
#define FALSE                                   0x00
#define TRUE                                    0x01

/* ------------------------------------------------------------------------- */
/* Bootloader Address Mapping                                                */
/* ------------------------------------------------------------------------- */
#define BOOTLOADER_START        0x2A
#define BOOTLOADER_END          0x00FFF
#define RESET_VECTOR            0x01000
#define INTERRUPT_VECTOR_LOW    0x01008
#define INTERRUPT_VECTOR_HIGH   0x01018
#define APPLICATION_START       RESET_VECTOR

/* ------------------------------------------------------------------------- */
/* Intel HEX file record types                                               */
/* ------------------------------------------------------------------------- */
#define HEX_DATA_REC            0x00            /* data record */
#define HEX_EOF_REC             0x01            /* end of file record */
#define HEX_EXTADDR_REC         0x04            /* extened linear address record */

/* ------------------------------------------------------------------------- */
/* Intel HEX file section start offsets                                      */
/* ------------------------------------------------------------------------- */
#define HEX_LEN_START           0x01            /* start of record length */
#define HEX_ADDR_START          0x03            /* start of address */
#define HEX_TYPE_START          0x07            /* start of record type */
#define HEX_DATA_START          0x09            /* start of data */
#define HEX_HEADER_LEN          0x04            /* lenght of lenght-, address- and type field in byte */
#define HEX_LINE_LEN_MAX        50              /* maximum length a line in the HEX file */

#define ACK                     0x06            /* positive acknowledge (ACK) */
#define NAK                     0x15            /* negative acknowledge (NAK) */

/* test conditions */
#define FLASH                                   EECON1bits.EEPGD == 1
#define EEPROM                                  EECON1bits.EEPGD == 0
#define CONFIG                                  EECON1bits.CFGS  == 1


#define BOOT_TIMEOUT                    20
#define INH                                             PORTCbits.RC2
#define Timer0ON                                T0CONbits.TMR0ON

/////////////////////////////////////////////////////


/////////////////// Functions ////////////////////////

void    Init_Ports(void);
void    TimeOut(u8);
void    Tx_Char(u8 Data);
void    Tx_String(const rom u8 *);
void    Select_CH_UART1(u8);
u8              Read_Char(void);
void    interrupt_at_high_vector(void);
void    High_ISR(void);
void    interrupt_at_low_vector(void);
void    Low_ISR(void);

void    zap(void);
u8              g2x(void);
void    clear_buffer(void);
void    table_write(void);
void    flash8(void);
void    checksum(void);
u8              gx(void);

/////////////////////////////////////////////////////


/////////////////// Variables ///////////////////////

u16 Inptr;
unsigned short erase;
u8 OneSecFlg;
u8 RxData=FALSE;
u8 delay_time;
u8 cksum,rectype,bcount;
u8 DO_NOT_INCREMENT;
u8 buff[8];
u8 index;


//const rom u8 StartMSG[] = "\rBootloader v1.0\r\r";

const rom u8 BLString[7][60] = { "\r\n==================================================\r\n",
                                                                 "                  Bootloader V01.00\r\n",
                                                                 "==================================================\r\n",
                                                                 " Press 'D' to DOWNLOAD firmware.\r\n",
                                                                 "==================================================\r\n",
                                                                 "\r\nPress:"
                                                          };
/*
const rom u8 BLString[9][60] = { "\r\n==================================================\r\n",
                                                                "                  Bootloader V01.00\r\n",
                                                                "==================================================\r\n",
                                                                " 1. Download Firmware.\r\n",
                                                                " 2. Verify Firmware.\r\n",
                                                                " 3. Execute Firmware.\r\n",
                                                                "==================================================\r\n",
                                                                "\r\nPress:"
                                                          };
*/


const rom u8 Ready[]            = "\r\nReady to download firmware...\r\n";
const rom u8 TimeOutMSG[]       = "\r\nDownload timeout\r\n";
const rom u8 DownloadSucc[] = "\r\nSuccessfully downloaded.\r\n";


/////////////////////////////////////////////////////

//#define PROG_START                            0x800//0x1000                   // 4k (4x1024=4096)


#define MEM_TOP                                 0xFDC0                  // 64960 65536
//#define UPPER_ADDRESS_BYTE    0x01
//#define MEM_TOP                               0xFDBF          // 64959 (64x9=240) 65536
#define FILL_BYTE                               0xFF

 


so can you please help me to find where the bug is, i am not my application address is getting overwrite


[ Edited Sat Aug 11 2012, 03:02PM ]
Back to top
Ajay Bhargav
Sat Aug 11 2012, 03:06PM
Rickey's World Admin


Registered Member #1
Joined: Fri Feb 24 2006, 07:56AM
Location (Home Town): Punjab, India
Posts: 12665
I cannot understand your question.. which address is getting overwritten?? where does your application starts from?
Back to top
mangesh.ghugal
Sun Aug 12 2012, 04:42AM
Registered Member #7657
Joined: Mon May 05 2008, 06:27PM
Location (Home Town): mumbai
Posts: 27
my application is starting from 0x1000 check out the header file.

my bootloader is from 0x2A to 0x0fff
Back to top
Shailesh NAYAK
Thu Aug 23 2012, 03:49AM

Registered Member #2498
Joined: Mon Jul 23 2007, 04:20AM
Location (Home Town): Mumbai
Posts: 75
Hi,
Please wait for some days ... we are working on your request exclusively. as it get finished we will intimate you.
Best Regards
Back to top
 

Jump:     Back to top

Syndicate this thread: rss 0.92 Syndicate this thread: rss 2.0 Syndicate this thread: RDF
Powered by e107 Forum System

© 2010 Rickey's World
Render time: 0.1502 sec, 0.0071 of that for queries. DB queries: 56. Memory Usage: 3,900kB