Atmega 2560 UART串行数据限制

huangapple go评论71阅读模式
英文:

Atmega 2560 UART serial data limit

问题

你好,我正在使用ATmega 2560和SIM800L。我需要从服务器提取100KB的数据,但由于RAM限制,我只能提取5KB。但是我有SD卡来存储数据。
我正在尝试使用循环缓冲区来实现它。有人可以指导我整个过程吗?

我尝试了循环缓冲区的概念,但在缓冲区大小小于实际服务器数据时,我无法接收数据。

我想提取数据块并将其存储在SD卡上。

英文:

Hello I am working atmega 2560 with SIM800L. I require to extract data of 100KB from server but i am able achieve only 5KB (RAM constraints) but I have SD card to store the data.
I am trying to implement it using circular buffer. Can anyone guide me through the process?

I tried concept of circular buffer but i am unable to receive data when buffer size is less actual server data

I want to extract chunks of data and store it in SD card

答案1

得分: 1

问题是,在文件系统繁忙写入SD卡的情况下,您需要能够接收和缓冲传入的数据。

为了实现这一点,假设您没有使用实时操作系统(即使使用了实时操作系统),您的串口输入将需要是中断驱动的,其中UART Rx中断处理程序将数据放入FIFO缓冲区(通常实现为循环缓冲区,正如您所建议的)。缓冲区的大小需要足够大,以存储在文件系统忙于处理SD卡写入期间可能接收到的字符。请记住,SD卡的延迟可能是可变且不确定的,取决于卡的物理约束。例如,通常情况下,当跨越特定的物理边界进行写入时,卡会在几毫秒内“停顿”,即使在其他情况下数据可以写入得很快。

在这种情况下,串行数据流速率可能相对较低,与SD卡的延迟相比较低,这意味着您可以使用较小的缓冲区。例如,在9600,N,8,1的情况下,128字节的缓冲区将允许133毫秒的文件系统延迟。这对于您可能要使用的任何SD卡来说可能已经足够了。

在呈现与逻辑扇区大小匹配的数据时,文件系统效率最高。通常对于小型文件系统,使用512字节的缓冲区。因此,您的软件应该从串行FIFO中读取数据,直到它已经收集了一个512字节的块,然后将其写入SD卡。在此期间,中断驱动的串行驱动程序可以同时将数据放入FIFO中(在上面的示例中最多达到133毫秒),然后当您返回到整理新块时,代码将立即将缓冲数据传输到整理块中,并继续实时(即数据到达时)收集更多数据,直到再次填满该块。

另一种选择,尽管不太通用(即它专门针对这个特定的任务),是使用双缓冲,其中UART Rx中断处理程序写入两个512字节缓冲区中的一个,并且当一个缓冲区被填满时,它设置一个由主线程轮询的标志,触发将该缓冲区写入文件系统。与此同时,中断处理程序切换到备用缓冲区并填充该缓冲区,而SD卡正在写入。这种方法的缺点是它需要两个相对较大的缓冲区,并且不容易允许您对传入的串行数据执行其他处理,而不仅仅是记录它。

如果您需要特定于缓冲中断驱动串行I/O 的帮助,那可能需要一个新的更具体的问题。

英文:

The issue is that you need to be able to receive and buffer incoming data whilst the filesystem is busy writing to the SD card.

For that to happen and assuming that you are not using an RTOS (and probably even if you are using an RTOS), your serial input will need to be interrupt driven where the UART Rx interrupt handler places data into a FIFO buffer (normally implemented as a circular buffer as you suggest). The size of the buffer will need to be sufficient to store as many characters as could be received for the duration the file system is busy dealing with the SD card write. Bearing in mind that SD card latency is likely to be variable and non-deterministic depending on physical constraints of the card. For example it is usual for a card to "stall" for a few milliseconds when writing across specific physical boundaries, even when otherwise data can be written very fast.

In this case the serial data stream rate is likely to be low compared to the SD card latency, which means that you can likely get away with a small buffer. For example at 9600,N,8,1, a buffer of 128 bytes will allow for 133ms of filesystem latency. That is probably sufficient for any SD card you are likely to use.

Filesystems work most efficiently when presented with data matching the logical sector size. Typically for a small filesystem 512 byte buffers are used. So your software should read from the serial FIFO until it has collated a 512 byte block, then write that to the SD card. While that is happening, the interrupt driven serial driver can concurrently place data into the FIFO (for up to 133ms in the example given above), then when you return to collating a new block, the code will immediately transfer the buffered data to the collating block and continue collecting further data in real-time (i.e. as it arrives) until the block is again filled.

An alternative, though less generalised solution (i.e. it is specific to this particular task) would be to use double buffering, where the UART Rx interrupt handler writes to one of two 512 byte buffers, and when a buffer is filled, sets a flag polled by the main thread that triggers a write of that buffer to the file system. Meanwhile the interrupt handler switches to the alternate buffer and fills that while the SD card is being written to. The disadvantage of that approach is that it requires two relatively large buffers, and does not easily allow other processing you might want to perform on the incoming serial data other than simply logging it.

If you need help specifically with buffered interrupt driven serial I/O, that probably deserves a new and more specific question.

huangapple
  • 本文由 发表于 2023年7月17日 17:21:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76703051.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定