CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

PIC24 write_program_memory of vector table - change ISRs?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
allenhuffman



Joined: 17 Jun 2019
Posts: 537
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PIC24 write_program_memory of vector table - change ISRs?
PostPosted: Thu Dec 03, 2020 12:50 pm     Reply with quote

If one uses write_program_memory() to update the vector table (IVT), does that immediately impact the registered routines, or is that memory loaded into RAM on the next boot and used, like it is on some Motorla architectures?

For example, on a PIC24FJ64GA002 system I work with, we have the concept of an "A" and "B" firmware load, splitting up the flash. This was designed to have a fallback partition to run from, but that part did not get implemented.

When running from "A", there is an IVT pointing to the code in partition A (normal start of flash area).

When "A" is running, and does a firmware update, it starts writing the HEX data to partition "B" (ORG address set there - separate HEX file). The last step it does is to write the vector table.

When we restart, it jumps to partition "B" ORG address.

As I read the data sheet, I wondered if -- as soon as we write that IVT -- does it immediately start vectoring to code in partition B?

I have stumbled into a very strange issue with our firmware updating that only happens when the vector table gets written.

Thanks for any clarification. The data sheet:

https://ww1.microchip.com/downloads/en/DeviceDoc/39881e.pdf

...says:

Quote:
The Interrupt Vector Table (IVT) is shown in Figure 7-1.
The IVT resides in program memory, starting at location,
000004h. The IVT contains 126 vectors, consisting of
8 non-maskable trap vectors, plus up to 118 sources of
interrupt. In general, each interrupt source has its own
vector. Each interrupt vector contains a 24-bit wide
address. The value programmed into each interrupt vector location is the starting address of the associated
Interrupt Service Routine (ISR).


To me, that sounds like as soon as I write_program_memory() to that range, I am changing where the vector goes immediately.
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Thu Dec 03, 2020 1:38 pm     Reply with quote

The key point is that is why the PIC has a Harvard architecture. It allows it
to overlap fetches from the program memory with ones from the RAM, since
they are on separate address busses, and have separate data busses. This
allows fast operation without needing to use a cache of any sort. Hence
immediate effect....
allenhuffman



Joined: 17 Jun 2019
Posts: 537
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Thu Dec 03, 2020 1:40 pm     Reply with quote

Thanks!

Now I have a situation of "how did this ever work" where we reprogram the vector table, immediately sending all the I2C and Timer IRQs to new code... If the variable offsets line up, I guess it would work fine. But if they don't, it seems like it would cause a crash.

I think that is what I am seeing now, since I added some global flags inside the I2C IRQs that were not there before. Interesting.
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
jeremiah



Joined: 20 Jul 2010
Posts: 1315

View user's profile Send private message

PostPosted: Fri Dec 04, 2020 1:51 pm     Reply with quote

Some other things to consider:
To "overwrite" an existing address, the whole page (reset location and IVT, maybe some code) has to be erased first. Otherwise it doesn't overwrite the existing address, it only overwrites the unused bits (effectively an AND operation). For example, say your original timer 1 ISR address was 0x0400 for A and in B it is located at 0x0800. If you don't erase the whole page, then the resultant address will be 0x0400 AND 0x0800 = 0x0000. However, if you erase the whole page (as required), the reset address is now gone (unless you re-write it) and if you had any code on that page, it is gone.

EDIT: typo'ed the math


Last edited by jeremiah on Fri Dec 04, 2020 11:06 pm; edited 1 time in total
allenhuffman



Joined: 17 Jun 2019
Posts: 537
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Fri Dec 04, 2020 2:00 pm     Reply with quote

jeremiah wrote:
Some other things to consider:
To "overwrite" an existing address, the whole page (reset location and IVT, maybe some code) has to be erased first. Otherwise it doesn't overwrite the existing address, it only overwrites the unused bits (effectively an AND operation). For example, say your original timer 1 ISR address was 0x0400 for A and in B it is located at 0x0800. If you don't erase the whole page, then the resultant address will be 0x0400 AND 0x0800 = 0x0C00. However, if you erase the whole page (as required), the reset address is now gone (unless you re-write it) and if you had any code on that page, it is gone.


This may be why the code disables all interrupts before writing.

To others following along at home...

write_program_memory() is documented to automatically erase a block before it writes to it, IF the start address falls on the boundary of a block size. i.e.,

If you have 1K block sizes (1024 bytes), writing to location 0 would format all 1024 bytes in the block first. But if you tried to write to location 1, it would not. Each time a write crosses over a boundary, it formats the entire block so subsequent writes will work.

Thus, that call may or may not erase the block for you.
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group