mirror of
https://github.com/hathach/tinyusb.git
synced 2026-03-01 04:58:35 +00:00
add more unit tests for tu_fifo
This commit is contained in:
@ -84,6 +84,7 @@ MaxEmptyLinesToKeep: 2
|
||||
NamespaceIndentation: All
|
||||
PenaltyBreakBeforeFirstCallParameter: 1000000
|
||||
PenaltyBreakOpenParenthesis: 1000000
|
||||
PPIndentWidth: 2
|
||||
QualifierAlignment: Custom
|
||||
QualifierOrder: ['static', 'const', 'volatile', 'restrict', 'type']
|
||||
SpaceAfterTemplateKeyword: false
|
||||
|
||||
@ -85,7 +85,7 @@ bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, uint16_t item_si
|
||||
// Pull & Push
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
#ifdef TUP_MEM_CONST_ADDR
|
||||
#ifdef CFG_TUSB_FIFO_ACCESS_FIXED_ADDR_RW32
|
||||
// Intended to be used to read from hardware USB FIFO in e.g. STM32 where all data is read from a constant address
|
||||
// Code adapted from dcd_synopsys.c
|
||||
// TODO generalize with configurable 1 byte or 4 byte each read
|
||||
@ -164,7 +164,7 @@ static void _ff_push_n(tu_fifo_t *f, const void *app_buf, uint16_t n, uint16_t w
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef TUP_MEM_CONST_ADDR
|
||||
#ifdef CFG_TUSB_FIFO_ACCESS_FIXED_ADDR_RW32
|
||||
case TU_FIFO_FIXED_ADDR_RW32:
|
||||
// Intended for hardware buffers from which it can be read word by word only
|
||||
if (n <= lin_count) {
|
||||
@ -244,7 +244,7 @@ static void _ff_pull_n(tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t rd_ptr,
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef TUP_MEM_CONST_ADDR
|
||||
#ifdef CFG_TUSB_FIFO_ACCESS_FIXED_ADDR_RW32
|
||||
case TU_FIFO_FIXED_ADDR_RW32:
|
||||
if (n <= lin_count) {
|
||||
// Linear only
|
||||
|
||||
@ -24,8 +24,7 @@
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#ifndef TUSB_MCU_H_
|
||||
#define TUSB_MCU_H_
|
||||
#pragma once
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Port/Platform Specific
|
||||
@ -697,9 +696,3 @@
|
||||
#ifndef TUP_DCD_EDPT_CLOSE_API
|
||||
#define TUP_DCD_EDPT_ISO_ALLOC
|
||||
#endif
|
||||
|
||||
#if defined(TUP_USBIP_DWC2) // && CFG_TUD_DWC2_DMA_ENABLE == 0
|
||||
#define TUP_MEM_CONST_ADDR
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@ -24,8 +24,7 @@
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#ifndef TUSB_OPTION_H_
|
||||
#define TUSB_OPTION_H_
|
||||
#pragma once
|
||||
|
||||
#include "common/tusb_compiler.h"
|
||||
|
||||
@ -305,15 +304,26 @@
|
||||
#define CFG_TUH_DWC2_DMA_ENABLE CFG_TUH_DWC2_DMA_ENABLE_DEFAULT
|
||||
#endif
|
||||
|
||||
#if defined(TUP_USBIP_DWC2) && CFG_TUD_DWC2_SLAVE_ENABLE == 1
|
||||
#define TUP_DCD_EDPT_DEDICATED_FIFO
|
||||
#if defined(TUP_USBIP_DWC2)
|
||||
#if CFG_TUD_DWC2_SLAVE_ENABLE
|
||||
#define CFG_TUD_EDPT_DEDICATED_FIFO
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_DWC2_SLAVE_ENABLE
|
||||
#define CFG_TUH_EDPT_DEDICATED_FIFO
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(CFG_TUD_EDPT_DEDICATED_FIFO) || defined(CFG_TUH_EDPT_DEDICATED_FIFO)
|
||||
#define CFG_TUSB_FIFO_ACCESS_FIXED_ADDR_RW32
|
||||
#endif
|
||||
|
||||
//------------- ChipIdea -------------//
|
||||
// Enable CI_HS VBUS Charge. Set this to 1 if the USB_VBUS pin is not connected to 5V VBUS (note: 3.3V is insufficient).
|
||||
// Enable CI_HS VBUS Charge. Set this to 1 if the USB_VBUS pin is not connected to 5V VBUS (note: 3.3V is
|
||||
// insufficient).
|
||||
#ifndef CFG_TUD_CI_HS_VBUS_CHARGE
|
||||
#ifndef CFG_TUD_CI_HS_VBUS_CHARGE_DEFAULT
|
||||
#define CFG_TUD_CI_HS_VBUS_CHARGE_DEFAULT 0
|
||||
#define CFG_TUD_CI_HS_VBUS_CHARGE_DEFAULT 0
|
||||
#endif
|
||||
|
||||
#define CFG_TUD_CI_HS_VBUS_CHARGE CFG_TUD_CI_HS_VBUS_CHARGE_DEFAULT
|
||||
@ -738,7 +748,3 @@
|
||||
|
||||
// To avoid GCC compiler warnings when -pedantic option is used (strict ISO C)
|
||||
typedef int make_iso_compilers_happy;
|
||||
|
||||
#endif /* TUSB_OPTION_H_ */
|
||||
|
||||
/** @} */
|
||||
|
||||
132
test/unit-test/CMakeLists.txt
Normal file
132
test/unit-test/CMakeLists.txt
Normal file
@ -0,0 +1,132 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
project(tinyusb_unit_tests LANGUAGES C)
|
||||
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_C_EXTENSIONS ON)
|
||||
|
||||
# Command to invoke Ceedling. Supports multi-word commands such as "bundle exec ceedling".
|
||||
set(CEEDLING_COMMAND "ceedling" CACHE STRING "Command used to invoke Ceedling (Ruby gem).")
|
||||
separate_arguments(CEEDLING_COMMAND_LIST NATIVE_COMMAND "${CEEDLING_COMMAND}")
|
||||
if (CEEDLING_COMMAND_LIST STREQUAL "")
|
||||
message(FATAL_ERROR "CEEDLING_COMMAND is empty; set it to a valid Ceedling invocation.")
|
||||
endif ()
|
||||
|
||||
list(GET CEEDLING_COMMAND_LIST 0 CEEDLING_LAUNCHER)
|
||||
find_program(CEEDLING_LAUNCHER_PATH NAMES ${CEEDLING_LAUNCHER})
|
||||
if (NOT CEEDLING_LAUNCHER_PATH)
|
||||
message(FATAL_ERROR "Could not find '${CEEDLING_LAUNCHER}' on PATH; adjust CEEDLING_COMMAND or PATH.")
|
||||
endif ()
|
||||
list(REMOVE_AT CEEDLING_COMMAND_LIST 0)
|
||||
list(INSERT CEEDLING_COMMAND_LIST 0 ${CEEDLING_LAUNCHER_PATH})
|
||||
|
||||
set(CEEDLING_WORKDIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
set(CEEDLING_BUILD_DIR ${CEEDLING_WORKDIR}/_build)
|
||||
|
||||
# Helper to add a Ceedling-backed test target that compiles into a real CMake executable.
|
||||
function(add_ceedling_test TARGET_NAME TEST_SOURCE PRODUCT_SOURCES MOCK_SOURCES)
|
||||
set(runner ${CEEDLING_BUILD_DIR}/test/runners/${TARGET_NAME}_runner.c)
|
||||
|
||||
add_custom_target(ceedling_gen_${TARGET_NAME}
|
||||
COMMAND ${CEEDLING_COMMAND_LIST} test:${TARGET_NAME}
|
||||
WORKING_DIRECTORY ${CEEDLING_WORKDIR}
|
||||
BYPRODUCTS ${runner}
|
||||
USES_TERMINAL
|
||||
COMMENT "Generate Ceedling runner/mocks for ${TARGET_NAME}"
|
||||
)
|
||||
|
||||
add_executable(${TARGET_NAME}
|
||||
${TEST_SOURCE}
|
||||
${runner}
|
||||
${MOCK_SOURCES}
|
||||
${CEEDLING_BUILD_DIR}/vendor/unity/src/unity.c
|
||||
${CEEDLING_BUILD_DIR}/vendor/cmock/src/cmock.c
|
||||
${PRODUCT_SOURCES}
|
||||
)
|
||||
|
||||
set_source_files_properties(
|
||||
${runner}
|
||||
${MOCK_SOURCES}
|
||||
${CEEDLING_BUILD_DIR}/vendor/unity/src/unity.c
|
||||
${CEEDLING_BUILD_DIR}/vendor/cmock/src/cmock.c
|
||||
PROPERTIES GENERATED TRUE
|
||||
)
|
||||
|
||||
add_dependencies(${TARGET_NAME} ceedling_gen_${TARGET_NAME})
|
||||
|
||||
target_include_directories(${TARGET_NAME} PRIVATE
|
||||
${CEEDLING_WORKDIR}/test
|
||||
${CEEDLING_WORKDIR}/test/support
|
||||
${CEEDLING_BUILD_DIR}/test/runners
|
||||
${CEEDLING_BUILD_DIR}/test/mocks/${TARGET_NAME}
|
||||
${CEEDLING_BUILD_DIR}/vendor/unity/src
|
||||
${CEEDLING_BUILD_DIR}/vendor/cmock/src
|
||||
${CEEDLING_WORKDIR}/../../src
|
||||
${CEEDLING_WORKDIR}/../../src/common
|
||||
${CEEDLING_WORKDIR}/../../src/device
|
||||
${CEEDLING_WORKDIR}/../../src/class
|
||||
${CEEDLING_WORKDIR}/../../src/class/msc
|
||||
${CEEDLING_WORKDIR}/../../src/host
|
||||
${CEEDLING_WORKDIR}/../../src/typec
|
||||
${CEEDLING_WORKDIR}/../../src/osal
|
||||
)
|
||||
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE _UNITY_TEST_)
|
||||
target_compile_options(${TARGET_NAME} PRIVATE -Wall -Wextra)
|
||||
add_test(NAME ${TARGET_NAME} COMMAND ${TARGET_NAME})
|
||||
endfunction()
|
||||
|
||||
# Custom targets to keep plain Ceedling entry-points available.
|
||||
add_custom_target(ceedling_all
|
||||
COMMAND ${CEEDLING_COMMAND_LIST} test:all
|
||||
WORKING_DIRECTORY ${CEEDLING_WORKDIR}
|
||||
USES_TERMINAL
|
||||
COMMENT "Run Ceedling (Unity) unit tests"
|
||||
)
|
||||
|
||||
add_custom_target(ceedling_clean
|
||||
COMMAND ${CEEDLING_COMMAND_LIST} clean
|
||||
WORKING_DIRECTORY ${CEEDLING_WORKDIR}
|
||||
USES_TERMINAL
|
||||
COMMENT "Clean Ceedling build outputs"
|
||||
)
|
||||
|
||||
add_custom_target(ceedling_clobber
|
||||
COMMAND ${CEEDLING_COMMAND_LIST} clobber
|
||||
WORKING_DIRECTORY ${CEEDLING_WORKDIR}
|
||||
USES_TERMINAL
|
||||
COMMENT "Clobber Ceedling build outputs"
|
||||
)
|
||||
|
||||
# Per-test wiring: mocks are generated under _build/test/mocks/<name>/.
|
||||
add_ceedling_test(
|
||||
test_common_func
|
||||
${CEEDLING_WORKDIR}/test/test_common_func.c
|
||||
""
|
||||
""
|
||||
)
|
||||
|
||||
add_ceedling_test(
|
||||
test_fifo
|
||||
${CEEDLING_WORKDIR}/test/test_fifo.c
|
||||
${CEEDLING_WORKDIR}/../../src/common/tusb_fifo.c
|
||||
""
|
||||
)
|
||||
target_compile_definitions(test_fifo PRIVATE CFG_TUSB_FIFO_ACCESS_FIXED_ADDR_RW32=1)
|
||||
|
||||
add_ceedling_test(
|
||||
test_usbd
|
||||
${CEEDLING_WORKDIR}/test/device/usbd/test_usbd.c
|
||||
"${CEEDLING_WORKDIR}/../../src/tusb.c;${CEEDLING_WORKDIR}/../../src/device/usbd.c;${CEEDLING_WORKDIR}/../../src/device/usbd_control.c;${CEEDLING_WORKDIR}/../../src/common/tusb_fifo.c"
|
||||
"${CEEDLING_BUILD_DIR}/test/mocks/test_usbd/mock_dcd.c;${CEEDLING_BUILD_DIR}/test/mocks/test_usbd/mock_msc_device.c"
|
||||
)
|
||||
|
||||
add_ceedling_test(
|
||||
test_msc_device
|
||||
${CEEDLING_WORKDIR}/test/device/msc/test_msc_device.c
|
||||
"${CEEDLING_WORKDIR}/../../src/tusb.c;${CEEDLING_WORKDIR}/../../src/device/usbd.c;${CEEDLING_WORKDIR}/../../src/device/usbd_control.c;${CEEDLING_WORKDIR}/../../src/class/msc/msc_device.c;${CEEDLING_WORKDIR}/../../src/common/tusb_fifo.c"
|
||||
"${CEEDLING_BUILD_DIR}/test/mocks/test_msc_device/mock_dcd.c"
|
||||
)
|
||||
|
||||
enable_testing()
|
||||
@ -128,6 +128,7 @@
|
||||
:defines:
|
||||
:test:
|
||||
- _UNITY_TEST_
|
||||
- CFG_TUSB_FIFO_ACCESS_FIXED_ADDR_RW32
|
||||
:release: []
|
||||
|
||||
# Enable to inject name of a test as a unique compilation symbol into its respective executable build.
|
||||
|
||||
@ -30,51 +30,52 @@
|
||||
#include "osal/osal.h"
|
||||
#include "tusb_fifo.h"
|
||||
|
||||
#define FIFO_SIZE 64
|
||||
uint8_t tu_ff_buf[FIFO_SIZE * sizeof(uint8_t)];
|
||||
#define FIFO_SIZE 64
|
||||
uint8_t tu_ff_buf[FIFO_SIZE * sizeof(uint8_t)];
|
||||
tu_fifo_t tu_ff = TU_FIFO_INIT(tu_ff_buf, FIFO_SIZE, uint8_t, false);
|
||||
|
||||
tu_fifo_t* ff = &tu_ff;
|
||||
tu_fifo_t *ff = &tu_ff;
|
||||
tu_fifo_buffer_info_t info;
|
||||
|
||||
uint8_t test_data[4096];
|
||||
uint8_t rd_buf[FIFO_SIZE];
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
void setUp(void) {
|
||||
tu_fifo_clear(ff);
|
||||
memset(&info, 0, sizeof(tu_fifo_buffer_info_t));
|
||||
|
||||
for(int i=0; i<sizeof(test_data); i++) test_data[i] = i;
|
||||
for (size_t i = 0; i < sizeof(test_data); i++) {
|
||||
test_data[i] = i;
|
||||
}
|
||||
memset(rd_buf, 0, sizeof(rd_buf));
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
void tearDown(void) {
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Tests
|
||||
//--------------------------------------------------------------------+
|
||||
void test_normal(void)
|
||||
{
|
||||
for(uint8_t i=0; i < FIFO_SIZE; i++) tu_fifo_write(ff, &i);
|
||||
void test_normal(void) {
|
||||
for (uint8_t i = 0; i < FIFO_SIZE; i++) {
|
||||
tu_fifo_write(ff, &i);
|
||||
}
|
||||
|
||||
for(uint8_t i=0; i < FIFO_SIZE; i++)
|
||||
{
|
||||
for (uint8_t i = 0; i < FIFO_SIZE; i++) {
|
||||
uint8_t c;
|
||||
tu_fifo_read(ff, &c);
|
||||
TEST_ASSERT_EQUAL(i, c);
|
||||
}
|
||||
}
|
||||
|
||||
void test_item_size(void)
|
||||
{
|
||||
uint8_t ff4_buf[FIFO_SIZE * sizeof(uint32_t)];
|
||||
void test_item_size(void) {
|
||||
uint8_t ff4_buf[FIFO_SIZE * sizeof(uint32_t)];
|
||||
tu_fifo_t ff4 = TU_FIFO_INIT(ff4_buf, FIFO_SIZE, uint32_t, false);
|
||||
|
||||
uint32_t data4[2*FIFO_SIZE];
|
||||
for(uint32_t i=0; i<sizeof(data4)/4; i++) data4[i] = i;
|
||||
uint32_t data4[2 * FIFO_SIZE];
|
||||
for (uint32_t i = 0; i < sizeof(data4) / 4; i++) {
|
||||
data4[i] = i;
|
||||
}
|
||||
|
||||
// fill up fifo
|
||||
tu_fifo_write_n(&ff4, data4, FIFO_SIZE);
|
||||
@ -84,78 +85,77 @@ void test_item_size(void)
|
||||
|
||||
// read 0 -> 4
|
||||
rd_count = tu_fifo_read_n(&ff4, rd_buf4, 5);
|
||||
TEST_ASSERT_EQUAL( 5, rd_count );
|
||||
TEST_ASSERT_EQUAL_UINT32_ARRAY( data4, rd_buf4, rd_count ); // 0 -> 4
|
||||
TEST_ASSERT_EQUAL(5, rd_count);
|
||||
TEST_ASSERT_EQUAL_UINT32_ARRAY(data4, rd_buf4, rd_count); // 0 -> 4
|
||||
|
||||
tu_fifo_write_n(&ff4, data4+FIFO_SIZE, 5);
|
||||
tu_fifo_write_n(&ff4, data4 + FIFO_SIZE, 5);
|
||||
|
||||
// read all 5 -> 68
|
||||
rd_count = tu_fifo_read_n(&ff4, rd_buf4, FIFO_SIZE);
|
||||
TEST_ASSERT_EQUAL( FIFO_SIZE, rd_count );
|
||||
TEST_ASSERT_EQUAL_UINT32_ARRAY( data4+5, rd_buf4, rd_count ); // 5 -> 68
|
||||
TEST_ASSERT_EQUAL(FIFO_SIZE, rd_count);
|
||||
TEST_ASSERT_EQUAL_UINT32_ARRAY(data4 + 5, rd_buf4, rd_count); // 5 -> 68
|
||||
}
|
||||
|
||||
void test_read_n(void)
|
||||
{
|
||||
void test_read_n(void) {
|
||||
uint16_t rd_count;
|
||||
|
||||
// fill up fifo
|
||||
for(uint8_t i=0; i < FIFO_SIZE; i++) tu_fifo_write(ff, test_data+i);
|
||||
for (uint8_t i = 0; i < FIFO_SIZE; i++) {
|
||||
tu_fifo_write(ff, test_data + i);
|
||||
}
|
||||
|
||||
// case 1: Read index + count < depth
|
||||
// read 0 -> 4
|
||||
rd_count = tu_fifo_read_n(ff, rd_buf, 5);
|
||||
TEST_ASSERT_EQUAL( 5, rd_count );
|
||||
TEST_ASSERT_EQUAL_MEMORY( test_data, rd_buf, rd_count ); // 0 -> 4
|
||||
TEST_ASSERT_EQUAL(5, rd_count);
|
||||
TEST_ASSERT_EQUAL_MEMORY(test_data, rd_buf, rd_count); // 0 -> 4
|
||||
|
||||
// case 2: Read index + count > depth
|
||||
// write 10, 11, 12
|
||||
tu_fifo_write(ff, test_data+FIFO_SIZE);
|
||||
tu_fifo_write(ff, test_data+FIFO_SIZE+1);
|
||||
tu_fifo_write(ff, test_data+FIFO_SIZE+2);
|
||||
tu_fifo_write(ff, test_data + FIFO_SIZE);
|
||||
tu_fifo_write(ff, test_data + FIFO_SIZE + 1);
|
||||
tu_fifo_write(ff, test_data + FIFO_SIZE + 2);
|
||||
|
||||
rd_count = tu_fifo_read_n(ff, rd_buf, 7);
|
||||
TEST_ASSERT_EQUAL( 7, rd_count );
|
||||
TEST_ASSERT_EQUAL(7, rd_count);
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY( test_data+5, rd_buf, rd_count ); // 5 -> 11
|
||||
TEST_ASSERT_EQUAL_MEMORY(test_data + 5, rd_buf, rd_count); // 5 -> 11
|
||||
|
||||
// Should only read until empty
|
||||
TEST_ASSERT_EQUAL( FIFO_SIZE-5+3-7, tu_fifo_read_n(ff, rd_buf, 100) );
|
||||
TEST_ASSERT_EQUAL(FIFO_SIZE - 5 + 3 - 7, tu_fifo_read_n(ff, rd_buf, 100));
|
||||
}
|
||||
|
||||
void test_write_n(void)
|
||||
{
|
||||
void test_write_n(void) {
|
||||
// case 1: wr + count < depth
|
||||
tu_fifo_write_n(ff, test_data, 32); // wr = 32, count = 32
|
||||
|
||||
uint16_t rd_count;
|
||||
|
||||
rd_count = tu_fifo_read_n(ff, rd_buf, 16); // wr = 32, count = 16
|
||||
TEST_ASSERT_EQUAL( 16, rd_count );
|
||||
TEST_ASSERT_EQUAL_MEMORY( test_data, rd_buf, rd_count );
|
||||
TEST_ASSERT_EQUAL(16, rd_count);
|
||||
TEST_ASSERT_EQUAL_MEMORY(test_data, rd_buf, rd_count);
|
||||
|
||||
// case 2: wr + count > depth
|
||||
tu_fifo_write_n(ff, test_data+32, 40); // wr = 72 -> 8, count = 56
|
||||
tu_fifo_write_n(ff, test_data + 32, 40); // wr = 72 -> 8, count = 56
|
||||
|
||||
tu_fifo_read_n(ff, rd_buf, 32); // count = 24
|
||||
TEST_ASSERT_EQUAL_MEMORY( test_data+16, rd_buf, rd_count);
|
||||
tu_fifo_read_n(ff, rd_buf, 32); // count = 24
|
||||
TEST_ASSERT_EQUAL_MEMORY(test_data + 16, rd_buf, rd_count);
|
||||
|
||||
TEST_ASSERT_EQUAL(24, tu_fifo_count(ff));
|
||||
}
|
||||
|
||||
void test_write_double_overflowed(void)
|
||||
{
|
||||
void test_write_double_overflowed(void) {
|
||||
tu_fifo_set_overwritable(ff, true);
|
||||
|
||||
uint8_t rd_buf[FIFO_SIZE] = { 0 };
|
||||
uint8_t* buf = test_data;
|
||||
uint8_t rd_buf[FIFO_SIZE] = {0};
|
||||
uint8_t *buf = test_data;
|
||||
|
||||
// full
|
||||
buf += tu_fifo_write_n(ff, buf, FIFO_SIZE);
|
||||
TEST_ASSERT_EQUAL(FIFO_SIZE, tu_fifo_count(ff));
|
||||
|
||||
// write more, should still full
|
||||
buf += tu_fifo_write_n(ff, buf, FIFO_SIZE-8);
|
||||
buf += tu_fifo_write_n(ff, buf, FIFO_SIZE - 8);
|
||||
TEST_ASSERT_EQUAL(FIFO_SIZE, tu_fifo_count(ff));
|
||||
|
||||
// double overflowed: in total, write more than > 2*FIFO_SIZE
|
||||
@ -165,14 +165,13 @@ void test_write_double_overflowed(void)
|
||||
// reading back should give back data from last FIFO_SIZE write
|
||||
tu_fifo_read_n(ff, rd_buf, FIFO_SIZE);
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY(buf-16, rd_buf+FIFO_SIZE-16, 16);
|
||||
TEST_ASSERT_EQUAL_MEMORY(buf - 16, rd_buf + FIFO_SIZE - 16, 16);
|
||||
|
||||
// TODO whole buffer should match, but we deliberately not implement it
|
||||
// TEST_ASSERT_EQUAL_MEMORY(buf-FIFO_SIZE, rd_buf, FIFO_SIZE);
|
||||
}
|
||||
|
||||
static uint16_t help_write(uint16_t total, uint16_t n)
|
||||
{
|
||||
static uint16_t help_write(uint16_t total, uint16_t n) {
|
||||
tu_fifo_write_n(ff, test_data, n);
|
||||
total = tu_min16(FIFO_SIZE, total + n);
|
||||
|
||||
@ -182,12 +181,11 @@ static uint16_t help_write(uint16_t total, uint16_t n)
|
||||
return total;
|
||||
}
|
||||
|
||||
void test_write_overwritable2(void)
|
||||
{
|
||||
tu_fifo_set_overwritable(ff, true);
|
||||
void test_write_overwritable2(void) {
|
||||
tu_fifo_set_overwritable(ff, true);
|
||||
|
||||
// based on actual crash tests detected by fuzzing
|
||||
uint16_t total = 0;
|
||||
// based on actual crash tests detected by fuzzing
|
||||
uint16_t total = 0;
|
||||
|
||||
total = help_write(total, 12);
|
||||
total = help_write(total, 55);
|
||||
@ -202,13 +200,15 @@ void test_write_overwritable2(void)
|
||||
total = help_write(total, 192);
|
||||
}
|
||||
|
||||
void test_peek(void)
|
||||
{
|
||||
void test_peek(void) {
|
||||
uint8_t temp;
|
||||
|
||||
temp = 10; tu_fifo_write(ff, &temp);
|
||||
temp = 20; tu_fifo_write(ff, &temp);
|
||||
temp = 30; tu_fifo_write(ff, &temp);
|
||||
temp = 10;
|
||||
tu_fifo_write(ff, &temp);
|
||||
temp = 20;
|
||||
tu_fifo_write(ff, &temp);
|
||||
temp = 30;
|
||||
tu_fifo_write(ff, &temp);
|
||||
|
||||
temp = 0;
|
||||
|
||||
@ -222,12 +222,13 @@ void test_peek(void)
|
||||
TEST_ASSERT_EQUAL(30, temp);
|
||||
}
|
||||
|
||||
void test_get_read_info_when_no_wrap()
|
||||
{
|
||||
void test_get_read_info_when_no_wrap() {
|
||||
uint8_t ch = 1;
|
||||
|
||||
// write 6 items
|
||||
for(uint8_t i=0; i < 6; i++) tu_fifo_write(ff, &ch);
|
||||
for (uint8_t i = 0; i < 6; i++) {
|
||||
tu_fifo_write(ff, &ch);
|
||||
}
|
||||
|
||||
// read 2 items
|
||||
tu_fifo_read(ff, &ch);
|
||||
@ -238,19 +239,22 @@ void test_get_read_info_when_no_wrap()
|
||||
TEST_ASSERT_EQUAL(4, info.len_lin);
|
||||
TEST_ASSERT_EQUAL(0, info.len_wrap);
|
||||
|
||||
TEST_ASSERT_EQUAL_PTR(ff->buffer+2, info.ptr_lin);
|
||||
TEST_ASSERT_EQUAL_PTR(ff->buffer + 2, info.ptr_lin);
|
||||
TEST_ASSERT_NULL(info.ptr_wrap);
|
||||
}
|
||||
|
||||
void test_get_read_info_when_wrapped()
|
||||
{
|
||||
void test_get_read_info_when_wrapped() {
|
||||
uint8_t ch = 1;
|
||||
|
||||
// make fifo full
|
||||
for(uint8_t i=0; i < FIFO_SIZE; i++) tu_fifo_write(ff, &ch);
|
||||
for (uint8_t i = 0; i < FIFO_SIZE; i++) {
|
||||
tu_fifo_write(ff, &ch);
|
||||
}
|
||||
|
||||
// read 6 items
|
||||
for(uint8_t i=0; i < 6; i++) tu_fifo_read(ff, &ch);
|
||||
for (uint8_t i = 0; i < 6; i++) {
|
||||
tu_fifo_read(ff, &ch);
|
||||
}
|
||||
|
||||
// write 2 items
|
||||
tu_fifo_write(ff, &ch);
|
||||
@ -258,15 +262,14 @@ void test_get_read_info_when_wrapped()
|
||||
|
||||
tu_fifo_get_read_info(ff, &info);
|
||||
|
||||
TEST_ASSERT_EQUAL(FIFO_SIZE-6, info.len_lin);
|
||||
TEST_ASSERT_EQUAL(FIFO_SIZE - 6, info.len_lin);
|
||||
TEST_ASSERT_EQUAL(2, info.len_wrap);
|
||||
|
||||
TEST_ASSERT_EQUAL_PTR(ff->buffer+6, info.ptr_lin);
|
||||
TEST_ASSERT_EQUAL_PTR(ff->buffer + 6, info.ptr_lin);
|
||||
TEST_ASSERT_EQUAL_PTR(ff->buffer, info.ptr_wrap);
|
||||
}
|
||||
|
||||
void test_get_write_info_when_no_wrap()
|
||||
{
|
||||
void test_get_write_info_when_no_wrap() {
|
||||
uint8_t ch = 1;
|
||||
|
||||
// write 2 items
|
||||
@ -275,20 +278,21 @@ void test_get_write_info_when_no_wrap()
|
||||
|
||||
tu_fifo_get_write_info(ff, &info);
|
||||
|
||||
TEST_ASSERT_EQUAL(FIFO_SIZE-2, info.len_lin);
|
||||
TEST_ASSERT_EQUAL(FIFO_SIZE - 2, info.len_lin);
|
||||
TEST_ASSERT_EQUAL(0, info.len_wrap);
|
||||
|
||||
TEST_ASSERT_EQUAL_PTR(ff->buffer+2, info .ptr_lin);
|
||||
TEST_ASSERT_EQUAL_PTR(ff->buffer + 2, info.ptr_lin);
|
||||
// application should check len instead of ptr.
|
||||
// TEST_ASSERT_NULL(info.ptr_wrap);
|
||||
}
|
||||
|
||||
void test_get_write_info_when_wrapped()
|
||||
{
|
||||
void test_get_write_info_when_wrapped() {
|
||||
uint8_t ch = 1;
|
||||
|
||||
// write 6 items
|
||||
for(uint8_t i=0; i < 6; i++) tu_fifo_write(ff, &ch);
|
||||
for (uint8_t i = 0; i < 6; i++) {
|
||||
tu_fifo_write(ff, &ch);
|
||||
}
|
||||
|
||||
// read 2 items
|
||||
tu_fifo_read(ff, &ch);
|
||||
@ -296,15 +300,14 @@ void test_get_write_info_when_wrapped()
|
||||
|
||||
tu_fifo_get_write_info(ff, &info);
|
||||
|
||||
TEST_ASSERT_EQUAL(FIFO_SIZE-6, info.len_lin);
|
||||
TEST_ASSERT_EQUAL(FIFO_SIZE - 6, info.len_lin);
|
||||
TEST_ASSERT_EQUAL(2, info.len_wrap);
|
||||
|
||||
TEST_ASSERT_EQUAL_PTR(ff->buffer+6, info .ptr_lin);
|
||||
TEST_ASSERT_EQUAL_PTR(ff->buffer + 6, info.ptr_lin);
|
||||
TEST_ASSERT_EQUAL_PTR(ff->buffer, info.ptr_wrap);
|
||||
}
|
||||
|
||||
void test_empty(void)
|
||||
{
|
||||
void test_empty(void) {
|
||||
uint8_t temp;
|
||||
TEST_ASSERT_TRUE(tu_fifo_empty(ff));
|
||||
|
||||
@ -323,7 +326,7 @@ void test_empty(void)
|
||||
TEST_ASSERT_EQUAL(FIFO_SIZE, info.len_lin);
|
||||
TEST_ASSERT_EQUAL(0, info.len_wrap);
|
||||
|
||||
TEST_ASSERT_EQUAL_PTR(ff->buffer, info .ptr_lin);
|
||||
TEST_ASSERT_EQUAL_PTR(ff->buffer, info.ptr_lin);
|
||||
// application should check len instead of ptr.
|
||||
// TEST_ASSERT_NULL(info.ptr_wrap);
|
||||
|
||||
@ -332,11 +335,12 @@ void test_empty(void)
|
||||
TEST_ASSERT_FALSE(tu_fifo_empty(ff));
|
||||
}
|
||||
|
||||
void test_full(void)
|
||||
{
|
||||
void test_full(void) {
|
||||
TEST_ASSERT_FALSE(tu_fifo_full(ff));
|
||||
|
||||
for(uint8_t i=0; i < FIFO_SIZE; i++) tu_fifo_write(ff, &i);
|
||||
for (uint8_t i = 0; i < FIFO_SIZE; i++) {
|
||||
tu_fifo_write(ff, &i);
|
||||
}
|
||||
|
||||
TEST_ASSERT_TRUE(tu_fifo_full(ff));
|
||||
|
||||
@ -353,11 +357,10 @@ void test_full(void)
|
||||
// write info
|
||||
}
|
||||
|
||||
void test_rd_idx_wrap()
|
||||
{
|
||||
void test_rd_idx_wrap(void) {
|
||||
tu_fifo_t ff10;
|
||||
uint8_t buf[10];
|
||||
uint8_t dst[10];
|
||||
uint8_t buf[10];
|
||||
uint8_t dst[10];
|
||||
|
||||
tu_fifo_config(&ff10, buf, 10, 1, 1);
|
||||
|
||||
@ -376,3 +379,187 @@ void test_rd_idx_wrap()
|
||||
TEST_ASSERT_EQUAL(n, 2);
|
||||
TEST_ASSERT_EQUAL(ff10.rd_idx, 6);
|
||||
}
|
||||
|
||||
void test_advance_write_pointer_cases(void) {
|
||||
tu_fifo_clear(ff);
|
||||
|
||||
tu_fifo_advance_write_pointer(ff, 3);
|
||||
TEST_ASSERT_EQUAL(3, ff->wr_idx);
|
||||
TEST_ASSERT_EQUAL(3, tu_fifo_count(ff));
|
||||
|
||||
// advance to cross depth but stay within 0..2*depth window
|
||||
ff->wr_idx = FIFO_SIZE - 2; // 62
|
||||
ff->rd_idx = 0;
|
||||
tu_fifo_advance_write_pointer(ff, 10); // 62 + 10 = 72 within window
|
||||
TEST_ASSERT_EQUAL(72, ff->wr_idx);
|
||||
TEST_ASSERT_EQUAL(FIFO_SIZE, tu_fifo_count(ff));
|
||||
|
||||
// advance past the unused index space (beyond 2*depth)
|
||||
ff->wr_idx = (uint16_t)(2 * FIFO_SIZE - 3); // 125
|
||||
ff->rd_idx = 0;
|
||||
tu_fifo_advance_write_pointer(ff, 6); // forces wrap across unused space
|
||||
TEST_ASSERT_EQUAL(3, ff->wr_idx);
|
||||
TEST_ASSERT_EQUAL(3, tu_fifo_count(ff));
|
||||
}
|
||||
|
||||
void test_advance_read_pointer_cases(void) {
|
||||
tu_fifo_clear(ff);
|
||||
|
||||
ff->wr_idx = 6;
|
||||
tu_fifo_advance_read_pointer(ff, 3);
|
||||
TEST_ASSERT_EQUAL(3, ff->rd_idx);
|
||||
TEST_ASSERT_EQUAL(3, tu_fifo_count(ff));
|
||||
|
||||
ff->wr_idx = FIFO_SIZE + 10; // 74
|
||||
ff->rd_idx = FIFO_SIZE - 10; // 54
|
||||
tu_fifo_advance_read_pointer(ff, 20); // move to match write index within window
|
||||
TEST_ASSERT_EQUAL(74, ff->rd_idx);
|
||||
TEST_ASSERT_EQUAL(0, tu_fifo_count(ff));
|
||||
|
||||
ff->wr_idx = 9;
|
||||
ff->rd_idx = (uint16_t)(2 * FIFO_SIZE - 1); // 127
|
||||
tu_fifo_advance_read_pointer(ff, 6); // crosses unused index space
|
||||
TEST_ASSERT_EQUAL(5, ff->rd_idx);
|
||||
TEST_ASSERT_EQUAL(4, tu_fifo_count(ff));
|
||||
}
|
||||
|
||||
void test_write_n_fixed_addr_rw32_nowrap(void) {
|
||||
tu_fifo_clear(ff);
|
||||
|
||||
volatile uint32_t reg = 0x11223344;
|
||||
uint8_t expected[8] = {0x44, 0x33, 0x22, 0x11, 0x44, 0x33, 0x22, 0x11};
|
||||
|
||||
for (uint8_t n = 1; n <= 8; n++) {
|
||||
tu_fifo_clear(ff);
|
||||
uint16_t written = tu_fifo_write_n_access(ff, (const void *)®, n, TU_FIFO_FIXED_ADDR_RW32);
|
||||
TEST_ASSERT_EQUAL(n, written);
|
||||
TEST_ASSERT_EQUAL(n, tu_fifo_count(ff));
|
||||
|
||||
uint8_t out[8] = {0};
|
||||
tu_fifo_read_n(ff, out, n);
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, out, n);
|
||||
}
|
||||
}
|
||||
|
||||
void test_write_n_fixed_addr_rw32_wrapped(void) {
|
||||
tu_fifo_clear(ff);
|
||||
|
||||
volatile uint32_t reg = 0xA1B2C3D4;
|
||||
uint8_t expected[8] = {0xD4, 0xC3, 0xB2, 0xA1, 0xD4, 0xC3, 0xB2, 0xA1};
|
||||
|
||||
for (uint8_t n = 1; n <= 8; n++) {
|
||||
tu_fifo_clear(ff);
|
||||
// Position the fifo near the end so writes wrap
|
||||
ff->wr_idx = FIFO_SIZE - 3;
|
||||
ff->rd_idx = FIFO_SIZE - 3;
|
||||
|
||||
uint16_t written = tu_fifo_write_n_access(ff, (const void *)®, n, TU_FIFO_FIXED_ADDR_RW32);
|
||||
TEST_ASSERT_EQUAL(n, written);
|
||||
TEST_ASSERT_EQUAL(n, tu_fifo_count(ff));
|
||||
|
||||
uint8_t out[8] = {0};
|
||||
tu_fifo_read_n(ff, out, n);
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, out, n);
|
||||
}
|
||||
}
|
||||
|
||||
void test_read_n_fixed_addr_rw32_nowrap(void) {
|
||||
uint8_t pattern[8] = {0x10, 0x21, 0x32, 0x43, 0x54, 0x65, 0x76, 0x87};
|
||||
uint32_t reg_expected[8] = {
|
||||
0x00000010, 0x00002110, 0x00322110, 0x43322110, 0x00000054, 0x00006554, 0x00766554, 0x87766554};
|
||||
|
||||
for (uint8_t n = 1; n <= 8; n++) {
|
||||
tu_fifo_clear(ff);
|
||||
tu_fifo_write_n(ff, pattern, 8);
|
||||
|
||||
uint32_t reg = 0;
|
||||
uint16_t read_cnt = tu_fifo_read_n_access(ff, ®, n, TU_FIFO_FIXED_ADDR_RW32);
|
||||
TEST_ASSERT_EQUAL(n, read_cnt);
|
||||
TEST_ASSERT_EQUAL(8 - n, tu_fifo_count(ff));
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX32(reg_expected[n - 1], reg);
|
||||
}
|
||||
}
|
||||
|
||||
void test_read_n_fixed_addr_rw32_wrapped(void) {
|
||||
uint8_t pattern[8] = {0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87};
|
||||
uint32_t reg_expected[8] = {
|
||||
0x000000F0, 0x0000E1F0, 0x00D2E1F0, 0xC3D2E1F0, 0x000000B4, 0x0000A5B4, 0x0096A5B4, 0x8796A5B4};
|
||||
|
||||
for (uint8_t n = 1; n <= 8; n++) {
|
||||
tu_fifo_clear(ff);
|
||||
ff->rd_idx = FIFO_SIZE - 2;
|
||||
ff->wr_idx = (uint16_t)(ff->rd_idx + n);
|
||||
|
||||
for (uint8_t i = 0; i < n; i++) {
|
||||
uint8_t idx = (uint8_t)((ff->rd_idx + i) % FIFO_SIZE);
|
||||
ff->buffer[idx] = pattern[i];
|
||||
}
|
||||
|
||||
uint32_t reg = 0;
|
||||
uint16_t read_cnt = tu_fifo_read_n_access(ff, ®, n, TU_FIFO_FIXED_ADDR_RW32);
|
||||
TEST_ASSERT_EQUAL(n, read_cnt);
|
||||
TEST_ASSERT_EQUAL(0, tu_fifo_count(ff));
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX32(reg_expected[n - 1], reg);
|
||||
}
|
||||
}
|
||||
|
||||
void test_get_read_info_advanced_cases(void) {
|
||||
tu_fifo_clear(ff);
|
||||
|
||||
ff->wr_idx = 20;
|
||||
ff->rd_idx = 2;
|
||||
tu_fifo_get_read_info(ff, &info);
|
||||
TEST_ASSERT_EQUAL(18, info.len_lin);
|
||||
TEST_ASSERT_EQUAL(0, info.len_wrap);
|
||||
TEST_ASSERT_EQUAL_PTR(ff->buffer + 2, info.ptr_lin);
|
||||
TEST_ASSERT_NULL(info.ptr_wrap);
|
||||
|
||||
ff->wr_idx = 68; // ptr = 4
|
||||
ff->rd_idx = 56; // ptr = 56
|
||||
tu_fifo_get_read_info(ff, &info);
|
||||
TEST_ASSERT_EQUAL(8, info.len_lin);
|
||||
TEST_ASSERT_EQUAL(4, info.len_wrap);
|
||||
TEST_ASSERT_EQUAL_PTR(ff->buffer + 56, info.ptr_lin);
|
||||
TEST_ASSERT_EQUAL_PTR(ff->buffer, info.ptr_wrap);
|
||||
}
|
||||
|
||||
void test_get_write_info_advanced_cases(void) {
|
||||
tu_fifo_clear(ff);
|
||||
|
||||
ff->wr_idx = 10;
|
||||
ff->rd_idx = 104; // ptr = 40
|
||||
tu_fifo_get_write_info(ff, &info);
|
||||
TEST_ASSERT_EQUAL(30, info.len_lin);
|
||||
TEST_ASSERT_EQUAL(0, info.len_wrap);
|
||||
TEST_ASSERT_EQUAL_PTR(ff->buffer + 10, info.ptr_lin);
|
||||
TEST_ASSERT_NULL(info.ptr_wrap);
|
||||
|
||||
ff->wr_idx = 60;
|
||||
ff->rd_idx = 20;
|
||||
tu_fifo_get_write_info(ff, &info);
|
||||
TEST_ASSERT_EQUAL(4, info.len_lin);
|
||||
TEST_ASSERT_EQUAL(20, info.len_wrap);
|
||||
TEST_ASSERT_EQUAL_PTR(ff->buffer + 60, info.ptr_lin);
|
||||
TEST_ASSERT_EQUAL_PTR(ff->buffer, info.ptr_wrap);
|
||||
}
|
||||
|
||||
void test_correct_read_pointer_cases(void) {
|
||||
tu_fifo_clear(ff);
|
||||
|
||||
// wr beyond depth: rd should be wr - depth
|
||||
ff->wr_idx = FIFO_SIZE + 6; // 70
|
||||
tu_fifo_correct_read_pointer(ff);
|
||||
TEST_ASSERT_EQUAL(6, ff->rd_idx);
|
||||
|
||||
// wr exactly at depth: rd should wrap to zero
|
||||
ff->wr_idx = FIFO_SIZE;
|
||||
tu_fifo_correct_read_pointer(ff);
|
||||
TEST_ASSERT_EQUAL(0, ff->rd_idx);
|
||||
|
||||
// wr below depth: rd should be wr + depth
|
||||
ff->wr_idx = 10;
|
||||
tu_fifo_correct_read_pointer(ff);
|
||||
TEST_ASSERT_EQUAL(FIFO_SIZE + 10, ff->rd_idx);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user