我有必须从PC串行端口(115200波特)下载大文件,并将其通过SPI(〜2兆赫)写入到串行闪存的微控制器。闪存写入操作必须是通过写命令和页面地址开头256个字节的块。所述系统上可用的总RAM是1 KB用80字节堆栈大小。

此,目前通过从UART然后乒乓效应的另一个256字节的缓冲区被填充通过中断对RX缓冲区就绪信号而闪光被写入到与写入忙填充256字节缓冲器的工作。重复该缓冲器交换,直到操作完成。

我宁愿设置TX / RX中断两者的SPI处理程序和上单独环形缓冲器操作UART端口。所以,相反轮询新的字节,等待操作完成,我可以简单地填充TX缓冲区和启用中断或检查的缓冲区传入的数据。这将使而不是等待外围设备的实际工作有更多的时钟周期。

实施IRQ与128字节循环缓冲器之后,我轮询数据的UART RX缓冲器,并立即将其放置在SPI TX缓冲区做文件传输。我用这种方法遇到的问题是,我没有为缓冲区和PC足够的内存接收缓冲区更快填充比我得到过的闪光灯发送缓冲区中的数据。显然,传输速度是没问题的(115.2千赫和2MHz出),但有各256字节的页被发送之后的写入周期的等待。


有出现频繁SPI中断都阻断一些UART中断并造成字节错过。我所选择的解决方案是使用用于UART环形缓冲器接收中断和数据馈送到由轮询发送到串行闪存字节传输和写完成一个256字节的页缓冲器。 A 128环形缓冲器足够大,以防止SPI写期间溢出。

有帮助吗?

解决方案

我会做这样的事情分散聚集的PC上。创建这样的结构的链接列表:

typedef struct data_buffer {
    char flags;
    char[128] data;
}

有在所述标志中的一个比特意味着“闪烁”“ReadyToFlash”和一个。您应该能够调整你的链表缓冲区的数目保持闪光灯从捕捉UART,因为它写,反之亦然。

如果闪光灯到达一个缓冲块,是不是“ReadyToFlash”它会拖延和你需要让你的UART IRQ重新启动它。如果UART到达一个块是“ReadyToFlash”或“闪烁”是灌装速度太快,你可能需要另一个缓冲区,如果你有动态内存,你可以在运行时做此调整和缓冲添加到列表上飞,否则你就只需要做一些实证检验。

其他提示

是否UART和应用支持RS-232握手的PC侧(流量控制)?如果是这样,当你的接收缓冲区获得接近充满,拥有ISR下降CTS线 - 如果PC端配置尊重硬件流控制,应立即停止发送,当它看到这种情况。一旦你已经耗尽(或几乎耗尽)接收缓冲区,再次断言CTS和PC应该开始重新发送。

请注意,这使得嵌入式设备上的软件要复杂得多 - 这是否是一个折衷你愿意做就必须通过分析你和你的经理和球队完成

这正是流量控制是为创建的,我知道它的一个巨大的痛苦成立,但如果你的串行线路配置流量控制你的问题将成为历史。

我假设你正在传输二进制文件,以便XON-XOFF是不是最好的解决方案,这让硬件流控制。

另一种选择是使用一个协议与内置的流量控制如XModem协议。我在那里闪光灯是写在128字节的页面类似的嵌入式项目。什么巧合XModem一种128字节的块发送数据然后等待ACK发送之前的下一个。

不知道什么,我缺少在这里,但如果事实是,数据从PC来的平均速率比平均速率高,你可以把它写入闪存,那么你要么将需要一个大量的RAM,或者你会需要流量控制。

但是,你是说当你有块缓存工作,但现在你有一个字节的缓冲区是不?

可以坚持其通过UART RX中断填充块缓冲器,并且当每一个缓冲器是满的,它交给所述SPI /闪存代码清空使用SPI中断该缓冲器?这将节省复制每个字节,而不必为每个字节执行循环缓冲器逻辑两次,你只需要做到这一点对于每个块。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top