如何在内存受限的嵌入式系统上处理大量数据传输?

Jud*_*den 6 c embedded serial-port interrupt spi

我有一个微控制器必须从PC串口(115200波特)下载大文件,并通过SPI(~2 MHz)将其写入串行闪存.闪存写入必须是256字节块,然后是写入命令和页面地址.系统上可用的总RAM为1 kB,堆栈大小为80字节.

目前这是通过从UART填充256字节缓冲区然后通过ping到ponging到另一个256字节缓冲区来填充另一个256字节缓冲区由RX缓冲区就绪信号上的中断填充,同时使用忙写入写入闪存.重复缓冲区交换,直到操作完成.

我更喜欢为在单独的循环缓冲区上运行的SPI和UART端口设置TX/RX中断处理程序.因此,我可以简单地填充TX缓冲区并启用中断或检查缓冲区是否有输入数据,而不是轮询新字节并等待操作完成.这将为实际工作提供更多的时钟周期,而不是等待外设.

在使用128字节循环缓冲区实现IRQ之后,我在UART RX缓冲区中查询数据并立即将其放入SPI TX缓冲区以进行文件传输.我使用这种方法的问题是我没有足够的RAM用于缓冲区,并且PC接收缓冲区的填充速度比我将数据传输到闪存传输缓冲区要快.显然,传输速度不是问题(115.2 kHz输入和2 MHz输出),但在每个256字节页面传输后有一个写周期等待.


频繁的SPI中断似乎阻塞了一些UART中断并导致丢失了字节.我选择的解决方案是使用环形缓冲区用于UART接收中断,并将数据馈送到256字节页缓冲区,通过轮询字节传输和写完成将其发送到串行闪存.128个环形缓冲区足以防止SPI写入期间出现溢出.

jos*_*rry 3

我会在电脑上做类似分散聚集的事情。创建一个结构体的链表,如下所示:

typedef struct data_buffer {
    char flags;
    char[128] data;
}
Run Code Online (Sandbox Code Playgroud)

标志中的一位表示“ReadyToFlash”,另一位表示“Flashing”。您应该能够调整链接列表中的缓冲区数量,以防止闪存在写入时捕获 UART,反之亦然。

如果闪存到达非“ReadyToFlash”的缓冲区块,它将停止运行,您需要让 UART IRQ 启动它备份。如果 UART 到达“ReadyToFlash”或“Flashing”的块,则它填充得太快,您可能需要另一个缓冲区,如果您有动态内存,您可以在运行时进行此调整,并动态地将缓冲区添加到列表中,否则您只需要进行一些实证测试。