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.

[参考译文] TMS320F28027:编译器在结构中添加空白地址

Guru**** 2522770 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1340722/tms320f28027-compiler-adding-blank-address-in-a-struct

器件型号:TMS320F28027

您好!

该问题只会在结构中使用 unsigned long 并且只在结构大小大于特定 threashold 的情况下出现(9?)  

测试过的编译器

16.9.10 LTS
20.2.5 LTS

示例:

在工作代码中、outside Var 的地址为: 0x00008306
这是正确的、因为先前的变量 W3具有地址:0x00008305    

在有错误的代码中、outside Var 的地址为: 0x00008320
这是不正确的、因为先前的变量 W10具有地址:0x0000831E
因此、compier 让0x0000831F 留空。 然而、你可以在变量"all"中看到这个地址、所以这个运行状态可能会成为 memcopy 例程的危险

代码工作正常

typedef union _TMP
{
    struct
    {
        union
        {
            struct
            {
                unsigned short w0;
                unsigned short w1;
                unsigned short w2;
                unsigned short w3;
            } EXPANDED;
            struct
            {
                unsigned long w0_w1;
                unsigned short w2_w3[2];
            } COMPRESSED;
            unsigned short all[4];
        } SUBSYSTEM;
        unsigned short outsideVar;
    }expand;
    unsigned short all[5];
} TMP;

带错误的代码:

typedef union _TMP
{
    struct
    {
        union
        {
            struct
            {
                unsigned short w0;
                unsigned short w1;
                unsigned short w2;
                unsigned short w3;
                unsigned short w4;
                unsigned short w5;
                unsigned short w6;
                unsigned short w7;
                unsigned short w8;
                unsigned short w9;
                unsigned short w10;
            } EXPANDED;
            struct
            {
                unsigned long w0_w1;
                unsigned short w2_w18[9];
            } COMPRESSED;
            unsigned short all[11];
        } SUBSYSTEM;
        unsigned short outsideVar;
    }expand;
    unsigned short all[12];
} TMP;

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Nicola、

    为了说明这一点、两个编译代码的功能是否相同? 我很好奇为什么第一个情况会是好的,考虑到 outside Var 和所有[4]都指向完全相同的地址,而在编译的代码中,有一个"错误",它们不会重叠。 这是否有意为之? 您如何 使用此结构定义变量/其字段? 我很难理解这个问题、因为我不明白这个结构是如何被使用的(即、 是否所有字段都应该指向同一个数组/变量地址?)。 请提供一些有关如何使用该结构的示例代码。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Omer、这是一个正在运行的示例。 我不使用此结构、它只是为了测试而写的、

    typedef union _TMP
    {
        struct
        {
            union
            {
                struct
                {
                    unsigned short w0;
                    unsigned short w1;
                    unsigned short w2;
                    unsigned short w3;
                    unsigned short w4;
                    unsigned short w5;
                    unsigned short w6;
                    unsigned short w7;
                    unsigned short w8;
                    unsigned short w9;
                    unsigned short w10;
                } EXPANDED;
                struct
                {
                    unsigned long w0_w1;
                    unsigned short w2_w10[9];
                } COMPRESSED;
                unsigned short all[11];
            } SUBSYSTEM;
            unsigned short outsideVar;
        }expand;
        unsigned short all[12];
    } TMP;
    
    TMP test;
    
    while (1)
    {
        test.expand.SUBSYSTEM.EXPANDED.w0 = 0;
        test.expand.SUBSYSTEM.EXPANDED.w1 = 1;
        test.expand.SUBSYSTEM.EXPANDED.w2 = 2;
        test.expand.SUBSYSTEM.EXPANDED.w3 = 3;
        test.expand.SUBSYSTEM.EXPANDED.w4 = 4;
        test.expand.SUBSYSTEM.EXPANDED.w5 = 5;
        test.expand.SUBSYSTEM.EXPANDED.w6 = 6;
        test.expand.SUBSYSTEM.EXPANDED.w7 = 7;
        test.expand.SUBSYSTEM.EXPANDED.w8 = 8;
        test.expand.SUBSYSTEM.EXPANDED.w9 = 9;
        test.expand.SUBSYSTEM.EXPANDED.w10 = 10;
        test.expand.outsideVar = 11;
    }

    请注意、如果我更改

    unsigned long w0_w1; 

    unsigned short w0_w1[2];

    一切都很好

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗨 dev123 - Omer、

    数组和长整型值有一些奇怪。 C2000编译器指南优化-C 提供了提示、默认情况下、字节为16位、看起来 W0_W1[2]实际上是32位长。 超长在 C lib 数组中表现不佳。数据通常具有随机中断。 不久前报告了类似的行为、因为存储是位次序、所以使用数组将32位转换为函数。 假设测试代码中使用数组的嵌套结构也是如此。  

     /cfs-file/__key/communityserver-discussions-components-files/171/TI_2D00_C2000-Optimizing-C_2C00_C_2B002B00_-Compilers-spru514y.pdf

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    编译器按设计工作。  有关所涉及概念的一般介绍、请参阅 此常见问题解答 (不是来自 TI)。   

    以下是一些与 C2000架构相关的事实。

    • 每个地址对应于一个16位字、而不是一个8位字节
    • 该类型 宽度为32位、必须在2字边界上对齐
    • 该类型 短接 16位宽、且不需要对齐

    此结构...

                struct
                {
                    unsigned long w0_w1;
                    unsigned short w2_w18[9];
                } COMPRESSED;

    ...包含一个 。  因此、它必须与2字边界对齐、并且必须包含偶数个字。  此结构中成员的总大小为11个字。  因此、一个填充字被添加到末尾、总长度为12个字。  这种对齐和填充要求会传播出去、并导致结构成员 外侧 Var 始终位于偶数地址。

    如果我更改

    全屏
    1
    无符号长整型 W0_W1
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    全屏
    1
    unsigned short W0_W1[2]
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    一切都很好

    [/报价]

    因为您删除了 ,则不需要填充和对齐。

    谢谢。此致、

    -乔治