1

我正在为处理器编写 SD 卡 SPI 驱动程序。我知道 SPI 驱动程序很好,因为我也将它用于 LCD,并且直到现在,一直在愉快地向卡发送命令。我在处理一项特定交易时遇到了麻烦,这与我所看到的任何其他交易都没有什么不同。

在 SPI 总线上写出数据后,我等待中断回调说接收和发送完成。有两个回调,它们将 a 中的以下布尔标志设置struct为 true:

m_transaction_status.sdts_rx_complete

m_transaction_status.sdts_tx_complete

在正常的程序流程中,我等待这些标志设置后再继续:

while ((m_transaction_status.sdts_rx_complete == false) //
        || (m_transaction_status.sdts_tx_complete == false))
{
    // Check whether we've had an error.
    if (m_transaction_status.sdts_error == true)
    {
        LOG_ERROR(SD::MODULE,
                "transfer_data: Transaction error.");
        transfer_status = false;
        break;
    }
}

对于问题事务,我在回调中设置了一个断点,可以看到两个标志都已设置,但是当我返回正常流程时,变量突然不可用,并且似乎false因为我永远卡在循环中。此循环用于所有其他事务,没有问题。

我有什么理由可以调查为什么这些变量被设置但随后(显然)被清除或解除分配或其他不愉快的事情?

编辑:

中断确实是微型中断(准确地说是瑞萨电子 RL78)。

结构声明是:

/**
 * The state of an SD SPI transaction.
 */
struct SDTransactionStatus
{
    /** Transaction error flag. */
    bool sdts_error;
    /** Transmission completion flag. */
    bool sdts_tx_complete;
    /** Reception completion flag. */
    bool sdts_rx_complete;
};

struct实现为我SD班级的私人成员。标志是通过回调中的简单设置器函数设置的。

4

1 回答 1

1

我不知道你的特定微控制器,也不知道你必须使用的 C++ 编译器,但这不应该改变我要说的任何内容。

我相信问题是,在你的循环中你永远不会改变你的标志的值,你只是读取它们,所以编译器可以自由地优化东西并且只在循环之外读取你的变量(即缓存它们),因为它没有不知道他们可以改变。类似于以下内容:

const bool complete = !m_transaction_status.sdts_rx_complete
                   || !m_transaction_status.sdts_tx_complete;
const bool error = m_transaction_status.sdts_error;
while (complete) {
  if (error) {
    //...
  }
}

你明白为什么这不能给出好的结果。解决方法是告诉编译器您的变量可以“在其背后”更改,并且实际上每次您在代码中访问它们时都需要重新读取它们。

由于您不是多线程或任何东西,您可以通过volatile在您的声明中为您的变量添加一个限定符来做到这一点struct

struct SDTransactionStatus
{
    volatile bool sdts_error;
    volatile bool sdts_tx_complete;
    volatile bool sdts_rx_complete;
};

现在,为什么你没有早点发现这个问题有点神秘,但你必须记住,“编译器可以自由优化”并不意味着它总是必须. 作为一个疯狂的猜测,我会说您使用该循环的其他地方不适合这种优化,而您遇到问题的地方却可以。

当然,我可能对整个事情都错了,但是信息太少,很难说,无论如何,这个优化/易失性问题仍然存在于你的代码中,即使它不是你当前问题的原因,所以你仍然必须修复它,因为即使您当前的问题无关紧要,我所描述的也可能随时发生。

编辑:哦,你可能应该检查你的整个代码库,以确保这不会发生在其他地方。

于 2013-04-26T13:05:53.987 回答