Forums

STM32F4 DMA question

Started by Tim Wescott September 10, 2013
So I'm running into a response time issue on a serial port on an 
STM32F407.  I was hoping that I could give myself more time to get to the 
ISR by piping the UART receive to the DMA.

I got it set up to what appeared to be correct according to the user's 
manual, and what I ended up with that the DMA will transfer exactly one 
byte from the UART, then turn itself off.

This may give me a little bit more time than what I have now -- but I was 
hoping that I'd have something that would behave more like an on-going 
FIFO, letting the serial port stack bytes up in memory, then letting my 
ISR respond at its leisure to go empty the thing.

Does anyone have any mileage with this problem, that could shed some 
light on whether it's doable and how, or at least tell me that I'm out of 
luck?

Thanks.

-- 
Tim Wescott
Control system and signal processing consulting
www.wescottdesign.com
On 09/11/13 00:57, Tim Wescott wrote:
> So I'm running into a response time issue on a serial port on an > STM32F407. I was hoping that I could give myself more time to get to the > ISR by piping the UART receive to the DMA. > > I got it set up to what appeared to be correct according to the user's > manual, and what I ended up with that the DMA will transfer exactly one > byte from the UART, then turn itself off. > > This may give me a little bit more time than what I have now -- but I was > hoping that I'd have something that would behave more like an on-going > FIFO, letting the serial port stack bytes up in memory, then letting my > ISR respond at its leisure to go empty the thing. > > Does anyone have any mileage with this problem, that could shed some > light on whether it's doable and how, or at least tell me that I'm out of > luck? > > Thanks. >
Don't have info on the particular cpu, but most dma type ops that are useful can be set up to autoincrement the address for the next byte and maybe even wrap around at the buffer end ?. Anyway, why are you having problems with interrupts ?. Unless you are running at a very high baud rate, there should be more than enough time to read the uart data, stick it in a FIFO buffer, do the housekeeping and get out fast. If the system is designed right, you should *never* need to block interrupts from the uart either. With modern processors, interrupt latency should be insignificant. More info needed ?... Chris
chris <meru@devnull.com> writes:
> [...] > With modern processors, interrupt latency should be insignificant.
Interrupt latency is not just a function of the processor's hardware architecture but also (probably more significantly) of any part of the code that keeps interrupts disabled. The latency will be potentially extended by as much as the longest amount of time interrupts are disabled throughout the code base. I'm not an expert in linux or real-time linux, but I've often thought that must be one key difference between the two. -- Randy Yates Digital Signal Labs http://www.digitalsignallabs.com
On 11/09/13 22:45, chris wrote:

> With modern processors, interrupt latency should be insignificant.
Even with 486 processors you could find a 10:1 variation in latency (and not just interrupts), depending on what was in the cache. It won't have got better as caches have got larger and memory latency has increased w.r.t. instruction time. IIRC the i960 allowed the current contents of the cache to be frozen, for just that reason.
On 09/11/13 23:24, Tom Gardner wrote:
> On 11/09/13 22:45, chris wrote: > >> With modern processors, interrupt latency should be insignificant. > > Even with 486 processors you could find a 10:1 variation > in latency (and not just interrupts), depending on what > was in the cache. It won't have got better as caches have > got larger and memory latency has increased w.r.t. > instruction time. > > IIRC the i960 allowed the current contents of the cache > to be frozen, for just that reason. >
Perhaps so, but we have come a long way from the days of 6502 style processors, where, depending on how many devices you wire-or'd onto the irq line, it could take anything up to 100uS just to find out what caused the interrupt, never mind process it. Haven't used the 32F4 Cortex, but the 32F100 series that I am using has a fully vectored interrupt system that uses a vector address table, much like the old 68000 series from 1983 (?). It took years, but Arm finally got that bit of it right. Just to put it in context, we are talking about serial comms here and even at ~100K bits/second, that means you have 100uS to deal with each received byte. Believe me, that's a lifetime for a fast cpu like Cortex :-)... Chris
On 09/11/13 22:54, Randy Yates wrote:

> > Interrupt latency is not just a function of the processor's hardware > architecture but also (probably more significantly) of any part of the > code that keeps interrupts disabled. The latency will be potentially > extended by as much as the longest amount of time interrupts are > disabled throughout the code base.
Of course, but a well designed system should never need to disable interrupts for more than a few cycles. Also,a good cpu design provides facilities for assignment of interrupt priorities, so that critical devices or s/w always get service within a predictable timescale. Usually, all the instruction timing stuff is in the processor data sheet, so you can work out worst case latency with a fair degree of accuracy... Chris
On 12/09/13 13:09, chris wrote:
> On 09/11/13 23:24, Tom Gardner wrote: >> On 11/09/13 22:45, chris wrote: >> >>> With modern processors, interrupt latency should be insignificant. >> >> Even with 486 processors you could find a 10:1 variation >> in latency (and not just interrupts), depending on what >> was in the cache. It won't have got better as caches have >> got larger and memory latency has increased w.r.t. >> instruction time. >> >> IIRC the i960 allowed the current contents of the cache >> to be frozen, for just that reason. >> > > Perhaps so, but we have come a long way from the days of 6502
There's 14 years difference there: 6502:1975, i486:1989
> style processors, where, depending on how many devices you > wire-or'd onto the irq line, it could take anything up to 100uS > just to find out what caused the interrupt, never mind process > it.
I think you mean 100us. "S" is for Siemens the SI unit of conductance, or sometimes Samples.
> Haven't used the 32F4 Cortex, but the 32F100 series that I am using > has a fully vectored interrupt system that uses a vector address > table, much like the old 68000 series from 1983 (?). It took years, > but Arm finally got that bit of it right. > > Just to put it in context, we are talking about serial comms here > and even at ~100K bits/second, that means you have 100uS to deal > with each received byte. Believe me, that's a lifetime for a fast > cpu like Cortex :-)...
But you are missing the point. I've no quibble with the *average* latency, but the *worst case* latency will be much much higher. But then my background is that a hard-realtime deadline is just that: a *dead*line.
On 09/12/13 13:43, Tom Gardner wrote:

> > There's 14 years difference there: 6502:1975, i486:1989 >
And, the point being ?. The comment was to illustrate how far things have developed since the early days, where high speed comms was not so easy to program due to timing limitations, or did you think I meant something else ?.
> > I think you mean 100us. "S" is for Siemens the SI unit of > conductance, or sometimes Samples.
Well, I understood what I meant and it seems so did you, so why the need for the rather pompous correction ?.
> > But you are missing the point. I've no quibble with the *average* > latency, but the *worst case* latency will be much much higher.
All that data should be in the processor data sheet and if you are working that close to the edge, you have to take it into consideration. But, let's keep it in context: The original question to Tim was about problems with serial uart interrupts, not in depth discussions about latency, which i'm sure we are all aware of and not relevant to the context.
> > But then my background is that a hard-realtime deadline is > just that: a *dead*line.
Quite used to counting the uS here as well, but much less need for it with the micros we have to work with now. An abundance of riches and choice springs to mind :-)... Chris
On Thu, 12 Sep 2013 12:09:25 +0000, chris wrote:

> On 09/11/13 23:24, Tom Gardner wrote: >> On 11/09/13 22:45, chris wrote: >> >>> With modern processors, interrupt latency should be insignificant. >> >> Even with 486 processors you could find a 10:1 variation in latency >> (and not just interrupts), depending on what was in the cache. It won't >> have got better as caches have got larger and memory latency has >> increased w.r.t. instruction time. >> >> IIRC the i960 allowed the current contents of the cache to be frozen, >> for just that reason. >> >> > Perhaps so, but we have come a long way from the days of 6502 style > processors, where, depending on how many devices you wire-or'd onto the > irq line, it could take anything up to 100uS just to find out what > caused the interrupt, never mind process it. > > Haven't used the 32F4 Cortex, but the 32F100 series that I am using has > a fully vectored interrupt system that uses a vector address table, much > like the old 68000 series from 1983 (?). It took years, > but Arm finally got that bit of it right. > > Just to put it in context, we are talking about serial comms here and > even at ~100K bits/second, that means you have 100uS to deal with each > received byte. Believe me, that's a lifetime for a fast cpu like Cortex > :-)...
I'm not even sure that the serial port is double-buffered -- I know that I figured out how to get just one byte at a time out via DMA, and my problems disappeared. -- Tim Wescott Wescott Design Services http://www.wescottdesign.com
On Wed, 11 Sep 2013 21:45:13 +0000, chris wrote:

> On 09/11/13 00:57, Tim Wescott wrote: >> So I'm running into a response time issue on a serial port on an >> STM32F407. I was hoping that I could give myself more time to get to >> the ISR by piping the UART receive to the DMA. >> >> I got it set up to what appeared to be correct according to the user's >> manual, and what I ended up with that the DMA will transfer exactly one >> byte from the UART, then turn itself off. >> >> This may give me a little bit more time than what I have now -- but I >> was hoping that I'd have something that would behave more like an >> on-going FIFO, letting the serial port stack bytes up in memory, then >> letting my ISR respond at its leisure to go empty the thing. >> >> Does anyone have any mileage with this problem, that could shed some >> light on whether it's doable and how, or at least tell me that I'm out >> of luck? >> >> Thanks. >> >> > Don't have info on the particular cpu, but most dma type ops that are > useful can be set up to autoincrement the address for the next byte and > maybe even wrap around at the buffer end ?. > > Anyway, why are you having problems with interrupts ?. Unless you are > running at a very high baud rate, there should be more than enough time > to read the uart data, > stick it in a FIFO buffer, do the housekeeping and get out fast. If the > system is designed right, you should *never* need to block interrupts > from the uart either. > With modern processors, interrupt latency should be insignificant. > > More info needed ?...
Well, I ended up solving the problem another way. But yes -- it struck me as odd that I should be having trouble. I needed something quick, so bandaiding the problem by allowing more latency seemed like a good idea, at least until I had the leisure to chase down the real problem. -- Tim Wescott Wescott Design Services http://www.wescottdesign.com