Overriding linker location for a single IDF routine?

go4retro
Posts: 18
Joined: Thu Jan 10, 2019 5:36 am

Overriding linker location for a single IDF routine?

Postby go4retro » Fri Jan 18, 2019 4:24 am

For performance reasons, I need to ensure gpio_set_level runs from IRAM, not flash. But, when I do this:

[mapping]
archive: libdriver.a
entries:
driver:gpio_set_level (noflash)

and add the requisite item in component.mk:

OMPONENT_ADD_LDFRAGMENTS += linker.lf

I get the following error:

ERROR: Duplicate definition of fragment 'libdriver_a' found in [...]components\app_trace\linker.lf and [..]\main\linker.lf.

I read over the pages describing this build system component, and I don't see an example where the developer wants to move a single function out.

Is there a solution to this problem, short of deleting something from the IDF?

Jim

Ritesh
Posts: 1383
Joined: Tue Sep 06, 2016 9:37 am
Location: India
Contact:

Re: Overriding linker location for a single IDF routine?

Postby Ritesh » Fri Jan 18, 2019 6:03 pm

go4retro wrote:
Fri Jan 18, 2019 4:24 am
For performance reasons, I need to ensure gpio_set_level runs from IRAM, not flash. But, when I do this:

[mapping]
archive: libdriver.a
entries:
driver:gpio_set_level (noflash)

and add the requisite item in component.mk:

OMPONENT_ADD_LDFRAGMENTS += linker.lf

I get the following error:

ERROR: Duplicate definition of fragment 'libdriver_a' found in [...]components\app_trace\linker.lf and [..]\main\linker.lf.

I read over the pages describing this build system component, and I don't see an example where the developer wants to move a single function out.

Is there a solution to this problem, short of deleting something from the IDF?

Jim
Hi,

Did you try with IRAM_ATTR section for your function? i believe it should be done with that if you want to put specific function into IRAM section for that. you don't need to change LD Script for that.

Hope I understood correctly which you want to do still let me correct if anything wrong for that.
Regards,
Ritesh Prajapati

go4retro
Posts: 18
Joined: Thu Jan 10, 2019 5:36 am

Re: Overriding linker location for a single IDF routine?

Postby go4retro » Fri Jan 18, 2019 6:19 pm

I did. All of my developed functions are marked as IRAM_ATTR. But, my functions use the ESP_IDF function gpio_set_level, which I did not write, and it is not marked as IRAM. So, I am trying to use the linker fragment capability to move it out of flash and into IRAM.

If I can't do this, my initial project attempt is unfortunately completed and unsuccessful, as I had a hard latency timeout of 10uS, and currently, my IRAM_ATTR ISR is taking > 20uS to start and use gpio_set_level to acknowledge the event. And, yes, I can resolve the issue by adding some more hardware, either as a second uC that is not running an OS, or as some discrete TTL or a CPLD. But, that will drive up complexity.

Jim

Ritesh
Posts: 1383
Joined: Tue Sep 06, 2016 9:37 am
Location: India
Contact:

Re: Overriding linker location for a single IDF routine?

Postby Ritesh » Fri Jan 18, 2019 7:25 pm

go4retro wrote:
Fri Jan 18, 2019 6:19 pm
I did. All of my developed functions are marked as IRAM_ATTR. But, my functions use the ESP_IDF function gpio_set_level, which I did not write, and it is not marked as IRAM. So, I am trying to use the linker fragment capability to move it out of flash and into IRAM.

If I can't do this, my initial project attempt is unfortunately completed and unsuccessful, as I had a hard latency timeout of 10uS, and currently, my IRAM_ATTR ISR is taking > 20uS to start and use gpio_set_level to acknowledge the event. And, yes, I can resolve the issue by adding some more hardware, either as a second uC that is not running an OS, or as some discrete TTL or a CPLD. But, that will drive up complexity.

Jim
ok. then you need to put driver file into common ld script like below.
.iram0.text :
{
/* Code marked as runnning out of IRAM */
_iram_text_start = ABSOLUTE(.);
*(.iram1 .iram1.*)
*libfreertos.a:(.literal .text .literal.* .text.*)
*libesp32.a:panic.o(.literal .text .literal.* .text.*)
*libesp32.a:core_dump.o(.literal .text .literal.* .text.*)
*libphy.a:(.literal .text .literal.* .text.*)
*librtc.a:(.literal .text .literal.* .text.*)
*libhal.a:(.literal .text .literal.* .text.*)
*libcoexist.a:(.literal .text .literal.* .text.*)
/* libpp */
*libpp.a:esf_buf.o(.literal .text .literal.* .text.*)
*libpp.a:if_hwctrl.o(.literal .text .literal.* .text.*)
*libpp.a:lmac.o(.literal .text .literal.* .text.*)
*libpp.a:pm.o(.literal .text .literal.* .text.*)
*libpp.a:pm_for_bcn_only_mode.o(.literal .text .literal.* .text.*)
*libpp.a:pp.o(.literal .text .literal.* .text.*)
*libpp.a:rate_control.o(.literal .text .literal.* .text.*)
*libpp.a:trc.o(.literal .text .literal.* .text.*)
*libpp.a:wdev.o(.literal .text .literal.* .text.*)
_iram_text_end = ABSOLUTE(.);
} > iram0_0_seg
so, you can put perticular driver file into IRAM as well as per requirement.

/components/esp32/ld/esp32.common.ld

Let me know if need exact syntax for that like how to include any file into IRAM section
Regards,
Ritesh Prajapati

go4retro
Posts: 18
Joined: Thu Jan 10, 2019 5:36 am

Re: Overriding linker location for a single IDF routine?

Postby go4retro » Sat Jan 19, 2019 3:54 am

I hate to impose, but I am scared to make the changes to the common files. I see in the file mentioned this section:

Code: Select all

  .iram0.text :
  {
    /* Code marked as runnning out of IRAM */
    _iram_text_start = ABSOLUTE(.);

    mapping[iram0_text]
    
    INCLUDE esp32.spiram.rom-functions-iram.ld
    _iram_text_end = ABSOLUTE(.);
    _iram_end = ABSOLUTE(.);
  } > iram0_0_seg

  ASSERT(((_iram_text_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)),
          "IRAM0 segment data does not fit.")
but, it does not match your copy in any way.

I then looked at the spiram.rom-functions-iram.ld to add it there, but those all look like object file references, not a libdriver.a reference. So, yes, some more guidance would be helpful.

Jim

Ritesh
Posts: 1383
Joined: Tue Sep 06, 2016 9:37 am
Location: India
Contact:

Re: Overriding linker location for a single IDF routine?

Postby Ritesh » Sat Jan 19, 2019 9:03 am

go4retro wrote:
Sat Jan 19, 2019 3:54 am
I hate to impose, but I am scared to make the changes to the common files. I see in the file mentioned this section:

Code: Select all

  .iram0.text :
  {
    /* Code marked as runnning out of IRAM */
    _iram_text_start = ABSOLUTE(.);

    mapping[iram0_text]
    
    INCLUDE esp32.spiram.rom-functions-iram.ld
    _iram_text_end = ABSOLUTE(.);
    _iram_end = ABSOLUTE(.);
  } > iram0_0_seg

  ASSERT(((_iram_text_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)),
          "IRAM0 segment data does not fit.")
but, it does not match your copy in any way.

I then looked at the spiram.rom-functions-iram.ld to add it there, but those all look like object file references, not a libdriver.a reference. So, yes, some more guidance would be helpful.

Jim
Why you are worried to do changes into common ld script? We have already do everything for UART driver to put into IRAM section and works fine without any issue.

So, I suggest to do that change first and check that it is working or not.
Regards,
Ritesh Prajapati

go4retro
Posts: 18
Joined: Thu Jan 10, 2019 5:36 am

Re: Overriding linker location for a single IDF routine?

Postby go4retro » Sat Jan 19, 2019 7:52 pm

I'm not worried to do it, I'm worried to do it wrong, and so I am asking for the specifics. I tried to "patch" my common ld using your example, but mine does not look anything like yours and so I am lost.

For now, I am more than willing to do it. Long term, doing this means I probably will need to have multiple copies of esp-idf in my toolchain, as not all projects will need or want the code in IRAM.

But for now, I am happy to make the changes, just don't know specifically how and it seems better to state that and get specific help rather than try something and have it not work, and make the problem worse.

Jim

Ritesh
Posts: 1383
Joined: Tue Sep 06, 2016 9:37 am
Location: India
Contact:

Re: Overriding linker location for a single IDF routine?

Postby Ritesh » Sun Jan 20, 2019 8:31 am

go4retro wrote:
Sat Jan 19, 2019 7:52 pm
I'm not worried to do it, I'm worried to do it wrong, and so I am asking for the specifics. I tried to "patch" my common ld using your example, but mine does not look anything like yours and so I am lost.

For now, I am more than willing to do it. Long term, doing this means I probably will need to have multiple copies of esp-idf in my toolchain, as not all projects will need or want the code in IRAM.

But for now, I am happy to make the changes, just don't know specifically how and it seems better to state that and get specific help rather than try something and have it not work, and make the problem worse.

Jim
Ok. Do changes into common linker script by your own way and let me know if you still need help for that. Also Espressif SDK Engineer can help you in case need help into details specific for IDF related changes.
Regards,
Ritesh Prajapati

go4retro
Posts: 18
Joined: Thu Jan 10, 2019 5:36 am

Re: Overriding linker location for a single IDF routine?

Postby go4retro » Sun Jan 20, 2019 8:35 pm

I think you misunderstand. I don't know how to do it, and I was looking for some more help. I don't seem to have a esp32.common.ld (mine is called esp32.common.ld.in, and mine does not look like yours, so I was afraid to patch it because I can't find anything similar in my copy.

But, I took a stab anyway. I changed these lines in common.ld.in:

Code: Select all

  .iram0.text :
  {
    /* Code marked as runnning out of IRAM */
    _iram_text_start = ABSOLUTE(.);

    *libdriver.a:gpio_set_level.o(.literal .text .literal.* .text.*)

    mapping[iram0_text]
    
    INCLUDE esp32.spiram.rom-functions-iram.ld
    _iram_text_end = ABSOLUTE(.);
    _iram_end = ABSOLUTE(.);
  } > iram0_0_seg
Using your notation. I recompiled and reflashed, but the situation did not improve. I assume I did not do this correctly. What should I change?

Jim

Ritesh
Posts: 1383
Joined: Tue Sep 06, 2016 9:37 am
Location: India
Contact:

Re: Overriding linker location for a single IDF routine?

Postby Ritesh » Mon Jan 21, 2019 4:49 am

go4retro wrote:
Sun Jan 20, 2019 8:35 pm
I think you misunderstand. I don't know how to do it, and I was looking for some more help. I don't seem to have a esp32.common.ld (mine is called esp32.common.ld.in, and mine does not look like yours, so I was afraid to patch it because I can't find anything similar in my copy.

But, I took a stab anyway. I changed these lines in common.ld.in:

Code: Select all

  .iram0.text :
  {
    /* Code marked as runnning out of IRAM */
    _iram_text_start = ABSOLUTE(.);

    *libdriver.a:gpio_set_level.o(.literal .text .literal.* .text.*)

    mapping[iram0_text]
    
    INCLUDE esp32.spiram.rom-functions-iram.ld
    _iram_text_end = ABSOLUTE(.);
    _iram_end = ABSOLUTE(.);
  } > iram0_0_seg
Using your notation. I recompiled and reflashed, but the situation did not improve. I assume I did not do this correctly. What should I change?

Jim
Hi,

Ok. Would you please provide below details regarding your build details?

1) ESP32 IDF version
2) ESP32 board which you are using including GPIO details
Regards,
Ritesh Prajapati

Who is online

Users browsing this forum: Bing [Bot], ESP_Sprite and 210 guests