|
|
View previous topic :: View next topic |
Author |
Message |
allenhuffman
Joined: 17 Jun 2019 Posts: 554 Location: Des Moines, Iowa, USA
|
PIC24 write_program_memory of vector table - change ISRs? |
Posted: Thu Dec 03, 2020 12:50 pm |
|
|
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: 19539
|
|
Posted: Thu Dec 03, 2020 1:38 pm |
|
|
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: 554 Location: Des Moines, Iowa, USA
|
|
Posted: Thu Dec 03, 2020 1:40 pm |
|
|
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: 1354
|
|
Posted: Fri Dec 04, 2020 1:51 pm |
|
|
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: 554 Location: Des Moines, Iowa, USA
|
|
Posted: Fri Dec 04, 2020 2:00 pm |
|
|
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 ? |
|
|
|
|
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
|