DMA exceptions while sampling audio

Hi, I’m using the ALSA C library to sample an audio signal from both Line-In R and Line-In L with a sampling rate of 96KHz (I’m calling the ALSA snd_pcm_readi C function to get audio samples).
Periodically, after some time that the console sampling application is running, the following warnings are displayed on the console:

[ 5780.743403] ------------[ cut here ]------------
[ 5780.748067] WARNING: at /workdir/oe/tmp-glibc/work-shared/colibri-t30/kernel-source/arch/arm/mach-tegra/dma.c:259 tegra_dma_abort_req+0xb4/0xc8()
[ 5780.761102] Req was not queued on time
[ 5780.764849] Modules linked in: atmel_mxt_ts
[ 5780.769114] [] (unwind_backtrace+0x0/0xe8) from [] (dump_stack+0x20/0x24)
[ 5780.777660] [] (dump_stack+0x20/0x24) from [] (warn_slowpath_common+0x5c/0x74)
[ 5780.786633] [] (warn_slowpath_common+0x5c/0x74) from [] (warn_slowpath_fmt+0x40/0x48)
[ 5780.796215] [] (warn_slowpath_fmt+0x40/0x48) from [] (tegra_dma_abort_req+0xb4/0xc8)
[ 5780.805717] [] (tegra_dma_abort_req+0xb4/0xc8) from [] (handle_continuous_head_request+0x38/0x60)
[ 5780.816344] [] (handle_continuous_head_request+0x38/0x60) from [] (handle_continuous_sngl_dma+0x90/0xa8)
[ 5780.827578] [] (handle_continuous_sngl_dma+0x90/0xa8) from [] (handle_dma_isr_locked+0x54/0x64)
[ 5780.838030] [] (handle_dma_isr_locked+0x54/0x64) from [] (dma_isr+0xa8/0x100)
[ 5780.846921] [] (dma_isr+0xa8/0x100) from [] (handle_irq_event_percpu+0xb0/0x254)
[ 5780.856070] [] (handle_irq_event_percpu+0xb0/0x254) from [] (handle_irq_event+0x4c/0x6c)
[ 5780.865913] [] (handle_irq_event+0x4c/0x6c) from [] (handle_fasteoi_irq+0xe8/0x10c)
[ 5780.875320] [] (handle_fasteoi_irq+0xe8/0x10c) from [] (generic_handle_irq+0x30/0x40)
[ 5780.884908] [] (generic_handle_irq+0x30/0x40) from [] (handle_IRQ+0xa0/0xbc)
[ 5780.893706] [] (handle_IRQ+0xa0/0xbc) from [] (asm_do_IRQ+0x18/0x1c)
[ 5780.901811] [] (asm_do_IRQ+0x18/0x1c) from [] (__irq_svc+0x38/0xd0)
[ 5780.909814] Exception stack(0xc07f3df0 to 0xc07f3e38)
[ 5780.914873] 3de0:                                 00000000 fe040100 c08a5a60 c08a5a60
[ 5780.923058] 3e00:c07f2000 00000000 00000040 00000035 00000000 c087f258 c07f4040 c07f3e84
[ 5780.931241] 3e20: c07f3e88 c07f3e38 c0061aec c00614bc 20000153 ffffffff
[ 5780.937884] [] (__irq_svc+0x38/0xd0) from [] (__do_softirq+0x6c/0x21c)
[ 5780.946166] [] (__do_softirq+0x6c/0x21c) from [] (irq_exit+0x5c/0xac)
[ 5780.954358] [] (irq_exit+0x5c/0xac) from [] (handle_IRQ+0x84/0xbc)
[ 5780.962288] [] (handle_IRQ+0x84/0xbc) from [] (asm_do_IRQ+0x18/0x1c)
[ 5780.970391] [] (asm_do_IRQ+0x18/0x1c) from [] (__irq_svc+0x38/0xd0)
[ 5780.978394] Exception stack(0xc07f3ed8 to 0xc07f3f20)
[ 5780.983451] 3ec0:                                   c07f3f28 00000fa0
[ 5780.991640] 3ee0:00000000 000f4240 000027ff 00000000 e6af8800 e6af8870 fe205000 c087f258
[ 5780.999829] 3f00:c087e1c4 c07f3f54 009c3ff0 c07f3f20 c005ff60 c004109c 20000153 ffffffff
[ 5781.008027] [] (__irq_svc+0x38/0xd0) from [] (tegra_idle_enter_lp2+0xf0/0x13c)
[ 5781.017007] [] (tegra_idle_enter_lp2+0xf0/0x13c) from [] (cpuidle_idle_call+0x1bc/0x304)
[ 5781.026851] [] (cpuidle_idle_call+0x1bc/0x304) from [] (cpu_idle+0xc0/0x104)
[ 5781.035665] [] (cpu_idle+0xc0/0x104) from [] (rest_init+0x94/0xac)
[ 5781.043608] [] (rest_init+0x94/0xac) from [] (start_kernel+0x2cc/0x324)
[ 5781.051962] ---[ end trace bac093f91cc211c1 ]---

At first, my sampling application seems to be not affected by these warnings (i.e. the snd_pcm_readi function doesn’t return an error code).
After some warnings the snd_pcm_readi function returns an error.
After this, if I restart my application, I observe a strange behaviour (e.g. Left and Right audio channels are swapped). The correct behaviour is restored only when I reboot the Toradex.

Can you help me to find a solution to this problem?

Thank you in advance.

Hi @doc and Welcome to the Toradex Community!

Have you done any changes to the Software? If yes, please share the changes.
Could you provide an example application, thus we can reproduce the error?

Best regards,
Jaski

Hi @jaski.tx, thank you for your comment.
I’ve not used any existing code. I’ve built my application from scratch looking at the documentation that is available for the ALSA library.
The audio acquisition code is now contained in a bigger application so I need some time to extract the audio initialization and sampling code. I’ll share it as soon as possible.
Thanks again.

You are welcome. I will wait for your application code.
Thanks

Hi @jaski.tx, this is the audio sampling code that I have extracted from my application.
I have tested it: after some time the program is running DMA warnings are shown on the console and the program exit with the following error message: Read from audio interface failed (-32): Broken pipe.

#include <stdio.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>

int main(int argc, char *argv[]) {

	int err;
	char *buffer;
	int buffer_frames = 1024;
	unsigned int rate = 96000;
	int nChannels = 2;
	snd_pcm_t *capture_handle;
	snd_pcm_hw_params_t *hw_params;
	snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;

	if ((err = snd_pcm_open (&capture_handle, "hw:0,0", SND_PCM_STREAM_CAPTURE, 0)) < 0)
	{
		printf ("Cannot open audio device (hw:0,0): %s\n", snd_strerror (err));
		return 1;
	}

	if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0)
	{
		printf ("Cannot allocate hardware parameter structure (%s)\n", snd_strerror (err));
		snd_pcm_close(capture_handle);
	    return 1;
	}

	if ((err = snd_pcm_hw_params_any (capture_handle, hw_params)) < 0)
	{
	    printf ("Cannot initialize hardware parameters structure (%s)\n", snd_strerror (err));
	    snd_pcm_hw_params_free (hw_params);
	    snd_pcm_close(capture_handle);
	    return 1;
	}

	if ((err = snd_pcm_hw_params_set_access (capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
	{
		printf ("Cannot set sound data access type (%s)\n", snd_strerror (err));
		snd_pcm_hw_params_free (hw_params);
		snd_pcm_close(capture_handle);
	    return 1;
	}

	if ((err = snd_pcm_hw_params_set_format (capture_handle, hw_params, format)) < 0)
	{
		printf ("Cannot set sample format (%s)\n", snd_strerror (err));
		snd_pcm_hw_params_free (hw_params);
		snd_pcm_close(capture_handle);
	    return 1;
	}

	if ((err = snd_pcm_hw_params_set_rate_near (capture_handle, hw_params, &rate, 0)) < 0)
	{
	    printf ("Cannot set sample rate (%s)\n", snd_strerror (err));
	    snd_pcm_hw_params_free (hw_params);
	    snd_pcm_close(capture_handle);
	    return 1;
	}

	if ((err = snd_pcm_hw_params_set_channels (capture_handle, hw_params, nChannels)) < 0)
	{
	    printf ("Cannot set channels count (%s)\n", snd_strerror (err));
	    snd_pcm_hw_params_free (hw_params);
	    snd_pcm_close(capture_handle);
	    return 1;
	}

	if ((err = snd_pcm_hw_params (capture_handle, hw_params)) < 0)
	{
		printf ("Cannot set hardware parameters (%s)\n", snd_strerror (err));
		snd_pcm_hw_params_free (hw_params);
		snd_pcm_close(capture_handle);
		return 1;
	}

	snd_pcm_hw_params_free (hw_params);

	if ((err = snd_pcm_prepare (capture_handle)) < 0) {
	    printf ("Cannot prepare audio interface for use (%s)\n", snd_strerror (err));
	    snd_pcm_close(capture_handle);
	    return 1;
	}

	buffer = malloc(buffer_frames * snd_pcm_format_width(format) / 8 * nChannels);
	if(buffer == NULL)
	{
		printf("Failed to allocate room for PCM input data\n");
		snd_pcm_close(capture_handle);
	}

	do
	{
		if ((err = snd_pcm_readi (capture_handle, buffer, buffer_frames)) != buffer_frames) {
			printf ("Read from audio interface failed (%d):%s\n", err, snd_strerror (err));
			free(buffer);
			snd_pcm_close(capture_handle);
			return 1;
		}
		usleep(2000); // Simulate sound data processing
	} while(1);


	free(buffer);
	snd_pcm_close (capture_handle);

	return(0);
}

Try increasing the IRQ of your application. Your application might not fill the buffer on time.

Hi, @matthias.tx, thank you for your answer.
Sorry for my ignorance, can you provide me the instructions for increasing the IRQ of my application?

Hi @doc,
you can add just the priorities setting the niceness level. you can find a tutorial here: https://www.thegeekstuff.com/2013/08/nice-renice-command-examples/
But also try to record an audio sample first via the console using arecord and check if you get dropout there.

Thank you!