• AVR Freaks

Hot!Difficulty locating interrupts w/ CodeOffset and XC8 v1.45

Author
dave94025
New Member
  • Total Posts : 6
  • Reward points : 0
  • Joined: 2018/05/31 10:57:14
  • Location: 0
  • Status: offline
2019/08/09 13:59:31 (permalink)
0

Difficulty locating interrupts w/ CodeOffset and XC8 v1.45

I've implemented a bootloader that I've used on numerous projects with both PIC18F and PIC32MX parts, but I had to move to a newer version of XC8 (v1.45) in order to use the PIC18F46K42 which I've been using.   This version of the compiler has worked fine for standalone applications but I've recently run into issues trying to implement a bootloaded version of my code with it.
 
Previously if you compiled code with the CodeOffset parameter (on the Linker, Additional Options page) it would start the code at that offset and stick the Lo/Hi interrupt vectors at this address + 0x08 and 0x18 respectively, which makes sense and if you write the bootloader such that you jump to these addresses on an interrupt then eveything works fine.
 
However, try as I might I can't get the compiler to do this.  It keeps wanting to put the interrupt vectors at the base of memory (0x08, 0x18) regardless of what value is in the CodeOffset field and any attempts to explicitly move them or locate them is met with errors, or warnings with any redirection ignored.
 
You can see from the attached file the memory map for a previous controllers (PIC18F26K20 with a jump for the Low priority interrupt at 0x4048 and the High priority interrupt dropped inline at 0x4058).   But, for the PIC18F46K42 the interrupts are down at 0x08 and 0x18 with nothing at 0x4048 and 0x4058.
 
Unfortunately the previous version of the compiler doesn't support this part, or I would use it.  I've also tried later versions of XC8 (v2.00) with the same results.
 
Any ideas on how to fix this?
 
Thanks,
Dave.

Attached Image(s)

#1

14 Replies Related Threads

    du00000001
    Just Some Member
    • Total Posts : 3665
    • Reward points : 0
    • Joined: 2016/05/03 13:52:42
    • Location: Germany
    • Status: offline
    Re: Difficulty locating interrupts w/ CodeOffset and XC8 v1.45 2019/08/12 08:57:09 (permalink)
    0
    What happens if you just complement V1.33 with the device-header "borrowed" from 1.45.
    (OK - might require additional changes in XC.h to get the right device-header(s) included.)
     
    Provided there are some other dervatives with the same command-set, this should be able to bring XC 1.33 back to fruitition.
     
    Re: what to do to get V1.45 (and beyond) to "cooperate": What's in the release notes ?

    PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
    #2
    dave94025
    New Member
    • Total Posts : 6
    • Reward points : 0
    • Joined: 2018/05/31 10:57:14
    • Location: 0
    • Status: offline
    Re: Difficulty locating interrupts w/ CodeOffset and XC8 v1.45 2019/08/12 09:05:57 (permalink)
    0
    I fixed the issue by adding the following code:
     
    asm("PSECT HiVector,class=CODE,delta=1,abs");
    asm("ORG 0x4048");
    asm("GOTO _IsrHigh");

    asm("PSECT LoVector,class=CODE,delta=1,abs");
    asm("ORG 0x4058");
    asm("GOTO _IsrLow");


    Dave.
    #3
    mbrowning
    USNA79
    • Total Posts : 1741
    • Reward points : 0
    • Joined: 2005/03/16 14:32:56
    • Location: Melbourne, FL
    • Status: offline
    Re: Difficulty locating interrupts w/ CodeOffset and XC8 v1.45 2019/08/12 10:23:56 (permalink)
    +2 (2)
    You're using K42 devices in C and NOT using vectored interrupts? They are so much easier than the legacy mode.
     
    On VIC devices like K42, the vector table is not moved by codeoffset. With vectored interrupts enabled, the vector table is placed at "IVTBASE" which defaults to 0x008. In my code that assumes a bootloader from 0-0x7ff, I set IVTBASE to 0x808 and the vector table is placed at 0x808.
     
    I found that with XC8 1.45 and 2.05 (in C90 mode) using the "legacy" interrupt format
     void high_priority interrupt highisr(void){..}

    that the compiler ignores IVTBASE and places the "vectors" at 0x008 and 0x018
    But by using 2.05 in C99 mode you can specify the base
    Using the new interrupt format introduced in 1.45 you can move the IVT wherever you want.
    void __interrupt(base(0x808), high_priority) highisr(void) {..}

    This places the interrupt jumps at 0x808 and 0x818.
    Make sure to set IVTBASE to the new address.
        IVTLOCK        = 0x55;
        IVTLOCK        = 0xaa;
        IVTLOCKbits.IVTLOCKED = 0x00;    // unlock IVT
        IVTBASE        = 0x808;
        IVTLOCK        = 0x55;
        IVTLOCK        = 0xAA;
        IVTLOCKbits.IVTLOCKED = 0x01;    // lock IVT

    Unfortunately converting legacy code to the C99 format is a bit of work. I do agree that 1.45 and later in C89/C90 mode should allow moving the IVTBASE.
    post edited by mbrowning - 2019/08/12 10:28:08
    #4
    dave94025
    New Member
    • Total Posts : 6
    • Reward points : 0
    • Joined: 2018/05/31 10:57:14
    • Location: 0
    • Status: offline
    Re: Difficulty locating interrupts w/ CodeOffset and XC8 v1.45 2019/08/12 12:08:46 (permalink)
    0
    The issue was simply that I'm modifying an existing 8 bit bootloader that is shared with a bunch of other PIC18F conntrollers (all of which have the former Hi/Lo interrupt scheme), so it's much simpler to conform to that architecture for this particular project.   The vectored interrupt table is a great addition, I'm looking forward to using that on future 8 bit projects without this constraint.
     
    Thanks,
    Dave.
    #5
    mad_c
    Super Member
    • Total Posts : 1234
    • Reward points : 0
    • Joined: 2010/12/12 17:48:27
    • Location: Brisbane, Australia
    • Status: offline
    Re: Difficulty locating interrupts w/ CodeOffset and XC8 v1.45 2019/08/12 19:51:35 (permalink)
    +4 (4)
    dave94025
    I'm looking forward to using that on future 8 bit projects without this constraint.

     
    This Developer Help article explains how codeoffset works with the different devices.
     
    Jeff.
    #6
    dave94025
    New Member
    • Total Posts : 6
    • Reward points : 0
    • Joined: 2018/05/31 10:57:14
    • Location: 0
    • Status: offline
    Re: Difficulty locating interrupts w/ CodeOffset and XC8 v1.45 2019/08/13 07:13:25 (permalink)
    0
    Unfortunately, there isn't a built in way (i.e. with a locating instruction on the interrupt line) to reset the legacy interrupt vector location for a VIC controller if using the legacy interrupt calls.   The assembly directives, however, did the trick.   It's also kind of a pain that the application code is located at the top of memory and works it's way down, rather than the other way around (like it used to).   That made creating a bootable image much smaller (or simpler) than having to move a lot of empty code space or having to sort through the memory image to figure out where there's code and where there's nothing.  Of course if you're parsing a hex file that's simpler but if you're creating a binary image from the hex file it adds a lot of unnecessary bloat.   You can move the upper bound of the image size by defining the ROM range which addresses this, but you have to manage this manually as the program grows over time...
    #7
    mbrowning
    USNA79
    • Total Posts : 1741
    • Reward points : 0
    • Joined: 2005/03/16 14:32:56
    • Location: Melbourne, FL
    • Status: offline
    Re: Difficulty locating interrupts w/ CodeOffset and XC8 v1.45 2019/08/13 09:51:40 (permalink)
    0
    dave94025
    Unfortunately, there isn't a built in way (i.e. with a locating instruction on the interrupt line) to reset the legacy interrupt vector location for a VIC controller if using the legacy interrupt calls.

    It isn't clear to me why you can't just change to the new style interrupt calls which will move the interrupt goto's without inline assembly. You could even set IVTBASE to the new "vector" and save a few cycles of interrupt latency.
     
    If the bootloader needs to use interrupts, it can set IVTBASE back. You have to adapt the bootloader for each processor anyway.
    #8
    dave94025
    New Member
    • Total Posts : 6
    • Reward points : 0
    • Joined: 2018/05/31 10:57:14
    • Location: 0
    • Status: offline
    Re: Difficulty locating interrupts w/ CodeOffset and XC8 v1.45 2019/08/13 10:04:08 (permalink)
    0
    That might well work in some applications, but in my particular application the interrupt vectors in the application are in a table that has a bunch of other stuff in it (application start address, image CRC, image size, etc.) so once you start looking at the changes they get to be quite extensive:
    - change the table scheme,
    - move to IVT based interrupts (only for these controllers),
    - setup interrupts to use the IVT scheme,
    - break out the code that runs on all the controllers into multiple code bases (some with and some without IVT), since in some cases multiple interrupt sources are in a single interrupt "level",
     
    So, it adds up and sure I could do all of that, but adding a couple of lines of assembly to put the vectors where I need them to be is far simpler and also more intuitive (at least for me) when I have to go back and support this later on.
     
    Dave.
    #9
    mbrowning
    USNA79
    • Total Posts : 1741
    • Reward points : 0
    • Joined: 2005/03/16 14:32:56
    • Location: Melbourne, FL
    • Status: offline
    Re: Difficulty locating interrupts w/ CodeOffset and XC8 v1.45 2019/08/13 11:42:30 (permalink)
    +1 (1)
    I certainly understand legacy issues and you've clearly thought out how to effectively mix various processors in the same code environment.
     
    I just want to point out that you don't need to enable IVT to use the new interrupt syntax. It just allows you to include the base() parameter so the GOTO's are moved to the base() specified location (4048 and 4058 for your case) so it would effectively be just like how "codeoffset" works for non-IVT PICs. There would be no code changes beyond that, and you don't need the inline assembly.
     
    A simple "#ifdef IVTBASE" could be used to select between old and new syntax's if you need to keep compatibility with non-IVT devices.
     
    Whether you change interrupt syntax or not, changing IVTBASE to 4048 will just cause the hardware to go to 4048/4058 on interrupt instead of 0008/0018 thus saving a couple cycles of latency. I would think the code has to have some kind of PIC related dependencies to account for all the SFR and CONFIG differences.
    #10
    dave94025
    New Member
    • Total Posts : 6
    • Reward points : 0
    • Joined: 2018/05/31 10:57:14
    • Location: 0
    • Status: offline
    Re: Difficulty locating interrupts w/ CodeOffset and XC8 v1.45 2019/08/13 12:57:18 (permalink)
    0
    Oh, I did try what you're suggesting along the way but the compiler didn't like the base/offset notation with the older interrupt low/high notation.   Perhaps, I could have massaged that some to make it work but I tried to (unsuccessfully) for a while and then simply gave up.
     
    Have you tried using the Hi/Low interrupt notation with the new notation?
     
    Dave.
    #11
    mbrowning
    USNA79
    • Total Posts : 1741
    • Reward points : 0
    • Joined: 2005/03/16 14:32:56
    • Location: Melbourne, FL
    • Status: offline
    Re: Difficulty locating interrupts w/ CodeOffset and XC8 v1.45 2019/08/13 13:17:08 (permalink)
    +2 (2)
    Have you tried using the Hi/Low interrupt notation with the new notation?

    Yes. I really love on this family how little built-in interrupt overhead there is.
    Simple test project
    #pragma config MVECEN = OFF                // Multi-vector disabled for interrupts
    // Lots of other config bits. Lots and lots of them
    #include <xc.h>
    void main(void) {
        INTCON0bits.IPEN = 1;            // enable priorities
        while(1){
            LATA0 = 1;
        }
    }

    void __interrupt(base(0x808), high_priority) highisr(void) {
        if (TMR0IE && TMR0IF) TMR0IF=0;
    }

    void __interrupt(base(0x808), low_priority) lowisr(void) {
        if (TMR1IE && TMR1IF) TMR1IF=0;
    }

    Resulting hex - all other locations are 0xffff
        1,027    0800          EF0E                    GOTO 0x81C                  
        1,028    0802          F004                    NOP                         
        1,029    0804          FFFF                    NOP                         
        1,030    0806          FFFF                    NOP                         
        1,031    0808          EF20                    GOTO 0x840                  
        1,032    080A          F004                    NOP                         
        1,033    080C          FFFF                    NOP                         
        1,034    080E          FFFF                    NOP                         
        1,035    0810          FFFF                    NOP                         
        1,036    0812          FFFF                    NOP                         
        1,037    0814          FFFF                    NOP                         
        1,038    0816          FFFF                    NOP                         
        1,039    0818          EF19                    GOTO 0x832                  
        1,040    081A          F004                    NOP                         
        1,041    081C          EF10                    GOTO 0x820                  
        1,042    081E          F004                    NOP                         
        1,043    0820          0E08                    MOVLW 0x8                   
        1,044    0822          6ED5                    MOVWF 0xFD5, ACCESS         
        1,045    0824          0E08                    MOVLW 0x8                   
        1,046    0826          6ED6                    MOVWF 0xFD6, ACCESS         
        1,047    0828          0E00                    MOVLW 0x0                   
        1,048    082A          6ED7                    MOVWF 0xFD7, ACCESS         
        1,049    082C          0100                    MOVLB 0x0                   
        1,050    082E          EF27                    GOTO 0x84E                  
        1,051    0830          F004                    NOP                         
        1,052    0832          0139                    MOVLB 0x39                  
        1,053    0834          A194                    BTFSS 0x94, 0, BANKED       
        1,054    0836          0011                    RETFIE 1                    
        1,055    0838          A1A4                    BTFSS 0xA4, 0, BANKED       
        1,056    083A          0011                    RETFIE 1                    
        1,057    083C          91A4                    BCF 0xA4, 0, BANKED         
        1,058    083E          0011                    RETFIE 1                    
        1,059    0840          0139                    MOVLB 0x39                  
        1,060    0842          AF93                    BTFSS 0x93, 7, BANKED       
        1,061    0844          0011                    RETFIE 1                    
        1,062    0846          AFA3                    BTFSS 0xA3, 7, BANKED       
        1,063    0848          0011                    RETFIE 1                    
        1,064    084A          9FA3                    BCF 0xA3, 7, BANKED         
        1,065    084C          0011                    RETFIE 1                    
        1,066    084E          013F                    MOVLB 0x3F                  
        1,067    0850          8BD2                    BSF 0xD2, 5, BANKED         
        1,068    0852          81BA                    BSF 0xBA, 0, BANKED         
        1,069    0854          D7FE                    BRA 0x852                   
        1,070    0856          FFFF                    NOP                 

    Without setting IVTBASE, the hardware will start executing at 0x008/0x018 for interrupts.
    #12
    crosland
    Super Member
    • Total Posts : 1936
    • Reward points : 0
    • Joined: 2005/05/10 10:55:05
    • Location: Warks, UK
    • Status: offline
    Re: Difficulty locating interrupts w/ CodeOffset and XC8 v1.45 2020/03/28 04:52:37 (permalink)
    +1 (1)
    This was a great help.
     
    I normally include the config words in the bootloader code. It seems essential that, at the very least,

    #pragma config MVECEN = OFF

    Needs to be included in the application, otherwise XC8 tries to build a vector table.
     
    I had to replicate the whole CONFIG2L/Hh settings in my app to avoid mismatches. 
     
    #13
    crosland
    Super Member
    • Total Posts : 1936
    • Reward points : 0
    • Joined: 2005/05/10 10:55:05
    • Location: Warks, UK
    • Status: offline
    Re: Difficulty locating interrupts w/ CodeOffset and XC8 v1.45 2020/04/05 03:06:17 (permalink)
    0
    mbrowning
    void __interrupt(base(0x808), high_priority) highisr(void) {
        if (TMR0IE && TMR0IF) TMR0IF=0;
    }

    Without setting IVTBASE, the hardware will start executing at 0x008/0x018 for interrupts.



    In XC8 2.10 (maybe earlier) The compiler generates the code to move IVTBASE as part of the C startup.
    #14
    mbrowning
    USNA79
    • Total Posts : 1741
    • Reward points : 0
    • Joined: 2005/03/16 14:32:56
    • Location: Melbourne, FL
    • Status: offline
    Re: Difficulty locating interrupts w/ CodeOffset and XC8 v1.45 2020/04/05 05:10:31 (permalink)
    0
    Thanks. I tried 2.10 a few months ago and had some debugging issues so I went back to 2.05. Guess I missed that improvement.
    #15
    Jump to:
    © 2020 APG vNext Commercial Version 4.5