cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
maps-mpls
Mentor
Mentor
211 Views
Registered: ‎06-20-2017

Putting time critical functions in TCM on R5 from Vendor (Xilinx) library

Jump to solution

Solved:  See @prsullivan 's solution and my additional findings after that.

Background:  I have an application where I need to keep interrupt latency and variance as low as possible for an infrequent interrupt.  Perfect application for the R5 processor, right?

So I am moved my time critical interrupt handler (text) and time critical (data and bss) to TCMB region in the linker script.  That is, I put my interrupt handler and time critical globals in my baremetal r5 application in custom tcmb_bss, tcmb_data, and tcmb_text sections I created in the linker script, and selectively move data and code to those sections in the .c source with arm __attribute(...) directives.

It all seems to be work.

However, the XScuGic_InterruptHandler pre-compiled in libxil.a gets loaded in the normal .text section, currently mapped to DDR. The R5 application is too big to fit everything in the .tcmb_text section--or to put it another way, the application is too big to put the .text section into the TCMB region.

Consequently, until first interrupt has longer latency than subsequent interrupts, as Xilinx's is XScuGic_InterruptHandler located in the library to the standard .text section.

The way I have it now, with my stuff in TCMB, and Xilinx's in DDR, subsequent interrupts are pretty fast and fairly consistent so long as the XScuGic_InterruptHandler doesn't get flushed from cache.

So the question is:  How do we force the XScuGic_InterruptHandler from libxil.a into TCMB? The TCMB is not large enough to hold the entire .text section for this application.

Do I need to edit the vendor provided xscugic.h or .c files? That doesn't seem to be ideal long term, as I try to keep fairly current with new Xilinx releases, and that is one more opportunity to forget to modify when upgrading. 

Is  there a modification I can make to the makefile to force one function from libxil.a to be relocated at compile time to my custom .tcmb_text section?  A linker command line argument for example?  Or would that theoretically cause problems with relative addressing?

I would prefer to not lock down the XScuGic_InterruptHandler in cache--especially since I have room to spare in the TCMB regions, and use the cache for other purposes. I'd rather have XScuGic_InterruptHandler in TCMB.

As it is, I get fast and low latency interrupts for all interrupts so long as I don't throw the first interrupt latency into the analysis, and so long as cache doesn't get flushed.

*** Destination: Rapid design and development cycles *** Unappreciated answers get deleted, unappreciative OPs get put on ignored list ***
0 Kudos
1 Solution

Accepted Solutions
prsullivan
Visitor
Visitor
142 Views
Registered: ‎12-13-2018

I had to do a very similar thing with my project. XScuGic_InterruptHandler is in port.c correct? If so you can locate the the text section of a source file from the precompiled library with your linker file. In your case I think you would need something like this in your tcmb_text section: 

SECTIONS
{
  .tcmb_text: {
    *port.o(.text)
  } > psu_r5_tcm_b_ram_addr
}

 

View solution in original post

2 Replies
prsullivan
Visitor
Visitor
143 Views
Registered: ‎12-13-2018

I had to do a very similar thing with my project. XScuGic_InterruptHandler is in port.c correct? If so you can locate the the text section of a source file from the precompiled library with your linker file. In your case I think you would need something like this in your tcmb_text section: 

SECTIONS
{
  .tcmb_text: {
    *port.o(.text)
  } > psu_r5_tcm_b_ram_addr
}

 

View solution in original post

maps-mpls
Mentor
Mentor
110 Views
Registered: ‎06-20-2017

Thank you @prsullivan , that was the clue I needed. 

Some other points for others who may come across this esoteric thread:

 

1.  UG1085 implies that .text should go in tcma (not tcmb as I indicated) and .data and .bss in tcmb.  I am not sure if the TCM is split via Harvard addressing (e.g., tcma for instruction, tcmb for data), or if there were a penalty for putting .text in tcmb, or data/bss in tcma, but out of an abundance of caution and frankly getting things working, I used tcma for vectors and code, tcmb for data and stack.

maps-mpls_0-1618267664621.png

 

2.  If you attempt to remap a standard section, such as .text from from xscugic_intr.o, you have to do it in the linker script before the .text section in the linker script, or the standard .text section will have already sucked it up :

  
/* ... */
MEMORY
{
   psu_ocm_ram_0_MEM_0     : ORIGIN = 0xFFFC0000, LENGTH = 0x40000
   psu_qspi_linear_0_MEM_0 : ORIGIN = 0xC0000000, LENGTH = 0x20000000
   psu_r5_0_atcm_MEM_0     : ORIGIN = 0x0,        LENGTH = 0x10000 /* time critical code */
   psu_r5_0_btcm_MEM_0     : ORIGIN = 0x20000,    LENGTH = 0x0C800 /* time critical data */
   psu_r5_0_btcm_MEM_1     : ORIGIN = 0x21000,    LENGTH = 0x03800 /* stack              */
   psu_r5_0_ddr_MEM_0      : ORIGIN = 0x70000000, LENGTH = 0x07000000
   r5_0_reserved_DDR       : ORIGIN = 0x77000000, LENGTH = 0x100000
}
/* Specify the default entry point to the program */
ENTRY(_boot)
/* Define the sections, and where they are mapped in memory */
SECTIONS
{
   .vectors : {
     KEEP (*(.vectors))
     *(.boot)
   } > psu_r5_0_atcm_MEM_0
   .tcma_text : {
     *(tcma_text)
     *xscugic_intr.o(.text) /* must occur before .text below */
   } > psu_r5_0_atcm_MEM_0
   .tcmb_data : {
    *(tcmb_data)
    *xscugic_intr.o(.data) /* must occur before .data below */
   } > psu_r5_0_btcm_MEM_0
  .tcmb_bss (NOLOAD) : {
    . = ALIGN(4);
    __bss_start__ = .;
    *(tcmb_bss)
    *xscugic_intr.o(.bss) /* must occur before .bss below */
    . = ALIGN(4);
   __bss_end__ = .;
  } > psu_r5_0_btcm_MEM_0
  .text : { /* .tcmb_text above before .text here */
    *(.text)
    *(.text.*)
    *(.gnu.linkonce.t.*)
    *(.plt)
    *(.gnu_warning)
    *(.gcc_execpt_table)
    *(.glue_7)
    *(.glue_7t)
    *(.vfp11_veneer)
    *(.ARM.extab)
    *(.gnu.linkonce.armextab.*)
  } >   psu_r5_0_ddr_MEM_0
/* ... */

 

*** Destination: Rapid design and development cycles *** Unappreciated answers get deleted, unappreciative OPs get put on ignored list ***
0 Kudos