Skip to content

Commit 71847bc

Browse files
committed
[RFC][utest] Add audio driver test framework
Achieve driver framework by operating memory to simulate audio peripheral drivers. And it could be as a draft standrad for other drivers test framework. Signed-off-by: 1078249029 <[email protected]>
1 parent f0609c1 commit 71847bc

File tree

7 files changed

+652
-0
lines changed

7 files changed

+652
-0
lines changed

examples/utest/testcases/Kconfig

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ rsource "kernel/Kconfig"
1212
rsource "cpp11/Kconfig"
1313
rsource "drivers/serial_v2/Kconfig"
1414
rsource "drivers/serial_bypass/Kconfig"
15+
rsource "drivers/audio/Kconfig"
1516
rsource "drivers/ipc/Kconfig"
1617
rsource "posix/Kconfig"
1718
rsource "mm/Kconfig"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
menu "Utest Driver Framewaork API Testcase"
2+
3+
config UTEST_AUDIO_TC
4+
bool "rt_audio_api testcase"
5+
default n
6+
7+
endmenu
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Import('rtconfig')
2+
from building import *
3+
4+
cwd = GetCurrentDir()
5+
src = []
6+
CPPPATH = [cwd]
7+
8+
if GetDepend(['UTEST_AUDIO_TC']):
9+
src += ['audio_tc.c', 'drv_mic.c', 'drv_player.c']
10+
11+
group = DefineGroup('utestcases', src, depend = ['RT_USING_UTESTCASES'], CPPPATH = CPPPATH)
12+
13+
Return('group')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
/*
2+
* Copyright (c) 2006-2025 RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2025-05-01 wumingzi first version
9+
*/
10+
11+
#include "common.h"
12+
13+
rt_uint8_t player_flag = 0;
14+
15+
/* Allocate and initialize memory filled by fill_byte */
16+
static void *alloc_filled_mem(rt_uint8_t fill_byte, rt_size_t size)
17+
{
18+
void *ptr = rt_malloc(size);
19+
if (ptr != NULL)
20+
{
21+
rt_memset(ptr, fill_byte, size);
22+
}
23+
return ptr;
24+
}
25+
26+
/* Check if the memory is filled with fill_byte */
27+
static rt_err_t check_filled_mem(rt_uint8_t fill_byte, rt_uint8_t *mem, size_t size)
28+
{
29+
rt_uint8_t *p = mem;
30+
for (size_t i = 0; i < size; ++i)
31+
{
32+
if (*(p+i) != fill_byte)
33+
{
34+
return -RT_ERROR;
35+
}
36+
}
37+
return RT_EOK;
38+
}
39+
40+
static void player_test(void)
41+
{
42+
int res = 0;
43+
void* player_buffer = RT_NULL;
44+
rt_device_t dev_obj;
45+
46+
dev_obj = rt_device_find(SOUND_PLAYER_DEVICE_NAME);
47+
if (dev_obj == RT_NULL)
48+
{
49+
uassert_not_null(dev_obj);
50+
goto __exit;
51+
}
52+
if (dev_obj->type != RT_Device_Class_Sound)
53+
{
54+
LOG_E("Not an audio player device\n");
55+
goto __exit;
56+
}
57+
58+
res = rt_device_open(dev_obj, RT_DEVICE_OFLAG_WRONLY);
59+
if (res != RT_EOK)
60+
{
61+
LOG_E("Audio player device failed\n");
62+
uassert_true(0);
63+
goto __exit;
64+
}
65+
66+
/* The sampling rate is set by the driver default, so there isn't configuration step */
67+
68+
struct rt_audio_device *audio_dev = rt_container_of(dev_obj, struct rt_audio_device, parent);
69+
struct rt_audio_buf_info buf_info = audio_dev->replay->buf_info;
70+
struct sound_device *snd_dev = rt_container_of(audio_dev, struct sound_device, audio);
71+
72+
player_buffer = alloc_filled_mem(0xAA, TX_DMA_BLOCK_SIZE);
73+
if (player_buffer == RT_NULL)
74+
{
75+
rt_kprintf("Allocate test memory failed\n");
76+
uassert_true(0);
77+
goto __exit;
78+
}
79+
80+
if(snd_dev->tx_fifo == RT_NULL)
81+
{
82+
rt_kprintf("snd_dev->tx_fifo == RT_NULL ");
83+
uassert_true(0);
84+
goto __exit;
85+
}
86+
res = rt_device_write(dev_obj, 0, player_buffer, TX_DMA_BLOCK_SIZE);
87+
if (res != RT_EOK && res != TX_DMA_BLOCK_SIZE)
88+
{
89+
rt_kprintf("Failed to write data to the player device, res = %d\n",res);
90+
uassert_true(0);
91+
goto __exit;
92+
}
93+
94+
player_flag = 1;
95+
while (1)
96+
{
97+
if(player_flag == 2)
98+
{
99+
break;
100+
}
101+
rt_thread_mdelay(10);
102+
}
103+
104+
res = check_filled_mem(0xAA, &buf_info.buffer[0], TX_DMA_BLOCK_SIZE);
105+
if (res != RT_EOK)
106+
{
107+
rt_kprintf("The first memory check failed! Buffer dump\n");
108+
109+
for (rt_size_t i = 0; i < TX_DMA_FIFO_SIZE; i++)
110+
{
111+
rt_kprintf("%02X ", buf_info.buffer[i]);
112+
if (i % 16 == 15) rt_kprintf("\n");
113+
}
114+
rt_kprintf("\n");
115+
uassert_true(0);
116+
goto __exit;
117+
}
118+
119+
rt_free(player_buffer);
120+
player_buffer = RT_NULL;
121+
122+
player_buffer = alloc_filled_mem(0x55, TX_DMA_BLOCK_SIZE);
123+
if (player_buffer == RT_NULL)
124+
{
125+
rt_kprintf("Allocate test memory failed\n");
126+
uassert_true(0);
127+
goto __exit;
128+
}
129+
130+
res = rt_device_write(dev_obj, TX_DMA_BLOCK_SIZE, player_buffer, TX_DMA_BLOCK_SIZE);
131+
if (res != RT_EOK && res != TX_DMA_BLOCK_SIZE)
132+
{
133+
rt_kprintf("Failed to write data to the player device, res = %d\n",res);
134+
uassert_true(0);
135+
goto __exit;
136+
}
137+
138+
player_flag = 2;
139+
while (res != RT_EOK)
140+
{
141+
if(player_flag == 3)
142+
{
143+
break;
144+
}
145+
146+
rt_thread_mdelay(10);
147+
}
148+
149+
res = check_filled_mem(0x55,&buf_info.buffer[TX_DMA_BLOCK_SIZE], TX_DMA_BLOCK_SIZE);
150+
if (res != RT_EOK)
151+
{
152+
rt_kprintf("The second memory check failed! Buffer dump\n");
153+
154+
for (rt_size_t i = 0; i < TX_DMA_FIFO_SIZE; i++)
155+
{
156+
rt_kprintf("%02X ", buf_info.buffer[i]);
157+
if (i % 16 == 15) rt_kprintf("\n");
158+
}
159+
rt_kprintf("\n");
160+
uassert_true(0);
161+
goto __exit;
162+
}
163+
164+
__exit:
165+
166+
if (player_buffer)
167+
{
168+
rt_free(player_buffer);
169+
player_buffer = RT_NULL;
170+
}
171+
172+
if (dev_obj != RT_NULL)
173+
{
174+
player_flag = 4;
175+
rt_device_close(dev_obj);
176+
}
177+
}
178+
179+
static void mic_test(void)
180+
{
181+
rt_device_t dev_obj;
182+
rt_uint8_t *mic_buffer = RT_NULL;
183+
rt_ssize_t res = 0;
184+
rt_ssize_t length = 0;
185+
mic_buffer = (rt_uint8_t *)rt_malloc(RX_DMA_BLOCK_SIZE);
186+
if (mic_buffer == RT_NULL)
187+
{
188+
rt_kprintf("The mic_buffer memory allocate failed\n");
189+
uassert_true(0);
190+
goto __exit;
191+
}
192+
193+
194+
dev_obj = rt_device_find(SOUND_MIC_DEVICE_NAME);
195+
if (dev_obj == RT_NULL)
196+
{
197+
LOG_E("Not a mic device\n");
198+
uassert_true(0);
199+
goto __exit;
200+
}
201+
202+
res = rt_device_open(dev_obj, RT_DEVICE_OFLAG_RDONLY);
203+
if (res != RT_EOK)
204+
{
205+
LOG_E("Audio player device failed\n");
206+
uassert_true(0);
207+
goto __exit;
208+
}
209+
210+
length = rt_device_read(dev_obj, 0, mic_buffer,RX_DMA_BLOCK_SIZE);
211+
if(length < 0)
212+
{
213+
LOG_E("Mic device read err\n");
214+
}
215+
if(mic_flag == 1)
216+
{
217+
res = check_filled_mem(0xAA, (rt_uint8_t*)(mic_buffer), length);
218+
}
219+
if (res != RT_EOK)
220+
{
221+
LOG_E("The first memory check failed! Buffer dump\n");
222+
for (rt_size_t i = 0; i < RX_DMA_FIFO_SIZE; i++)
223+
{
224+
rt_kprintf("%02X ",mic_buffer[i]);
225+
if (i % 16 == 15) rt_kprintf("\n");
226+
}
227+
rt_kprintf("\n");
228+
uassert_true(0);
229+
goto __exit;
230+
}
231+
mic_flag = 2;
232+
233+
while (1)
234+
{
235+
if(mic_flag == 3)
236+
{
237+
length = rt_device_read(dev_obj, 0, mic_buffer, RX_DMA_FIFO_SIZE);
238+
if(length < 0)
239+
{
240+
LOG_E("Mic device read err\n");
241+
}
242+
res = check_filled_mem(0x55, (rt_uint8_t*)(&mic_buffer[0]), length);
243+
244+
if(res != RT_EOK)
245+
{
246+
LOG_E("The second memory check failed! Buffer dump\n");
247+
for (rt_size_t i = 0; i < RX_DMA_FIFO_SIZE; i++)
248+
{
249+
rt_kprintf("%02X ",mic_buffer[i]);
250+
if (i % 16 == 15) rt_kprintf("\n");
251+
}
252+
rt_kprintf("\n");
253+
uassert_true(0);
254+
goto __exit;
255+
}
256+
257+
break;
258+
}
259+
rt_thread_mdelay(100);
260+
}
261+
262+
__exit:
263+
if (mic_buffer)
264+
{
265+
rt_free(mic_buffer);
266+
}
267+
268+
if (dev_obj != RT_NULL)
269+
{
270+
mic_flag = 4;
271+
rt_device_close(dev_obj);
272+
}
273+
}
274+
275+
static void testcase(void)
276+
{
277+
UTEST_UNIT_RUN(player_test);
278+
UTEST_UNIT_RUN(mic_test);
279+
}
280+
281+
static rt_err_t utest_tc_init(void)
282+
{
283+
return RT_EOK;
284+
}
285+
286+
static rt_err_t utest_tc_cleanup(void)
287+
{
288+
return RT_EOK;
289+
}
290+
291+
UTEST_TC_EXPORT(testcase, "testcases.drivers.audio.audio_tc", utest_tc_init, utest_tc_cleanup, 10);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright (c) 2006-2025 RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2025-05-02 wumingzi first version
9+
*/
10+
11+
#include <rtthread.h>
12+
#include <rtdevice.h>
13+
#include <rttypes.h>
14+
#include "utest.h"
15+
16+
/* DMA buffer of audio player device refresh is triggered only when the amount of transmitted data is
17+
* greater than the size of a single block in the data queue */
18+
#define TX_DMA_BLOCK_SIZE RT_AUDIO_REPLAY_MP_BLOCK_SIZE
19+
#define TX_DMA_FIFO_SIZE (RT_AUDIO_REPLAY_MP_BLOCK_SIZE * 2)
20+
#define RX_DMA_BLOCK_SIZE RT_AUDIO_RECORD_PIPE_SIZE
21+
#define RX_DMA_FIFO_SIZE (RT_AUDIO_RECORD_PIPE_SIZE * 2)
22+
23+
#define SOUND_PLAYER_DEVICE_NAME "sound0"
24+
#define SOUND_MIC_DEVICE_NAME "mic0"
25+
26+
#define PLAYER_SAMPLEBITS 16
27+
#define PLAYER_SAMPLERATE 16000
28+
#define PLAYER_CHANNEL 2
29+
#define PLAYER_VOLUME 30
30+
31+
#define MIC_SAMPLEBITS 16
32+
#define MIC_SAMPLERATE 16000
33+
#define MIC_CHANNEL 2
34+
#define MIC_TIME_MS 5000
35+
36+
extern rt_uint8_t mic_flag;
37+
extern rt_uint8_t player_flag ;
38+
39+
struct mic_device
40+
{
41+
struct rt_audio_device audio;
42+
struct rt_audio_configure config;
43+
rt_uint8_t *rx_fifo;
44+
};
45+
struct sound_device
46+
{
47+
struct rt_audio_device audio;
48+
struct rt_audio_configure config;
49+
rt_uint8_t volume;
50+
rt_uint8_t *tx_fifo;
51+
};

0 commit comments

Comments
 (0)