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.

Pre Defined Symbols to build ONLY cla.obj

Part Number: TMS320F28379D
Other Parts Discussed in Thread: C2000WARE

Tool/software:

Hello!

I am working on a multicore project, and I utilize the CLA on CPU 2 Subsystem. The way I have structured my project is basically as follows:

- core1 (main.c)

- core2 (main.c, cla.cla, cla.h - bridges core and cla)

- lib/ (bunch of c and h files) - this is a linked folder for both core1 and core2 projects

- mem.h

(Using CCS v12 and C2000Ware 5.04.00)

Basically, lib implements a LOT of my functionality and is meant to be used by either core, and the CLAs. I support variations by using preprocessor directives to check if symbols such as CPU1/CPU2/CLA and FLASH/RAM are defined - to basically alter definitions at compile time. Similarly - mem.h basically aliases the names for the different message RAMs using the same concept. This approach has worked very well for me- as I can alter project properties in CCSv12 to get everything to compile from pretty much the same source (lib).

I am running into issues extending this functionality to the parts of the code that are going to be run on the CLA. I basically want to set a predefined symbol for when JUST CLA.CLA is being compiled into an .obj file. For example,

I would like to alias the CPU-CLA message RAM addresses in mem.h based on whether a symbol called CLA/CPU1/CPU2 is defined or not - to create .obj files for the CPU and CLA which are then linked to the .out file. (call it cla_read buffer when being compiled with CLA, and cpu_write_buffer for cpu)

Another use case could be to check for the CLA symbol and use the CLAMAth library in some cases - else use alternative functions that work on CPUs.

I have gone through the CLA SW development guide, multicore development guide. Optimizing Compiler guides and have a question - Is there a way for me to set a symbol definition for JUST the compilation of the CLA code. If the CPU and CLA share some common source (mem.h) is it possible to get 2 .objs (compiled with CPU and CLA symbol respectively) that are then linked to the remainder of the executable). 

I realize that the shared source is much easier to across cores since the build and link are seperate for each subsytem. Is there a clean way to achieve something similar for the CLA?

  • A lot of the content in lib/ is fairly repititive stuff such as gpio read/write, epwm modifiers, that can be used from C28x and the CLA. Surely there is support for reusing the same source?

  • Hi Prakhar, 

    It should be seamless to have the same code ve used across the CLA/C28. 

    https://software-dl.ti.com/C2000/docs/cla_software_dev_guide/_static/pdf/C2000_CLA_Software_Development_Guide.pdf 

    See this document for the case where the same code can be made to run on either core using predefined symbols

    /cfs-file/__key/communityserver-discussions-components-files/171/CLAProjectStructureUG.pdf

    Let me know if this answers your quesiton

    Regards,

    Ozino

  • Something that I am still not sure about is the compilation of shared files such as solution.c/h from the document you shared.

    When the main.c file is being compiled by C28x compiler - I assume that the the dependencies (lib.c/h) get built into obj files. When the CLA compiler is invoked to compile tasks.cla into an object, does it recompile the dependencies (lib.c/h) with the __TMS320C28XX_CLA__ symbol? Or does it reuse the .objs from the C28 compiler?

    Asking because I followed the recommendations from the document you shared - such that 

    // shared.h header file
    
    #ifndef __TMS320C28XX_CLA__
    // Declare C28 functions
    
    #include "c28_utils.h" //c28 ONLY helpers
    void func1();
    void func2();
    
    # else 
    // Declare CLA funcs
    
    void func1();
    void func2();
    
    #endif


    // shared.c defintion file
    
    
    # include "shared.h"
    #ifndef __TMS320C28XX_CLA__
    // Declare C28 functions
    
    void func1() {
     // do something
     }
    void func2(){
     // do something
     }
    # else 
    // Declare CLA funcs
    void func1() {
     // do something else
     }
    void func2(){
     // do something else
     }
    
    #endif



    But I still get the warning 

    Invalid to call C28 function "func1" defined in "./shared.obj" from CLA file "./cpu2_cla.obj"

    I have used some source analysis tools and ensured that shared.h is ONLY included in the .cla file and not in the C28 CPU main file. 

  • Hi,

    You do not need to have to define the function twice. You would only need to have its definition one and have the function called where appropriate.

    I would recommend you take a look at our CLA supported reference design https://dev.ti.com/tirex/explore/node?node=A__AMlfQ8j5xnIEkwEg-43-8A__digital_power_c2000ware_sdk_software_package__5C6SEVO__LATEST&placeholder=true

    Pay attention to the function CLLLC_runISR1() it is called in both main.c and clatasks.cla. However, based on the value of the #define CLLLC_ISR1_RUNNING_ON it will enable/disable the code associated with the respective core.

    This way only one instance of the function is referenced in either case.

    Regards,

    Ozino

  • Hi Ozino.


    Thanks for the reply. I went through the code for the linked project and it seems like there is a misunderstanding.

    The project you shared appears to be using 1 definition of an ISR and uses preprocessor directives to toggle where it is being executed (CPU or CLA). 

    In my case - I would like to alter the definition of the shared function based on whether it is being invoked by the CLA tasks, or the C28x core. Ideally, this would include differences in function signatures as well (therefore 2 different declarations in the header file on my previous comment).

    If you can answer the following questions - I think we will have resolved the misunderstanding

    1. Are dependencies (includes) scanned independently by the c28 and CLA compiler. AKA - can I expect two passes of the same source file if it is included in both the CLA and C28 code?
    2. As such - can I manipulate the compilers to generate 2 distinct .obj files for the source (given that one is compiled with __TMS320C28XX_CLA__ defined by the CLA compiler, and the other without the symbol by C28 compiler). Do I need to rename symbols in the alternate definition (I vaguely recall the CLA compiler prepending "cla" to all used symbol names)
    3. This would imply that it should be possible for me to invoke "the same" function from C28 and the CLA and achieve differing behavior. Is this possible?
  • Hi Prakhar,

    Thanks for the detailed explanation. What you've proposed should be feasible as long as the function definitions are defined such that they are applicable for respective core that is being targeted.

    Are dependencies (includes) scanned independently by the c28 and CLA compiler. AKA - can I expect two passes of the same source file if it is included in both the CLA and C28 code?

    As long as you use the necessary guards, C28x vs CLA, you should be able to keep two different definitions of the same function. THough I would think that would be possible.

    As such - can I manipulate the compilers to generate 2 distinct .obj files for the source (given that one is compiled with __TMS320C28XX_CLA__ defined by the CLA compiler, and the other without the symbol by C28 compiler). Do I need to rename symbols in the alternate definition (I vaguely recall the CLA compiler prepending "cla" to all used symbol names)

    Are you trying to generate separate output files (e.g. main1.out, main2.out)? Or are you looking for separate main.obj files for each core? I'm not sure that would be possible without renaming the main.c file or saving the generated object files between builds.

    This would imply that it should be possible for me to invoke "the same" function from C28 and the CLA and achieve differing behavior. Is this possible?

    my understanding is that this NOT be for the same build correct? I assume 1 option is the function running on the C28x and the other on the CLA?

    Regards,

    Ozino

  • Thanks for the reply.

    Are you trying to generate separate output files (e.g. main1.out, main2.out)? Or are you looking for separate main.obj files for each core? I'm not sure that would be possible without renaming the main.c file or saving the generated object files between builds.

    I am not running into issues between the 2 cores. If I understand correctly - each CPU subsystem has an .out file which is the relevant .objs linked together as per the linker script. If I wanted to use the same source file, in both the CPU and CLA on the same subsystem - and I had used the appropriate preprocessor directives to manipulate the definitions - is it possible for the same code - to be compiled by the different compilers (with different predefines) to generate distinct .objs - one for the C28 and the other for the CLA - which is then linked to the relevant calls made by CPUx_main.obj and cla_tasks.obj respectively?

    But I still get the warning 

    Invalid to call C28 function "func1" defined in "./shared.obj" from CLA file "./cpu2_cla.ob

    I assume that the error message I receive (mentioned in a previous reply) is generated because the shared.h file is compiled by the C28 compiler, and then the same .obj is being reused by the CLA.

    The only reason I am trying to achieve this behavior - is to manage my source code effectively. I am attempting to port some Motor Control code from the C28 to the CLA. I would like the code to be in the same file for future maintainability.

  • I am not running into issues between the 2 cores. If I understand correctly - each CPU subsystem has an .out file which is the relevant .objs linked together as per the linker script. If I wanted to use the same source file, in both the CPU and CLA on the same subsystem - and I had used the appropriate preprocessor directives to manipulate the definitions - is it possible for the same code - to be compiled by the different compilers (with different predefines) to generate distinct .objs - one for the C28 and the other for the CLA - which is then linked to the relevant calls made by CPUx_main.obj and cla_tasks.obj respectively?

    In theory, yes, it should be possible to modify the project such that you are able to generate two distinct outputs with their unique objs based on the targeted cores. I would recommend taking advantage of the build configuration option. This will allow you to specify predefine symbols unique to each build (e.g. C28, CLA) and this would generate the .bin, .objs in different directories. It would have similar setup to our FLASH vs RAM build configs. You can use that as a starting template

    I assume that the error message I receive (mentioned in a previous reply) is generated because the shared.h file is compiled by the C28 compiler, and then the same .obj is being reused by the CLA.

    The only reason I am trying to achieve this behavior - is to manage my source code effectively. I am attempting to port some Motor Control code from the C28 to the CLA. I would like the code to be in the same file for future maintainability.

    I would assume so. You'll have to make sure the necessary guards are in place within the file if you are trying to use the same file for both the C28 and CLA builds. This should work out for you. 

    Check out our porting guide and workshop on how you could go about enabling the CLA

    https://software-dl.ti.com/C2000/docs/cla_software_dev_guide/getting_started.html#workshops

    Regards,

    Ozino