heinbali01 wrote on Thursday, May 29, 2014:
That sounds like an interesting project you’re about to develop!
ADC, I suppose that you want to make recordings of sound or do analogue measurements? Where do these data go to? Analyse them, write them to a disk or send them out on the Ethernet?
Many roads lead to Rome, but here is a nice one:
Define an interrupt for the ADC/DMA peripheral and do as little as possible from within that interrupt:
• Check for errors, make sure you confirm or clear them (see manual STM32F4)
• Provide a new buffer to the DMA so it can be filled (often there are two alternating buffers)
• Send a reference to the filled buffer (just a pointer) with xQueueSendFromISR() to the consumer
• If xQueueSendFromISR() sets ‘*pxHigherPriorityTaskWoken’, make sure that a task-switch takes place after returning ( see portEND_SWITCHING_ISR( xSwitchRequired ) ).
• And if there is no new data, a task switch probably isn’t necessary
The consumer is a normal FreeRTOS task. It receives all ADC data. After doing its work, you can make the task sleep using xQueueReceive().
If there is no other task with a higher prority, the time between leaving the interrupt and waking-up up the consumer will be less than a µs. That’s the deterministic behaviour.
( some people believe that their program will become more responsive if they handle the data ‘directly’ from within the interrupt )
Your consumer task may take it easy, as long as the queue has enough free space.
Now when you make something like a streaming audio player (or recorder), you might want to use more than one task:
- A task which fetches the data (from a disk, USB, internet)
- A task which decodes the data (from MP3 to raw)
- An interrupt (as above) which checks DMA status and swaps buffers
And then you make sure that there is enough buffer space between these three. I tend to have 5 to 10 seconds of audio prepared to be sent out on DMA, just to avoid drops of sound.
Is this more or less what you were asking for?