chipKIT® Development Platform

Inspired by Arduino™

Interrupt: vector overlap

Created Mon, 21 Sep 2015 17:01:53 +0000 by martijnj


martijnj

Mon, 21 Sep 2015 17:01:53 +0000

Hi all, I bought a chipKIT Max32 on recommendation, to run some existing code written a few years back for this unit. However, the exact same code now refuses to link, with the error

../pic32mx/bin/ld.exe: function at exception vector 3 too large
../pic32mx/bin/ld.exe: section .vector_4 loaded at [9d000280,9d000293] overlaps section .vector_3 loaded at [9d000260,9d000287]

Any advice?

The interrupt itself is

void __attribute__((naked, at_vector(3), nomips16)) ExtInt0Handler(void){
  asm volatile ("mtc0 $k0, $12\n\t");
  asm volatile ("sw $zero, 0($t6)\n\t");
  asm volatile ("sw $v1, 0($v0)\n\t");
  asm volatile ("mtc0 $k1, $12\n\t");
  asm volatile ("eret\n\t");
}

I'm new to development with PIC32, although I'm experienced in C, have used the high-level arduino interface before, and understand basic ASM.

Any ideas why it won't compile now when it used to compile fine? (circa 2011, I presume the toolchain has updated since then?)

Cheers, Martijn


majenko

Mon, 21 Sep 2015 18:12:50 +0000

Yes, the interrupt system has changed with the newer toolchain.

You should read this: [url]http://chipkit.net/interrupts-made-easy-with-chipkit/[/url]


martijnj

Tue, 22 Sep 2015 07:10:48 +0000

Thank you very much for the fast reply. I did read the post you mentioned earlier, but I interpreted this as the now-recommended approach instead of the required approach.

Due to time constraints, I'd really like to run the code as is - is it possible to revert to the old toolchain? Do you happen to know which version the change occurred at?

Thanks for your time.


majenko

Tue, 22 Sep 2015 09:41:17 +0000

The change occurred at the time we got support for the MZ processor, which is on the Wi-Fire.

The -old toolchain will be in an older version of MPIDE which you can download here: http://chipkit.s3.amazonaws.com/index.html

Which one you want I can't remember - you'll have to download them at random to find one that doesn't have the WiFire board. Try some time around 2012/2013.


martijnj

Tue, 22 Sep 2015 11:17:39 +0000

Reverting to mpide-0023-windows-20120903 allows my code to compile and run, which is good!

I am now nervous about compatibility. In my troubleshooting I have seen many implementations of an interrupt. For future reference, what's the correct way to implement an external interrupt? Consider the following code, which to me is the "simplest" version I've seen

void __ISR(_EXTERNAL_0_VECTOR, IPL7) MyExtTrig(void)
{
  Serial.println("Trig!");
  clearIntFlag(_EXTERNAL_0_IRQ);
}

void setup(void)
{
  Serial.begin(9600);
  Serial.println("Started");
}

void loop(void)
{
  Serial.println("Waiting");
  delay(5000);
}

On MPIDE0150 I get "__ISR" not defined unless I include <plib.h>, and a linking error unless I declare the function 'extern "C"'. Then it does compile.

The same code in UECIDE gives me an assembler error instead, saying "symbol `__vector_dispatch_3' is already defined". If I do include <plib.h> then it gives me lots of "expected unqualified-id before numeric constant" errors.

Given that these tools are using the same toolchain (?), I am unnerved by the differing results. I prefer UECIDE as an interface, but I can't make my code compile!


majenko

Tue, 22 Sep 2015 11:28:56 +0000

UECIDE always uses the most up to date toolchain it knows of. The stable version is stuck at the 2014 toolchain, which has MZ support so uses the newer style.

For external interrupts you should really be using the API's attachInterrupt() etc calls. The external interrupts are already bound to those routines and if you try and intercept it things will complain.

It's only for other interrupts that you should be playing with the interrupt routines themselves.

For all current versions of MPIDE and UECIDE you should be using

void __USER_ISR myISR() { ... }

for defining an interrupt routine. The __USER_ISR was created specially to address the differences in the MX and MZ interrupt systems. It is different depending on which chip you are compiling for. Then point to it using the setIntVector etc routines.

Again, I reiterate, that is only for "extra" interrupts that aren't otherwise being handled by the API, so timers, etc.