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.

[参考译文] 编译器:主动变量删除

Guru**** 2609285 points
Other Parts Discussed in Thread: MOTORWARE

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

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/634757/compiler-aggressive-variable-removal

主题中讨论的其他部件:MOTORWARE

工具/软件:TI C/C++编译器

我遇到了很多问题,编译器优化删除了有用的变量。 我使用TI 16.9 Tm3 LTS C2000编译器。  此时,我让一切都变得不稳定,但即使这样也不总是有效。

我正在寻找一个好的示例。 因此,我可以询问问题是什么:

我有一些SPI通信似乎不起作用:

//! \brief定义串行外设接口(SPI)对象
//!
typedef结构_SPI_Obj_

 UINT16_t     SPICCR;       //!< SPI配置控制寄存器
 UINT16_t     SPICTL;       //!< SPI操作控制寄存器
 UINT16_t     SPIST;        //!< SPI状态寄存器
 UINT16_t     rsvd_1;       //!<保留
 UINT16_t     SPIBRR;       //!< SPI波特率寄存器
 UINT16_t     rsvd_2;//!<       保留
 UINT16_t     SPIEMU;       //!< SPI仿真缓冲寄存器
 UINT16_t     SPIRXBUF;     //!< SPI串行输入缓冲寄存器
 UINT16_t     SPITXBUF;     //!< SPI串行输出缓冲寄存器
 UINT16_t     SPIDAT;       //!< SPI串行数据寄存器
 UINT16_t     SPIFFTX;      //!< SPI FIFO传输寄存器
 UINT16_t     SPIFFRX;      //!< SPI FIFO接收寄存器
 UINT16_t     SPIFFCT;      //!< SPI FIFO控制寄存器
 UINT16_t     rsvd_3[2];    //!<保留
 UINT16_t     SPIPRI;       //!< SPI优先级寄存器
} SPI_Obj;


//! \brief定义串行外设接口(SPI)句柄
//!
typedef结构_SPI_Obj_ volatile *SPI_handle;

我将其更改为:

//! \brief定义串行外设接口(SPI)对象
//!
typedef结构_SPI_Obj_

 UINT16_t     SPICCR;       //!< SPI配置控制寄存器
 UINT16_t     SPICTL;       //!< SPI操作控制寄存器
 UINT16_t     SPIST;        //!< SPI状态寄存器
 UINT16_t     rsvd_1;       //!<保留
 UINT16_t     SPIBRR;       //!< SPI波特率寄存器
 UINT16_t     rsvd_2;//!<       保留
 UINT16_t     SPIEMU;       //!< SPI仿真缓冲寄存器
 volatile uint16_t     SPIRXBUF;     //!< SPI串行输入缓冲寄存器
 volatile uint16_t     SPITXBUF;     //!< SPI串行输出缓冲寄存器
 UINT16_t     SPIDAT;       //!< SPI串行数据寄存器
 UINT16_t     SPIFFTX;      //!< SPI FIFO传输寄存器
 UINT16_t     SPIFFRX;      //!< SPI FIFO接收寄存器
 UINT16_t     SPIFFCT;      //!< SPI FIFO控制寄存器
 UINT16_t     rsvd_3[2];    //!<保留
 UINT16_t     SPIPRI;       //!< SPI优先级寄存器
} SPI_Obj;


//! \brief定义串行外设接口(SPI)句柄
//!
typedef结构_SPI_Obj_ volatile *SPI_handle;

之后一切都正常。

那么,我如何防止编译器删除功能代码。只需使每个变量都具有易失性,或者是否有更好的方法。

谢谢!

注:导致此问题的代码:

 SPI->SPITXBUF =数据;

 SPI->SPITXBUF =数据;

多次写入同一内存位置。  我在硬件I/O,CLA通信和void指针处理方面遇到了这个问题。

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

    evs 说:
    那么如何防止编译器删除功能代码。只需使每个变量都具有易失性,或者是否有更好的方法。

    volatile关键字是这种情况的唯一解决方案。  请在 本文中阅读更多相关信息。  我不知道你需要把它应用到每个变量。  但您可能需要比现在更多地使用。

    谢谢,此致,

    -George

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

    感谢您的回复。

    这是TI提供的代码件(SPI.c Motorware)。 所以我确实假设我不必修改它就能使它正常工作。  我注意到它在版本18中有所改变。

    要找到一 个过于“聪明”的编译器来搜索程序所在的位置,这有点棘手。  SPI硬件是否工作不正常,或者编译器是否 使用了已删除的功能代码。 这 非常耗时。   这时我就有了一种易挥发性的偏执狂!

    我不认为这 是一种优雅的方式。 所以我做了一些错误,或者编译器删除功能代码的方法过于聪明。 所以,请您给我一些关于如何正确使用volatile的详细信息。

    使完整结构变得易失性的正确方法是什么?  或者我是否需要让每个成员都变得不稳定?

    谢谢!

     

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

    此结构旨在用作内存映射外设的接口。  在编译器的“后面”外设中发生了一些事情,因此这是一个教科书示例,说明您可能应该使整个结构变得易失。  执行此操作的最简单方法是:

    typedef volatile结构_SPI_Obj_
    {
    uint16_t. SPICCR; //!< SPI配置控制寄存器
    uint16_t SPICTL; //!< SPI操作控制寄存器
    uint16_t SPIST; //!< SPI状态寄存
    器uint16_t rsvd_1; //!<保留
    uint16_t. SPIBRR; //!< SPI波特率寄存器
    uint16_t rsvd_2; //!<保留
    uint16_t. SPIEMU; //!< SPI仿真缓冲器寄存
    器uint16_t SPIRXBUF; //!< SPI串行输入缓冲器寄存
    器uint16_t SPITXBUF; //!< SPI串行输出缓冲器寄存
    器uint16_t SPIDAT; //!< SPI串行数据寄存
    器uint16_t SPIFFTX; //!< SPI FIFO传输寄存器
    uint16_t SPIFFRX; //!< SPI FIFO接收寄存器
    uint16_t SPIFFCT; //!< SPI FIFO控制寄存器
    uint16_t rsvd_3[2]; //!<保留
    uint16_t. SPIPRI; //!< SPI优先级寄存
    器} SPI_Obj; 

    在标准C代码中,不能将结构声明为易失性结构,但可以将typedef声明为易失性结构。

    如果不能更改typedef,则必须将对象声明为volatile,如下所示:

    易失性SPI_Obj my_object; 
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    有关易失性的更细化信息:
    对于该结构中的每个字段,或者对于任何常规变量,如果该变量可能被程序的“明显”控制流(如中断或外围硬件)以外的其他内容修改, 或者,如果写入该变量可能会执行编译器不知道的操作,则必须声明该字段或变量volatile。 该结构中的所有字段都有可能执行编译器无法“看到”的操作,因此对于该结构,我强烈建议您声明_SPI_Obj_或SPI_Obj类型的任何对象为易失性对象。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    This is a TI provided piece of cod(SPI.c motorware)(这是TI提供的代码(SPI.c))。 所以我确实假设我不必修改它就能正常工作。[/QUOT]

    汽车用品包由不同的团队提供。  我会让他们知道这个论坛主题。

    谢谢,此致,

    -George

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

    感谢考古学家的详细解释。

     裸机编程主要在编译器的范围后面进行。 因此,许多 或多个变量都需要变化无常。 但我现在意识到我正在努力的是如何使结构变得易变。 所以我不能使用结构,但需要为我使用的结构创建一个新的易失类型。

    类似如下的内容:

    结构_CONTROLLER_Data_

     int日期a1;

    int data2;

    };

    typedef结构_controller_Data_ volatile CTRL_Obj;
    typedef CTRL_Obj *CTRL_handl;