Reusing interrupts from bootloader to application

566 views
Skip to first unread message

Remy Echavarria

unread,
Sep 13, 2011, 9:30:59 AM9/13/11
to PIC24 Assembly-to-C Book
Hi! I'm attempting to use a modified version of the bootloader in
order to use the UART to transmit a hex file to my PIC24HJ256GP206,
interpret it, write it to the microcontroller, then boot into the
application. Unfortunately, the application also needs the UART in
order to communicate with the host computer also. This results in both
the host application and the bootloader attempting to use UART 2.

When I program the micro from the hex file (minus the first block and
the config bits), the program does not run, and results in a watchdog
reset. From this point, the UART is no longer accessible to the
bootloader. What can I do to ensure that both the bootloader and the
application have access to the UART?

Remy Echavarria

unread,
Sep 13, 2011, 11:11:10 AM9/13/11
to PIC24 Assembly-to-C Book
I just realized that I wasn't even writing to the IVT table. I don't
understand why sending the goto instruction from the ResetDevice
function would cause the interrupts to stop working at this point even
on a reset.

Robert Reese

unread,
Sep 13, 2011, 9:22:57 PM9/13/11
to pic24-assemb...@googlegroups.com
I am assuming that you started from bootloader version 3 (look in the main.c, see if VERSION_MAJOR is 3).  This is the version of the bootloader that uses a remapped IVT table so that the bootloader program area is never written during bootloading.

If I understand correctly, what you want to do is for a normal program to detect that you want to bootload, then you invoke the bootloader from the main program (perhaps by just jumping to location 0x200 directly where the bootloader resides). I guess you have also modified the bootloader code so that when it is jumped to like this, it does the actual bootloading (right now, the bootloader will only bootload if it detects a  MCLR reset or a power-on reset, so just jumping to it will not cause a bootload -- you have to change this check somehow).
 
This is as far as I understand what you are trying to do. I don't understand your question about the ResetDevice function or interrupts (or which interrupts you are concerned about).
 
If you could post the modified main.c of the bootloader, that would be helpful, or describe in more detail how you modified the bootloader to accomplish what you are trying to do.
--
You received this message because you are subscribed to the Google Groups "PIC24 Assembly-to-C Book" group.
To post to this group, send email to pic24-assemb...@googlegroups.com.
To unsubscribe from this group, send email to pic24-assembly-to-...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/pic24-assembly-to-c-book?hl=en.


Remy Echavarria

unread,
Sep 14, 2011, 9:42:47 AM9/14/11
to PIC24 Assembly-to-C Book
Ah, no. I actually started from the microchip bootloader and modified
it using your clockfreq, configbits (same one from the target program
so I don't have to rewrite it from the application's hex file), i2c,
serial, timer, uart, and util source files (not the ones from the
bootloader though). I did add in your MCLR and POR reset protections
though.

What I am doing is just going from the bootloader (on a reset or power
on) to the main program. The catch here is that my hex file is coming
in from a different communication protocol, so I have to catch it
using the UART (using the _U2RXInterrupt and _U2TXInterrupt). I also
use _T3Interrupt to catch the time, but I believe that I could find a
workaround for that one. So far I have not been successful in using
the linker script from the bully bootloader (after I modified the
addresses so they wouldn't collide with the bootloader's program
space) because the interrupts will not work when I use it. I have also
attempted to rename my interrupts to match up with the linker script.
Are they not working because (your version of) the bootloader linker
script it is lacking the extra code that (your version of) the
application's linker script uses to point between DefaultInterrupt and
the intended interrupt?

If this is the case, I believe I may have to use the application
linker script (from the bully bootloader) and remap the IVT to a
mutually unused page of program memory. Then I would have to write a
function at both the beginning of my bootloader and the beginning of
the application to rewrite the remapped IVT to point the interrupts to
the bootloader's / application's version of the interrupts. In that
case, I would need to know the address of the interrupt function I'm
pointing to, which I'll need to figure out.

I have added the code from main.c below. Is there a way to attach
files to the group?


Thanks!

Remy



/********************************************************************
* FileName: main.c
* Dependencies:
* Processor: PIC24H Family
* Hardware: Explorer 16
* Compiler: C30 2.01
* Company: Microchip Technology, Inc.
*
* Software License Agreement
*
* The software supplied herewith by Microchip Technology Incorporated
* (the “Company”) for its PICmicro® Microcontroller is intended and
* supplied to you, the Company’s customer, for use solely and
* exclusively on Microchip PICmicro Microcontroller products. The
* software is owned by the Company and/or its supplier, and is
* protected under applicable copyright laws. All rights are reserved.
* Any use in violation of the foregoing restrictions may subject the
* user to criminal sanctions under applicable laws, as well as to
* civil liability for the breach of the terms and conditions of this
* license.
*
* THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
* TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
* IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
*********************************************************************/


//#include "p24Hxxxx.h"
#include "pic24_all.h"
#include "pic24_delay.h"
#include "display.h"
#define EXT
#include "interrup.h"
#include "ram.h"
#undef EXT
#include "def.h"

//1.00a-004-boot-rme #define FCY 40000000
//1.00a-004-boot-rme #define BAUDRATE 9600
//1.00a-004-boot-rme #define BRGVAL ((FCY/BAUDRATE)/16)-1

// External Oscillator
//1.00a-004-boot-rme _FOSCSEL(FNOSC_PRIPLL); // Primary (XT,
HS, EC) Oscillator with PLL
//1.00a-004-boot-rme _FOSC(FCKSM_CSDCMD & OSCIOFNC_OFF &
POSCMD_XT); // Clock Switching and Fail Safe Clock Monitor is disabled
// OSC2 Pin Function: OSC2 is Clock Output
// Primary Oscillator Mode: XT Crystanl


//1.00a-005-boot-rme _FWDT(FWDTEN_OFF); // Watchdog
Timer Enabled/disabled by user software
// (LPRC can be disabled by clearing SWDTEN bit in RCON
register
//_FPOR(PWRTEN_OFF); // Turn off the power-up timers.
//_FGS(GCP_OFF); // Disable Code Protection





extern UWord32 ReadLatch(UWord16, UWord16);

void PutChar(unsigned char);
void GetChar(unsigned char *);
void WriteBuffer(unsigned char *, int);
void ReadPM(unsigned char *, uReg32);
void WritePM(unsigned char *, uReg32);



int main(void)

{
// initialize_interrupt_table();
configClock(); //1.00a-004-boot-rme
configI2C1(50); //1.00b-mag-002-rme //50MHz
configUART2(19200); // configure UART2 for 19200 //1.00a-004-boot-rme
//Initializes LCD Display and sends Micro-Mag title to display
DELAY_MS(45); //1.00b-mag-006-rme
display_init(); //1.00b-mag-005-rme //Initializes the LCD display
display_send_title(); //1.00b-mag-005-rme //Sends the title to the
LCD display


CONFIG_DIRECTION_PIN_2(); //1.00a-004-boot-rme
SET_DIRECTION_RECEIVE_2(); //1.00a-004-boot-rme



configOutputs();


mcsio_initialization_2(); //1.00a-004-boot-rme
interrupt_initialization(); //1.00a-004-boot-rme






// Configure Oscillator to operate the device at 40Mhz
// Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
// Fosc= 8M*40(2*2)=80Mhz for 8M input clock
//1.00a-004-boot-rme PLLFBD=38; // M=40
//1.00a-004-boot-rme CLKDIVbits.PLLPOST=0; // N1=2
//1.00a-004-boot-rme CLKDIVbits.PLLPRE=0; // N2=2
//1.00a-004-boot-rme OSCTUN=0; // Tune FRC oscillator, if FRC is
used



//1.00a-005-boot-rme RCONbits.SWDTEN=0; /* Disable Watch
Dog Timer*/


while(OSCCONbits.LOCK!=1) {}; /* Wait for PLL to lock*/


//1.00a-003-rme SourceAddr.Val32 = 0xc00;
SourceAddr.Word.LW = 0x8600;
SourceAddr.Word.HW = 0x0000;
Delay.Val32 = ReadLatch(SourceAddr.Word.HW, SourceAddr.Word.LW);

if(Delay.Val[0] == 0 || (_POR==0 && _EXTR==0))
{
ResetDevice();
}

//1.00a-004-boot-rme T2CONbits.T32 = 1; /* to increment every
instruction cycle */
//1.00a-004-boot-rme IFS0bits.T3IF = 0; /* Clear the Timer3 Interrupt
Flag */
//1.00a-004-boot-rme IEC0bits.T3IE = 0; /* Disable Timer3 Interrup
Service Routine */

if((Delay.Val32 & 0x000000FF) != 0xFF)
{
/* Convert seconds into timer count value */
//Delay.Val32 = ((UWord32)(FCY)) * ((UWord32)(Delay.Val[0]));

// PR3 = Delay.Word.HW;
// PR2 = Delay.Word.LW;

// /* Enable Timer */
// T2CONbits.TON=1;
}


//1.00a-004-boot-rme U2BRG = BRGVAL ; /* BAUD Rate Setting of
Uart2 */


//1.00a-004-boot-rme U2MODE = 0x8000; /* Reset UART to 8-n-1, alt
pins, and enable */
//1.00a-004-boot-rme U2STA = 0x0400; /* Reset status register and
enable TX */


/***************************/
/* Config MCSIO structures */
/***************************/
sw_status.cfg_valid = FALSE; //1.00a-004-boot-rme
sw_status.cfg_download = TRUE; //1.00a-004-boot-rme
sw_status.cfg_download_timer = 125; //1.00a-004-boot-rme
sw_status.filler = 0xFF; //1.00a-004-boot-rme
sw_status.serial_numb = 0x0001; //1.00a-004-boot-rme
sw_status.sw_version[0] = 'M'; //1.00a-004-boot-rme
sw_status.sw_version[1] = 'I'; //1.00a-004-boot-rme
sw_status.sw_version[2] = 'C'; //1.00a-004-boot-rme
sw_status.sw_version[3] = 'R'; //1.00a-004-boot-rme
sw_status.sw_version[4] = 'O'; //1.00a-004-boot-rme
sw_status.sw_version[5] = '-'; //1.00a-004-boot-rme
sw_status.sw_version[6] = 'B'; //1.00a-004-boot-rme
sw_status.sw_version[7] = 'O'; //1.00a-004-boot-rme
sw_status.sw_version[8] = 'O'; //1.00a-004-boot-rme
sw_status.sw_version[9] = 'T'; //1.00a-004-boot-rme
sw_status.sw_version[10] = ' '; //1.00a-004-boot-rme
sw_status.sw_version[11] = ' '; //1.00a-004-boot-rme
sw_status.sw_version[12] = 0X00; //1.00a-004-boot-rme
//1.00a-004-boot-rme
version_numb.name[0] = 'B'; //1.00a-004-boot-rme
version_numb.name[1] = 'O'; //1.00a-004-boot-rme
version_numb.name[2] = 'O'; //1.00a-004-boot-rme
version_numb.name[3] = 'T'; //1.00a-004-boot-rme
version_numb.name[4] = 'L'; //1.00a-004-boot-rme
version_numb.name[5] = 'O'; //1.00a-004-boot-rme
version_numb.name[6] = 'A'; //1.00a-004-boot-rme
version_numb.name[7] = 'D'; //1.00a-004-boot-rme
version_numb.name[8] = 'E'; //1.00a-004-boot-rme
version_numb.name[9] = 'R'; //1.00a-004-boot-rme
version_numb.name[10] = ' '; //1.00a-004-boot-rme
version_numb.name[11] = '1'; //1.00a-004-boot-rme
version_numb.name[12] = '.'; //1.00a-004-boot-rme
version_numb.name[13] = '0'; //1.00a-004-boot-rme
version_numb.name[14] = '0'; //1.00a-004-boot-rme
version_numb.name[15] = 0x00; //1.00a-004-boot-rme
//1.00a-004-boot-rme
//1.00a-004-boot-rme
version_numb.co_name[0] = 'M'; //1.00a-004-boot-rme
version_numb.co_name[1] = 'C'; //1.00a-004-boot-rme
version_numb.co_name[2] = 'S'; //1.00a-004-boot-rme
version_numb.co_name[3] = ' '; //1.00a-004-boot-rme
version_numb.co_name[4] = ' '; //1.00a-004-boot-rme
version_numb.co_name[5] = ' '; //1.00a-004-boot-rme
version_numb.co_name[6] = ' '; //1.00a-004-boot-rme
version_numb.co_name[7] = ' '; //1.00a-004-boot-rme
version_numb.co_name[8] = ' '; //1.00a-004-boot-rme
version_numb.co_name[9] = ' '; //1.00a-004-boot-rme
version_numb.co_name[10] = ' '; //1.00a-004-boot-rme
version_numb.co_name[11] = ' '; //1.00a-004-boot-rme
version_numb.co_name[12] = ' '; //1.00a-004-boot-rme
version_numb.co_name[13] = ' '; //1.00a-004-boot-rme
version_numb.co_name[14] = ' '; //1.00a-004-boot-rme
version_numb.co_name[15] = 0X00; //1.00a-004-boot-rme
//1.00a-004-boot-rme
version_numb.model_name[0] = 'B'; //1.00a-004-boot-rme
version_numb.model_name[1] = 'O'; //1.00a-004-boot-rme
version_numb.model_name[2] = 'O'; //1.00a-004-boot-rme
version_numb.model_name[3] = 'T'; //1.00a-004-boot-rme
version_numb.model_name[4] = 'L'; //1.00a-004-boot-rme
version_numb.model_name[5] = 'O'; //1.00a-004-boot-rme
version_numb.model_name[6] = 'A'; //1.00a-004-boot-rme
version_numb.model_name[7] = 'D'; //1.00a-004-boot-rme
version_numb.model_name[8] = 'E'; //1.00a-004-boot-rme
version_numb.model_name[9] = 'R'; //1.00a-004-boot-rme
version_numb.model_name[10] = ' '; //1.00a-004-boot-rme
version_numb.model_name[11] = '1'; //1.00a-004-boot-rme
version_numb.model_name[12] = '.'; //1.00a-004-boot-rme
version_numb.model_name[13] = '0'; //1.00a-004-boot-rme
version_numb.model_name[14] = '0'; //1.00a-004-boot-rme
version_numb.model_name[15] = 0X00; //1.00a-004-boot-rme
//1.00a-004-boot-rme
version_numb.installed_date.MONTH = 8; //1.00a-004-boot-rme
version_numb.installed_date.DATE = 23; //1.00a-004-boot-rme
version_numb.installed_date.YEAR = 11; //1.00a-004-boot-rme
//1.00a-004-boot-rme
version_numb.serial_number[0] = 'V'; //1.00a-004-boot-rme
version_numb.serial_number[1] = 'E'; //1.00a-004-boot-rme
version_numb.serial_number[2] = 'R'; //1.00a-004-boot-rme
version_numb.serial_number[3] = 'S'; //1.00a-004-boot-rme
version_numb.serial_number[4] = 'I'; //1.00a-004-boot-rme
version_numb.serial_number[5] = 'O'; //1.00a-004-boot-rme
version_numb.serial_number[6] = 'N'; //1.00a-004-boot-rme
version_numb.serial_number[7] = ' '; //1.00a-004-boot-rme
version_numb.serial_number[8] = '1'; //1.00a-004-boot-rme
version_numb.serial_number[9] = '.'; //1.00a-004-boot-rme
version_numb.serial_number[10] = '0'; //1.00a-004-boot-rme
version_numb.serial_number[11] = '0'; //1.00a-004-boot-rme
version_numb.serial_number[12] = 'A'; //1.00a-004-boot-rme
version_numb.serial_number[13] = ' '; //1.00a-004-boot-rme
version_numb.serial_number[14] = ' '; //1.00a-004-boot-rme
version_numb.serial_number[15] = 0X00; //1.00a-004-boot-rme
//1.00a-004-boot-rme
version_numb.cfg_version = 'B'; //1.00a-004-boot-rme
version_numb.cfg_type = 'B'; //1.00a-004-boot-rme
version_numb.cfg_month = 8; //1.00a-004-boot-rme
version_numb.cfg_dom = 23; //1.00a-004-boot-rme
version_numb.cfg_year = 11; //1.00a-004-boot-rme
version_numb.cfg_hour = 12; //1.00a-004-boot-rme
version_numb.cfg_minute = 47; //1.00a-004-boot-rme
version_numb.load_month = 8; //1.00a-004-boot-rme
version_numb.load_dom = 23; //1.00a-004-boot-rme
version_numb.load_year = 11; //1.00a-004-boot-rme
version_numb.load_hour = 21; //1.00a-004-boot-rme
version_numb.load_minute = 47; //1.00a-004-boot-rme
version_numb.model_numb = 'u'; //1.00a-004-boot-rme

system_transmit_success =0;
system_transmit_completed =0;
system_firmware_receiving = 0;


while(1)
{
char Command;
/* //1.00a-004-boot-rme
GetChar(&Command);

switch(Command)
{
case COMMAND_READ_PM: //tested
{
uReg32 SourceAddr;

GetChar(&(SourceAddr.Val[0]));
GetChar(&(SourceAddr.Val[1]));
GetChar(&(SourceAddr.Val[2]));
SourceAddr.Val[3]=0;

ReadPM(Buffer, SourceAddr);

WriteBuffer(Buffer, PM_ROW_SIZE*3);

break;
}

case COMMAND_WRITE_PM: // tested
{
uReg32 SourceAddr;
int Size;

GetChar(&(SourceAddr.Val[0]));
GetChar(&(SourceAddr.Val[1]));
GetChar(&(SourceAddr.Val[2]));
SourceAddr.Val[3]=0;

for(Size = 0; Size < PM_ROW_SIZE*3; Size++)
{
GetChar(&(Buffer[Size]));
}

Erase(SourceAddr.Word.HW,SourceAddr.Word.LW,PM_ROW_ERASE);

WritePM(Buffer, SourceAddr); //program page

PutChar(COMMAND_ACK); //Send Acknowledgement

break;
}

case COMMAND_READ_ID:
{
uReg32 SourceAddr;
uReg32 Temp;

SourceAddr.Val32 = 0xFF0000;

Temp.Val32 = ReadLatch(SourceAddr.Word.HW, SourceAddr.Word.LW);

WriteBuffer(&(Temp.Val[0]), 4);

SourceAddr.Val32 = 0xFF0002;

Temp.Val32 = ReadLatch(SourceAddr.Word.HW, SourceAddr.Word.LW);

WriteBuffer(&(Temp.Val[0]), 4);

break;
}

case COMMAND_WRITE_CM:
{
int Size;

for(Size = 0; Size < CM_ROW_SIZE*3;)
{
GetChar(&(Buffer[Size++]));
GetChar(&(Buffer[Size++]));
GetChar(&(Buffer[Size++]));

PutChar(COMMAND_ACK); //Send Acknowledgement
}

break;
}
case COMMAND_RESET:
{
uReg32 SourceAddr;
int Size;
uReg32 Temp;


for(Size = 0, SourceAddr.Val32 = 0xF80000; Size < CM_ROW_SIZE*3;
Size +=3, SourceAddr.Val32 += 2)
{
if(Buffer[Size] == 0)
{
Temp.Val[0]=Buffer[Size+1];
Temp.Val[1]=Buffer[Size+2];

WriteLatch( SourceAddr.Word.HW,
SourceAddr.Word.LW,
Temp.Word.HW,
Temp.Word.LW);

WriteMem(CONFIG_WORD_WRITE);
}
}

ResetDevice();

break;
}

case COMMAND_NACK:
{
ResetDevice();

break;
}


default:
PutChar(COMMAND_NACK);
break;
}
*/ //1.00a-004-boot-rme
if (old_sec_ticker != sec_ticker)
{
if((unsigned char) Delay.Val[0] == 0xFF)
{
sec_ticker = 0;
}
old_sec_ticker = sec_ticker;
if((sec_ticker > (unsigned char) Delay.Val[0]) && ((unsigned char)
Delay.Val[0] != 0xFF))
{
sec_ticker = sec_ticker;
ResetDevice();
}


checkRxErrorUART2();
CLRWDT(); // Clear Watchdog timer //1.00a-005-boot-
rme
if(mcsio_2.uart_state == RS485_IDLE)
mcsio_reset_transceiver_2();
}
if (mcsio_2.uart_state == RS485_MESSAGE_RECEIVED)
{
if (mcsio_msg_valid_2())
{
sec_ticker = 0;
old_sec_ticker = 0;
mcsio_msg_response_2(); // mcsio response
}
else
mcsio_reset_transceiver_2(); // Reset mcsio channel
}

}

}

/
******************************************************************************/

void GetChar(unsigned char * ptrChar)
{
while(1)
{
// if timer expired, signal to application to jump to user code
if(IFS0bits.T3IF == 1)
{
* ptrChar = COMMAND_NACK;
break;
}
// check for receive errors
if(U2STAbits.FERR == 1)
{
continue;
}

// must clear the overrun error to keep uart receiving
if(U2STAbits.OERR == 1)
{
U2STAbits.OERR = 0;
continue;
}

// get the data
if(U2STAbits.URXDA == 1)
{
T2CONbits.TON=0; // Disable timer countdown
* ptrChar = U2RXREG;
break;
}
}
}


/
******************************************************************************/

void ReadPM(unsigned char * ptrData, uReg32 SourceAddr)
{
int Size;
uReg32 Temp;

for(Size = 0; Size < PM_ROW_SIZE; Size++)
{
Temp.Val32 = ReadLatch(SourceAddr.Word.HW, SourceAddr.Word.LW);

ptrData[0] = Temp.Val[2];;
ptrData[1] = Temp.Val[1];;
ptrData[2] = Temp.Val[0];;

ptrData = ptrData + 3;

SourceAddr.Val32 = SourceAddr.Val32 + 2;
}
}

/
******************************************************************************/

void VerifyPM(unsigned char * ptrData, uReg32 SourceAddr)
{
int Size;
uReg32 Temp;

for(Size = 0; Size < PM_ROW_SIZE; Size++)
{
if(hexfile_error)
{
hexfile_error = hexfile_error;
break;
}
Temp.Val32 = ReadLatch(SourceAddr.Word.HW, SourceAddr.Word.LW);

hexfile_error = (ptrData[0] == Temp.Val[0]) ? hexfile_error :
VERIFY_ERROR;
hexfile_error = (ptrData[1] == Temp.Val[1]) ? hexfile_error :
VERIFY_ERROR;
hexfile_error = (ptrData[2] == Temp.Val[2]) ? hexfile_error :
VERIFY_ERROR;

ptrData = ptrData + 3;

SourceAddr.Val32 = SourceAddr.Val32 + 2;
}
}

/
******************************************************************************/

void WriteBuffer(unsigned char * ptrData, int Size)
{
int DataCount;

for(DataCount = 0; DataCount < Size; DataCount++)
{
PutChar(ptrData[DataCount]);
}
}

/
******************************************************************************/

void PutChar(unsigned char Char)
{
while(!U2STAbits.TRMT);

U2TXREG = Char;
}

/
******************************************************************************/

void WritePM(unsigned char * ptrData, uReg32 SourceAddr)
{
int Size,Size1;
uReg32 Temp;
uReg32 TempAddr;
uReg32 TempData;

for(Size = 0,Size1=0; Size < PM_ROW_SIZE; Size++)
{

Temp.Val[0]=ptrData[Size1+0];
Temp.Val[1]=ptrData[Size1+1];
Temp.Val[2]=ptrData[Size1+2];
Temp.Val[3]=0;
Size1+=3;

WriteLatch(SourceAddr.Word.HW,
SourceAddr.Word.LW,Temp.Word.HW,Temp.Word.LW);

// Device ID errata workaround: Save data at any address that has
LSB 0x18
if((SourceAddr.Val32 & 0x0000001F) == 0x18)
{
TempAddr.Val32 = SourceAddr.Val32;
TempData.Val32 = Temp.Val32;
}

if((Size !=0) && (((Size + 1) % 64) == 0))
{
// Device ID errata workaround: Reload data at address with LSB of
0x18
WriteLatch(TempAddr.Word.HW,
TempAddr.Word.LW,TempData.Word.HW,TempData.Word.LW);

WriteMem(PM_ROW_WRITE);
}

SourceAddr.Val32 = SourceAddr.Val32 + 2;
}


}

/
******************************************************************************/








On Sep 13, 9:22 pm, Robert Reese <rbrees...@gmail.com> wrote:
> I am assuming that you started from bootloader version 3 (look in the
> main.c, see if VERSION_MAJOR is 3).  This is the version of the bootloader
> that uses a remapped IVT table so that the bootloader program area is never
> written during bootloading.
>
> If I understand correctly, what you want to do is for a normal program to
> detect that you want to bootload, then you invoke the bootloader from the
> main program (perhaps by just jumping to location 0x200 directly where the
> bootloader resides). I guess you have also modified the bootloader code so
> that when it is jumped to like this, it does the actual bootloading (right
> now, the bootloader will only bootload if it detects a  MCLR reset or a
> power-on reset, so just jumping to it will not cause a bootload -- you have
> to change this check somehow).
>
> This is as far as I understand what you are trying to do. I don't understand
> your question about the ResetDevice function or interrupts (or which
> interrupts you are concerned about).
>
> If you could post the modified main.c of the bootloader, that would be
> helpful, or describe in more detail how you modified the bootloader to
> accomplish what you are trying to do.
>
> On Tue, Sep 13, 2011 at 10:11 AM, Remy Echavarria <remy.echavar...@gmail.com

Robert Reese

unread,
Sep 14, 2011, 5:42:35 PM9/14/11
to pic24-assemb...@googlegroups.com
I am unfamiliar with that particular Microchip bootloader (they have released more than one) -- I don't know what 'initialize_interrrupt_table()' does as we do not have an equivalent in our bootloader.  I don't think that I will be able to help you.
 
I can't answer your questions unless I have a zip archive that contains the project for both your bootloader, and for a sample application that you are trying to bootload so that I can compile both and see how the IVT tables are arranged for both bootloader and application.
 
Just as an FYI -- in our bootloader, the normal IVT1/IVT2 tables have vectors in them that jump to another program memory  location  where the application vector table is (above the bootloader space). So, the bootloader is fixed and does not change during programming. This does eat up more program memory for the bootloader, and our IVT1/IVT2 tables actually point to the same application locations for both tables so we don't really have two IVT tables.  Our bootloader requires  a modified linker script for the bootloader code, and a modified linker script for the application code, in order to do the IVT remapping this way.
 
You may have more success going from our bootloader and making your modifications to that code instead of starting with the Microchip bootloader, and putting some of our stuff in there.  Our bootloader started from a Microchip bootloader, and then evolved from there.

Remy

unread,
Apr 25, 2012, 2:52:48 PM4/25/12
to pic24-assemb...@googlegroups.com
At the time I was going to try to reprogram the IVT every time I restarted the bootloader. What I ended up doing was having the ALTIVT point directly to the bootloader's interrupts and the normal IVT point to the beginning of program memory (based off of your linker script). In the application linker script, I basically used your linker script to make that second jump to the main program's interrupts.


Remy
>
>
>
>
>
>
>

> > wrote:
> > I just realized that I wasn't even writing to the IVT table. I don't
> > understand why sending the goto instruction from the ResetDevice
> > function would cause the interrupts to stop working at this point even
> > on a reset.
>
> > On Sep 13, 9:30 am, Remy Echavarria <> wrote:
> > > Hi! I'm attempting to use a modified version of the bootloader in
> > > order to use the UART to transmit a hex file to my PIC24HJ256GP206,
> > > interpret it, write it to the microcontroller, then boot into the
> > > application. Unfortunately, the application also needs  the UART in
> > > order to communicate with the host computer also. This results in both
> > > the host application and the bootloader attempting to use UART 2.
>
> > > When I program the micro from the hex file (minus the first block and
> > > the config bits), the program does not run, and results in a watchdog
> > > reset. From this point, the UART is no longer accessible to the
> > > bootloader. What can I do to ensure that both the bootloader and the
> > > application have access to the UART?
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "PIC24 Assembly-to-C Book" group.

--

 
Reply all
Reply to author
Forward
0 new messages