From fa207129cd96aef629f54142e67ad9fa48c9025c Mon Sep 17 00:00:00 2001 From: Graham Wacey Date: Mon, 1 Jul 2024 16:42:07 +0100 Subject: [PATCH] applications: nrf5340_audio: Audio module improvements Corrections from use, additional testing and fake function updates. Signed-off-by: Graham Wacey --- include/audio_defines.h | 2 +- include/audio_module/audio_module.h | 25 +++ include/data_fifo.h | 20 ++- lib/data_fifo/data_fifo.c | 10 ++ subsys/audio_module/CMakeLists.txt | 2 +- subsys/audio_module/Kconfig | 9 +- subsys/audio_module/audio_module.c | 161 ++++++++++-------- tests/subsys/audio_module/CMakeLists.txt | 2 +- .../src/audio_module_test_common.c | 14 +- .../src/audio_module_test_common.h | 1 + .../{fakes.c => audio_module_test_fakes.c} | 131 +++++++++----- .../{fakes.h => audio_module_test_fakes.h} | 16 +- .../subsys/audio_module/src/bad_param_test.c | 56 +++--- .../subsys/audio_module/src/functional_test.c | 160 ++++++++++++----- tests/subsys/audio_module/src/main.c | 5 +- tests/subsys/audio_module/testcase.yaml | 2 +- 16 files changed, 394 insertions(+), 222 deletions(-) rename tests/subsys/audio_module/src/{fakes.c => audio_module_test_fakes.c} (74%) rename tests/subsys/audio_module/src/{fakes.h => audio_module_test_fakes.h} (87%) diff --git a/include/audio_defines.h b/include/audio_defines.h index d9e0b8d795af..2e554611a850 100644 --- a/include/audio_defines.h +++ b/include/audio_defines.h @@ -57,7 +57,7 @@ struct audio_metadata { * bits_per_sample = 24 * carrier_size = 32 */ - uint8_t carried_bits_pr_sample; + uint8_t carried_bits_per_sample; /* A 32 bit mask indicating which channel(s)/locations are active within * the data. A bit set indicates the location is active and diff --git a/include/audio_module/audio_module.h b/include/audio_module/audio_module.h index 640772cab2c6..8aa6452d6ec0 100644 --- a/include/audio_module/audio_module.h +++ b/include/audio_module/audio_module.h @@ -23,6 +23,19 @@ extern "C" { #include "audio_defines.h" +/** + * @brief Helper macro to configure the modules parameters. + */ +#define AUDIO_MODULE_PARAMETERS(p, dest, stk, stk_size, pri, fifo_rx, fifo_tx, slab, slab_size) \ + (p).description = (dest); \ + (p).thread.stack = (stk); \ + (p).thread.stack_size = (stk_size); \ + (p).thread.priority = (pri); \ + (p).thread.msg_rx = (fifo_rx); \ + (p).thread.msg_tx = (fifo_tx); \ + (p).thread.data_slab = (slab); \ + (p).thread.data_size = (slab_size); + /** * @brief Number of valid location bits. */ @@ -409,6 +422,10 @@ int audio_module_stop(struct audio_module_handle *handle); /** * @brief Send an audio data item to an audio module, all data is consumed by the module. * + * @note: The data pointer and its associated size that are passed via the audio data + * pointer, can be NULL and/or 0. It is the responsibility of the low level module functions + * to handle this correctly. + * * @param handle [in/out] The handle for the receiving module instance. * @param audio_data [in] Pointer to the audio data to send to the module. * @param response_cb [in] Pointer to a callback to run when the buffer is @@ -423,6 +440,10 @@ int audio_module_data_tx(struct audio_module_handle *handle, /** * @brief Retrieve an audio data item from an audio module. * + * @note: The data pointer and its associated size that are passed via the audio data + * pointer, can be NULL and/or 0. It is the responsibility of the low level module functions + * to handle this correctly. + * * @param handle [in/out] The handle to the module instance. * @param audio_data [out] Pointer to the audio data from the module. * @param timeout [in] Non-negative waiting period to wait for operation to complete @@ -441,6 +462,10 @@ int audio_module_data_rx(struct audio_module_handle *handle, struct audio_data * * returned via the module or final module's output FIFO. All the input data is consumed * within the call and thus the input data buffer maybe released once the function returns. * + * @note: The data I/O pointers and their associated sizes that are passed via the audio data + * pointers, can be NULL and/or 0. It is the responsibility of the low level module functions + * to handle this correctly. + * * @param handle_tx [in/out] The handle to the module to send the input audio data to. * @param handle_rx [in/out] The handle to the module to receive audio data from. * @param audio_data_tx [in] Pointer to the audio data to send. diff --git a/include/data_fifo.h b/include/data_fifo.h index 258e359d2ac1..a4a71dd506ca 100644 --- a/include/data_fifo.h +++ b/include/data_fifo.h @@ -42,10 +42,10 @@ struct data_fifo { }; #define DATA_FIFO_DEFINE(name, elements_max_in, block_size_max_in) \ - char __aligned(WB_UP(1)) \ - _msgq_buffer_##name[(elements_max_in) * sizeof(struct data_fifo_msgq)] = {0}; \ - char __aligned(WB_UP(1)) \ - _slab_buffer_##name[(elements_max_in) * (block_size_max_in)] = {0}; \ + char __aligned(WB_UP( \ + 1)) _msgq_buffer_##name[(elements_max_in) * sizeof(struct data_fifo_msgq)] = {0}; \ + char __aligned(WB_UP(1)) _slab_buffer_##name[(elements_max_in) * (block_size_max_in)] = { \ + 0}; \ struct data_fifo name = {.msgq_buffer = _msgq_buffer_##name, \ .slab_buffer = _slab_buffer_##name, \ .block_size_max = block_size_max_in, \ @@ -163,7 +163,7 @@ int data_fifo_empty(struct data_fifo *data_fifo); int data_fifo_uninit(struct data_fifo *data_fifo); /** - * @brief Initialise the data_fifo. + * @brief Initialize the data_fifo. * * @param data_fifo Pointer to the data_fifo structure. * @@ -172,6 +172,16 @@ int data_fifo_uninit(struct data_fifo *data_fifo); */ int data_fifo_init(struct data_fifo *data_fifo); +/** + * @brief Test if the data_fifo state. + * + * @param data_fifo Pointer to the data_fifo structure. + * + * @retval false Uninitialized. + * @retval true Initialized. + */ +bool data_fifo_state(struct data_fifo *data_fifo); + /** * @} */ diff --git a/lib/data_fifo/data_fifo.c b/lib/data_fifo/data_fifo.c index 4a865b15bbed..c0ef1cec683e 100644 --- a/lib/data_fifo/data_fifo.c +++ b/lib/data_fifo/data_fifo.c @@ -206,3 +206,13 @@ int data_fifo_init(struct data_fifo *data_fifo) return ret; } + +bool data_fifo_state(struct data_fifo *data_fifo) +{ + __ASSERT_NO_MSG(data_fifo != NULL); + __ASSERT_NO_MSG(data_fifo->elements_max != 0); + __ASSERT_NO_MSG(data_fifo->block_size_max != 0); + __ASSERT_NO_MSG((data_fifo->block_size_max % WB_UP(1)) == 0); + + return data_fifo->initialized; +} diff --git a/subsys/audio_module/CMakeLists.txt b/subsys/audio_module/CMakeLists.txt index 674c375ff352..f0fa0d2532d1 100644 --- a/subsys/audio_module/CMakeLists.txt +++ b/subsys/audio_module/CMakeLists.txt @@ -4,4 +4,4 @@ # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # -target_sources(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/audio_module.c) +zephyr_sources_ifdef(CONFIG_AUDIO_MODULE audio_module.c) diff --git a/subsys/audio_module/Kconfig b/subsys/audio_module/Kconfig index f0ea1d118a3b..1a52346bd278 100644 --- a/subsys/audio_module/Kconfig +++ b/subsys/audio_module/Kconfig @@ -3,8 +3,7 @@ # # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # - -menu "Audio Module" +menu "Audio Modules" config AUDIO_MODULE tristate "Enable the audio module" @@ -20,8 +19,12 @@ config AUDIO_MODULE_NAME_SIZE int "Maximum size for module naming in characters" default 20 +#----------------------------------------------------------------------------# +menu "Log levels" + module = AUDIO_MODULE module-str = audio_module source "subsys/logging/Kconfig.template.log_config" -endmenu # Audio Module +endmenu # Log levels +endmenu # Audio Modules diff --git a/subsys/audio_module/audio_module.c b/subsys/audio_module/audio_module.c index 846a0fb4d3b7..06c6ae2cadc6 100644 --- a/subsys/audio_module/audio_module.c +++ b/subsys/audio_module/audio_module.c @@ -153,8 +153,10 @@ static void audio_data_release_cb(struct audio_module_handle_private *handle, } if (k_sem_count_get(&hdl->sem) == 0) { + LOG_DBG("Audio data has been consumed in module %s", hdl->name); + /* Audio data has been consumed by all modules so now can free the data memory. */ - k_mem_slab_free(hdl->thread.data_slab, (void **)&audio_data->data); + k_mem_slab_free(hdl->thread.data_slab, (void *)audio_data->data); } } @@ -185,14 +187,14 @@ static int data_tx(struct audio_module_handle *tx_handle, struct audio_module_ha } /* Copy. The audio data itself will remain in its original location. */ - memcpy(&data_msg_rx->audio_data, audio_data, sizeof(struct audio_data)); + memcpy(&(data_msg_rx->audio_data), audio_data, sizeof(struct audio_data)); data_msg_rx->tx_handle = tx_handle; data_msg_rx->response_cb = data_in_response_cb; ret = data_fifo_block_lock(rx_handle->thread.msg_rx, (void **)&data_msg_rx, sizeof(struct audio_module_message)); if (ret) { - data_fifo_block_free(rx_handle->thread.msg_rx, (void **)&data_msg_rx); + data_fifo_block_free(rx_handle->thread.msg_rx, (void *)data_msg_rx); LOG_WRN("Module %s failed to queue audio data, ret %d", rx_handle->name, ret); @@ -244,7 +246,7 @@ static int tx_fifo_put(struct audio_module_handle *handle, LOG_ERR("Failed to send audio data to output of module %s, ret %d", handle->name, ret); - data_fifo_block_free(handle->thread.msg_tx, (void **)&data_msg_tx); + data_fifo_block_free(handle->thread.msg_tx, (void *)data_msg_tx); ret = k_sem_take(&handle->sem, K_NO_WAIT); if (ret) { @@ -254,6 +256,8 @@ static int tx_fifo_put(struct audio_module_handle *handle, return ret; } + LOG_DBG("Sent audio data to output of module %s", handle->name); + return 0; } @@ -275,7 +279,7 @@ static int send_to_connected_modules(struct audio_module_handle *handle, LOG_WRN("Nowhere to send the audio data from module %s so releasing it", handle->name); - k_mem_slab_free(handle->thread.data_slab, (void **)audio_data->data); + k_mem_slab_free(handle->thread.data_slab, (void *)audio_data->data); return 0; } @@ -332,6 +336,8 @@ static int send_to_connected_modules(struct audio_module_handle *handle, return ret; } + + LOG_DBG("Sent audio data to TX message queue for module %s", handle->name); } return 0; @@ -367,7 +373,7 @@ static void module_thread_input(struct audio_module_handle *handle, void *p2, vo * will control the data flow. */ ret = k_mem_slab_alloc(handle->thread.data_slab, (void **)&data, K_NO_WAIT); - __ASSERT(ret, "No free data for module %s, ret %d", handle->name, ret); + __ASSERT(ret == 0, "No free data for module %s, ret %d", handle->name, ret); /* Configure new audio data. */ audio_data.data = data; @@ -377,7 +383,7 @@ static void module_thread_input(struct audio_module_handle *handle, void *p2, vo ret = handle->description->functions->data_process( (struct audio_module_handle_private *)handle, NULL, &audio_data); if (ret) { - k_mem_slab_free(handle->thread.data_slab, (void **)(&data)); + k_mem_slab_free(handle->thread.data_slab, (void *)(data)); LOG_ERR("Data process error in module %s, ret %d", handle->name, ret); continue; @@ -426,7 +432,7 @@ static void module_thread_output(struct audio_module_handle *handle, void *p2, v */ ret = data_fifo_pointer_last_filled_get(handle->thread.msg_rx, (void **)&msg_rx, &size, K_FOREVER); - __ASSERT(ret, "Module %s error in getting last filled", handle->name); + __ASSERT(ret == 0, "Module %s error in getting last filled", handle->name); LOG_DBG("Module %s new audio data received", handle->name); @@ -449,7 +455,7 @@ static void module_thread_output(struct audio_module_handle *handle, void *p2, v &msg_rx->audio_data); } - data_fifo_block_free(handle->thread.msg_rx, (void **)&msg_rx); + data_fifo_block_free(handle->thread.msg_rx, (void *)msg_rx); } CODE_UNREACHABLE; @@ -481,21 +487,17 @@ static void module_thread_in_out(struct audio_module_handle *handle, void *p2, v while (1) { data = NULL; - LOG_DBG("Module %s is waiting for audio data", handle->name); - /* Get a new input message. * Since this input message is queued outside the module, this will then control the * data flow. */ ret = data_fifo_pointer_last_filled_get(handle->thread.msg_rx, (void **)&msg_rx, &size, K_FOREVER); - __ASSERT(ret, "Module %s error in getting last filled", handle->name); - - LOG_DBG("Module %s new audio data received", handle->name); + __ASSERT(ret == 0, "Module %s error in getting last filled %d", handle->name, ret); /* Get a new output buffer. */ ret = k_mem_slab_alloc(handle->thread.data_slab, (void **)&data, K_NO_WAIT); - __ASSERT(ret, "No free data buffer for module %s, dropping input, ret %d", + __ASSERT(ret == 0, "No free data buffer for module %s, dropping input, ret %d", handle->name, ret); /* Configure new audio audio_data. */ @@ -513,9 +515,9 @@ static void module_thread_in_out(struct audio_module_handle *handle, void *p2, v &msg_rx->audio_data); } - data_fifo_block_free(handle->thread.msg_rx, (void **)(&msg_rx)); + data_fifo_block_free(handle->thread.msg_rx, (void *)(msg_rx)); - k_mem_slab_free(handle->thread.data_slab, (void **)(&data)); + k_mem_slab_free(handle->thread.data_slab, (void *)(data)); LOG_ERR("Data process error in module %s, ret %d", handle->name, ret); continue; @@ -529,7 +531,7 @@ static void module_thread_in_out(struct audio_module_handle *handle, void *p2, v &msg_rx->audio_data); } - data_fifo_block_free(handle->thread.msg_rx, (void **)&msg_rx); + data_fifo_block_free(handle->thread.msg_rx, (void *)msg_rx); } CODE_UNREACHABLE; @@ -562,7 +564,7 @@ int audio_module_open(struct audio_module_parameters const *const parameters, /* Clear handle to known state. */ memset(handle, 0, sizeof(struct audio_module_handle)); - /* Allocate the context memory. */ + /* Store pointer to the context. */ handle->context = context; memcpy(handle->name, name, CONFIG_AUDIO_MODULE_NAME_SIZE); @@ -610,6 +612,14 @@ int audio_module_open(struct audio_module_parameters const *const parameters, return -EINVAL; } + if (handle->thread.msg_rx != NULL && !data_fifo_state(handle->thread.msg_rx)) { + data_fifo_init(handle->thread.msg_rx); + } + + if (handle->thread.msg_tx != NULL && !data_fifo_state(handle->thread.msg_tx)) { + data_fifo_init(handle->thread.msg_tx); + } + sys_slist_init(&handle->handle_dest_list); k_mutex_init(&handle->dest_mutex); @@ -659,12 +669,12 @@ int audio_module_close(struct audio_module_handle *handle) } } - if (handle->thread.msg_rx != NULL) { - data_fifo_empty(handle->thread.msg_rx); + if (handle->thread.msg_rx != NULL && data_fifo_state(handle->thread.msg_rx)) { + data_fifo_uninit(handle->thread.msg_rx); } - if (handle->thread.msg_tx != NULL) { - data_fifo_empty(handle->thread.msg_tx); + if (handle->thread.msg_tx != NULL && data_fifo_state(handle->thread.msg_tx)) { + data_fifo_uninit(handle->thread.msg_tx); } /* @@ -674,6 +684,9 @@ int audio_module_close(struct audio_module_handle *handle) k_thread_abort(handle->thread_id); + /* Ensure module handle data is fully cleared. */ + memset(handle, 0, sizeof(struct audio_module_handle)); + LOG_DBG("Closed module %s", handle->name); return 0; @@ -829,6 +842,8 @@ int audio_module_connect(struct audio_module_handle *handle_from, return ret; } + LOG_DBG("Connection(s) created"); + return 0; } @@ -1011,8 +1026,8 @@ int audio_module_data_tx(struct audio_module_handle *handle, return -ECANCELED; } - if (audio_data == NULL || audio_data->data == NULL || audio_data->data_size == 0) { - LOG_ERR("Data parameter error for module %s", handle->name); + if (audio_data == NULL) { + LOG_ERR("Output audio data for module %s has a NULL pointer", handle->name); return -EINVAL; } @@ -1024,11 +1039,11 @@ int audio_module_data_rx(struct audio_module_handle *handle, struct audio_data * { int ret; - struct audio_module_message *msg_tx; - size_t msg_tx_size; + struct audio_module_message *msg_rx = NULL; + size_t msg_rx_size = 0; - if (handle == NULL) { - LOG_ERR("Module handle is NULL"); + if (handle == NULL || audio_data == NULL) { + LOG_ERR("Module handle or audio data pointer are NULL"); return -EINVAL; } @@ -1048,31 +1063,41 @@ int audio_module_data_rx(struct audio_module_handle *handle, struct audio_data * return -ECANCELED; } - if (audio_data == NULL || audio_data->data == NULL || audio_data->data_size == 0) { - LOG_ERR("Input audio data for module %s has NULL pointer or a zero size buffer", - handle->name); - return -EINVAL; - } - - ret = data_fifo_pointer_last_filled_get(handle->thread.msg_tx, (void **)&msg_tx, - &msg_tx_size, timeout); + ret = data_fifo_pointer_last_filled_get(handle->thread.msg_tx, (void **)&msg_rx, + &msg_rx_size, timeout); if (ret) { LOG_ERR("Failed to retrieve data from module %s, ret %d", handle->name, ret); return ret; } - if (msg_tx->audio_data.data == NULL || - msg_tx->audio_data.data_size > audio_data->data_size) { - LOG_ERR("Data output pointer NULL or not enough room for buffer from module %s", - handle->name); - ret = -EINVAL; + if (msg_rx == NULL) { + LOG_ERR("Failed to retrieve message from %s", handle->name); + return -ECANCELED; + } + + if (audio_data->data_size != 0) { + if (msg_rx->audio_data.data_size > audio_data->data_size) { + LOG_ERR("Not enough room for buffer from module %s", handle->name); + ret = -ECANCELED; + } else if (audio_data->data == NULL) { + LOG_WRN("Data pointer to buffer is NULL"); + } else { + memcpy(&audio_data->meta, &msg_rx->audio_data.meta, + sizeof(struct audio_metadata)); + memcpy((uint8_t *)audio_data->data, (uint8_t *)msg_rx->audio_data.data, + msg_rx->audio_data.data_size); + audio_data->data_size = msg_rx->audio_data.data_size; + } } else { - memcpy(&audio_data->meta, &msg_tx->audio_data.meta, sizeof(struct audio_metadata)); - memcpy((uint8_t *)audio_data->data, (uint8_t *)msg_tx->audio_data.data, - msg_tx->audio_data.data_size); + LOG_WRN("Data buffer size is 0"); } - data_fifo_block_free(handle->thread.msg_tx, (void **)&msg_tx); + if (msg_rx->response_cb != NULL) { + msg_rx->response_cb((struct audio_module_handle_private *)msg_rx->tx_handle, + &msg_rx->audio_data); + } + + data_fifo_block_free(handle->thread.msg_tx, (void *)msg_rx); return ret; } @@ -1117,41 +1142,43 @@ int audio_module_data_tx_rx(struct audio_module_handle *handle_tx, return -EINVAL; } - if (audio_data_tx->data == NULL || audio_data_tx->data_size == 0 || - audio_data_rx->data == NULL || audio_data_rx->data_size == 0) { - LOG_ERR("One or both of the have invalid output audio data"); - return -EINVAL; - } - - ret = data_tx(NULL, handle_tx, audio_data_tx, NULL); + ret = data_tx(NULL, handle_rx, audio_data_tx, NULL); if (ret) { LOG_ERR("Failed to send audio data to module %s, ret %d", handle_tx->name, ret); return ret; } - LOG_DBG("Wait for message on module %s TX queue", handle_rx->name); - - ret = data_fifo_pointer_last_filled_get(handle_rx->thread.msg_rx, (void **)&msg_rx, + ret = data_fifo_pointer_last_filled_get(handle_rx->thread.msg_tx, (void **)&msg_rx, &msg_rx_size, timeout); if (ret) { - LOG_ERR("Failed to retrieve audio data from module %s, ret %d", handle_rx->name, + LOG_ERR("Failed to retrieve audio data from module %s, ret %d", handle_tx->name, ret); return ret; } - if (msg_rx->audio_data.data == NULL || msg_rx->audio_data.data_size == 0) { - LOG_ERR("Data output buffer too small for received buffer from module %s " - "(%d)", - handle_rx->name, msg_rx->audio_data.data_size); - ret = -EINVAL; + if (audio_data_rx->data_size != 0) { + if (msg_rx->audio_data.data_size > audio_data_rx->data_size) { + LOG_ERR("Not enough room for buffer from module %s", handle_rx->name); + ret = -ECANCELED; + } else if (audio_data_rx->data == NULL) { + LOG_WRN("Data pointer to buffer is NULL"); + } else { + memcpy(&audio_data_rx->meta, &msg_rx->audio_data.meta, + sizeof(struct audio_metadata)); + memcpy((uint8_t *)audio_data_rx->data, (uint8_t *)msg_rx->audio_data.data, + msg_rx->audio_data.data_size); + audio_data_rx->data_size = msg_rx->audio_data.data_size; + } } else { - memcpy(&audio_data_rx->meta, &msg_rx->audio_data.meta, - sizeof(struct audio_metadata)); - memcpy((uint8_t *)audio_data_rx->data, (uint8_t *)msg_rx->audio_data.data, - msg_rx->audio_data.data_size); + LOG_WRN("Data buffer size is 0"); + } + + if (msg_rx->response_cb != NULL) { + msg_rx->response_cb((struct audio_module_handle_private *)msg_rx->tx_handle, + &msg_rx->audio_data); } - data_fifo_block_free(handle_rx->thread.msg_rx, (void **)&msg_rx); + data_fifo_block_free(handle_rx->thread.msg_tx, (void *)msg_rx); return ret; }; diff --git a/tests/subsys/audio_module/CMakeLists.txt b/tests/subsys/audio_module/CMakeLists.txt index 1c05b1024015..12183fa65a27 100644 --- a/tests/subsys/audio_module/CMakeLists.txt +++ b/tests/subsys/audio_module/CMakeLists.txt @@ -11,7 +11,7 @@ project("Audio module") target_sources(app PRIVATE src/main.c - src/fakes.c + src/audio_module_test_fakes.c src/audio_module_test_common.c src/bad_param_test.c src/functional_test.c diff --git a/tests/subsys/audio_module/src/audio_module_test_common.c b/tests/subsys/audio_module/src/audio_module_test_common.c index 00964ac66768..6c98b50913bd 100644 --- a/tests/subsys/audio_module/src/audio_module_test_common.c +++ b/tests/subsys/audio_module/src/audio_module_test_common.c @@ -6,9 +6,10 @@ #include #include +#include "audio_module/audio_module.h" #include "audio_module_test_common.h" -#include "audio_module/audio_module.h" +#include "audio_module_test_fakes.h" const char *TEST_INSTANCE_NAME = "Test instance"; const char *TEST_STRING = "This is a test string"; @@ -19,6 +20,7 @@ void test_context_set(struct mod_context *ctx, struct mod_config const *const co memcpy(&ctx->test_string, TEST_STRING, sizeof(TEST_STRING)); ctx->test_uint32 = TEST_UINT32; memcpy(&ctx->config, config, sizeof(struct mod_config)); + fake_fifo_counter_reset(); } int test_open_function(struct audio_module_handle_private *handle, @@ -96,8 +98,14 @@ int test_data_process_function(struct audio_module_handle_private *handle, ARG_UNUSED(handle); memcpy(audio_data_tx, audio_data_rx, sizeof(struct audio_data)); - memcpy(audio_data_tx->data, audio_data_rx->data, audio_data_rx->data_size); - audio_data_tx->data_size = audio_data_rx->data_size; + + if (audio_data_rx->data != NULL && audio_data_tx->data != NULL) { + memcpy(audio_data_tx->data, audio_data_rx->data, audio_data_rx->data_size); + + audio_data_tx->data_size = audio_data_rx->data_size; + } else { + printk("The input and output data pointers are NULL"); + } return 0; } diff --git a/tests/subsys/audio_module/src/audio_module_test_common.h b/tests/subsys/audio_module/src/audio_module_test_common.h index 61c8c847895b..d978f1b1fb07 100644 --- a/tests/subsys/audio_module/src/audio_module_test_common.h +++ b/tests/subsys/audio_module/src/audio_module_test_common.h @@ -18,6 +18,7 @@ #define TEST_CONNECTIONS_NUM (5) #define TEST_MODULES_NUM (TEST_CONNECTIONS_NUM - 1) #define TEST_MOD_DATA_SIZE (40) +#define TEST_AUDIO_DATA_ITEMS_NUM (20) struct mod_config { int test_int1; diff --git a/tests/subsys/audio_module/src/fakes.c b/tests/subsys/audio_module/src/audio_module_test_fakes.c similarity index 74% rename from tests/subsys/audio_module/src/fakes.c rename to tests/subsys/audio_module/src/audio_module_test_fakes.c index a00a269bdb61..3dad57c239b7 100644 --- a/tests/subsys/audio_module/src/fakes.c +++ b/tests/subsys/audio_module/src/audio_module_test_fakes.c @@ -9,16 +9,16 @@ #include #include "audio_module_test_common.h" -#include "fakes.h" +#include "audio_module_test_fakes.h" /* Overload the message buffer pointer with a point to one of the an arrays below */ -static int fifo_num; +int fifo_num; struct test_slab_queue { size_t head; size_t tail; size_t size; - size_t locked; + struct k_sem sem; void **data[FAKE_FIFO_MSG_QUEUE_SIZE]; struct audio_module_message msg[FAKE_FIFO_MSG_QUEUE_SIZE]; @@ -28,26 +28,17 @@ struct test_msg_fifo_queue { size_t head; size_t tail; size_t size; - size_t locked; + struct k_sem sem; void **data[FAKE_FIFO_MSG_QUEUE_SIZE]; }; +/* FIFO "slab" */ static struct test_slab_queue test_fifo_slab[FAKE_FIFO_NUM]; +/* FIFO "message" queue */ static struct test_msg_fifo_queue test_fifo_msg_queue[FAKE_FIFO_NUM]; -void data_fifo_deinit(struct data_fifo *data_fifo) -{ - data_fifo->msgq_buffer = (char *)NULL; - data_fifo->slab_buffer = (char *)NULL; - data_fifo->elements_max = 0; - data_fifo->block_size_max = 0; - data_fifo->initialized = false; - - fifo_num = 0; -} - /* * Stubs are defined here, so that multiple *.c files can share them * without having linker issues. @@ -62,20 +53,30 @@ DEFINE_FAKE_VALUE_FUNC(int, data_fifo_pointer_last_filled_get, struct data_fifo DEFINE_FAKE_VOID_FUNC2(data_fifo_block_free, struct data_fifo *, void *); DEFINE_FAKE_VALUE_FUNC(int, data_fifo_num_used_get, struct data_fifo *, uint32_t *, uint32_t *); DEFINE_FAKE_VALUE_FUNC(int, data_fifo_empty, struct data_fifo *); +DEFINE_FAKE_VALUE_FUNC(int, data_fifo_uninit, struct data_fifo *); DEFINE_FAKE_VALUE_FUNC(int, data_fifo_init, struct data_fifo *); +DEFINE_FAKE_VALUE_FUNC(bool, data_fifo_state, struct data_fifo *); +void fake_fifo_counter_reset(void) +{ + fifo_num = 0; +} + +/* Custom fakes implementation */ int fake_data_fifo_pointer_first_vacant_get__succeeds(struct data_fifo *data_fifo, void **data, k_timeout_t timeout) { + int ret; struct test_slab_queue *test_fifo_slab_data = (struct test_slab_queue *)data_fifo->slab_buffer; - if (test_fifo_slab_data->head == test_fifo_slab_data->tail) { - return -EINVAL; - } + zassert_not_equal(data_fifo, NULL, "Data FIFO pointer is NULL"); - *data = &test_fifo_slab_data->msg[test_fifo_slab_data->tail % test_fifo_slab_data->size]; - test_fifo_slab_data->tail = (test_fifo_slab_data->tail + 1) % test_fifo_slab_data->size; + ret = k_sem_take(&test_fifo_slab_data->sem, timeout); + zassert_equal(ret, 0, "Failed to take the slab semaphore: ret %d", ret); + + *data = &test_fifo_slab_data->msg[test_fifo_slab_data->head]; + test_fifo_slab_data->head = (test_fifo_slab_data->head + 1) % test_fifo_slab_data->size; return 0; } @@ -116,15 +117,13 @@ int fake_data_fifo_block_lock__succeeds(struct data_fifo *data_fifo, void **data struct test_msg_fifo_queue *test_fifo_msg = (struct test_msg_fifo_queue *)data_fifo->msgq_buffer; - if (((test_fifo_msg->head + 1) % test_fifo_msg->size) == test_fifo_msg->tail) { - return -EINVAL; - } + zassert_not_equal(data_fifo, NULL, "Data FIFO pointer is NULL"); + + k_sem_give(&test_fifo_msg->sem); test_fifo_msg->data[test_fifo_msg->head] = *data; test_fifo_msg->head = (test_fifo_msg->head + 1) % test_fifo_msg->size; - test_fifo_msg->locked++; - return 0; } @@ -158,13 +157,15 @@ int fake_data_fifo_block_lock__put_fails(struct data_fifo *data_fifo, void **dat int fake_data_fifo_pointer_last_filled_get__succeeds(struct data_fifo *data_fifo, void **data, size_t *size, k_timeout_t timeout) { + int ret; struct audio_module_message *msg; struct test_msg_fifo_queue *test_fifo_msg = (struct test_msg_fifo_queue *)data_fifo->msgq_buffer; - if (test_fifo_msg->tail == test_fifo_msg->head) { - return -EINVAL; - } + zassert_not_equal(data_fifo, NULL, "Data FIFO pointer is NULL"); + + ret = k_sem_take(&test_fifo_msg->sem, timeout); + zassert_equal(ret, 0, "Failed to take the message semaphore: ret %d", ret); msg = (struct audio_module_message *)test_fifo_msg->data[test_fifo_msg->tail]; @@ -174,8 +175,6 @@ int fake_data_fifo_pointer_last_filled_get__succeeds(struct data_fifo *data_fifo *data = msg; *size = sizeof(struct audio_module_message); - test_fifo_msg->locked--; - return 0; } @@ -205,14 +204,13 @@ void fake_data_fifo_block_free__succeeds(struct data_fifo *data_fifo, void *data { ARG_UNUSED(data); + zassert_not_equal(data_fifo, NULL, "Data FIFO pointer is NULL"); + struct test_slab_queue *test_fifo_slab_data = (struct test_slab_queue *)data_fifo->slab_buffer; - if (test_fifo_slab_data->tail == test_fifo_slab_data->head) { - return; - } - - test_fifo_slab_data->head = (test_fifo_slab_data->head + 1) % test_fifo_slab_data->size; + k_sem_give(&test_fifo_slab_data->sem); + test_fifo_slab_data->tail = (test_fifo_slab_data->tail + 1) % test_fifo_slab_data->size; } int fake_data_fifo_num_used_get__succeeds(struct data_fifo *data_fifo, uint32_t *alloced_num, @@ -222,7 +220,7 @@ int fake_data_fifo_num_used_get__succeeds(struct data_fifo *data_fifo, uint32_t (struct test_msg_fifo_queue *)data_fifo->msgq_buffer; *alloced_num = test_fifo_msg->head - test_fifo_msg->tail; - *locked_num = test_fifo_msg->locked; + *locked_num = k_sem_count_get(&test_fifo_msg->sem); return 0; } @@ -239,19 +237,25 @@ int fake_data_fifo_num_used_get__fails(struct data_fifo *data_fifo, uint32_t *al int fake_data_fifo_empty__succeeds(struct data_fifo *data_fifo) { + int ret; struct test_msg_fifo_queue *test_fifo_msg = (struct test_msg_fifo_queue *)data_fifo->msgq_buffer; struct test_slab_queue *test_fifo_slab_data = (struct test_slab_queue *)data_fifo->slab_buffer; + zassert_not_equal(data_fifo, NULL, "Data FIFO pointer is NULL"); + test_fifo_msg->head = 0; test_fifo_msg->tail = 0; test_fifo_msg->size = FAKE_FIFO_MSG_QUEUE_SIZE; - test_fifo_msg->locked = 0; + k_sem_reset(&test_fifo_msg->sem); test_fifo_slab_data->head = 0; test_fifo_slab_data->tail = 0; test_fifo_slab_data->size = FAKE_FIFO_MSG_QUEUE_SIZE; + ret = k_sem_init(&test_fifo_slab_data->sem, FAKE_FIFO_MSG_QUEUE_SIZE, + FAKE_FIFO_MSG_QUEUE_SIZE); + zassert_equal(ret, 0, "Failed to initialize the slab semaphore: ret %d", ret); return 0; } @@ -284,13 +288,42 @@ int fake_data_fifo_empty__timeout_fails(struct data_fifo *data_fifo) return -EAGAIN; } +int fake_data_fifo_uninit__succeeds(struct data_fifo *data_fifo) +{ + int ret; + + zassert_not_equal(data_fifo, NULL, "Data FIFO pointer is NULL"); + + if (data_fifo->initialized) { + ret = data_fifo_empty(data_fifo); + if (ret) { + return ret; + } + + data_fifo->initialized = false; + } + + return 0; +} + +int fake_data_fifo_uninit__fails(struct data_fifo *data_fifo) +{ + ARG_UNUSED(data_fifo); + + return -EINVAL; +} + int fake_data_fifo_init__succeeds(struct data_fifo *data_fifo) { + int ret; struct test_msg_fifo_queue *test_fifo_msg = &test_fifo_msg_queue[fifo_num]; struct test_slab_queue *test_fifo_slab_data = &test_fifo_slab[fifo_num]; + zassert_not_equal(data_fifo, NULL, "Data FIFO pointer is NULL"); + data_fifo->msgq_buffer = (char *)test_fifo_msg; data_fifo->slab_buffer = (char *)test_fifo_slab_data; + data_fifo->elements_max = FAKE_FIFO_MSG_QUEUE_SIZE; data_fifo->block_size_max = TEST_MOD_DATA_SIZE; data_fifo->initialized = true; @@ -300,23 +333,22 @@ int fake_data_fifo_init__succeeds(struct data_fifo *data_fifo) test_fifo_msg->head = 0; test_fifo_msg->tail = 0; test_fifo_msg->size = FAKE_FIFO_MSG_QUEUE_SIZE; - test_fifo_msg->locked = 0; + ret = k_sem_init(&test_fifo_msg->sem, 0, FAKE_FIFO_MSG_QUEUE_SIZE); + zassert_equal(ret, 0, "Failed to initialize the message semaphore: ret %d", ret); test_fifo_slab_data->head = 0; test_fifo_slab_data->tail = 0; test_fifo_slab_data->size = FAKE_FIFO_MSG_QUEUE_SIZE; + ret = k_sem_init(&test_fifo_slab_data->sem, FAKE_FIFO_MSG_QUEUE_SIZE, + FAKE_FIFO_MSG_QUEUE_SIZE); + zassert_equal(ret, 0, "Failed to initialize the slab semaphore: ret %d", ret); for (int i = 0; i < FAKE_FIFO_MSG_QUEUE_SIZE; i++) { - if (((test_fifo_slab_data->head + 1) % test_fifo_slab_data->size) == - test_fifo_slab_data->tail) { - return -ENOMSG; - } - test_fifo_slab_data->data[test_fifo_slab_data->head] = - (void **)&test_fifo_slab_data->msg[i]; - test_fifo_slab_data->head = - (test_fifo_slab_data->head + 1) % test_fifo_slab_data->size; + test_fifo_slab_data->data[i] = (void **)&test_fifo_slab_data->msg[i]; } + data_fifo->initialized = true; + return 0; } @@ -326,3 +358,10 @@ int fake_data_fifo_init__fails(struct data_fifo *data_fifo) return -EINVAL; } + +bool fake_data_fifo_state__succeeds(struct data_fifo *data_fifo) +{ + zassert_not_equal(data_fifo, NULL, "Data FIFO pointer is NULL"); + + return data_fifo->initialized; +} diff --git a/tests/subsys/audio_module/src/fakes.h b/tests/subsys/audio_module/src/audio_module_test_fakes.h similarity index 87% rename from tests/subsys/audio_module/src/fakes.h rename to tests/subsys/audio_module/src/audio_module_test_fakes.h index 52bdcfc1aeae..b38c870e8eae 100644 --- a/tests/subsys/audio_module/src/fakes.h +++ b/tests/subsys/audio_module/src/audio_module_test_fakes.h @@ -13,13 +13,6 @@ #include "audio_module_test_common.h" -/** - * @brief Deinitialize data FIFO structure. - * - * @param data_fifo [in/out] The data FIFO instance. - */ -void data_fifo_deinit(struct data_fifo *data_fifo); - /* Fake functions declaration. */ DECLARE_FAKE_VALUE_FUNC(int, data_fifo_pointer_first_vacant_get, struct data_fifo *, void **, k_timeout_t); @@ -29,7 +22,9 @@ DECLARE_FAKE_VALUE_FUNC(int, data_fifo_pointer_last_filled_get, struct data_fifo DECLARE_FAKE_VOID_FUNC2(data_fifo_block_free, struct data_fifo *, void *); DECLARE_FAKE_VALUE_FUNC(int, data_fifo_num_used_get, struct data_fifo *, uint32_t *, uint32_t *); DECLARE_FAKE_VALUE_FUNC(int, data_fifo_empty, struct data_fifo *); +DECLARE_FAKE_VALUE_FUNC(int, data_fifo_uninit, struct data_fifo *); DECLARE_FAKE_VALUE_FUNC(int, data_fifo_init, struct data_fifo *); +DECLARE_FAKE_VALUE_FUNC(bool, data_fifo_state, struct data_fifo *); /* List of fakes used by this unit tester */ #define DO_FOREACH_FAKE(FUNC) \ @@ -40,9 +35,13 @@ DECLARE_FAKE_VALUE_FUNC(int, data_fifo_init, struct data_fifo *); FUNC(data_fifo_block_free) \ FUNC(data_fifo_num_used_get) \ FUNC(data_fifo_empty) \ + FUNC(data_fifo_uninit) \ FUNC(data_fifo_init) \ + FUNC(data_fifo_state) \ } while (0) +void fake_fifo_counter_reset(void); + int fake_data_fifo_pointer_first_vacant_get__succeeds(struct data_fifo *data_fifo, void **data, k_timeout_t timeout); int fake_data_fifo_pointer_first_vacant_get__timeout_fails(struct data_fifo *data_fifo, void **data, @@ -71,7 +70,10 @@ int fake_data_fifo_empty__count_fails(struct data_fifo *data_fifo); int fake_data_fifo_empty__no_wait_fails(struct data_fifo *data_fifo); int fake_data_fifo_empty__slab_init_fails(struct data_fifo *data_fifo); int fake_data_fifo_empty__timeout_fails(struct data_fifo *data_fifo); +int fake_data_fifo_uninit__succeeds(struct data_fifo *data_fifo); +int fake_data_fifo_uninit__fails(struct data_fifo *data_fifo); int fake_data_fifo_init__succeeds(struct data_fifo *data_fifo); int fake_data_fifo_init__fails(struct data_fifo *data_fifo); +bool fake_data_fifo_state__succeeds(struct data_fifo *data_fifo); #endif /* _FAKES_H_ */ diff --git a/tests/subsys/audio_module/src/bad_param_test.c b/tests/subsys/audio_module/src/bad_param_test.c index 1439aae03332..abce776a77c5 100644 --- a/tests/subsys/audio_module/src/bad_param_test.c +++ b/tests/subsys/audio_module/src/bad_param_test.c @@ -6,9 +6,9 @@ #include #include - -#include "fakes.h" #include "audio_module/audio_module.h" + +#include "audio_module_test_fakes.h" #include "audio_module_test_common.h" static struct audio_module_functions mod_1_functions = {.open = NULL, @@ -26,7 +26,7 @@ static struct audio_module_configuration *config = (struct audio_module_configuration *)&configuration; static struct audio_module_handle handle, handle_tx, handle_rx; static struct mod_context context; -static uint8_t test_data[FAKE_FIFO_MSG_QUEUE_DATA_SIZE]; +static uint8_t test_data[TEST_MOD_DATA_SIZE]; static struct data_fifo mod_fifo_tx, mod_fifo_rx; static struct audio_data test_block, test_block_tx, test_block_rx; static char mod_thread_stack[TEST_MOD_THREAD_STACK_SIZE]; @@ -155,7 +155,7 @@ ZTEST(suite_audio_module_bad_param, test_data_tx_bad_state) NULL, &mod_fifo_rx); test_block.data = &test_data[0]; - test_block.data_size = FAKE_FIFO_MSG_QUEUE_DATA_SIZE; + test_block.data_size = TEST_MOD_DATA_SIZE; ret = audio_module_data_tx(&handle, &test_block, NULL); zassert_equal(ret, -ECANCELED, "Data TX function did not return -EALREADY (%d): ret %d", @@ -199,11 +199,7 @@ ZTEST(suite_audio_module_bad_param, test_data_tx_null) NULL, NULL); test_block.data = &test_data[0]; - test_block.data_size = FAKE_FIFO_MSG_QUEUE_DATA_SIZE; - - ret = audio_module_data_tx(NULL, &test_block, NULL); - zassert_equal(ret, -EINVAL, "Data TX function did not return -EINVAL (%d): ret %d", -EINVAL, - ret); + test_block.data_size = TEST_MOD_DATA_SIZE; ret = audio_module_data_tx(&handle, &test_block, NULL); zassert_equal(ret, -ECANCELED, "Data TX function did not return -ECANCELED (%d): ret %d", @@ -214,20 +210,6 @@ ZTEST(suite_audio_module_bad_param, test_data_tx_null) ret = audio_module_data_tx(&handle, NULL, NULL); zassert_equal(ret, -EINVAL, "Data TX function did not return -EINVAL (%d): ret %d", -EINVAL, ret); - - test_block.data = NULL; - test_block.data_size = FAKE_FIFO_MSG_QUEUE_DATA_SIZE; - - ret = audio_module_data_tx(&handle, &test_block, NULL); - zassert_equal(ret, -EINVAL, "Data TX function did not return -EINVAL (%d): ret %d", -EINVAL, - ret); - - test_block.data = &test_data[0]; - test_block.data_size = 0; - - ret = audio_module_data_tx(&handle, &test_block, NULL); - zassert_equal(ret, -EINVAL, "Data TX function did not return -EINVAL (%d): ret %d", -EINVAL, - ret); } ZTEST(suite_audio_module_bad_param, test_data_rx_bad_state) @@ -241,7 +223,7 @@ ZTEST(suite_audio_module_bad_param, test_data_rx_bad_state) &mod_fifo_tx, NULL); test_block.data = &test_data[0]; - test_block.data_size = FAKE_FIFO_MSG_QUEUE_DATA_SIZE; + test_block.data_size = TEST_MOD_DATA_SIZE; ret = audio_module_data_rx(&handle, &test_block, K_NO_WAIT); zassert_equal(ret, -ECANCELED, "Data RX function did not return -ECANCELED (%d): ret %d", @@ -285,7 +267,7 @@ ZTEST(suite_audio_module_bad_param, test_data_rx_null) NULL, NULL); test_block.data = &test_data[0]; - test_block.data_size = FAKE_FIFO_MSG_QUEUE_DATA_SIZE; + test_block.data_size = TEST_MOD_DATA_SIZE; ret = audio_module_data_rx(NULL, &test_block, K_NO_WAIT); zassert_equal(ret, -EINVAL, "Data RX function did not return -EINVAL (%d): ret %d", -EINVAL, @@ -302,18 +284,18 @@ ZTEST(suite_audio_module_bad_param, test_data_rx_null) ret); test_block.data = NULL; - test_block.data_size = FAKE_FIFO_MSG_QUEUE_DATA_SIZE; + test_block.data_size = TEST_MOD_DATA_SIZE; ret = audio_module_data_rx(&handle, &test_block, K_NO_WAIT); - zassert_equal(ret, -EINVAL, "Data RX function did not return -EINVAL (%d): ret %d", -EINVAL, - ret); + zassert_equal(ret, -ECANCELED, "Data RX function did not return -ECANCELED (%d): ret %d", + -ECANCELED, ret); test_block.data = &test_data[0]; test_block.data_size = 0; ret = audio_module_data_rx(&handle, &test_block, K_NO_WAIT); - zassert_equal(ret, -EINVAL, "Data RX function did not return -EINVAL (%d): ret %d", -EINVAL, - ret); + zassert_equal(ret, -ECANCELED, "Data RX function did not return -ECANCELED (%d): ret %d", + -ECANCELED, ret); } ZTEST(suite_audio_module_bad_param, test_data_tx_rx_bad_state) @@ -331,9 +313,9 @@ ZTEST(suite_audio_module_bad_param, test_data_tx_rx_bad_state) AUDIO_MODULE_STATE_RUNNING, &mod_fifo_tx, &mod_fifo_rx); test_block_tx.data = &test_data[0]; - test_block_tx.data_size = FAKE_FIFO_MSG_QUEUE_DATA_SIZE; + test_block_tx.data_size = TEST_MOD_DATA_SIZE; test_block_rx.data = &test_data[0]; - test_block_rx.data_size = FAKE_FIFO_MSG_QUEUE_DATA_SIZE; + test_block_rx.data_size = TEST_MOD_DATA_SIZE; ret = audio_module_data_tx_rx(&handle_tx, &handle_rx, &test_block_tx, &test_block_rx, K_NO_WAIT); @@ -424,9 +406,9 @@ ZTEST(suite_audio_module_bad_param, test_data_tx_rx_null) AUDIO_MODULE_STATE_RUNNING, NULL, NULL); test_block_tx.data = &test_data[0]; - test_block_tx.data_size = FAKE_FIFO_MSG_QUEUE_DATA_SIZE; + test_block_tx.data_size = TEST_MOD_DATA_SIZE; test_block_rx.data = &test_data[0]; - test_block_rx.data_size = FAKE_FIFO_MSG_QUEUE_DATA_SIZE; + test_block_rx.data_size = TEST_MOD_DATA_SIZE; ret = audio_module_data_tx_rx(NULL, &handle_rx, &test_block_tx, &test_block_rx, K_NO_WAIT); zassert_equal(ret, -EINVAL, "Data TX/RX function did not return -EINVAL (%d): ret %d", @@ -459,7 +441,7 @@ ZTEST(suite_audio_module_bad_param, test_data_tx_rx_null) -EINVAL, ret); test_block_tx.data = NULL; - test_block_tx.data_size = FAKE_FIFO_MSG_QUEUE_DATA_SIZE; + test_block_tx.data_size = TEST_MOD_DATA_SIZE; ret = audio_module_data_tx_rx(&handle_tx, &handle_rx, &test_block_tx, &test_block_rx, K_NO_WAIT); @@ -475,9 +457,9 @@ ZTEST(suite_audio_module_bad_param, test_data_tx_rx_null) -EINVAL, ret); test_block_tx.data = &test_data[0]; - test_block_tx.data_size = FAKE_FIFO_MSG_QUEUE_DATA_SIZE; + test_block_tx.data_size = TEST_MOD_DATA_SIZE; test_block_rx.data = NULL; - test_block_rx.data_size = FAKE_FIFO_MSG_QUEUE_DATA_SIZE; + test_block_rx.data_size = TEST_MOD_DATA_SIZE; ret = audio_module_data_tx_rx(&handle_tx, &handle_rx, &test_block_tx, &test_block_rx, K_NO_WAIT); diff --git a/tests/subsys/audio_module/src/functional_test.c b/tests/subsys/audio_module/src/functional_test.c index fa6e459a9061..0df0a51f49ba 100644 --- a/tests/subsys/audio_module/src/functional_test.c +++ b/tests/subsys/audio_module/src/functional_test.c @@ -7,11 +7,13 @@ #include #include #include - -#include "fakes.h" #include "audio_module/audio_module.h" + +#include "audio_module_test_fakes.h" #include "audio_module_test_common.h" +#define FAKE_FIFO_CALL_TX_RX_TEST_COUNT (3) + K_THREAD_STACK_DEFINE(mod_stack, TEST_MOD_THREAD_STACK_SIZE); K_MEM_SLAB_DEFINE(data_slab, TEST_MOD_DATA_SIZE, FAKE_FIFO_MSG_QUEUE_SIZE, 4); @@ -45,9 +47,7 @@ static struct audio_module_parameters mod_parameters = { .data_slab = &data_slab, .data_size = TEST_MOD_DATA_SIZE}}; struct audio_module_parameters test_mod_parameters; -static struct audio_module_handle handle; static struct mod_context *handle_context; -static struct data_fifo mod_fifo_tx, mod_fifo_rx; /** * @brief Set the minimum for a handle. @@ -217,10 +217,12 @@ static void test_close(const struct audio_module_functions *test_fnct, enum audio_module_state test_state) { int ret; - int empty_call_count = 0; char *test_inst_name = "TEST instance 1"; struct audio_module_description test_mod_description; struct audio_module_functions test_mod_functions; + struct data_fifo fifo_tx; + struct data_fifo fifo_rx; + struct audio_module_handle handle; /* Register resets */ DO_FOREACH_FAKE(RESET_FAKE); @@ -253,21 +255,19 @@ static void test_close(const struct audio_module_functions *test_fnct, data_fifo_empty_fake.custom_fake = fake_data_fifo_empty__succeeds; if (fifo_rx_set) { - data_fifo_deinit(&mod_fifo_rx); - data_fifo_init(&mod_fifo_rx); - handle.thread.msg_rx = &mod_fifo_rx; + ret = data_fifo_init(&fifo_rx); + zassert_equal(ret, 0, "Failed to initialise the RX data FIFO: ret %d", ret); - empty_call_count++; + handle.thread.msg_rx = &fifo_rx; } else { handle.thread.msg_rx = NULL; } if (fifo_tx_set) { - data_fifo_deinit(&mod_fifo_tx); - data_fifo_init(&mod_fifo_tx); - handle.thread.msg_tx = &mod_fifo_tx; + ret = data_fifo_init(&fifo_tx); + zassert_equal(ret, 0, "Failed to initialise the TX data FIFO: ret %d", ret); - empty_call_count++; + handle.thread.msg_tx = &fifo_tx; } else { handle.thread.msg_tx = NULL; } @@ -279,9 +279,6 @@ static void test_close(const struct audio_module_functions *test_fnct, ret = audio_module_close(&handle); zassert_equal(ret, 0, "Close function did not return successfully: ret %d", ret); - zassert_equal(data_fifo_empty_fake.call_count, empty_call_count, - "Failed close, data FIFO empty called %d times", - data_fifo_empty_fake.call_count); zassert_mem_equal(&mod_description, &test_mod_description, sizeof(struct audio_module_description), "Failed close, modified the modules description"); @@ -310,26 +307,28 @@ static void test_open(enum audio_module_type test_type, bool fifo_rx_set, bool f { int ret; char *test_inst_name = "TEST instance 1"; + struct data_fifo fifo_tx = {0}; + struct data_fifo fifo_rx = {0}; + struct audio_module_handle handle; /* Fake internal empty data FIFO success */ data_fifo_init_fake.custom_fake = fake_data_fifo_init__succeeds; + data_fifo_state_fake.custom_fake = fake_data_fifo_state__succeeds; mod_description.functions = &ft_pop; test_context_set(&test_mod_context, &mod_config); if (fifo_rx_set) { - data_fifo_deinit(&mod_fifo_rx); - data_fifo_init(&mod_fifo_rx); - mod_parameters.thread.msg_rx = &mod_fifo_rx; + data_fifo_init(&fifo_rx); + mod_parameters.thread.msg_rx = &fifo_rx; } else { mod_parameters.thread.msg_rx = NULL; } if (fifo_tx_set) { - data_fifo_deinit(&mod_fifo_tx); - data_fifo_init(&mod_fifo_tx); - mod_parameters.thread.msg_tx = &mod_fifo_tx; + data_fifo_init(&fifo_tx); + mod_parameters.thread.msg_tx = &fifo_tx; } else { mod_parameters.thread.msg_tx = NULL; } @@ -459,6 +458,7 @@ static void test_start_stop(bool start, const struct audio_module_functions *tes enum audio_module_state return_state, int ret_expected) { int ret; + struct audio_module_handle handle; mod_description.functions = test_fnct; test_initialize_handle(&handle, &mod_description, &mod_context, NULL); @@ -562,6 +562,7 @@ ZTEST(suite_audio_module_functional, test_names_get_fnct) int ret; char *base_name; char instance_name[CONFIG_AUDIO_MODULE_NAME_SIZE] = {0}; + struct audio_module_handle handle; char *test_base_name_empty = ""; char *test_base_name_long = "Test base name that is longer than the size of CONFIG_AUDIO_MODULE_NAME_SIZE"; @@ -629,6 +630,7 @@ ZTEST(suite_audio_module_functional, test_names_get_fnct) ZTEST(suite_audio_module_functional, test_reconfigure_fnct) { int ret; + struct audio_module_handle handle; mod_description.functions = &ft_pop; test_initialize_handle(&handle, &mod_description, &mod_context, &mod_config); @@ -659,6 +661,7 @@ ZTEST(suite_audio_module_functional, test_reconfigure_fnct) ZTEST(suite_audio_module_functional, test_configuration_get_fnct) { int ret; + struct audio_module_handle handle; mod_description.functions = &ft_pop; test_initialize_handle(&handle, &mod_description, &mod_context, &mod_config); @@ -919,25 +922,28 @@ ZTEST(suite_audio_module_functional, test_data_tx_fnct) char test_data[TEST_MOD_DATA_SIZE]; struct audio_data audio_data = {0}; struct audio_module_message *msg_rx; + struct data_fifo fifo_rx; + struct audio_module_handle handle; test_context_set(&mod_context, &mod_config); /* Fake internal empty data FIFO success */ data_fifo_init_fake.custom_fake = fake_data_fifo_init__succeeds; + data_fifo_uninit_fake.custom_fake = fake_data_fifo_uninit__succeeds; + data_fifo_empty_fake.custom_fake = fake_data_fifo_empty__succeeds; data_fifo_pointer_first_vacant_get_fake.custom_fake = fake_data_fifo_pointer_first_vacant_get__succeeds; data_fifo_block_lock_fake.custom_fake = fake_data_fifo_block_lock__succeeds; data_fifo_pointer_last_filled_get_fake.custom_fake = fake_data_fifo_pointer_last_filled_get__succeeds; data_fifo_block_free_fake.custom_fake = fake_data_fifo_block_free__succeeds; + data_fifo_state_fake.custom_fake = fake_data_fifo_state__succeeds; - data_fifo_deinit(&mod_fifo_rx); - - data_fifo_init(&mod_fifo_rx); + fake_data_fifo_init__succeeds(&fifo_rx); memcpy(&handle.name, test_inst_name, sizeof(*test_inst_name)); handle.description = &mod_description; - handle.thread.msg_rx = &mod_fifo_rx; + handle.thread.msg_rx = &fifo_rx; handle.thread.msg_tx = NULL; handle.thread.data_slab = &data_slab; handle.thread.data_size = TEST_MOD_DATA_SIZE; @@ -948,22 +954,40 @@ ZTEST(suite_audio_module_functional, test_data_tx_fnct) test_data[i] = TEST_MOD_DATA_SIZE - i; } - audio_data.data = &test_data[0]; + audio_data.data = NULL; audio_data.data_size = TEST_MOD_DATA_SIZE; ret = audio_module_data_tx(&handle, &audio_data, NULL); zassert_equal(ret, 0, "Data TX function did not return successfully: ret %d", ret); - ret = data_fifo_pointer_last_filled_get(&mod_fifo_rx, (void **)&msg_rx, &size, K_NO_WAIT); + ret = data_fifo_pointer_last_filled_get(&fifo_rx, (void **)&msg_rx, &size, K_NO_WAIT); zassert_equal(ret, 0, "Data TX function did not return 0: ret %d", 0, ret); - zassert_mem_equal(msg_rx->audio_data.data, &test_data[0], TEST_MOD_DATA_SIZE, - "Failed open, module contexts differ"); + + audio_data.data = test_data; + audio_data.data_size = 0; + + ret = audio_module_data_tx(&handle, &audio_data, NULL); + zassert_equal(ret, 0, "Data TX function did not return successfully: ret %d", ret); + + data_fifo_empty(&fifo_rx); + + audio_data.data = test_data; + audio_data.data_size = TEST_MOD_DATA_SIZE; + + ret = audio_module_data_tx(&handle, &audio_data, NULL); + zassert_equal(ret, 0, "Data TX function did not return successfully: ret %d", ret); + + ret = data_fifo_pointer_last_filled_get(&fifo_rx, (void **)&msg_rx, &size, K_NO_WAIT); + zassert_equal(ret, 0, "Data TX function did not return 0: ret %d", 0, ret); + zassert_mem_equal(msg_rx->audio_data.data, test_data, TEST_MOD_DATA_SIZE, + "Failed Data TX, data differs"); zassert_equal(msg_rx->audio_data.data_size, TEST_MOD_DATA_SIZE, "Failed Data TX function, data sizes differs"); - zassert_equal(data_fifo_pointer_first_vacant_get_fake.call_count, 1, + zassert_equal(data_fifo_pointer_first_vacant_get_fake.call_count, + FAKE_FIFO_CALL_TX_RX_TEST_COUNT, "Data TX failed to get item, data FIFO get called %d times", data_fifo_pointer_first_vacant_get_fake.call_count); - zassert_equal(data_fifo_block_lock_fake.call_count, 1, + zassert_equal(data_fifo_block_lock_fake.call_count, FAKE_FIFO_CALL_TX_RX_TEST_COUNT, "Failed to send item, data FIFO send called %d times", data_fifo_pointer_first_vacant_get_fake.call_count); } @@ -974,64 +998,106 @@ ZTEST(suite_audio_module_functional, test_data_rx_fnct) char *test_inst_name = "TEST instance 1"; char test_data[TEST_MOD_DATA_SIZE]; char data[TEST_MOD_DATA_SIZE] = {0}; - struct audio_data audio_data_in; struct audio_data audio_data_out = {0}; struct audio_module_message *data_msg_tx; + struct data_fifo fifo_tx = {0}; + struct audio_module_handle handle; test_context_set(&mod_context, &mod_config); /* Fake internal empty data FIFO success */ data_fifo_init_fake.custom_fake = fake_data_fifo_init__succeeds; + data_fifo_uninit_fake.custom_fake = fake_data_fifo_uninit__succeeds; + data_fifo_empty_fake.custom_fake = fake_data_fifo_empty__succeeds; data_fifo_pointer_first_vacant_get_fake.custom_fake = fake_data_fifo_pointer_first_vacant_get__succeeds; data_fifo_block_lock_fake.custom_fake = fake_data_fifo_block_lock__succeeds; data_fifo_pointer_last_filled_get_fake.custom_fake = fake_data_fifo_pointer_last_filled_get__succeeds; data_fifo_block_free_fake.custom_fake = fake_data_fifo_block_free__succeeds; + data_fifo_state_fake.custom_fake = fake_data_fifo_state__succeeds; - data_fifo_deinit(&mod_fifo_tx); - - data_fifo_init(&mod_fifo_tx); + fake_data_fifo_init__succeeds(&fifo_tx); memcpy(&handle.name, test_inst_name, sizeof(*test_inst_name)); handle.description = &mod_description; handle.thread.msg_rx = NULL; - handle.thread.msg_tx = &mod_fifo_tx; + handle.thread.msg_tx = &fifo_tx; handle.thread.data_slab = &data_slab; handle.thread.data_size = TEST_MOD_DATA_SIZE; handle.state = AUDIO_MODULE_STATE_RUNNING; handle.context = (struct audio_module_context *)&mod_context; - ret = data_fifo_pointer_first_vacant_get(handle.thread.msg_tx, (void **)&data_msg_tx, - K_NO_WAIT); /* fill data */ for (int i = 0; i < TEST_MOD_DATA_SIZE; i++) { test_data[i] = TEST_MOD_DATA_SIZE - i; } - audio_data_in.data = &test_data[0]; - audio_data_in.data_size = TEST_MOD_DATA_SIZE; + ret = data_fifo_pointer_first_vacant_get(handle.thread.msg_tx, (void **)&data_msg_tx, + K_NO_WAIT); + zassert_equal(ret, 0, "FIFO get function did not return successfully: ret %d", ret); + + data_msg_tx->audio_data.data = test_data; + data_msg_tx->audio_data.data_size = TEST_MOD_DATA_SIZE; + data_msg_tx->tx_handle = NULL; + data_msg_tx->response_cb = NULL; + + ret = data_fifo_block_lock(handle.thread.msg_tx, (void **)&data_msg_tx, + sizeof(struct audio_module_message)); + zassert_equal(ret, 0, "FIFO lock function did not return successfully: ret %d", ret); + + audio_data_out.data = NULL; + audio_data_out.data_size = TEST_MOD_DATA_SIZE; + + ret = audio_module_data_rx(&handle, &audio_data_out, K_NO_WAIT); + zassert_equal(ret, 0, "Data RX function did not return successfully: ret %d", ret); + + ret = data_fifo_pointer_first_vacant_get(handle.thread.msg_tx, (void **)&data_msg_tx, + K_NO_WAIT); + zassert_equal(ret, 0, "FIFO get function did not return successfully: ret %d", ret); + + data_msg_tx->audio_data.data = test_data; + data_msg_tx->audio_data.data_size = TEST_MOD_DATA_SIZE; + data_msg_tx->tx_handle = NULL; + data_msg_tx->response_cb = NULL; + + ret = data_fifo_block_lock(handle.thread.msg_tx, (void **)&data_msg_tx, + sizeof(struct audio_module_message)); + zassert_equal(ret, 0, "FIFO lock function did not return successfully: ret %d", ret); + + audio_data_out.data = data; + audio_data_out.data_size = 0; + + ret = audio_module_data_rx(&handle, &audio_data_out, K_NO_WAIT); + zassert_equal(ret, 0, "Data RX function did not return successfully: ret %d", ret); + + ret = data_fifo_pointer_first_vacant_get(handle.thread.msg_tx, (void **)&data_msg_tx, + K_NO_WAIT); + zassert_equal(ret, 0, "FIFO get function did not return successfully: ret %d", ret); - memcpy(&data_msg_tx->audio_data, &audio_data_in, sizeof(struct audio_data)); + data_msg_tx->audio_data.data = test_data; + data_msg_tx->audio_data.data_size = TEST_MOD_DATA_SIZE; data_msg_tx->tx_handle = NULL; data_msg_tx->response_cb = NULL; ret = data_fifo_block_lock(handle.thread.msg_tx, (void **)&data_msg_tx, sizeof(struct audio_module_message)); + zassert_equal(ret, 0, "FIFO lock function did not return successfully: ret %d", ret); - audio_data_out.data = &data[0]; + audio_data_out.data = data; audio_data_out.data_size = TEST_MOD_DATA_SIZE; ret = audio_module_data_rx(&handle, &audio_data_out, K_NO_WAIT); zassert_equal(ret, 0, "Data RX function did not return successfully: ret %d", ret); - zassert_mem_equal(&test_data[0], audio_data_out.data, TEST_MOD_DATA_SIZE, + zassert_mem_equal(test_data, audio_data_out.data, TEST_MOD_DATA_SIZE, "Failed Data RX function, data differs"); - zassert_equal(audio_data_in.data_size, audio_data_out.data_size, + zassert_equal(audio_data_out.data_size, TEST_MOD_DATA_SIZE, "Failed Data RX function, data sizes differs"); - zassert_equal(data_fifo_pointer_last_filled_get_fake.call_count, 1, + zassert_equal(data_fifo_pointer_last_filled_get_fake.call_count, + FAKE_FIFO_CALL_TX_RX_TEST_COUNT, "Data RX function failed to get item, data FIFO get called %d times", data_fifo_pointer_last_filled_get_fake.call_count); - zassert_equal(data_fifo_block_free_fake.call_count, 1, + zassert_equal(data_fifo_block_free_fake.call_count, FAKE_FIFO_CALL_TX_RX_TEST_COUNT, "Data RX function failed to free item, data FIFO free called %d times", data_fifo_block_free_fake.call_count); } diff --git a/tests/subsys/audio_module/src/main.c b/tests/subsys/audio_module/src/main.c index 72e80831e58e..708a7c01dca5 100644 --- a/tests/subsys/audio_module/src/main.c +++ b/tests/subsys/audio_module/src/main.c @@ -7,8 +7,7 @@ #include #include #include - -#include "fakes.h" +#include "audio_module_test_fakes.h" /* This function runs before each test */ static void run_before(void *fixture) @@ -22,5 +21,5 @@ static void run_before(void *fixture) FFF_RESET_HISTORY(); } -ZTEST_SUITE(suite_audio_module_bad_param, NULL, NULL, NULL, NULL, NULL); +ZTEST_SUITE(suite_audio_module_bad_param, NULL, NULL, run_before, NULL, NULL); ZTEST_SUITE(suite_audio_module_functional, NULL, NULL, run_before, NULL, NULL); diff --git a/tests/subsys/audio_module/testcase.yaml b/tests/subsys/audio_module/testcase.yaml index 35ad5da21c38..d4dc1b9d13f3 100644 --- a/tests/subsys/audio_module/testcase.yaml +++ b/tests/subsys/audio_module/testcase.yaml @@ -1,7 +1,7 @@ tests: nrf5340_audio.audio_module_test: sysbuild: true - platform_allow: qemu_cortex_m3 nrf5340dk/nrf5340/cpuapp + platform_allow: qemu_cortex_m3 integration_platforms: - qemu_cortex_m3 - nrf5340dk/nrf5340/cpuapp