This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MCU-PLUS-SDK-AM243X: overwriting sdk-functions with own implementation not working correctly

Part Number: MCU-PLUS-SDK-AM243X

Tool/software:

Hello,

we use the MCU PLUS SDK 09.02, since the industrial comms SDK also uses this one. the current industrial comms sdk version we use is 09.02.00.15.

in a thread with the help of George, I did find out how to "overwrite" sdk.functions with our own implementations: https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1383392/mcu-plus-sdk-am243x-not-stripping-symbol-x-because-it-is-named-in-a-relocation/5313715?tisearch=e2e-sitesearch&keymatch=%2525252525252520user%252525252525253A453845#5313715

This worked pretty fine all the time. SO in general we did overwrite the abort-handlers with our own implementation. This worked by providing the implementation AND the sdk-files (copied) additionally in our application-build. When linking the sdk, in this case the freertos-library of the sdk, our abort-handlers were used. The thing is that our implementation will call c++-code and thus is placed inside a .cpp-file (surrounded with extern "C").

It looks like this in the sdk:


and like this in our folder:

where the "TIAbortImplTIFREERTOS.cpp" contains the copied code of the HwiP_armv7r_handlers_freertos.c-file. (with the extern "C" around and calls to C++-code).

The section .text.hwi is placed in the TCMA like this:

    GROUP
    {
        .text.hwi: palign(8)
    } > MCU1_0_TCMA

As already said that worked pretty fine. But we noticed as soon as we directly link the freeRtos-library in the linker-script like this:

     GROUP 
    {
        .code:
        {
            -l "freertos.am243x.r5f.ti-arm-clang.debug.lib"(.text),
        }
    } > MCU1_0_SRAM_DATA 

the whole .text.hwi-section is also moved there and is NOT placed in the TCMA and our whole abort-handler implementations are not present. It uses the one from the freertos-library. That's also noticable in the map-file.

we tried it like this:

    GROUP
    {
        .text.hwi:
        {
            *(.text.hwi),
        } palign(8)
    } > MCU1_0_TCMA

but that's also not working.

It only seems to work if we place it explicitly like this:

    GROUP
    {
        .text.hwi:
        {
            -l "libti-implementation-mcu1_0.a"(.text.hwi),
        } palign(8)
    } > MCU1_0_TCMA

We made sure that the freertos.am243x.r5f.ti-arm-clang.debug.lib is linked at last in our linking-order.

What's the explanation for this behaviour and is there a way around to prevent explicitly linking the library again in the linker-script? The point is that the whole package which also includes the sdk and our implementations is used by multiple projects and we do not want to modify every linker-script in every project if the freertos-library is placed somewhere explicitly. We also try to minimize the modification of the sdk-files and instead provide our own implementations in the package.

Best regards

Felix

  • Hi Felix,

    Which library file includes your implementation? Is it freertos.am243x.r5f.ti-arm-clang.debug.lib or libti-implementation-mcu1_0.a?

    If your implementation of code is in libti-implementation-mcu1_0.a file, put the complete lib in TCMA as you are doing for .text.hwi.

    Regards,

    Tushar

  • Hi Tushar,

    yes, our implementation is inside libti-implementation-mcu1_0.a. There are also more parts inside which may not be placed inside the tcma, that's why we were referrencing only the .text.hwi-section.

    But this is just a workaround for us. The problem is that our own implementations will be dropped out if we reference the .text-section of the freertos.am243x.r5f.ti-arm-clang.debug.lib, but not explicilty our library inside the linker-script. It seems to include all subsections, such as .text.hwi of the freertos.am243x.r5f.ti-arm-clang.debug.lib as well and thus the abort-handler implementations. And if we do not explicitly link the libti-implementation-mcu1_0.a inside the linker-script, our implementations will not be used at all by the linker.

    I mean technically I may understand what the linker does here but my question is if we somehow can prevent to additionally explicitly link libti-implementation-mcu1_0.a in the linker-script? because it is linked with the linker-command already and we do not get any info about that our implementation got dropped.
    This linker-behaviour is really error-prone because this will silently drop our implementations in case we did overwrite any implementation of the sdk. e.g. if we would place the drivers-lib of the sdk somewhere but we did some modifications to the drivers with our own implementations outside of the sdk. Then those will also be dropped (without any warning or message) if not referenced again explicitly in the linker-script. This could break our whole firmware.

    And just again to make that clear: the overwriting works fine if we do not explicilty reference the freertos.am243x.r5f.ti-arm-clang.debug.lib in the linker-script.
    And also to make it again more understandable: our goal is to provide a platform for multiple projects, so the user just uses a whole package which includes the sdk as well as our implementations which may override some stuff of the sdk. The user is not and should not be aware of the overriding of the sdk-implementation, since he/she just wants to use the package and rely on its functionality. A explicit placement of an sdk-library somewhere in memory should not lead to the behaviour that it will simply drop our overriding implementations. It should simply place the .text.hwi-section where the user defines the place for the .text.hwi-section, no matter if a library's .text-section is placed somewhere else. I mean we could totally live with the *(.text.hwi)-solution if it would work, but it doesn't. We still need to explicitly link the override-containing library.

    Is there a possibility to achieve this?

    I tried to understand the clang-linker of TI a bit more following the online-documentation: https://software-dl.ti.com/codegen/docs/tiarmclang/rel4_0_2_LTS/compiler_manual/linker_description/05_linker_command_files/accessing-files-and-libraries-from-a-linker-command-file-spnu1185422.html

    and the special subsection-handling here (https://software-dl.ti.com/codegen/docs/tiarmclang/rel4_0_2_LTS/compiler_manual/intro_to_object_modules/how-the-assembler-handles-sections-stdz0693935-add.html#subsections) states:
    "By default, when the linker sees a SECTION directive in the linker command file like “.text”, it gathers .text and all subsections of .text into one large output section named “.text”. You can instead use the SECTION directive to control the subsection independently. See SECTIONS Directive Syntax for an example."

    I understand this. So what the linker does makes totally sense in the default case . But the second sentence says that I can use exactly this SECTION directive to control the subsections independently.

    If we look here (https://software-dl.ti.com/codegen/docs/tiarmclang/rel4_0_2_LTS/compiler_manual/linker_description/05_linker_command_files/the-sections-directive-stdz0759595.html#specifying-input-sections):
    "The specification *(.text) means the unallocated .text sections from all input files."

    I guess the subsections are already allocated from the freertos.am243x.r5f.ti-arm-clang.debug.lib? The *(.text.hwi) would not take them into account, right? But why? My guess is, that a mentioned library has a higher "priority" for the linker and the subsections will be automatically included there. And only afterwards all other .text.hwi-sections outside of the library would be linked where the .text.hwi-input-section is placed.

    There are also other chapters for including libraries but they do not cover the case how the subsections are handled if there is a wildcard-reference to the same subsection-name outside the mentioned library.

    So is there a possibility to somehow tell the linker to not use the subsections with the same name of a library if it is already mentioned somewhere else in the linker-script? Or is there any other solution to achieve this without accidentially removing all of our overridng implementations?

  • I've brought this thread to the attention of the compiler experts for further analysis.

  • Please understand that I am unable to test the suggestions I make in this thread.  

    Whenever the linker sees a library specified, on the command line or in a command file, it uses files from that library to resolves references to symbols that, at that point in the link, are unresolved.  Therefore, naming a library in a linker command file tends to confuse things, and should be avoided.

    Please see this part of the online documentation to learn about --reread_libraries and --priority.  The typical way to control the order over multiple libraries is to use --priority, and specify the libraries on the command line, in the required order.

    Is this practical?

    Thanks and regards,

    -George

  • Hey George,

    thanks for the hint. It clarifies the situation a bit and yes, we use the --reread_libs-option indeed. Just to get it right: The linker uses the libraries in the command line. If there are undefined symbols referenced and the linker finds them in the library, they will get resolved. Then it will process the linker-command-file (?). and if there are still unresolved symbols, it will read the libraries again with the --reread_libs-option. I understand that mentioning a library in the command-file can confuse things, but sometimes it's needed to place code in faster memory-parts, especially when working with those arm-cores with tcm and internal SRAM as well as external RAM. So we can reduce it but never avoid it completely.

    Is there also an order of processing inside the linker-command-file? The point here is that the abort-handlers and irq-service-routines are referenced in the vector-table, which only gets placed inside the linker-command-file into the 0x00000000-address. The vector-table is also part of our library, which is mentioned first in the link-order. And the vector-table is placed in the copied files of the sdk like that (the symbols are mentioned on the right side, "HwiP_data_abort_handler" and so on):

    I checked our link-command and the library containing our implementations is linked first and thus also the vector-table which references our abort-handler-implementations.  The freertos-library with the sdk-implementations of the vector-table and abort-handlers is linked last.
    So I would've expected that the *(.text.hwi), which occurs first in the linker-command-file, so before the mentioned freertos-library, which also contains the same symbols, will reference them there and put them into tcma. But instead I need to explicitly mention our library.
    That's the point I didn't understand. Because the symbols and the vector-table are already there and were presented to the linker, before the freertos-library. Removing the freertos-library from the linker-command-file will use our implementations again.

    So it seems a library in the linker-command-file has a higher-priority. Or I do not really understand at which stage in the linking-order the command-file is used.

    Best regards

    Felix

  • Hello,

    Please note that due to some vacations/holidays, it may be a few days to get a response.

    Thank you

    ki

  • I think most of the confusion comes from trying to solve these different questions all at once.

    1. What library is used to resolve a call to function?
    2. How to allocate a function from a library into special memory?

    It is better to solve these separately.  

    To solve #1 ... Stop using --reread_libs and use --priority instead.  Then specify the libraries on the command line in the required order.  

    To solve #2 ...  I think TIAbortImplTIFREERTOS.cpp is a file you implement. It eventually becomes an object file in a custom library.  It defines an input section named .text.hwi.  Change the name of this input section to something else, like .text.custom_hwi.  Do that with code similar to ...

    __attribute__((section(".text.custom_hwi")))

    This means you need code in a linker command file to allocate .text.custom_hwi.  I understand you do not want to change existing linker command files.  Instead of that, supply yet another linker command file with lines similar to ...

    SECTIONS
    {
        .text.custom_hwi > MCU1_0_TCMA, palign(8)
    }

    This additional linker command file presumes some other linker command file defines a memory range named MCU1_0_TCMA.  Note specifying multiple SECTIONS directives in different files is supported.

    Thanks and regards,

    -George

  • thanks for the answer George,

    we will try the second option first and will do the first option in the long-run, since our project grew really big and the --reread_libs solved the issues we faced. And you know how long short-term solutions last in some projects...

    Until I have tried it one questions for better understanding:
    why does the *(.text.hwi)-input-section not take the .text.hwi of our already linked library or somehow drops them as soon as it encounters the freertos-library and why does explicitly linking our library libti-implementation-mcu1_0.a like

    .text.hwi:
            {
                -l "libti-implementation-mcu1_0.a"(.text.hwi),
            } palign(8)

    work again? I would've assumed the * is capturing libti-implementation-mcu1_0.a and thus working the same as the * in this case. I guess it has something to do with the "-l"?

    best regards

    Felix

  • why does the *(.text.hwi)-input-section not take the .text.hwi of our already linked library or somehow drops them as soon as it encounters the freertos-library

    To be certain, I need to see more details about the link.  But I'm confident this ...

    Whenever the linker sees a library specified, on the command line or in a command file, it uses files from that library to resolves references to symbols that, at that point in the link, are unresolved.

    ... explains it.

    Thanks and regards,

    -George