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.

TMS320F28388D: DriverLib and c++ support

Part Number: TMS320F28388D
Other Parts Discussed in Thread: C2000WARE

Hello everyone,

I lost 2 days while tracking down a mysterious linker error. The linker couldn't find a symbol, but I was 100% sure that the symbol must exist.

Reducing the problem more and more I ended up starting from scratch with the TI-Example Project "empty_bitfield_driverlib" for the TMS320F28388D out of C2000Ware_3_03_00_00.

The "self written"code is as little as this:

#include "f28x_project.h"
#include "driverlib.h"
#include "device.h"

void main(void)
{
    Device_init(); //driverlib function
}

After comparing every Linker and compiler-settings I finally found the difference. In my project, the file containing the main is a .cpp file and in the example, it is a .c file.
So I changed the main of the example to .cpp and got the same linking error. (So it's very easy to reproduce)

Since we want to use cpp, changing the file to a simple c file is not acceptable. I then changed the driverlib.c to a driverlib.cpp and now the linker could find the symbol. (I now have 100+ Warnings about deprecated piece of code inside the driverlib.cpp)

I now ran into similar problems several times. Since c is a subset of cpp ther linker should not run into problems finding the symbols. From c to cpp I understand, that there might be some limitations.

Furthermore I am not able to load the example project onto the TMS320F28388D ControlCard (Rev 1.) I always get the error:

C28xx_CPU1: File Loader: Verification failed: Values at address 0x00000@Program do not match Please verify target memory and memory map.
C28xx_CPU1: GEL: File: C:\Users\marcel.kummer\workspace_v10\empty_bitfield_driverlib_project\CPU1_RAM\empty_bitfield_driverlib_project.out: a data verification error occurred, file load failed.

1) Are there any limitations to using c and cpp at the same time? Since all your libs are in c this would mean cpp is not fully supported.
2) Furthermore, can you please explain, why the linker fails to find the symbol for cpp sources if the used function is written in a c file?
3) Is there any way to get rid of all the warnings generated by the driverlib.cpp? (driverlib.c renamed to .cpp)
4) What do I have to do to successfully load the example project onto the controlCard

PS:
Compiler-Version: TI v20.2.1.LTS
CCS: 10.1.1.00004 

Thanks and regards,

Marcel Kummer.

  • Since c is a subset of cpp ther linker should not run into problems finding the symbols.

    The issue is C .vs. C++ linkage. C++ applies name-mangling to support function overloading which C doesn't. See Language linkage and What is the effect of extern “C” in C++? for some background information.

    For include files for C libraries, such as those from the C2000ware example device/device.h, which have not been written to have extern "C" blocks to allow them to be included from C++, you can wrap the include statement in the the C++ source file. E.g. with the following in a empty_bitfield_driverlib_project/empty_bitfield_driverlib_main.cpp then using C2000Ware_3_03_00_00 and ti-cgt-c2000_20.2.2.LTS the program linked:

    #include "f28x_project.h"
    #include "driverlib.h"
    extern "C" {
    #include "device.h"
    }
    
    void main(void)
    {
        Device_init(); //driverlib function
    }

    Edit: Clarify that it is the the example device/device.h which doesn't have extern "C", rather than the driverlib functions.

  • 3) Is there any way to get rid of all the warnings generated by the driverlib.cpp? (driverlib.c renamed to .cpp)

    The issue is the following in C2000Ware_3_03_00_00_Software/driverlib/f2838x/driverlib/debug.h:

    //*****************************************************************************
    //
    // Prototype for the function that is called when an invalid argument is passed
    // to an API.  This is only used when doing a DEBUG build. It is the
    // application's responsibility to define the __error__ function.
    //
    //*****************************************************************************
    extern void __error__(char *filename, uint32_t line);
    
    //*****************************************************************************
    //
    // The ASSERT macro, which does the actual assertion checking.  Typically, this
    // will be for procedure arguments.
    //
    //*****************************************************************************
    #ifdef DEBUG
    #define ASSERT(expr) do                                                       \
                         {                                                        \
                             if(!(expr))                                          \
                             {                                                    \
                                 __error__(__FILE__, __LINE__);                   \
                             }                                                    \
                         }                                                        \
                         while(0)
    #else
    #define ASSERT(expr)
    #endif

    The issue is that the filename argument in the prototype for the __error__ function is not const-qualified. When the ASSERT macro is used the C++ compiler is reporting a "#2825-D conversion from a string literal to "char *" is deprecated" warning that the C compiler doesn't.

    A string literal is const-qualified, so I think driverlib should be changed so that the __error__ function has a const-qualified filename parameter. I.e.:

    extern void __error__(const char *filename, uint32_t line);

    //*****************************************************************************
    //
    // Error handling function to be called when an ASSERT is violated
    //
    //*****************************************************************************
    void __error__(const char *filename, uint32_t line)
    {
        //
        // An ASSERT condition was evaluated as false. You can use the filename and
        // line parameters to determine what went wrong.
        //
        ESTOP0;
    }

  • Hi Marcel,

    You can try out the solutions provided by Chester.

    Once you get it to compile, you can load it to the Control Card through CCS using a target configuration file.

    Best Regards

    Siddharth

  • Hello,

    thank you, all your info helped me a lot. The example project is working now. I will now try the same with my own project, if I don't come back with another question this week this case can be closed.

    Regards,

    Marcel.