Hot!Can the interrupt table be placed in RAM with the PIC32MM series?

Page: 12 > Showing page 1 of 2
Author
dabraham
New Member
  • Total Posts : 27
  • Reward points : 0
  • Joined: 2017/11/29 13:12:50
  • Location: 0
  • Status: offline
2017/12/03 03:58:27 (permalink)
0

Can the interrupt table be placed in RAM with the PIC32MM series?

Has anyone been successful at getting full code running in RAM including interrupts and the vectors? I want to do this because the NVR clear page takes way too long – 15ish mS. If I can run the entire program in RAM, then this time will not affect my code according to the ds. I have seen bits on the forum, but nothing concrete.
 
from the ds;
 
Performing an RTSP operation while executing (fetching) instructions from Program Flash Memory causes the CPU to stall (wait) until the programming operation is finished. The CPU will not execute any instruction, or respond to interrupts, during this time. If any interrupts occur during the programming cycle, they remain pending until the cycle completes.
If performing an RTSP operation while executing (fetching) instructions from RAM memory, the CPU can continue to execute instructions and respond to interrupts during the programming operation. Any executable code scheduled to execute during the RTSP operation must be placed in RAM memory; this includes the relevant interrupt vector and the Interrupt Service Routine (ISR) instructions.
 
Doug
#1

29 Replies Related Threads

    al_bin
    Super Member
    • Total Posts : 159
    • Reward points : 0
    • Joined: 2011/02/11 06:28:47
    • Location: 0
    • Status: online
    Re: Can the interrupt table be placed in RAM with the PIC32MM series? 2017/12/03 05:05:04 (permalink)
    0
    http://ww1.microchip.com/downloads/en/DeviceDoc/61113E.pdf:
    "The Reset state of bits 31-12 of the Ebase register initialize the

    exception base register to 0x80000000."
     
    Albert
    #2
    dabraham
    New Member
    • Total Posts : 27
    • Reward points : 0
    • Joined: 2017/11/29 13:12:50
    • Location: 0
    • Status: offline
    Re: Can the interrupt table be placed in RAM with the PIC32MM series? 2017/12/03 08:57:35 (permalink)
    0
    ok,
    so if I set BEV to 0 then the fetch will be from ram right and I can use the default address setting?
     
    How then does one get the c complier/linker to put the table at the default address? I see I could use ramfunc for the c code functions I have. Do I have to do this manually?
     
    Doug
     
    For example:
    __attribute__((ramfunc,section(".ramfunc"),far,unique_section))
    unsigned int myramfunct (void_
    { /* code */ }
    #3
    al_bin
    Super Member
    • Total Posts : 159
    • Reward points : 0
    • Joined: 2011/02/11 06:28:47
    • Location: 0
    • Status: online
    Re: Can the interrupt table be placed in RAM with the PIC32MM series? 2017/12/03 09:43:13 (permalink)
    0
    C startup code change Ebase from default to linker defined value.
    You can revert this, can't you? Or change linker value in ld script
    Don't change BEV.
     
    Albert
    post edited by al_bin - 2017/12/03 09:52:13
    #4
    dabraham
    New Member
    • Total Posts : 27
    • Reward points : 0
    • Joined: 2017/11/29 13:12:50
    • Location: 0
    • Status: offline
    Re: Can the interrupt table be placed in RAM with the PIC32MM series? 2017/12/03 14:34:09 (permalink)
    0
    I am new to this and I fully do not understand what you mean. From the doc it looks like bev needs to be zero in order to use the new address value, but it has to be 1 in order to write a new value.
    I have never done a linker script, so this is new too. Would I use the memory and section commands? What other commands might I have to use?
     
    Thx Doug
     
    2.12.12 Ebase Register (CP0 Register 15, Select 1)
    The Ebase register is a read/write register containing the base address of the exception vectors
    used when the BEV bit (Status<22>) equals ‘0’,
    #5
    aschen0866
    Super Member
    • Total Posts : 4356
    • Reward points : 0
    • Joined: 2006/01/08 22:18:32
    • Location: San Diego
    • Status: offline
    Re: Can the interrupt table be placed in RAM with the PIC32MM series? 2017/12/03 14:52:32 (permalink)
    0
    BEV has nothing to do with what you want to achieve. 
     
    I think it would be much easier if you are willing to use the Single Vector mode, so that you can place a small ISR in the RAM. Using PIC32MX795F512L Timer 3 as an example:

    #define __ISR_SINGLE_AT_VECTOR__
    void __attribute__((interrupt, __ramfunc__)) GeneralIntHandler(void)
    {
    if (IFS0bits.T3IF)
    {
    ...
    IFS0CLR = _IFS0_T3IF_MASK;
    }
    }

    Take the default linker script for PIC32MX795F512L and add it to the project. First change you want to make is set ebase to a new value, for example,

    _ebase_address = 0xA0010000;

    Find .app_excpt output section in the linker script, change it to

    .app_excpt _GEN_EXCPT_ADDR :
    {
    KEEP(*(.gen_handler))
    } AT > exception_mem

    Remove everything from .vector_0 to .vector_63. These are about all you need to create a custom linker script from the default.
    Now, go to Project Properties->xc32-ld, under "Additional driver options", add "-mno-default-isr-vectors", which tells the linker not to use the default ISR.
    Build your project and check the map file to make sure the ISR is at the right place.
    #6
    aschen0866
    Super Member
    • Total Posts : 4356
    • Reward points : 0
    • Joined: 2006/01/08 22:18:32
    • Location: San Diego
    • Status: offline
    Re: Can the interrupt table be placed in RAM with the PIC32MM series? 2017/12/03 14:56:15 (permalink)
    0
    Your map file should show something like:

     
    .app_excpt 0xa0010180 0x10 load address 0x9fc01000
    *(.gen_handler)
    .gen_handler 0xa0010180 0x10 c:/program files (x86)/microchip/xc32/v1.44/bin/bin/../../lib/gcc/pic32mx/4.8.3/../../../../pic32mx/lib/./proc/32MX795F512L/crt0_mips32r2.o

    Note - The Virtual Memory Address is 0xa0010180 and the Load Memory Address is 0x9fc01000.
     
    #7
    dabraham
    New Member
    • Total Posts : 27
    • Reward points : 0
    • Joined: 2017/11/29 13:12:50
    • Location: 0
    • Status: offline
    Re: Can the interrupt table be placed in RAM with the PIC32MM series? 2017/12/03 15:17:16 (permalink)
    0
    ok, I will try making an example project like this. thanks.
     
    Doug
    #8
    dabraham
    New Member
    • Total Posts : 27
    • Reward points : 0
    • Joined: 2017/11/29 13:12:50
    • Location: 0
    • Status: offline
    Re: Can the interrupt table be placed in RAM with the PIC32MM series? 2017/12/05 04:21:06 (permalink)
    0
    I am working on understanding the ld file. This will take some time with me playing around with it. On the _ebase_address, did you mean 0xa0001000?
     
    Also, I have no exception_mem defined in the ld file. Would I also define that at 0xa0001000 in the memory section?
     
    I also have to change the spacing with the single vector right, and the location is at vector 0?
     
    Doug
    #9
    dabraham
    New Member
    • Total Posts : 27
    • Reward points : 0
    • Joined: 2017/11/29 13:12:50
    • Location: 0
    • Status: offline
    Re: Can the interrupt table be placed in RAM with the PIC32MM series? 2017/12/06 16:56:33 (permalink)
    0
    I changed the code for single interrupt - it took me a while to get it to call correctly due to the extra shadow needed. I can relocate the interrupt in code memory and it works, but I am unable to get the syntax correct for data memory. I cannot find how to make the interrupt a ramfunc. I am hoping this is the relocation truncation problem.
     
    Any help would be appreciated.
    Doug
     
    I get this error when I try to build
    build/default/production/main.o: In function `__vector_dispatch_8':
    c:/users/dabraham/desktop/pic32/lowpwr/lowpwr.x/main.c:(.vector_8+0x0): relocation truncated to fit: R_MICROMIPS_26_S1 against `_CHANGE_NOTICE_A'
    collect2.exe: error: ld returned 255 exit status
    nbproject/Makefile-default.mk:139: recipe for target 'dist/default/production/LOWPWR.X.production.hex' failed
     
    I cannot figure out how to add __ramfunc__ and get it to compile
     
    void __ISR_SINGLE_AT_VECTOR__ __attribute__ ((vector(_CHANGE_NOTICE_A_VECTOR), interrupt(IPL7SRS))) _CHANGE_NOTICE_A(void)
    {
    ....
    }
     
    I changed the linker script
    /* PROVIDE(_ebase_address = 0x9D000000); */
    PROVIDE(_ebase_address = 0xA0001000);
     
    unchanged memory map for reference
    MEMORY
    {
      kseg0_program_mem     (rx)  : ORIGIN = 0x9D000000, LENGTH = 0x8000
      debug_exec_mem              : ORIGIN = 0x9FC00490, LENGTH = 0x760
      kseg0_boot_mem              : ORIGIN = 0x9FC00490, LENGTH = 0x0
      kseg1_boot_mem              : ORIGIN = 0xBFC00000, LENGTH = 0x490
      config_BFC01744             : ORIGIN = 0xBFC01744, LENGTH = 0x4
      config_BFC01748             : ORIGIN = 0xBFC01748, LENGTH = 0x4
      config_BFC0174C             : ORIGIN = 0xBFC0174C, LENGTH = 0x4
      config_BFC01750             : ORIGIN = 0xBFC01750, LENGTH = 0x4
      config_BFC01754             : ORIGIN = 0xBFC01754, LENGTH = 0x4
      config_BFC01758             : ORIGIN = 0xBFC01758, LENGTH = 0x4
      config_BFC01760             : ORIGIN = 0xBFC01760, LENGTH = 0x4
      config_BFC017C4             : ORIGIN = 0xBFC017C4, LENGTH = 0x4
      config_BFC017C8             : ORIGIN = 0xBFC017C8, LENGTH = 0x4
      config_BFC017CC             : ORIGIN = 0xBFC017CC, LENGTH = 0x4
      config_BFC017D0             : ORIGIN = 0xBFC017D0, LENGTH = 0x4
      config_BFC017D4             : ORIGIN = 0xBFC017D4, LENGTH = 0x4
      config_BFC017D8             : ORIGIN = 0xBFC017D8, LENGTH = 0x4
      config_BFC017E0             : ORIGIN = 0xBFC017E0, LENGTH = 0x4
      kseg0_data_mem       (w!x)  : ORIGIN = 0x80000000, LENGTH = 0x2000
      sfrs                        : ORIGIN = 0xBF800000, LENGTH = 0x100000
      configsfrs_BFC01740         : ORIGIN = 0xBFC01740, LENGTH = 0x1C
      configsfrs_BFC017C0         : ORIGIN = 0xBFC017C0, LENGTH = 0x1C
    }
     
    I changed the linker script from kseg0_program_mem to kseg0_data_mem
      .app_excpt _GEN_EXCPT_ADDR :
      {
        KEEP(*(.gen_handler))
      } > kseg0_data_mem
     .vector_0 _ebase_address + 0x200 + ((_vector_spacing << 3) * 0) :
      {
         KEEP(*(.vector_0))
      } > kseg0_data_mem
     
     
     
     
     
     
    #10
    dabraham
    New Member
    • Total Posts : 27
    • Reward points : 0
    • Joined: 2017/11/29 13:12:50
    • Location: 0
    • Status: offline
    Re: Can the interrupt table be placed in RAM with the PIC32MM series? 2017/12/16 09:47:55 (permalink)
    0
    I need help in getting the syntax correct for making my interrupt a ramfunc. I have tried many things without success. I need the IPL7SRS to meet the system timing.
     
    void __ISR_SINGLE_AT_VECTOR__ __attribute__ ((vector(_CHANGE_NOTICE_A_VECTOR), interrupt(IPL7SRS))) _CHANGE_NOTICE_A(void)
    {
    ......
    }
     
    Doug
    #11
    picmadness
    Starting Member
    • Total Posts : 48
    • Reward points : 0
    • Joined: 2017/01/01 18:46:27
    • Location: 0
    • Status: offline
    Re: Can the interrupt table be placed in RAM with the PIC32MM series? 2017/12/16 21:35:51 (permalink)
    0
    Um why did you not use the ramfunc attribute for the ISR?
    #12
    dabraham
    New Member
    • Total Posts : 27
    • Reward points : 0
    • Joined: 2017/11/29 13:12:50
    • Location: 0
    • Status: offline
    Re: Can the interrupt table be placed in RAM with the PIC32MM series? 2017/12/17 05:36:30 (permalink)
    0
    If I try to add the __ramfunc__ then I get an error.
     
    Doug
    #13
    dabraham
    New Member
    • Total Posts : 27
    • Reward points : 0
    • Joined: 2017/11/29 13:12:50
    • Location: 0
    • Status: offline
    Re: Can the interrupt table be placed in RAM with the PIC32MM series? 2017/12/17 08:52:52 (permalink)
    0
    I put together a simple test program to test what I am trying to do. I need the nvm write not to stop interrupts, so the code has to be placed in ram. I also need ipl7srs interrupt for timing. The clock is set low so I can while still meeting the timing in order to reduce power to under 1mA.
     
    I cannot seem to get the syntax correct to put the isr in ram. I also played with the ld file with no luck. Once I can get the isr in ram, the other functions should be easy to convert to ram.
     
    #include <xc.h>
    #include <sys/attribs.h>

    #include <stdio.h>
    #include <stdint.h>
    #include <proc/p32mm0064gpl036.h>

    // FDEVOPT
    #pragma config SOSCHP = OFF // Secondary Oscillator High Power Enable bit->SOSC oprerates in normal power mode.

    // FICD
    #pragma config JTAGEN = OFF // JTAG Enable bit->JTAG is disabled
    #pragma config ICS = PGx3 // ICE/ICD Communication Channel Selection bits->Communicate on PGEC3/PGED3

    // FPOR
    #pragma config BOREN = BOR0 // Brown-out Reset disabled in hardware; SBOREN bit disabled
    #pragma config RETVR = OFF // Retention Voltage Regulator Enable bit->Retention regulator is disabled
    #pragma config LPBOREN = OFF // Low power BOR is disabled

    // FWDT
    #pragma config SWDTPS = PS1048576 // Sleep Mode Watchdog Timer Postscale Selection bits->1:1048576
    #pragma config FWDTWINSZ = PS25_0 // Watchdog Timer Window Size bits->Watchdog timer window size is 25%
    #pragma config WINDIS = OFF // Windowed Watchdog Timer Disable bit->Watchdog timer is in non-window mode
    #pragma config RWDTPS = PS1048576 // Run Mode Watchdog Timer Postscale Selection bits->1:1048576
    #pragma config RCLKSEL = LPRC // Run Mode Watchdog Timer Clock Source Selection bits->Clock source is LPRC (same as for sleep mode)
    #pragma config FWDTEN = OFF // Watchdog Timer Enable bit->WDT is disabled

    // FOSCSEL
    #pragma config FNOSC = FRCDIV // Oscillator Selection bits->Fast RC oscillator (FRC) with divide-by-N
    #pragma config PLLSRC = FRC // System PLL Input Clock Selection bit->FRC oscillator is selected as PLL reference input on device reset
    #pragma config SOSCEN = OFF // Secondary Oscillator Enable bit->Secondary oscillator (SOSC) is disabled
    #pragma config IESO = OFF // Two Speed Startup Enable bit->Two speed startup is disabled
    #pragma config POSCMOD = OFF // Primary Oscillator Selection bit->Primary oscillator is disabled
    #pragma config OSCIOFNC = OFF // System Clock on CLKO Pin Enable bit->OSCO pin operates as a normal I/O
    #pragma config SOSCSEL = OFF // Secondary Oscillator External Clock Enable bit->External clock is connected to SOSCO pin (RA4 and RB4 are controlled by I/O port registers)
    #pragma config FCKSM = CSECMD // Clock Switching and Fail-Safe Clock Monitor Enable bits->Clock switching is enabled; Fail-safe clock monitor is disabled

    // FSEC
    #pragma config CP = OFF // Code Protection Enable bit->Code protection is disabled

    #define UCHAR unsigned char
    #define USHORT uint16_t
    #define ULONG uint32_t
    #define DWORD uint32_t

    int main(void);
    void INTERRUPT_Initialize (void);
    void OSCILLATOR_Initialize(void);
    void TMR1_Initialize (void);
    void NVM_ErasePage(void* address);
    void NVM_WriteWord2(void* address, unsigned int data0, unsigned int data1);
    void NVM_Unlock(unsigned int nvmop);
    void PIN_MANAGER_Initialize(void);

    #define NUMBER_OF_INSTRUCTIONS_IN_PAGE (512*20) //
    #define NVM_OPERATION_WRITE_WORD 0x4002 // enb wr, write 2
    #define NVMERASE 0x4004 // enb wr, erase
    #define NVM_WRERR_LVDERR_MASK 0x3000 // could be wrong
    #define NVM_WRITE_CONTROL_BIT 0x8000 // could be wrong
    #define NVM_WRITE_OR_ERASE_ENABLE_BIT 0x4000 // could be wrong
    #define NVM_NO_OPERATION_MASK 0x000F // could be wrong

    #define NVM_DAT_ADD 0xBD006000 //

    #define NVMKEY1 0xAA996655 //
    #define NVMKEY2 0x556699AA //

    #define CLRLED1 LATACLR=0x0001
    #define SETLED1 LATASET=0x0001
    #define CLRLED2 LATCbits.LATC9=0
    #define SETLED2 LATCbits.LATC9=1

    #define CLRLED3BLU LATAbits.LATA2=0 // set blu led
    #define CLRLED3GRN LATBbits.LATB12=0 // set grn led
    #define CLRLED3RED LATAbits.LATA3=0 // set red led
    #define SETLED3BLU LATAbits.LATA2=1 // set blu led
    #define SETLED3GRN LATBbits.LATB12=1 // set grn led
    #define SETLED3RED LATAbits.LATA3=1 // set red led

    static USHORT Intcnt;
    static UCHAR Toggle;

    static DWORD NVRWD0;
    static DWORD NVRWD1;

    void __ISR_SINGLE_AT_VECTOR__ __attribute__ (( vector(0), interrupt(IPL7SRS))) GeneralIntHandler(void)
    {
        if (Toggle)
            SETLED1;
        else
            CLRLED1;
        
        Toggle=~Toggle;
        Intcnt=Intcnt+1;

        IFS0CLR=0x800;
    }

    // ************************************************************************
    // main code
    // ************************************************************************

    int main(void)
    {
        ULONG i, j;
        
        OSCILLATOR_Initialize();
        TMR1_Initialize();
        PIN_MANAGER_Initialize();
        INTERRUPT_Initialize();
        __builtin_enable_interrupts(); // INTERRUPT_GlobalEnable();
        
        IFS0 = 0;
        Toggle=0;
        
        while(1)
        {
            SETLED3BLU;
            for (i=0;i<0x10000;i++);
            CLRLED3BLU;
            for (i=0;i<0x10000;i++);
            
            if(Intcnt>500)
            {
                Intcnt=0;
                SETLED3BLU;
                NVM_ErasePage((void *)(NVM_DAT_ADD));
                for(i=0;i<8;i+=8)
                {
                    NVRWD0 = 0xDEADFACE;
                    NVRWD1 = 0x0F00BAA0;
                    NVM_WriteWord2((void *)(NVM_DAT_ADD+i),NVRWD0,NVRWD1);
                }
                CLRLED3BLU;
            }
        }
        return 0;
    }

    void NVM_ErasePage(void* address)
    {
        NVMADDR = ((unsigned int) address & 0x1FFFFFFF); /* convert virtual address to physical address and load into NVMADDR register */
        NVM_Unlock (NVMERASE); /* Unlock and Perform the NVM operation */
    }

    void NVM_WriteWord2(void* address, unsigned int data0, unsigned int data1)
    {
        NVMDATA0 = data0;
        NVMDATA1 = data1;
        NVMADDR = ((unsigned int) address & 0x1FFFFFFF); /* convert virtual address to physical address and load into NVMADDR register */
        NVM_Unlock (NVM_OPERATION_WRITE_WORD); /* Unlock and Perform the NVM operation */
    }

    void NVM_Unlock (unsigned int nvmop)
    {
        NVMCONCLR = NVM_NO_OPERATION_MASK; /* clearing error bits before performing an NVM operation */
        NVMCON = (NVM_WRITE_OR_ERASE_ENABLE_BIT | nvmop); /* Enable Flash Write/Erase Operations and Select Flash operation to perform */
        NVMKEY = NVMKEY1;
        NVMKEY = NVMKEY2;
        NVMCONSET = NVM_WRITE_CONTROL_BIT; /* Start the operation using the Set Register */
        while (NVMCON & NVM_WRITE_CONTROL_BIT); /* Wait for operation to complete */
        NVMCONCLR = NVM_WRITE_OR_ERASE_ENABLE_BIT; /* Disable NVM write enable */
    }

    void INTERRUPT_Initialize (void)
    {
        INTCONbits.MVEC = 0; // Enable Single Vector Configuration
        PRISSbits.SS0 = 1; // shadow
        IPC2bits.T1IP = 7; // Priority:
        IPC2bits.T1IS = 0; // Sub Priority:
    }

    void OSCILLATOR_Initialize(void)
    {
        SYSKEY = 0x12345678; // write invalid key to force lock
        SYSKEY = 0xAA996655; // write Key1 to SYSKEY
        SYSKEY = 0x556699AA; // write Key2 to SYSKEY
        OSCTUN = 0x01F; // TUN Center frequency +1.5%;
        OSCCON = 0x02000001; // 2Mhz non pll clock cannot write individual bits
        RNMICON = 0x0; // WDTO disabled; GNMI disabled; CF disabled; WDTS disabled; NMICNT 0; LVD disabled; SWNMI disabled;
        PWRCON = 0x0; // SBOREN disabled; VREGS disabled; RETEN disabled;
        SYSKEY = 0x00000000;
        REFO1CON = 0x0; // ON disabled; DIVSWEN disabled; RSLP disabled; ROSEL SYSCLK; OE disabled; SIDL disabled; RODIV 0;
        REFO1TRIM = 0x0; // ROTRIM 0;
    }

    void TMR1_Initialize (void)
    {
        T1CONbits.ON = 0; // disable Timer, before loading the period/counter value
        PR1 = 2000; // set period
        T1CON = 0xA000; //
        IFS0bits.T1IF = 0; // clear int flag
        IEC0bits.T1IE = 1; // set enable
        T1CONbits.ON = 1; // enable timer
    }

    void PIN_MANAGER_Initialize(void)
    {
    // LED1 RED RA0
    // LED2 RED RC9
    // LED3 BLU RA2
    // LED3 GRN RB12
    // LED RED RA3
    // S1 RB7
    // S2 RB13
    // POT RB3

        ANSELA = 0x0000; // analog select, 1=analog 0= digital
        ANSELB = 0x0000; //
        ANSELC = 0x0000;

        TRISA = 0x0002; // input output, 1=input 0=output
        TRISB = 0x0000; //
        TRISC = 0x0000;

        PORTA = 0x0000; // port value, does not work for read modify write
        PORTB = 0x0000;
        PORTC = 0x0000;

        LATA = 0x0000; // latch value
        LATB = 0x0000;
        LATC = 0x0000;

        ODCA = 0x0002; // open drain setting 1=od 0=normal
        ODCB = 0x0000;
        ODCC = 0x0000;

        CNPUA = 0x0000; // pull up - 1=on
        CNPUB = 0x0000;
        CNPUC = 0x0000;

        CNPDA = 0x0000; // pull down - 1=on, 0=off
        CNPDB = 0x0000;
        CNPDC = 0x0000;

        PORTAbits.RA1=0; // set zero

    #14
    andersm
    Super Member
    • Total Posts : 2485
    • Reward points : 0
    • Joined: 2012/10/07 14:57:44
    • Location: 0
    • Status: online
    Re: Can the interrupt table be placed in RAM with the PIC32MM series? 2017/12/17 10:47:22 (permalink)
    0
    Have you looked at the definition of the __ISR_SINGLE_AT_VECTOR__ macro, because there's a clear contradiction with your other attributes?
    #15
    aschen0866
    Super Member
    • Total Posts : 4356
    • Reward points : 0
    • Joined: 2006/01/08 22:18:32
    • Location: San Diego
    • Status: offline
    Re: Can the interrupt table be placed in RAM with the PIC32MM series? 2017/12/17 13:38:05 (permalink)
    0
    I made some changes to your code as well as the linker script. It seemed to be working in the MPLABX Simulator environment. I'd post the entire project if the forum does not give me "Access Denied" message.
    #16
    dabraham
    New Member
    • Total Posts : 27
    • Reward points : 0
    • Joined: 2017/11/29 13:12:50
    • Location: 0
    • Status: offline
    Re: Can the interrupt table be placed in RAM with the PIC32MM series? 2017/12/17 14:24:23 (permalink)
    0
    Hi,
     
    Thanks for your response. I shall try the code after this post. I checked again the functionality of using the __attribute__  with __ISR_SINGLE_AT_VECTOR__ and it does reduce timing as the code in the interrupt is less when using SRS. I ran three timing tests (below) and looked at the code in the interrupt. One test is as is, one is with IPL7SOFT and one is without the attribute at all (worst timing). To test this, I changed the interrupt source from T1 to change notice on A1 and supplied an external trigger.
     
    I also see that I may have used an incorrect address in the ld file when I tried to move to ram. I notice you used an offset of 0x1000 whereas I used just 0 and that may have caused yet another issue.
     
    __attribute__ (( vector(0), interrupt(IPL7SRS))) GeneralIntHandler(void)
     
    Test                                    Time from interrupt to first instruction execution (clk 2Mhz)
    IPL7SRS                              13.7US
    IPL7SOFT                            15.4US
    NO __attribute__                 20.2 US
     
    Doug
    #17
    dabraham
    New Member
    • Total Posts : 27
    • Reward points : 0
    • Joined: 2017/11/29 13:12:50
    • Location: 0
    • Status: offline
    Re: Can the interrupt table be placed in RAM with the PIC32MM series? 2017/12/17 14:56:45 (permalink)
    0
    ok I am getting somewhere - Thanks for the help.
     
    The code aschen posted works fine and the interrupt is located in memory. Now I need to know how to specify it such that the code in the interrupt is effectively an IPL7SRS interrupt which does not push/pop all regs?
     
    I checked the timing of the interrupt below and the Time from interrupt to first instruction execution (clk 2Mhz) is 24.5 US.
     
    void __attribute__((ramfunc, interrupt(single), at_vector(0), nomips16)) GeneralIntHandler(void)
    {
     
    Doug
    #18
    aschen0866
    Super Member
    • Total Posts : 4356
    • Reward points : 0
    • Joined: 2006/01/08 22:18:32
    • Location: San Diego
    • Status: offline
    Re: Can the interrupt table be placed in RAM with the PIC32MM series? 2017/12/17 18:25:51 (permalink)
    0
    dabraham
     I notice you used an offset of 0x1000 whereas I used just 0 and that may have caused yet another issue.

    The ebase must be at a 4K boundary. Since the chip you use only has 8K of data memory, 0x80001000 seems to be the only choice.
     
    Most of use don't use the Single Vector mode as it has no clear advantage during normal operation. The datasheet, while documenting the PRISS register, says this in the footnote:

    These bits are ignored if the MVEC bit (INTCON<12>) = 0.

    I am guessing it implies you can't use SRS in the Single Vector mode. Perhaps andersm could give you a more solid answer :)
     
     
    #19
    andersm
    Super Member
    • Total Posts : 2485
    • Reward points : 0
    • Joined: 2012/10/07 14:57:44
    • Location: 0
    • Status: online
    Re: Can the interrupt table be placed in RAM with the PIC32MM series? 2017/12/17 22:49:47 (permalink)
    0
    The PRISS.SS0 bit controls shadow set usage for single vector mode.
    #20
    Page: 12 > Showing page 1 of 2
    Jump to:
    © 2018 APG vNext Commercial Version 4.5