如何在 Rust 结构实现中编写 SPI DMA 代码?

Posted

技术标签:

【中文标题】如何在 Rust 结构实现中编写 SPI DMA 代码?【英文标题】:How to write SPI DMA code inside a Rust struct implementation? 【发布时间】:2021-05-15 17:27:10 【问题描述】:

我正在尝试使用 STM32 SPI DMA 编写 Rust 设备驱动程序。如果您查看stm32f1xx-hal example,则 SPI DMA 代码非常简单,但特征非常复杂。我无法弄清楚如何让编译器接受以下在wait 调用中失败的代码。

impl<SPI, REMAP, PINS, CH> DeviceDriver<SpiTxDma<SPI, REMAP, PINS, CH>>
where SpiTxDma<SPI, REMAP, PINS, CH>: WriteDma<&'static mut [u8], u8>,

    pub fn send(&mut self) 
        if let (Some(spi), Some(buf)) = (self.spi.take(), self.buf.take()) 
            let transfer = spi.write(buf);
            let (buf, spi) = transfer.wait();
            self.buf = Some(buf);
            self.spi = Some(spi);
        
    

错误:

25 |             let (buf, spi) = txdma.wait();
   |                                    ^^^^ method not found in `Transfer<stm32f1xx_hal::dma::R, &mut [u8], TxDma<SpiPayload<SPI, REMAP, PINS>, CH>>`

然而,如果我将CH 类型参数替换为固定的结构名称C5,则编译正常。

为什么要修复类型参数而不改变其他任何内容,会导致代码编译/失败?

显然,上面的方法在操场上是行不通的,所以这里是(non)buildable repo。

【问题讨论】:

【参考方案1】:

wait 方法仅在TxDma&lt;SpiPayload&lt;SPI, REMAP, PINS&gt;, CH&gt; 实现TransferPayload 时定义,具体类型C5 是这种情况,但不受约束的类型参数CH 是这种情况。尝试在代码中添加约束:

impl<SPI, REMAP, PINS, CH> DeviceDriver<SpiTxDma<SPI, REMAP, PINS, CH>>
where SpiTxDma<SPI, REMAP, PINS, CH>: WriteDma<&'static mut [u8], u8>,
      TxDma<SpiPayload<SPI, REMAP, PINS>, CH>: TransferPayload,

    pub fn send(&mut self) 
        if let (Some(spi), Some(buf)) = (self.spi.take(), self.buf.take()) 
            let transfer = spi.write(buf);
            let (buf, spi) = transfer.wait();
            self.buf = Some(buf);
            self.spi = Some(spi);
        
    

【讨论】:

以上是关于如何在 Rust 结构实现中编写 SPI DMA 代码?的主要内容,如果未能解决你的问题,请参考以下文章

小熊派 FreeRTOS+SPI+DMA 驱动 TFT-LCD

linux 应用层spi怎么使用dma

STM32CubeMX-SPI+DMA 驱动 2812 灯带

STM32CubeMX-SPI+DMA 驱动 2812 灯带

如何在stm32f2xx or stm32f4xx中使用spi dma来完成全双攻通信

linux中的SPI和DMA有啥关系?