Difference Between polling,DMA and Interrupt?

Thread Starter

Dilse

Joined Sep 26, 2018
2
i am currently working on STM32F4 boards and i want to know the Difference Between polling,DMA and Interrupt?and which is the best way to use communication in UART,SPI,I2C? please provide me with example codes for each.
 

ericgibbs

Joined Jan 29, 2010
18,766
hi Dilse,
Welcome to AAC.
Your question covers a lot of ground.:)
Have a look thru this PDF.
E

MOD: Deleted link , in consideration of any copyright existing.
 
Last edited:

MrChips

Joined Oct 2, 2009
30,714
Computer systems have to respond to external stimuli or events, whether it be a keyboard button pressed, mouse movement, ADC input, or incoming/outgoing data on a serial or parallel bus.

Polling
Polling is a procedure written in software that detects that an event has occurred. There are two types of polling, blocking and non-blocking.

In a blocking poll, the processor tests a flag or bit and waits until the state of the flag has changed to a desired state. Thus the processor is unable to proceed until this new state is detected.

In non-blocking poll, the processor may proceed with other tasks and only acts on the desired action when a defined flag state has been detected. Since the flag may change state while the processor was not testing the flag, there will be a delay before the desired action is taken which could be in the order of milliseconds, depending on what the processor is doing.

Interrupts
Interrupts overcome the short comings of polling. An event can interrupt the processor at anytime. Interrupt latency is the time it takes for the processor to acknowledge reception of the notification and can be of the order of sub-microseconds. The processor may choose to service the event immediately or may postpone servicing until an appropriate moment.

Direct Memory Access
DMA is a hardware process that can handle data transfers without processor intervention. Thus, events can happen behind the scene without needing to interrupt the processor. DMA is best suited (but not limited to) mass data transfers, from peripheral to memory, memory to peripheral, or memory to memory. A typical example of DMA data transfer is high-speed ADC sampling, video recording and playback, or audio recording and playback.

There is no single best mechanism. It depends on the total function of the system and its subsystems. You can have all three techniques being used for different parts of the system.
 

nsaspook

Joined Aug 27, 2009
13,086
I kinda fail to see what direct memory access has to do with polling and interrupt.
They are all related in the process of moving data from A to B. DMA normally uses interrupts to notify the cpu the block transfer is done or needs more data. In a single low-level driver you might use all three methods depending on conditions.

Example: 32-bit controller SPI driver

Polling hardware flags in an spi rx interrupt for empty flag
C:
/* spi interrupt in single vector sw0 */
static void spi_rx_irq(spi_t bus)
{
uint8_t rdata __attribute__((unused));
while (!((SPIxSTAT(pic_spi[bus]) & _SPI1STAT_SPIRBE_MASK))) {
if (pic_spi[bus].in) {
*pic_spi[bus].in++ = SPIxBUF(pic_spi[bus]);
}
else {
/* dump the received data with no callback */
rdata = SPIxBUF(pic_spi[bus]);
}
if (!--pic_spi[bus].len) {
pic_spi[bus].complete = true;
}
}
}
Use polling, interrupts and dma in a transfer routine depending on the spi bus
C:
static inline void _spi_transfer_bytes_async(spi_t bus, spi_cs_t cs, bool cont,
const void *out, void *in, size_t len)
{
const uint8_t *out_buffer = (const uint8_t *) out;
uint8_t dma_able = 8; /* default to NO DMA to trigger default method */
(void) cs;
(void) cont;
/* set input buffer params for the non-dma isr mode */
pic_spi[bus].in = in;
pic_spi[bus].len = len;
pic_spi[bus].complete = false;
/* check if we have both buffers */
if (out && in) {
dma_able = 0;
}
/* Translate a kernel (KSEG) virtual address to a physical address. */
switch (bus + dma_able) {
case 1:
trigger_bus_dma_rx(SPI1_DMA_RX, len, KVA_TO_PA(in));
trigger_bus_dma_tx(SPI1_DMA_TX, len, KVA_TO_PA(out_buffer));
break;
case 2:
trigger_bus_dma_rx(SPI2_DMA_RX, len, KVA_TO_PA(in));
trigger_bus_dma_tx(SPI2_DMA_TX, len, KVA_TO_PA(out_buffer));
break;
default: /* non-dma mode */
while (len--) {
if (out_buffer) {
SPIxBUF(pic_spi[bus]) = *out_buffer++;
/* Wait until TX FIFO is empty */
while ((SPIxSTAT(pic_spi[bus]) & _SPI1STAT_SPITBF_MASK)) {}
}
else {
SPIxBUF(pic_spi[bus]) = 0;
/* Wait until TX FIFO is empty */
while ((SPIxSTAT(pic_spi[bus]) & _SPI1STAT_SPITBF_MASK)) {}
}
}
}
}
Async spi port driver routine

C:
void spi_transfer_bytes(spi_t bus, spi_cs_t cs, bool cont,
const void *out, void *in, size_t len)
{
assert(bus != 0 && bus <= SPI_NUMOF_USED);
/* make sure at least one input or one output buffer is given */
assert(out || in);
if (cs != SPI_CS_UNDEF) {
gpio_clear((gpio_t) cs);
}
_spi_transfer_bytes_async(bus, cs, cont, out, in, len);
while (!spi_complete(bus)) {}
if (!cont && cs != SPI_CS_UNDEF) {
gpio_set((gpio_t) cs);
}
}
sync transfer routine

C:
void spi_1_isr_rx(void)
{
spi_rx_irq(1);
}
void spi_2_isr_rx(void)
{
spi_rx_irq(2);
}
void spi_3_isr_rx(void)
{
spi_rx_irq(3);
}
/* set transfer complete flag */
void dma_spi_1_isr_rx(void)
{
pic_spi[1].complete = true;
}
void dma_spi_2_isr_rx(void)
{
pic_spi[2].complete = true;
}
/* not currently used */
void dma_spi_3_isr_rx(void)
{
pic_spi[3].complete = true;
}

int32_t spi_complete(spi_t bus)
{
assert(bus != 0 && bus <= SPI_NUMOF);
return pic_spi[bus].complete;
}
Interrupt vectors

Cpu/interrupt driven SPI tx/rx works pretty well up to about a 1MHz clock but at higher transfers rates even the pic32mzef starts to slow down. So the final part of the driver is the DMA engine. Here we've only enabled transmit DMA to make a cpu usage tx/rx comparison using a 10MHz sck with three 18 byte blocks on spi 1&2.

41119636725_8f1569c51a_z.jpg
1. Cpu usage (SPIXT) during data transmit. 2. Cpu usage (SPIRT) during receive.

28146730988_3e64a1aabb_z.jpg
Data stream trace, there are times when almost all the cpu is needed to receive the SPI data stream
when both spi channels are transmitting.

41128899445_f94bc912a4_z.jpg
SPI ports 1 and 2 data with 10MHz sck.

41308865694_3276c098cf_z.jpg
Driver cpu usage for that data stream with full rx/tx dma on both channels.

https://github.com/nsaspook/RIOT/blob/PIC32MZEF/cpu/mips_pic32_common/periph/spi.c

RIOT OS port testing example.
https://raw.githubusercontent.com/n.../examples/serial_timer_periodic_wakeup/main.c
 
Last edited:

BobaMosfet

Joined Jul 1, 2009
2,110
i am currently working on STM32F4 boards and i want to know the Difference Between polling,DMA and Interrupt?and which is the best way to use communication in UART,SPI,I2C? please provide me with example codes for each.
There is an _amazing_ resource. It's called: ..... GOOGLE!

Just paste this in 'Difference Between polling,DMA and Interrupt?'

and voila, it brings up a wealth of excellent information about these things.
 

danadak

Joined Mar 10, 2018
4,057
Polling can be designed to be perfectly deterministic, eg. # clock cycles to
detect and execute.

Interrupts can be almost deterministic.

DMA, in low end isolated buss architectures can be deterministic. In higher end parts
buss arbitration adds uncertainty.

In general DMA offer almost pure HW speed, and allows a processor to
move data w/o CPU intervention (depends on architecture). Essentially
allowing multiple simultaneous data operations in a CPU.

Interrupts allow "stop what you are doing and focus on me" operations. Think
a school fire alarm going off.

All 3 have priority settings, eg. which DMA channel has what priority, which ISR
gets serviced first when simultaneous interrupts occur, polling of course is program
flow under control of coder.

All 3 methods have their own advantages/strengths, and weaknesses. Often a design
will use 2 or more of these methods to do the desired tasks and optimize the design.

Regards, Dana.
 
Top