【问题标题】:Handle corrupted SPI data using STM32F1 MCU使用 STM32F1 MCU 处理损坏的 SPI 数据
【发布时间】:2015-11-13 01:14:49
【问题描述】:

我正在为带有 STM32F1 MCU 的定制板开发应用程序,它需要能够从意外的数据损坏中恢复。

数据流如下: 主设备(Linux 机器)向从设备发送请求,从设备解析消息并准备发送回复。然后主人阅读回复。交换速度很快(@18MHz),实现如下:

if (::ioctl(_fd, SPI_IOC_MESSAGE(2), &transaction) < 0) {
    warn("message not sent");
    return false;
}

这两条消息之间的延迟约为 50us。消息长度是固定的。

在 STM 方面,我使用了一个 DMA 驱动的 SPI 驱动程序,该驱动程序按照我将在下面编写的方式实现。

我正在使用时钟频率为 APB1@36MHz(HSE@24MHz;AHB@72MHz;APB1@36MHz)的 SPI2。

在 SPI 配置为通过在 RXNEIE (CR2->RXDMAEN) 上发出 DMA 请求来读取消息(固定长度!)之后。处理完消息后,答案将通过 DMA1 (CR2->TXDMAEN) 传输。

在我以某种方式干预之前,一切都像魅力一样运作。我试图恢复的场景是在传输时拔掉 SCLK 线。

我正在努力从这件事中恢复过来。我将阐述我的想法,因为我不确定错误在哪里。

DMA 被配置为处理固定长度的消息。这就是为什么当我以某种方式进行干预时,DMA 控制器会等到整个消息被处理并且缓冲区被转移。假设,当 SCLK 突然消失时,我收到了三分之一的消息。 DMA 将等待剩下的三分之二。主控继续发送请求。因此,在 SCLK 返回后,下一条消息的 2/3 将被放置在缓冲区中。发出 DMA 中断,但最后一条消息的剩余轨迹丢失。它肯定会丢失,但我可以检测到使用 ERRIE 标志在将要设置的 OVR 标志上发出中断。

我已尝试处理该中断,但无济于事。

我现在拥有的中断处理程序检查是否设置了 BSY 标志(线索正在由 SPI 控制器处理)。如果设置了,我会杀死 DMA(它已经开始处理下一条消息)并留下 OVR 标志。一旦 BSY 被清除,我就会清除 OVR 并重置 DMA 以进行接收。

这没有多大帮助。

我可能使用的另一个选项是在 SCLK 的上升沿复位的专用定时器(AN3109 应用笔记启发的解决方案)。这样我就可以实现 DMA 超时。如果我只收到消息的一部分,如果 SCLK 长时间不在我们身边,我可以在定时器溢出时产生中断。不过,此解决方案存在问题。

我知道描述含糊不清,但我已经尽力了,希望有更深入了解的人可以提供帮助。

【问题讨论】:

  • 我不知道为什么你的时钟信号会突然消失,但你的设计本身似乎有问题。看来您的基本假设是您的奴隶将在 50us 内完成工作,而您的主人会要求答复。这实际上是行不通的。您需要在较短的时间内轮询您的奴隶并检查奴隶是否已完成。或者,您应该使用双主模式,因为通常从站应该是完全由主站驱动的消费者,而在您的情况下,它不适合。
  • SPI 使用SS 作为帧同步。你需要超时。
  • 在 DMA 中断处理程序中,我复制已经填充的数组并设置 DMA 来传输它。是不是太多了?从站随时准备就绪。如果主服务器在事务期间重新启动,时钟可能会消失。所以这是可能的,不是吗?

标签: linux stm32 spi


【解决方案1】:

在 CS 线上安装一个中断处理程序。在上升沿,如果传输尚未完成,则中止一切并从 DMA 重新开始。使用 SPI_CR1 中的 SSI 位,上升沿置位,下降沿清零。

【讨论】:

    猜你喜欢
    • 2017-06-29
    • 1970-01-01
    • 1970-01-01
    • 2018-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-18
    • 2012-07-27
    相关资源
    最近更新 更多