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

Author
dabraham
New Member
  • Total Posts : 17
  • 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

9 Replies Related Threads

    al_bin
    Super Member
    • Total Posts : 112
    • Reward points : 0
    • Joined: 2011/02/11 06:28:47
    • Location: 0
    • Status: offline
    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 : 17
    • 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 : 112
    • Reward points : 0
    • Joined: 2011/02/11 06:28:47
    • Location: 0
    • Status: offline
    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 : 17
    • 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 : 4184
    • 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 : 4184
    • 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 : 17
    • 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 : 17
    • 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 : 17
    • 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
    Jump to:
    © 2017 APG vNext Commercial Version 4.5