Author Topic: Concatenating FIFOs  (Read 966 times)

0 Members and 1 Guest are viewing this topic.

Offline AussieBruceTopic starter

  • Regular Contributor
  • *
  • Posts: 51
  • Country: au
Concatenating FIFOs
« on: January 30, 2023, 01:02:06 am »
I’m reading serial data into an NXP ARM UART, which incorporates a 16 byte FIFO. In fact I need bigger buffers (typ 512 bytes), which I can easily implement in RAM. I’m wondering what the best way is to combine these two buffers, on one hand it’s not clear why I shouldn’t simply disable the embedded FIFO and just run straight to the in-RAM one. OTOH, the UART FIFO is free, and may as well be in the mix if that helps. Is there a clever, or ‘best’ solution to this, and what are the factors involved, if any? Thanks in advance.
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4040
  • Country: nz
Re: Concatenating FIFOs
« Reply #1 on: January 30, 2023, 01:10:14 am »
If you disable the hardware FIFI and then at some point interrupts are disabled for more than one byte-time then you lose data.

The hardware FIFO makes things safe up to interrupts being disabled for 16 byte-times, which is a lot more and hopefully can never ever happen.

When you get an interrupt for data in the FIFO, copy everything that is there (but probably 1 byte 99.999% of the time) to the software buffer.

I don't know that particular chip, but it's probably got a setting to interrupt when it's 50% full or something like that (maybe with a timeout), so you can lower the number of interrupts burdening the machine, but still have a big safety margin.
« Last Edit: January 30, 2023, 04:39:09 am by brucehoult »
 
The following users thanked this post: AussieBruce

Offline Psi

  • Super Contributor
  • ***
  • Posts: 9954
  • Country: nz
Re: Concatenating FIFOs
« Reply #2 on: January 30, 2023, 01:13:41 am »
Yep the hardware FIFO doesn't need to make things more complicated.

For RX you can simply loop your single byte handler until the HW buffer is empty on data arrive interrupt. (or you can rewrite it to copy bigger chunks if you really want to)

For TX you can simply check if the buffer can handle more data instead of checking if the UART is ready for a byte. (or you can rewrite it to copy in bigger blocks at a time if you really want to)

The FIFO is very useful when running the UART at really high bit rates, or if you clock is really slow for power reasons.
You waste lots of cycles in overhead if you keep having to stop and go to the interrupt handler for every single byte.
« Last Edit: January 30, 2023, 01:20:07 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14488
  • Country: fr
Re: Concatenating FIFOs
« Reply #3 on: January 30, 2023, 02:26:34 am »
FIlling up a RAM FIFO several bytes at a time is not more difficult than one byte at a time. And as said above, a hardware FIFO will make things a lot more efficient.
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3147
  • Country: ca
Re: Concatenating FIFOs
« Reply #4 on: January 30, 2023, 04:12:20 am »
Hardware FIFO gives you time. Say, if you receive at 1 MBaud then you need to retrieve a character once every 10 us. But with 16-byte hardware FIFO you only have to retrieve characters once every 160 us. You don't have to do it that slow, but you can. Disabling hardware FIFO doesn't provide any benefits except, perhaps, in some weird cases.

If you want a big RAM buffer, you can use DMA to fill it continuously. Then hardware FIFO won't be used, but it won't hurt you neither, so you can leave it enabled.

If you rather want multiple RAM buffers served by DMA, the hardware FIFO will keep the reception going while you switch DMA buffers and will give you more time to switch.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 19517
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: Concatenating FIFOs
« Reply #5 on: January 30, 2023, 09:53:53 am »
I’m reading serial data into an NXP ARM UART, which incorporates a 16 byte FIFO. In fact I need bigger buffers (typ 512 bytes), which I can easily implement in RAM. I’m wondering what the best way is to combine these two buffers, on one hand it’s not clear why I shouldn’t simply disable the embedded FIFO and just run straight to the in-RAM one. OTOH, the UART FIFO is free, and may as well be in the mix if that helps. Is there a clever, or ‘best’ solution to this, and what are the factors involved, if any? Thanks in advance.

In general buffers allow an improved peak response time, but the mean response time is unchanged. No surprises there, but some people forget it.

The amount of time for which they enable an improved peak response time is a function of the peak response time, the mean response time, and the buffer size. Again, no surprises.

If you have several concatenated buffers, then those calculations are applicable to each buffer on its own. Depending on the peak/mean time and buffer size, it may be possible to omit one of the buffers. Only you can specify the parameters in your system, so only you can answer your question.

If your application involves re-sending data when some is omitted or garbled (i.e. a networking transport protocol), then there is the additional issue ("buffer bloat") that excessively large buffers can cause problems. Simplistically, if the buffer is longer than the protocol timeout period, then even correctly received data will have to be retransmitted - which increases the mean processing time and clogs up the buffer.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Online Siwastaja

  • Super Contributor
  • ***
  • Posts: 8179
  • Country: fi
Re: Concatenating FIFOs
« Reply #6 on: January 30, 2023, 10:03:27 am »
>ARM MCU
>UART

This combination is almost never a problem. UART is almost always significantly slower than CPU. Even with no FIFOs at all, you can easily afford the overhead of interrupting for every byte.

Usual problem in thinking is overestimating the interrupt latency or processing complexity. This may be a problem with application processors, but not with microcontrollers.

As a rule of thumb, you can do "a few simple things" - making some sanity checks, bounds checking, writing to a buffer, maybe a few calculations -  in 50-100 CPU clock cycles, including ISR entry and exit overhead.

Because a typical UART can only clock up to f_peripheral/8 because of x8 oversampling, and because every 10 baud time slots (start - data - stop) requires at most one interrupt, even if f_peripheral equals f_cpu, and even if you use UART at maximum possible speed, you have 80 clock cycles to process each byte. In reality, UART is usually not used at maximum theoretical possible speed.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf