I noticed a change in the time required to complete a DMA memory to memory transaction in a larger project.
I modified the hello_dma example to use systick_hw->cvr to time a simple DMA transaction.
I would expect DMA to be fairly constant in timing...
There is 'sometimes' a large variation in the time to start and complete the DMA transaction.
Why? Am I doing something wrong? Any idean what is happening?
Here is the timing in system ticks:
I modified the hello_dma example to use systick_hw->cvr to time a simple DMA transaction.
I would expect DMA to be fairly constant in timing...
There is 'sometimes' a large variation in the time to start and complete the DMA transaction.
Why? Am I doing something wrong? Any idean what is happening?
Here is the timing in system ticks:
Code:
[Time dma transfers of 40 bytes over 100 loopsUse systick_hw->cvrFirst time, Sys ticks 162Start tick number 16777095, end 16776932, delta is 163Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16775465, delta is 1747Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74Start tick number 16777212, end 16777138, delta is 74After 100 tries, min = 74, max = 1747, mean = 91 ticks/code]And, the source:[code]/** * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. * * SPDX-License-Identifier: BSD-3-Clause * * 20250528 tomdean - modified to use systick_hw->cvr top time the dma transaction * */// Use the DMA to copy data between two buffers in memory.#include <stdio.h>#include "pico/stdlib.h"#include "hardware/dma.h"#include "hardware/structs/systick.h" // access the systick register which runs at sysclk#define BUF_SIZE 40 #define NUM_LOOPS 100// Data will be copied from src to dstuint8_t src[BUF_SIZE] ;uint8_t dst[BUF_SIZE] ;int main() { uint32_t start, end, delta, min, max, sum; int idx ; stdio_init_all() ; systick_hw->csr = 0x5 ; // clksource processor clock, enable counter systick_hw->rvr = 0x00FFFFFF ; sleep_ms(1000) ; // give the usb system time to setup printf("\nTime dma transfers of %d bytes over %d loops\n", BUF_SIZE, NUM_LOOPS) ; // Get a free channel, panic() if there are none int chan = dma_claim_unused_channel(true) ; // 8 bit transfers. Both read and write address increment after each // transfer (each pointing to a location in src or dst respectively). // No DREQ is selected, so the DMA transfers as fast as it can. dma_channel_config c = dma_channel_get_default_config(chan) ; channel_config_set_transfer_data_size(&c, DMA_SIZE_8) ; channel_config_set_read_increment(&c, true) ; channel_config_set_write_increment(&c, true) ; dma_channel_configure( chan, // Channel to be configured &c, // The configuration we just created dst, // The initial write address src, // The initial read address BUF_SIZE, // Number of transfers ; false // Do not start immediately. ) ; // initialize the source buffer for (idx=0; idx<BUF_SIZE; idx++) { src[idx] = 0x10 + idx ; } printf("Use systick_hw->cvr\n"); start = systick_hw->cvr ; // cvr counts down dma_start_channel_mask(1u << chan) ; // We could choose to go and do something else whilst the DMA is doing its // thing. In this case the processor has nothing else to do, so we just // wait for the DMA to finish. dma_channel_wait_for_finish_blocking(chan) ; // The DMA has now copied our text from the transmit buffer (src) to the // receive buffer (dst), so we can print it out from there. printf("First time, Sys ticks %lu\n", start - systick_hw->cvr) ; // cvr counts down min = 99999999; max = 0; sum = 0; for (idx=0; idx<NUM_LOOPS; idx++) { systick_hw->cvr = 0 ; // any write clears cvr and disables counter systick_hw->csr = 0x5 ; // clksource processor clock, enable counter start = systick_hw->cvr ; // cvr counts down dma_channel_set_read_addr(chan,src, false) ; // don't start now dma_channel_set_write_addr(chan, dst, true) ; // start now dma_channel_wait_for_finish_blocking(chan) ; end = systick_hw->cvr ; // cvr counts down delta = start - end ; // cvr counts down if (delta < min) min = delta ; if (delta > max) max = delta ; sum += delta ; printf("Start tick number %lu, end %lu, delta is %lu\n", start, end, delta) ; } //printf("\n") ; printf("After %d tries, min = %lu, max = %4lu, mean = %lu ticks\n", NUM_LOOPS, min, max, sum / NUM_LOOPS) ;#if 0 printf("Use time_us_32()\n"); min = 99999999; max = 0; sum = 0; for (idx=0; idx<NUM_LOOPS; idx++) { start = time_us_32() ; dma_channel_set_read_addr(chan,src, false) ; // don't start now dma_channel_set_write_addr(chan, dst, true) ; // start now dma_channel_wait_for_finish_blocking(chan) ; delta = time_us_32() - start ; if (delta < min) min = delta ; if (delta > max) max = delta ; sum += delta ; //printf(" %lu", delta) ; } //printf("\n") ; printf("After %d tries, min = %lu, max = %lu, mean = %lu usec\n", NUM_LOOPS, min, max, sum / NUM_LOOPS) ;#endif while (1) ; // don't run off the end of the world!}Statistics: Posted by tomdean — Thu May 29, 2025 12:42 am