View previous topic :: View next topic |
Author |
Message |
powerpurzel
Joined: 23 Jul 2004 Posts: 6 Location: Germany
|
Relocating ISRs to beyond 0x20000 |
Posted: Sat Jul 23, 2005 12:37 pm |
|
|
Hi all!
In my current application I have a 18F8720 wired with 2x 128kByte SRAMs. As the PIC is used in extended MC-mode, the SRAM memory-address starts at 0x20000.
Most executable code and the interrupt service routines have to be put in SRAM.
But when I try to change the interrupt-vector by doing this:
Code: | #build(interrupt=0x20000)
|
...I get a compiler error: "constant out of the valid range 0..32767"
What can I do now? how can I work around this stupid restriction?
thanks in advance,
daniel |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Sat Jul 23, 2005 8:29 pm |
|
|
Put the ISR handler stub in low memory and the main body of the handler in high memory.
Code: |
#int_xxxx // some handler
void my_handler_stub
{
my_handler_body();
}
#org somewhere_high_in_memory
void my_handler_body
{
}
|
_________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
powerpurzel
Joined: 23 Jul 2004 Posts: 6 Location: Germany
|
|
Posted: Sun Jul 24, 2005 4:01 am |
|
|
Hi!
when having few ISRs, this would be a good solution!
But the problem is that I will need a stub for EVERY interrupt and the location of the handler bodies has to be at exactly the same memory address for every program that gets loaded to the SRAM.
I consider using your method with #int_global and write my own interrupt handler if there is really no other way to get the ISRs located into high memory by the compiler itself. |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Sun Jul 24, 2005 7:56 am |
|
|
powerpurzel wrote: | Hi!
when having few ISRs, this would be a good solution!
But the problem is that I will need a stub for EVERY interrupt and the location of the handler bodies has to be at exactly the same memory address for every program that gets loaded to the SRAM.
I consider using your method with #int_global and write my own interrupt handler if there is really no other way to get the ISRs located into high memory by the compiler itself. |
You could have a second layer of stubs - make the entries in high order memory stubs pointing to you rel locations. In this way all the fist level stubs in high order memory would be in consectitive locations and therefore would be the same for all applications. THe down side of this approach is that you have two sets of additional call and return functions for each interrupt handler. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
Ttelmah Guest
|
|
Posted: Sun Jul 24, 2005 8:38 am |
|
|
At the end of the day, the #build relocation will probably not do what you want. This is designed for use with things like bootloaders, where the actual global vector is relocated, and then the loader does the redirection, to this new vector.
You are presumably aware, that the physical interrupt vectors remain in low memory, even when you are running extended MC mode?. Hence you need to leave the low vector at the default location, or add your own redirection at this point. Normally you would just leave the global handler in low memory, and relocate the individual handlers into high memory.
If you have PCWH, simply use device editor, and change the entry for 'program memory', from it's default 65536, to 2097151. Then use a setup like:
Code: |
#ORG 0x20000,0x1FFFFF DEFAULT
#int_TIMER2
TIMER2_isr() {
}
#int_RDA
RDA_isr() {
}
#int_TBE
TBE_isr() {
}
void main() {
//suitable code here, and in each handler.
|
This will relocate the actual 'handlers', while leaving the global handler in low memory.
Your alternative, is to simply write your own #int global handler, and then have this vector to high memory. There have been examples for global handler published in the past.
Best Wishes |
|
|
powerpurzel
Joined: 23 Jul 2004 Posts: 6 Location: Germany
|
|
Posted: Sun Jul 24, 2005 11:48 am |
|
|
thanks for your replies!
@asmallri
Yeah, the second-layer-method will probably work well although a big overhead for interrupt handling is still needed. I will try this within the next days...
@Ttelmah
I already failed with a similar approach. I used #build(memory=0x0000:0x1FFFFF) to define the memory range and tried to #org the ISRs into high memory in the way you said but sadly the compiler error "invalid ORG range" was always shown :(
It does work with lower addresses (#org 0x2000, 0xffff default) but then the ISRs still remain at address 0x08.
...and: Yes, I'm aware that the interrupt vectors will remain in the internal flash memory space. But I thought only using the #build(interrupt=...) gives the ability to relocate the ISRs. Otherwise the ISRs will start at 0x08 !?
btw., compiler version 3.227 |
|
|
Ttelmah Guest
|
|
Posted: Sun Jul 24, 2005 2:33 pm |
|
|
You will note, that I do say you will need device editor, and to change the entry for the 'program memory'.
It compiles fine once this is done.
Best Wishes |
|
|
powerpurzel
Joined: 23 Jul 2004 Posts: 6 Location: Germany
|
|
Posted: Sun Jul 24, 2005 3:10 pm |
|
|
Thanks again.
Below you see my very simple test program.
The compiler still complains about the "default" keyword with the "invalid ORG range" message.
I used the device editor as you said.
Code: |
#include <18F8720.h>
#use delay(clock=24000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#ORG 0x20000,0x1FFFFF DEFAULT
#int_ext
void intextisr()
{
printf("external Interrupt");
}
#int_timer0
void timer0int()
{
printf("timer0 Interrupt");
}
void main()
{
int a=0;
setup_timer_0(T1_INTERNAL);
enable_interrupts(int_ext);
enable_interrupts(global);
enable_interrupts(int_timer0);
while(1)
{
printf("Some value a= %d",a);
a++;
delay_ms(200);
}
}
|
|
|
|
Ttelmah Guest
|
|
Posted: Mon Jul 25, 2005 2:31 am |
|
|
At this point I am 'wibbling' gently. The range worked for me (I tried compiling it under 3.226), but is refusing to do so this morning...
I suspect that by changing it, and immediately compiling, I 'tricked' the compiler in some way (probably confused it!...).
The range should actually be 2097152, for the whole of memory (one short as given). I only used the bottom meg on test, so this wouldn't have affected me.
The 'key' about #build, is it moves the INT_GLOBAL handler (not the ISR's themselves by default). It is the global handler that sits at 0x8, and this then calls the other routines.
I thought the problem with your sample, might be the lack of a fuse statement with 'EMCU', but this seems to make no difference to the problem. :-(
Best Wishes |
|
|
powerpurzel
Joined: 23 Jul 2004 Posts: 6 Location: Germany
|
|
Posted: Tue Jul 26, 2005 10:27 am |
|
|
Okay, thanks anyway.
The code I posted was a "user program" which is started from the loader by a goto, so I left the fuses away since the config registers are not changed.
Currently I'm doing some tests with asmallri's double-stub-method but it doesn't work as stable as needed.
Perhaps I should better put my loader into the bootblock and use the PIC in "MP with bootblock mode". -> what a waste of flash mem
But the problems with the interrupt handlers would disappear.
Hopefully this restriction of the compiler will be removed in a future version... |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Tue Jul 26, 2005 5:37 pm |
|
|
powerpurzel wrote: | I'm doing some tests with asmallri's double-stub-method but it doesn't work as stable as needed.... |
If you are writing this in C then it should work uness there is a compiler problem and there reason it should work is that this methid is no different than making a function call in an ISR. If yo are coding in assembler then don't forget you will need to set your own page registers is you are using long jumps _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
jac Guest
|
marcus |
Posted: Wed Sep 28, 2005 9:16 am |
|
|
Ttelmah wrote: | At this point I am 'wibbling' gently. The range worked for me (I tried compiling it under 3.226), but is refusing to do so this morning...
I suspect that by changing it, and immediately compiling, I 'tricked' the compiler in some way (probably confused it!...).
The range should actually be 2097152, for the whole of memory (one short as given). I only used the bottom meg on test, so this wouldn't have affected me.
The 'key' about #build, is it moves the INT_GLOBAL handler (not the ISR's themselves by default). It is the global handler that sits at 0x8, and this then calls the other routines.
I thought the problem with your sample, might be the lack of a fuse statement with 'EMCU', but this seems to make no difference to the problem. :-(
Best Wishes |
|
|
|
|