• AVR Freaks

Hot!ISR Vector table in c for PIC24FJ256GB110

Author
KMDN
Super Member
  • Total Posts : 261
  • Reward points : 0
  • Joined: 2014/03/08 03:40:44
  • Location: 0
  • Status: offline
2019/06/09 03:11:16 (permalink)
0

ISR Vector table in c for PIC24FJ256GB110

How Can I define ISR Vector table in c for PIC24FJ256GB110. Can some one provide example code for it.
 
 
#1

5 Replies Related Threads

    davekw7x
    Entropy++
    • Total Posts : 1827
    • Reward points : 0
    • Joined: 2012/01/16 12:01:07
    • Location: Second star on the right, straight on till morning
    • Status: offline
    Re: ISR Vector table in c for PIC24FJ256GB110 2019/06/09 07:19:53 (permalink)
    0
    kushalnandanwar
    How Can I define ISR Vector table in c for PIC24FJ256GB110.



    XC16 automatically generates Interrupt Vector Tables.  (Recent versions have a linker option that lets you suppress this, but the default is to generate the IVT.)

    XC16 also generates a Default Interrupt Handler that has a "break" instruction (for debugging) and a reset.  The default is to generate the handler, but you can suppress this *in case you want to create your very own default handler) also.

    For all interrupts that your project has an ISR, the linker puts your ISR code's adress into the IVT.  For all interrupts that do not have an ISR defined, the linker puts the address of the Default Interrupt handler.

    All of this can be changed in a custom linker script.  For example bootloaders and bootloadable applications have custom linker scripts that fill in their own IVT according to the project requirements.


    From the .lst file of my PIC24FJ256GB110 application here's the default handler that XC16 has placed at address 02c8

    000002c8 <__DefaultInterrupt>:
     2c8:    00 40 da        break     
     2ca:    00 00 fe        reset     


    Here is the top of the .lst file showing XC16-generated IVT and AIVT entries containing the address of the default handler:

    Disassembly of section .ivt._ADC1Interrupt:

    0000002e <.ivt._ADC1Interrupt>:
      2e:    c8 02 00        nop       
    Disassembly of section .ivt._AddressError:

    00000008 <.ivt._AddressError>:
       8:    c8 02 00        nop       
    Disassembly of section .aivt._AltADC1Interrupt:

    0000012e <.aivt._AltADC1Interrupt>:
     12e:    c8 02 00        nop       
    Disassembly of section .aivt._AltAddressError:

    00000108 <.aivt._AltAddressError>:
     108:    c8 02 00        nop       
    Disassembly of section .aivt._AltCNInterrupt:
    .
    .
    .

    Regards,

    Dave


    post edited by davekw7x - 2019/06/09 07:54:38

    Attached Image(s)


    Sometimes I just can't help myself...
    #2
    mpgmike
    Super Member
    • Total Posts : 332
    • Reward points : 0
    • Joined: 2014/01/23 17:27:06
    • Location: NJ
    • Status: offline
    Re: ISR Vector table in c for PIC24FJ256GB110 2019/06/10 06:53:04 (permalink)
    0
    If you just want to know how to structure your ISR to get it working:
     

    void __attribute__((interruption_auto_psv)) _T1Interrupt(void) {
      //clear IF, do something
    }
     
    void __attribute__((interruption_auto_psv)) _AD1Interrupt(void) {
      //clear IF, do something
    }


    I don't need the world to know my name, but I want to live a life so all my great-grandchildren proudly remember me.
    #3
    KMDN
    Super Member
    • Total Posts : 261
    • Reward points : 0
    • Joined: 2014/03/08 03:40:44
    • Location: 0
    • Status: offline
    Re: ISR Vector table in c for PIC24FJ256GB110 2019/06/18 11:11:11 (permalink)
    0
    davekw7x
    kushalnandanwar
    How Can I define ISR Vector table in c for PIC24FJ256GB110.



    XC16 automatically generates Interrupt Vector Tables.  (Recent versions have a linker option that lets you suppress this, but the default is to generate the IVT.)

    XC16 also generates a Default Interrupt Handler that has a "break" instruction (for debugging) and a reset.  The default is to generate the handler, but you can suppress this *in case you want to create your very own default handler) also.

    For all interrupts that your project has an ISR, the linker puts your ISR code's adress into the IVT.  For all interrupts that do not have an ISR defined, the linker puts the address of the Default Interrupt handler.

    All of this can be changed in a custom linker script.  For example bootloaders and bootloadable applications have custom linker scripts that fill in their own IVT according to the project requirements.


    From the .lst file of my PIC24FJ256GB110 application here's the default handler that XC16 has placed at address 02c8

    000002c8 <__DefaultInterrupt>:
     2c8:    00 40 da        break     
     2ca:    00 00 fe        reset     


    Here is the top of the .lst file showing XC16-generated IVT and AIVT entries containing the address of the default handler:

    Disassembly of section .ivt._ADC1Interrupt:

    0000002e <.ivt._ADC1Interrupt>:
      2e:    c8 02 00        nop       
    Disassembly of section .ivt._AddressError:

    00000008 <.ivt._AddressError>:
       8:    c8 02 00        nop       
    Disassembly of section .aivt._AltADC1Interrupt:

    0000012e <.aivt._AltADC1Interrupt>:
     12e:    c8 02 00        nop       
    Disassembly of section .aivt._AltAddressError:

    00000108 <.aivt._AltAddressError>:
     108:    c8 02 00        nop       
    Disassembly of section .aivt._AltCNInterrupt:
    .
    .
    .

    Regards,

    Dave






     
    Do you have any interrupt vector files which I can refer. 
    #4
    NorthGuy
    Super Member
    • Total Posts : 5808
    • Reward points : 0
    • Joined: 2014/02/23 14:23:23
    • Location: Northern Canada
    • Status: online
    Re: ISR Vector table in c for PIC24FJ256GB110 2019/06/18 12:42:07 (permalink)
    0
    kushalnandanwar
    Do you have any interrupt vector files which I can refer. 



    All the interrupts (and traps), along with their locations within IVT, are listed in the datasheet.
    #5
    davekw7x
    Entropy++
    • Total Posts : 1827
    • Reward points : 0
    • Joined: 2012/01/16 12:01:07
    • Location: Second star on the right, straight on till morning
    • Status: offline
    Re: ISR Vector table in c for PIC24FJ256GB110 2019/06/18 18:06:37 (permalink)
    0
    kushalnandanwar 
    Do you have any interrupt vector files which I can refer. 



    OK, here's my last gasp attempt: actual code from a simple (working) example for a PIC24FJ256GB106.  The principle is the same for other XC16 applications, and the code can be identical for a 'GB110:
     
    I will use Timer 2 as a counter that generates an interrupt every millisecond.


    // These are in a separate file, Timer2.c.
    // We assume that the timer has been initialized to generate an
    // interrupt every millisecond.
    //
    // Application code can retrieve the millis_count value by using
    // the millis() "getter" function.
    // Application code can not write the millis_count value.
    //
    static volatile uint32_t millis_count;

    // Interrupt Service routine simply increments the counter
    // The name of the function is critical.
    // Look for your chip in the xc16/vxxx/docs/vector_docs directory of
    // your XC16 distribution.
    //
    // For example open PIC24FJ256GB110.html in your browser and you will
    // see the names of each of the ISR routines that will be linked
    // into the Interrupt Vector Table.
    void __attribute__((interrupt, no_auto_psv)) _T2Interrupt ()
    {
        ++millis_count;
        IFS0bits.T2IF = 0;
    }

    // Disable the interrupt temporarily while retrieving the 32-bit value
    uint32_t millis()
    {
        uint32_t retval;
        IEC0bits.T2IE = 0;
        retval = millis_count;
        IEC0bits.T2IE = 1;
        return retval;
    }


    Then the millisecond count value can be used to make an LED toggle every second like this in main():
    Since there is no __delay_XX() function the toggling is non-blocking.  That is, you can do other stuff very frequently without waiting for a certain amount of elapsed time between LED toggle events.


    uint32_t millis(void);
    void init_system(void);

    int main()
    {
        // Initialize I/O, clock, timer2
        init_system();
        
        uint32_t now_ms;
        uint32_t old_ms = 0;
        int32_t  led_interval_ms = 1000;
        while (1) {
            now_ms = millis();
            if ((int32_t)(now_ms - old_ms) >= led_interval_ms) {
                old_ms += (uint32_t)led_interval_ms;
                LED1_Toggle();
            }
            // Do other stuff here!
        }
        // Never gets here!
        return -1;
    }


    Bottom line: Look at the generated code (in a .lst file or in disassembly in MPLABX.

    XC16 has placed the code for _T2Interrupt whever it wants to, and it has put the address of _T2Interrupt in the proper spot in the IVT.


    In the listing file: location 0x22 (the IVT location for the Timer 2 interrupt vector) has the address 02c8 (in little-endian order):
    Disassembly of section .ivt._T2Interrupt:

    00000022 <.ivt._T2Interrupt>:
      22:    c8 02 00        nop       

    At address 02c8 we see the code for the ISR itself


    000002c8 <__T2Interrupt>:
     2c8:    80 9f be        mov.d     w0, [w15++]
     2ca:    00 00 fa        lnk       #0x0
     2cc:    00 40 80        mov.w     0x800, w0
     2ce:    11 40 80        mov.w     0x802, w1
     2d0:    61 00 40        add.w     w0, #0x1, w0
     2d2:    e0 80 48        addc.w    w1, #0x0, w1
     2d4:    00 40 88        mov.w     w0, 0x800
     2d6:    11 40 88        mov.w     w1, 0x802
     2d8:    84 e0 a9        bclr.b    0x84, #0x7
     2da:    00 80 fa        ulnk      
     2dc:    4f 00 be        mov.d     [--w15], w0
     2de:    00 40 06        retfie    



    Regards,

    Dave


    post edited by davekw7x - 2019/06/18 18:09:34

    Sometimes I just can't help myself...
    #6
    Jump to:
    © 2019 APG vNext Commercial Version 4.5