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.

[参考译文] MSP432P401R:eUSCI 中断服务不理想/中断

Guru**** 2553420 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/594272/msp432p401r-eusci-interrupt-servicing-suboptimal-broken

器件型号:MSP432P401R

在不同的 eUSCI 部件上、定义了一个 IV (中断向量)、它给出了一个数字代码、表示实际向量的不同中断源中的哪一个已发出、已启用、并且是最高优先级。  这很好。

但是、读取该寄存器具有清除与上述四项相关的 IFG 的副作用  这很糟糕。  让我来展示一下原因...

例如、让我们讨论 eUSCI UART 的传输侧。  根据定义、TXIFG 为1 (有效)表示 TXBUF 为空、另一个字节可以写入 TXBUF 进行传输。  这是非常基础的。  如果 TXIFG 为0、则不应写入 TXBUF。

但现在考虑以下 eUSCI UART 的中断驱动发送代码。

首先是发件人:

ERROR_t GPS_SEND_BLOCK (uint8_t * ptr、uint16_t len){
if (!len ||!ptr)
返回失败;

如果(m_TX_Buf)
返回 EBUSY;

m_TX_len = len;
m_TX_idx = 0;
m_TX_Buf = ptr;
//
*启动时应将 UCTXIFG 置为有效,因此启用 TX 中断
*应导致调用 ISR。
//
//调用 USCI.enableTxIntr ();
BITBAND_peri (EUSCI_A2->IE、EUSCI_A_IE_TXIE_OFS)= 1
返回成功;
}

m_TX_Buf 用于保存指向我们要传输的缓冲区的指针、m_TX_idx 是我们在该缓冲区中的位置(要传输的下一个字节)、而 m_TX_len 是我们要传输的字节数量。

我们使用这样一个事实、即 TXIFG 应该挂起且具有一个空 TXBUF、以便在我们打开中断时立即将我们启动。

这里是中断服务例程。  仅显示 TX 部分。

void EUSCIA2_Handler()@C()@nived()__attribute__((interrupt){
uint8_t data;
uint8_t *buf;

switch (EUSCI_A2->IV){
MSP432U_IV_TXIFG 案例:
if (m_TX_idx >= m_TX_len){
buf = m_TX_Buf;
// USCI.disableTxIntr ();
BITBAND_PERI (EUSCI_A2->IE、EUSCI_A_IE_TXIE_OFS)= 0;
m_TX_Buf =空;
GPS_SEND_BLOCK_DONE (buf、m_TX_len、sucf);
返回;
}
数据= m_TX_Buf[m_TX_idx+];
// Usci.setTxbuf(data);
EUSCI_A2->TXBUF =数据;
返回;
}


现在、在最后一个字节上、我们将中断、m_TX_idx 将为 m_TX_len - 1、我们将最后一个字节填充到 TXBUF 中并从中断返回。  当最后一个字节从 TXBUF 转移到移位寄存器进行传输时、TXIFG 将再次出现、我们将中断。

通过在 switch 语句中读取 IV 寄存器、TXIFG 将被清零。  我们将看到 m_TX_idx >= m_TX_len 并输入终止子句。  我们将禁用 TxInterrupt 并进行标注以指示传输已完成。

但请注意、TXBUF 为空、TXIFG 清零、表示 TXBUF 已满。  这是错误的。  当读取 EUSCI_A2->IV 且 TXIFG 中断具有最高优先级时、清除 TXIFG 会产生副作用、这是直接结果。  如果我们尝试触发另一个 send_block、它将失败、因为当我们打开中断时、TXIFG 会关闭、我们不会进入中断例程来启动新的发送。  TXIFG 永远不会再次出现、因为没有任何东西会使它生效。  我们可以写入 TXBUF、这最终会使事情再次正常工作、但从技术上讲、这是不允许的、因为除非 TXIFG 为1、否则应该写入 TXBUF、表明 TXBUF 为空。

解决方法:

1) 1)将中断例程重新排序为类似的内容:

void EUSCIA2_Handler()@C()@nived()__attribute__((interrupt){
uint8_t data;
uint8_t *buf;

switch (EUSCI_A2->IV){
MSP432U_IV_TXIFG 案例:
数据= m_TX_Buf[m_TX_idx+];
// Usci.setTxbuf(data);
EUSCI_A2->TXBUF =数据;
if (m_TX_idx >= m_TX_len){
buf = m_TX_Buf;
// USCI.disableTxIntr ();
BITBAND_PERI (EUSCI_A2->IE、EUSCI_A_IE_TXIE_OFS)= 0;
m_TX_Buf =空;
GPS_SEND_BLOCK_DONE (buf、m_TX_len、Success);
}
返回;
}


因此、当写入最后一个字节时、我们会检测到这一点并禁用中断。  由于 TXIFG 的中断被禁用、当硬件完成移位寄存器中的字节的发送并将 TXBUF 复制到移位寄存器中时、TXBUF 将变为空、TXIFG 将变为1、并且不会发生中断。  由于不会发生中断、因此不会读取 EUSCI_A2->IV、也不会发生问题。  存在一个有效状态、这意味着 TXBUF 为空并且 TXIFG 被置为有效、这表明了这种情况。

那么、解决这个问题的方法是什么呢?  当我们发出信号完成时、HW 状态为 TXBUF 已满、TXIFG 无效。  信令完成表示当前发送已完成,如果需要,您可以触发另一个发送。  如果立即启动另一个发送、则必须等待发送完成前仍在进行中。  这将是一个字节时间、在低波特率下可能会很重要。

但它可以正常工作、这正是我目前对基于 MSP432的设计所做的工作。

2)将第四条改为"已死亡"的国际金融集团替换为"已死亡"。

在第一个示例中断处理程序中、将 BITBAND_PERI (EUSCI_A2->IFG、EUSCI_A_IFG_TXIFG_OFS)放置为1。  这将使 TXIFG 重新生效。

但是、不清楚这是如何与硬件的其余部分进行交互的。  BITBAND 操作将指示存储器系统对保存 TXIFG 标志的外设寄存器执行原子访问。  但不清楚的是、其余 eUSCI h/w 是如何与该寄存器交互的。  例如、如果一个 RXIFG 需要被置位(或者 STTIFG、START 中断标志)、是否有可能由于与代表 TXIFG 写入的存储器系统置位 IFG 寄存器的交互而丢失这个标志?

换言之、确保不存在硬件竞态条件是有问题的。

总之、使 h/w 中断系统自动清零 TXIFG 标志是有问题的/次优的。  这样做会为导致问题的 h/w 创建一个无效状态。

今后最好不要这样做。

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

    在您的应用中、是否可以在不读取 UCAxIV 的情况下简单检查 TXIFG?
    如果您正在处理 USCI 处理程序中的许多标志、它可能不是高效的、但如果您仅使用 TX 和 RX、则可以考虑使用它吗?

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

    [引用用户="Priya Thanigai]]Hello、

    在您的应用中、是否可以在不读取 UCAxIV 的情况下简单检查 TXIFG?
    如果您正在处理 USCI 处理程序中的许多标志、它可能不是高效的、但如果您仅使用 TX 和 RX、则可以考虑使用它吗?

    -Priya

    [/报价]

    可以了。  我本应该考虑到这一点。  变旧 (sigh)。

    谢谢

    此外、请将我的评论传递给您的系统架构师。  这就是我发布完整的报告的原因。  (我的背景是计算机架构和系统设计)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢您的再次光临! 此反馈非常有用、我会将其传递给我们的内部团队。
    我相信、我们在下一代器件中已经采取了不同的做法。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引述 user="Priya Thanigai">感谢您的回复! 此反馈非常有用、我会将其传递给我们的内部团队。
    我相信、我们在下一代器件中已经采取了不同的做法。

    [/报价]

    如果他们想要进行外部审核、我愿意花时间查看。

    只是一个想法。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    另一项建议可能更好。 置位和清零 UCSWRST 位将有助于恢复最后一个(丢失) TXIFG。
    如果您可以在禁用 TXIE 时置位 UCSWRST、并在重新启用前将其清零、则第一个 TXIFG 应再次置位。
    从 TRM 的22.3-1节中、

    eUSCI_A 通过硬复位或设置 UCSWRST 位来复位。 硬复位后、UCSWRST 位自动置位、使 eUSCI_A 保持复位状态。 当置位时、UCSWRST 位置位 UCTXIFG 位并复位 UCRXIE、UCTXIE、UCRXIFG、UCRXERR、UCBRK、 UCPE、UCOE、UCFE、UCSTOE 和 UCBTOE 位。 清零 UCSWRST 会释放 eUSCI_A 用于运行。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Priya Thanigai]]另一个建议,可能更好。 置位和清零 UCSWRST 位将有助于恢复最后一个(丢失) TXIFG。
    如果您可以在禁用 TXIE 时置位 UCSWRST、并在重新启用前将其清零、则第一个 TXIFG 应再次置位。
    从 TRM 的22.3-1节中、

    eUSCI_A 通过硬复位或设置 UCSWRST 位来复位。 硬复位后、UCSWRST 位自动置位、使 eUSCI_A 保持复位状态。 当置位时、UCSWRST 位置位 UCTXIFG 位并复位 UCRXIE、UCTXIE、UCRXIFG、UCRXERR、UCBRK、 UCPE、UCOE、UCFE、UCSTOE 和 UCBTOE 位。 清零 UCSWRST 会释放 eUSCI_A 用于运行。

    [/报价]

    感谢您尝试考虑解决方案。

    撞击 SWRST 是一个相当大的锤子。  UCSWRST 的问题在于它会消除所有的东西、包括正在进行的任何潜在接收。

    您的第一个建议是前进的道路。