我一直在用C语言实现单片机SPI外设的设备驱动,我想利用中断机制来实现接收和传输。
对于接收部分,我认为可以通过暴露函数来实现。SpiRegisterCallback 到SPI驱动接口中。这个功能可以让客户机的寄存器在接收到数据字节时立即调用它的功能(接收缓冲区满了就会调用中断)。
至于传输部分,我想使用一些简单的方法来实现。SpiTransmit 函数,它将接收到要传输的数据字节的指针和要传输的字节数。在实现方面,我将定义一些SPI驱动的内部回调函数。这个内部回调函数将被注册为传输缓冲区空中断。在这个回调函数中,传递过来的数据字节将被逐步放入传输缓冲区。我不知道这种方法是否合适。谁能给我一个建议,如何实现利用中断进行数据传输的SPI外设驱动?先谢谢大家的建议。
SPI往往对实时性要求很高,用函数指针引入回调意味着不必要的开销代码。从SPI到RAM的实际数据复制必须由你的驱动内部完成。这就是ISR应该做的所有工作。一些一般性的指导可以在下面找到 此处.
所以,你的ISR应该填满一个缓冲区,然后... 交换指针到缓冲区 (不慢 memcpy
!),这样调用者总是有一个有效数据的缓冲区,而ISR总是有一个工作缓冲区来填充。让调用者轮询一个标志,而不是从ISR内部调用一个回调。如果能腾出内存,我喜欢使用三层缓冲区。也就是说:一个缓冲区给ISR,一个缓冲区给调用者,还有一个备用的,ISR可以在不干扰调用者的情况下与之交换。
这都是相当复杂的代码,大多数程序员都会搞错。DMA在这里优于中断,所以你真的应该考虑用DMA代替。这是你在挑选MCU时应该考虑的问题。
要求 "任何建议 "并不能真正使这个问题成为一个伟大的问题,因为多个答案可能是可以接受的,而很少有答案是全面的。 它邀请的是评论,而不是答案。 然而,我将会纵容。
首先,根据任何定义,这都不是利用。 利用 "意味着将某物用于非预期的目的--在这种情况下,这不是正确的术语,你并没有 "利用 "中断机制,你仅仅是 使用 它。
在高时钟速率下,在某些情况下,处理中断所涉及的中断延迟和上下文切换时间可能比简单的忙等效率低。如果每次传输超过两三个字节,在任何情况下都应该考虑使用DMA(如果可用)--这样中断将是一个完整传输的DMA中断,而不是单个字符。 对于SD卡接口或EEPROM等应用,DMA将对性能产生显著影响,并使CPU腾出时间来同时进行其他有用的工作。 对于单字节传输使用繁忙等待,对于块传输使用DMA的驱动程序可能是最佳的。 如果你使用的是RTOS,并且ISR触发了一个任务上下文来处理数据,那么这一点尤其正确--上下文切换的开销可能与单字节的忙等待差不多,甚至更多。 例如,如果你的SPI时钟是>1MHz,你将为一个字节传输等待8us,你的ISR和回调可能很容易大于然后,在这种情况下,它是不值得的。
所以我的建议是,如果你使用的时钟很慢,并且可以得到一个很好的中断,那么就只考虑SPI的中断。其他 在等待中断的同时完成有用的工作。
在中断中允许回调的问题是,它允许回调提供者在中断上下文中做一些不明智或非法的事情,并且你失去了控制中断处理时间的能力。 如果回调的目的是为了让编写设备驱动程序的人使用,这也许是好的--他们应该知道自己在做什么,但是这 是 设备驱动程序。