Concerto compiler data/variable sizes

hi,

I'm programming my Concerto controller and I've just stumble across a part that I can't seem to find relevant documentation.

Within my code I'm implementing the same functionality as seen in the RAM_management_m3 and RAM_management_C28 examples.
Basically M3 writes to Shared S0 and C28 writes to Shared S3, and one read where the other is writing. Great, it's working and I can see the data coming and going, but I'm having problems regarding different variables sizes.

On the mentioned examples it is used int for the M3 and long int for C28 which means it's 32 bits for each core.

But what about other variable types? Where can I  find a table showing data types and size in bits for each core?

  • Ronaldo,

    Such a table doesn't exist, but I'll do you one better.

    C99 defines standard integer types which are the same across all platforms.  Using these variables helps to make code portable as they  abstract the differences between the native variables types between different architectures.  Try #include <stdint.h> and using the types defined here.  With standard integer types a uint16_t is the same on both the M3 and C28 core.

    Google stdint for more info

    Regards,

    Trey

  • In reply to Trey German:

    Hi Trey,

    I guess this answers half of my question and it's a nice clever way of doing it, I really like it and I'm learning more everyday as I move along with this project.

    But as you know C28 is a math monster and that's exactly the reason we're using the Concerto, there will be a nice amount of float64 being used across C28 and a few of those will have to be read from and written to C28 via ethernet across the M3 core.

    I found this table on www.arm.com about the M3 core, comparing to a PIC [  http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0234a/index.html section 4.1.5 (Data types and alignment)  ]

    Type

    Cortex-M3

    PIC

    Notes

    char

    8-bit signed

    8-bit signed

    Char is signed by default in both architectures

    short

    16-bit

    16-bit

     

    int

    32-bit

    16-bit

     

    short long

    N/A

    24-bit

     

    long

    32-bit

    32-bit

     

    long long

    64-bit

    N/A

    No 64-bit type for PIC

    float

    32-bit

    32-bit

     

    double

    64-bit

    32-bit

     

    long double

    64-bit

    N/A

     

    further researching shows me on F28M35x_Device.h

    #ifndef DSP28_DATA_TYPES
    #define DSP28_DATA_TYPES
    typedef int int16;
    typedef long int32;
    typedef long long int64;
    typedef unsigned long long Uint64;
    typedef float float32;
    typedef long double float64;
    #endif

    So to finalise my question (and leave it nicely documented on the forum for the future generations):

    Can I use a long double on both cores?
    Do you suggest some other implementation of 64bits float that give the code better portability? (e.g. float64 on the C28 and _something_ on M3).

    thanks.

  • In reply to Ronaldo Pace:

    Ronaldo,

    Ok so I did a little looking around and I was actually able to find you some tables.  The compiler guides (search for spnu151 and spru514 on the ti homepage) are a good resource for information like this.

  • In reply to Trey German:

    hi Trey,

    That is absolutely perfect.

    I'll be using the stdint.h for the integer types (staying away from the 8 bits) and float and long double for the floating point types. That way I'll be able to define a struct M3_send_data, copy its definition from the M3 project, paste it into the C28 project and rename to C28_recv_data and job done, guarantee sync between the two!

    thanks!

  • In reply to Ronaldo Pace:

    hi,

    further developing this project I stumbled across a related issue that I already fixed and I would like to share
    Also if anyone can double check if what I understood of is correct.

    On both cores I have the following structs for the shared ram portion where M3 writes and C28 reads:

    struct eeprom {
    	long double, long double, long double, long double, long double, 
    	uint64_t bit1 :1, uint64_t bit2 :1, uint64_t spare :62;
    };
    
    struct shared{
    	struct eeprom config;
    	long double;
    	uint64_t bit1 :1, uint64_t spare :63;
    };
    
    struct m3_shared_data {
    	struct shared items[MAX_ITEMS];
    };

    that's how I made it work. And in this configuration sizeof(struct eeprom) is 48 bytes

    but if I change the uint64_t to uint16_t and (of course) reduce the spare bits to 14 and 15 bits respectively, on C28 my memory sized will be reduced as expected, but on M3 struct eeprom will still use the 48 bytes instead of the expected 42 bytes. I also tested with uint32_t and the results still the same.

    As far as I understood this is happening because of note 2 on the corner of  Table 5-1 of the M3 page.
    "In TIARM9 ABI mode, 64bits data is aligned on a 32-bit boundary. In EABI mode, 64-bit data is aligned on a 64-bit boundary"

    Which means, the Concerto is EABI mode and the long double on the struct shared must align to 64-bit boundary of data. And the same issue would be visible if struct shared was using uint32 (or16) as the next long double on the array of struct shared would have to align to the next 64-bit.

    Is that it ???

  • In reply to Ronaldo Pace:

    Ronaldo, you are absolutely correct.

    Trey