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.

RTOS/PROCESSOR-SDK-AM335X: Linking errors

Part Number: PROCESSOR-SDK-AM335X


Tool/software: TI-RTOS

Guys...

Well, I've blown yet another week spinning my wheels trying to get this eco-system to work.  Of course, it doesn't.

I've pretty much given up getting help on my other thread.  ( e2e.ti.com/.../686579  From a "factory original" sample package, I make one minuscule line change, and the linker fails - No one can explain why)

So, I figured I'd just start from scratch. The target is a simple Beagle Bone Black.  Not that it matters when dealing with linker errors.

I created a new project, added the header files and a few calls from the MMCSD library. Then added it, plus "board" plus "osal" to the CFG file. Then even added "csl" and "I2C"...  And I get hundreds of linker errors. I would expect linker errors due structures and functions which the project needs to supply, so I included them.  And I don't get those. Instead I get linker errors for functions that are supposed to be supplied by the eco-system.  Things like  "SemaphoreP_create",  "HwiP_disable",  "_DebugP_assert", etc....  

(No, I do NOT expect this project to work yet, I expect it only to compile and link... to demonstrate that the eco system can properly include libraries that are completely hidden and out of my control to specify... but it won't even do that. Nor can I figure out where they are supposed to come from)

Comparing the CFG file from the example that I cannot change without the entire project breaking, to the new project which should contain the MMCSD, OSAL, BOARD, I see NOTHING that would cause it to fail to resolve "SemaphoreP_create",  "HwiP_disable",  "_DebugP_assert", etc....  In fact, it's RIGHT IN THERE, on line 13:

var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');

According to THIS thread, all I need to resolve the "SemaphoreP_create" symbol is OSAL and BOARD (Different chip, but the concept should be the same??? ).

Whenever, you link into any LLD driver provided in the RTOS SDK, you will need to link to OSAL and
board library whether you are using any RTOS or running the drivers in bare-metal... 

e2e.ti.com/.../576682

Well, that's not correct.  I did that, and it fails. I have proof.  It's a CCS 7.2 project that is attached.

SimpleMMC.zip

  • The RTOS team have been notified. They will respond here.
  • This was solved by changing the order of the modules in the CFG file...  Which in turn controls the order which they are listed in the auto-generated linker script...

    Moved the "mmcsd" module to AFTER the "csl" and "osal" in the configuration script.

    var socType			= "am335x";
    var osType 			= "tirtos";
    
    /*use CSL package*/
    var Csl = xdc.loadPackage('ti.csl');
    Csl.Settings.deviceType = socType;
    
    
    var Osal = xdc.useModule('ti.osal.Settings');
    Osal.osType = osType;
    Osal.socType = socType;
    
    /* Load the MMCSD package   */
    var Mmcsd = xdc.loadPackage('ti.drv.mmcsd');
    Mmcsd.Settings.enableProfiling = true;

    Now it links.

  • Thanks for confirming that the fix that I provided on the other thread works in this case as well.
  • Rahul Prabhu said:
    Thanks for confirming that the fix that I provided on the other thread works in this case as well.

    Rahul,
    Not so fast...
    On this project, which I tried to make from scratch, the GPIO is call is generating an abort exception...  because I need to call "Board_init()"  Okay...
    Then it's failing to link because it wants "UART_init"  (Why is this required??)
        boardCfg = BOARD_INIT_PINMUX_CONFIG |  BOARD_INIT_MODULE_CLOCK;
        Board_init(boardCfg);

    Even WITHOUT the BOARD_INIT_UART_STDIO flag!

    I added that to the cfg file (in the proper place, now that I understand that) , now it wants "UART_config"...  And I predict it's gonna just keep exploding from there,

    Why all these spaghetti dependencies on things that I am NOT using?

  • Christopher,

    Can you please provide the .cfg file that you are using. I suspect that you have added the following to the syntax but have not provided the SOC configuration for the driver to use:
    var UartPackage = xdc.loadPackage('ti.drv.uart');

    The design of the drivers has been done in such a way that UART driver base functionality if common across all platforms but it needs to get the SOC specific config from the UART_soc.c file

    To include the UART driver with built in default SOC configuration as follows

    /* Load the uart package */
    var socType = "am335x";
    var UartPackage = xdc.loadPackage('ti.drv.uart');
    UartPackage.Settings.socType = socType;

    Other way to do this is to add the UART_soc.c file directly in the project. Adding the UART_soc.c file at application level allows you to customize the interrupt hook up and mode of operation etc. Including the SOC version of the UART driver will include the SOC configuration provided by TI that has been tested with our evaluation platform.

    Regards,
    Rahul

    PS: Interms of why the application still needs the UART driver when linking with board, I suspect when you statically link with board library, the symbols for UART LLD are brought into the object file hence you need to link to all board library dependencies from the app even if you are not using that service. I will try to see if there is some way to prevent the compiler from including that symbol and let you know.
  • Rahul Prabhu said:
    Christopher,

    Can you please provide the .cfg file that you are using. I suspect that you have added the following to the syntax but have not provided the SOC configuration for the driver to use:
    var UartPackage = xdc.loadPackage('ti.drv.uart');

    Rahul,

    For a more comprehensive "compliant" see this one I started yesterday.  It details the problem from scratch.  Which we pretty much know is all related to the order of the libs.

    e2e.ti.com/.../2562363

    As for why the linker wants UART, I understand that part. 

    As a point of reference in Windows:  I write a lot of service code, which does NOT use any graphics.  After the project is build, the linker says it discarded all reference to "GDI" which is a library used for the graphics device.  But the GDI library needs to be included in the linker list.

    The reason it does that is because one other library I use has a function in it which then calls a GDI function.  But I don't use that function.  On the first linker pass, it sees that function, and resolves it to the GDI library.  Then on the next pass it discards that function as not used, and as a result, discards the entire GDI library as well.

    In this GCC world, apparently the "board" is using some UART call, which I assume the linker first thinks it needs, then tosses it.  But since I don't have any visibility into those libraries, I can't predict their dependencies.

    And since the linker is only left to right (as we discussed before) it wants that UART call because board uses it... but why does board use it...?

    I would love to be able to bring in these libraries as separate projects. Just as I did with everything in StarterWare 2.0.1.1.  These are in my workspace, and the course files are not linked to the other folders.

    With this I can now I have debug and release builds, can step into the libs, modify them as needed (I added a few assembler calls to CP15 for some custom needs).  Of course, I know that version of Starterware doesn't work with Sys/Bios due to conflicts.  But I was able to remove some of those conflicts in order to be able to use one of the libs in Sys/Bios.  USB being one of them.

    How can I create identical projects for "board", "csl", "osal", etc  inside my workspace?  I have no idea.  It is amazingly difficult unraveling the makefiles to determine the compiler settings and required source files for each of the libraries.  I've seen this kind of obfuscation before... someone who put it together thinks they are doing something really cool and insightful.  But all they are doing is making it a nightmare for someone else to unravel and support, especially when the structure is not documented, just some simple steps to build it... (by the way, didn't I mention that I can't even build the PDK in my windows 7 machine?  some crash which I never got an answer to. So building it in place with the script isn't an option)

    I did accomplish this with the NDK.  I have my own NDK project inside one of my other workspaces.  I can link to it without having to include those statements in the cfg file. That allows me to debug and add enhancements to it, which I've done to customize it.

    Wish I could do that with the PDK modules... :-( 

    Anyway, I've wandered off the topic LOL.  As the other thread indicates, I have many iterations of CFG files that do NOT work. Here is one of them (But I do have it working in a different CFG file...  uart needs to come AFTER osal ...)  

    7220.app.cfg

    And what is this??  Apparently "profile" needs it.

    Task.addHookSet({
    	registerFxn: '&TaskRegisterId',
    	switchFxn: '&mySwitch',
    });

    I can find nothing that tells me what it is or what it does, or how it's is to be used.  Just some circular definitions  ("addHookSet will add a hookset to the task..."   HUH??  )