diff --git a/examples/c/circular_buffer/circular_buffer.c b/examples/c/circular_buffer/circular_buffer.c index 99d5fc7..5ab56e2 100644 --- a/examples/c/circular_buffer/circular_buffer.c +++ b/examples/c/circular_buffer/circular_buffer.c @@ -110,7 +110,7 @@ void circular_buf_put(cbuf_handle_t cbuf, uint8_t data) advance_pointer(cbuf); } -int circular_buf_put2(cbuf_handle_t cbuf, uint8_t data) +int circular_buf_try_put(cbuf_handle_t cbuf, uint8_t data) { int r = -1; diff --git a/examples/c/circular_buffer/circular_buffer.h b/examples/c/circular_buffer/circular_buffer.h index e8ce583..202a250 100644 --- a/examples/c/circular_buffer/circular_buffer.h +++ b/examples/c/circular_buffer/circular_buffer.h @@ -2,6 +2,7 @@ #define CIRCULAR_BUFFER_H_ #include +#include /// Opaque circular buffer structure typedef struct circular_buf_t circular_buf_t; @@ -24,15 +25,15 @@ void circular_buf_free(cbuf_handle_t cbuf); /// Requires: cbuf is valid and created by circular_buf_init void circular_buf_reset(cbuf_handle_t cbuf); -/// Put version 1 continues to add data if the buffer is full +/// Put that continues to add data if the buffer is full /// Old data is overwritten /// Requires: cbuf is valid and created by circular_buf_init void circular_buf_put(cbuf_handle_t cbuf, uint8_t data); -/// Put Version 2 rejects new data if the buffer is full +/// Put that rejects new data if the buffer is full /// Requires: cbuf is valid and created by circular_buf_init /// Returns 0 on success, -1 if buffer is full -int circular_buf_put2(cbuf_handle_t cbuf, uint8_t data); +int circular_buf_try_put(cbuf_handle_t cbuf, uint8_t data); /// Retrieve a value from the buffer /// Requires: cbuf is valid and created by circular_buf_init diff --git a/examples/c/circular_buffer/circular_buffer_no_modulo.c b/examples/c/circular_buffer/circular_buffer_no_modulo.c index 2b7fb40..9896e43 100644 --- a/examples/c/circular_buffer/circular_buffer_no_modulo.c +++ b/examples/c/circular_buffer/circular_buffer_no_modulo.c @@ -119,7 +119,7 @@ void circular_buf_put(cbuf_handle_t cbuf, uint8_t data) advance_pointer(cbuf); } -int circular_buf_put2(cbuf_handle_t cbuf, uint8_t data) +int circular_buf_try_put(cbuf_handle_t cbuf, uint8_t data) { int r = -1; diff --git a/examples/c/circular_buffer/circular_buffer_no_modulo_threadsafe.c b/examples/c/circular_buffer/circular_buffer_no_modulo_threadsafe.c index 3fcaaf6..88ec4ea 100644 --- a/examples/c/circular_buffer/circular_buffer_no_modulo_threadsafe.c +++ b/examples/c/circular_buffer/circular_buffer_no_modulo_threadsafe.c @@ -80,7 +80,8 @@ size_t circular_buf_size(cbuf_handle_t cbuf) { assert(cbuf); - size_t size = cbuf->max; + // We account for the space we can't use for thread safety + size_t size = cbuf->max - 1; if(!circular_buf_full(cbuf)) { @@ -101,7 +102,8 @@ size_t circular_buf_capacity(cbuf_handle_t cbuf) { assert(cbuf); - return cbuf->max; + // We account for the space we can't use for thread safety + return cbuf->max - 1; } void circular_buf_put(cbuf_handle_t cbuf, uint8_t data) @@ -113,7 +115,7 @@ void circular_buf_put(cbuf_handle_t cbuf, uint8_t data) advance_pointer(cbuf); } -int circular_buf_put2(cbuf_handle_t cbuf, uint8_t data) +int circular_buf_try_put(cbuf_handle_t cbuf, uint8_t data) { int r = -1; diff --git a/examples/c/circular_buffer_test.c b/examples/c/circular_buffer_test.c deleted file mode 100644 index 045b177..0000000 --- a/examples/c/circular_buffer_test.c +++ /dev/null @@ -1,99 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "circular_buffer/circular_buffer.h" - -#define EXAMPLE_BUFFER_SIZE 10 - -void print_buffer_status(cbuf_handle_t cbuf); - -int main(void) -{ - uint8_t* buffer = malloc(EXAMPLE_BUFFER_SIZE * sizeof(uint8_t)); - - printf("\n=== C Circular Buffer Check ===\n"); - - cbuf_handle_t cbuf = circular_buf_init(buffer, EXAMPLE_BUFFER_SIZE); - - printf("Buffer initialized. "); - print_buffer_status(cbuf); - - printf("\n******\nAdding %d values\n", EXAMPLE_BUFFER_SIZE - 1); - for(uint8_t i = 0; i < (EXAMPLE_BUFFER_SIZE - 1); i++) - { - circular_buf_put(cbuf, i); - printf("Added %u, Size now: %zu\n", i, circular_buf_size(cbuf)); - } - - print_buffer_status(cbuf); - - printf("\n******\nAdding %d values\n", EXAMPLE_BUFFER_SIZE); - for(uint8_t i = 0; i < EXAMPLE_BUFFER_SIZE; i++) - { - circular_buf_put(cbuf, i); - printf("Added %u, Size now: %zu\n", i, circular_buf_size(cbuf)); - } - - print_buffer_status(cbuf); - - printf("\n******\nReading back values: "); - while(!circular_buf_empty(cbuf)) - { - uint8_t data; - circular_buf_get(cbuf, &data); - printf("%u ", data); - } - printf("\n"); - - print_buffer_status(cbuf); - - printf("\n******\nAdding %d values\n", EXAMPLE_BUFFER_SIZE + 5); - for(uint8_t i = 0; i < EXAMPLE_BUFFER_SIZE + 5; i++) - { - circular_buf_put(cbuf, i); - printf("Added %u, Size now: %zu\n", i, circular_buf_size(cbuf)); - } - - print_buffer_status(cbuf); - - printf("\n******\nReading back values: "); - while(!circular_buf_empty(cbuf)) - { - uint8_t data; - circular_buf_get(cbuf, &data); - printf("%u ", data); - } - printf("\n"); - - printf("\n******\nAdding %d values using non-overwrite version\n", EXAMPLE_BUFFER_SIZE + 5); - for(uint8_t i = 0; i < EXAMPLE_BUFFER_SIZE + 5; i++) - { - circular_buf_put2(cbuf, i); - } - - print_buffer_status(cbuf); - - printf("\n******\nReading back values: "); - while(!circular_buf_empty(cbuf)) - { - uint8_t data; - circular_buf_get(cbuf, &data); - printf("%u ", data); - } - printf("\n"); - - free(buffer); - circular_buf_free(cbuf); - - return 0; -} - -void print_buffer_status(cbuf_handle_t cbuf) -{ - printf("Full: %d, empty: %d, size: %zu\n", circular_buf_full(cbuf), circular_buf_empty(cbuf), - circular_buf_size(cbuf)); -} diff --git a/examples/c/circular_buffer_tests/circular_buffer_tests.c b/examples/c/circular_buffer_tests/circular_buffer_tests.c new file mode 100644 index 0000000..2e601dd --- /dev/null +++ b/examples/c/circular_buffer_tests/circular_buffer_tests.c @@ -0,0 +1,159 @@ +/* + * Copyright © 2021 Embedded Artistry LLC. + * See LICENSE file for licensing information. + */ + +// Cmocka needs these +// clang-format off +#include +#include +#include +#include +// clang-format on + +#include "circular_buffer/circular_buffer.h" + +#define CIRCULAR_BUFFER_SIZE 10 + +static uint8_t circular_buffer_storage_[CIRCULAR_BUFFER_SIZE] = {0}; +static cbuf_handle_t handle_ = NULL; + +static int circular_buffer_setup(void** __unused state) +{ + handle_ = circular_buf_init(circular_buffer_storage_, CIRCULAR_BUFFER_SIZE); + + return 0; +} + +static int circular_buffer_teardown(void** __unused state) +{ + circular_buf_free(handle_); + + return 0; +} + +void circular_buffer_init_test(void** __unused state) +{ + assert_non_null(handle_); + assert_true(circular_buf_empty(handle_)); + assert_false(circular_buf_full(handle_)); +#ifdef TEST_WITH_REDUCED_CAPACITY + // We are using a strategy that reserves an empty slot for thread safety + assert_int_equal(circular_buf_capacity(handle_), CIRCULAR_BUFFER_SIZE - 1); +#else + assert_int_equal(circular_buf_capacity(handle_), CIRCULAR_BUFFER_SIZE); +#endif +} + +void circular_buf_put_get_test(void** __unused state) +{ + const int capacity = circular_buf_capacity(handle_); + for(int i = 0; i < capacity; i++) + { + circular_buf_put(handle_, i); + + assert_int_equal(i + 1, circular_buf_size(handle_)); + } + + // Check overflow condition + circular_buf_put(handle_, capacity); + assert_int_equal(capacity, circular_buf_size(handle_)); + + // Check get - we are expecting that one byte has been overwritten + // so we should see that the data is [1..10] instead of [0..9] + for(int i = 0; i < capacity; i++) + { + uint8_t data; + circular_buf_get(handle_, &data); + assert_int_equal(data, i + 1); + } +} + +void circular_buf_try_put_get_test(void** __unused state) +{ + int success; + const int capacity = circular_buf_capacity(handle_); + + for(int i = 0; i < capacity; i++) + { + success = circular_buf_try_put(handle_, i); + assert_int_equal(success, 0); + assert_int_equal(i + 1, circular_buf_size(handle_)); + } + + // Check overflow condition + success = circular_buf_try_put(handle_, capacity); + assert_int_equal(success, -1); + + // Check get - we are expecting that the previous put failed, + // so we should see that the data is [0..9] + for(int i = 0; i < capacity; i++) + { + uint8_t data; + circular_buf_get(handle_, &data); + assert_int_equal(data, i); + } +} + +void circular_buffer_full_test(void** __unused state) +{ + const int capacity = circular_buf_capacity(handle_); + + for(int i = 0; i < capacity; i++) + { + assert_false(circular_buf_full(handle_)); + circular_buf_put(handle_, i); + } + + assert_true(circular_buf_full(handle_)); +} + +void circular_buffer_empty_test(void** __unused state) +{ + const int capacity = circular_buf_capacity(handle_); + + assert_true(circular_buf_empty(handle_)); + + for(int i = 0; i < capacity; i++) + { + circular_buf_put(handle_, i); + assert_false(circular_buf_empty(handle_)); + } +} + +void circular_buffer_get_more_than_stored_test(void** __unused state) +{ + uint8_t data; + + // We will put one and read two + + circular_buf_put(handle_, 1); + + assert_int_equal(0, circular_buf_get(handle_, &data)); + assert_int_equal(data, 1); + data = 0; + assert_int_equal(-1, circular_buf_get(handle_, &data)); + assert_int_equal(data, 0); +} + +#pragma mark - Public Functions - + +int circular_buffer_test_suite(void) +{ + const struct CMUnitTest circular_buffer_tests[] = { + cmocka_unit_test_setup_teardown(circular_buffer_init_test, circular_buffer_setup, + circular_buffer_teardown), + cmocka_unit_test_setup_teardown(circular_buf_put_get_test, circular_buffer_setup, + circular_buffer_teardown), + cmocka_unit_test_setup_teardown(circular_buf_try_put_get_test, circular_buffer_setup, + circular_buffer_teardown), + cmocka_unit_test_setup_teardown(circular_buffer_full_test, circular_buffer_setup, + circular_buffer_teardown), + cmocka_unit_test_setup_teardown(circular_buffer_empty_test, circular_buffer_setup, + circular_buffer_teardown), + cmocka_unit_test_setup_teardown(circular_buffer_get_more_than_stored_test, + circular_buffer_setup, circular_buffer_teardown), + }; + + return cmocka_run_group_tests(circular_buffer_tests, NULL, NULL); +} diff --git a/examples/c/circular_buffer_tests/circular_buffer_tests.h b/examples/c/circular_buffer_tests/circular_buffer_tests.h new file mode 100644 index 0000000..54f0dde --- /dev/null +++ b/examples/c/circular_buffer_tests/circular_buffer_tests.h @@ -0,0 +1,11 @@ +/* + * Copyright © 2021 Embedded Artistry LLC. + * See LICENSE file for licensing information. + */ + +#ifndef CIRCULAR_BUFFER_TESTS_H_ +#define CIRCULAR_BUFFER_TESTS_H_ + +int circular_buffer_test_suite(void); + +#endif // CIRCULAR_BUFFER_TESTS_H_ diff --git a/examples/c/linked_list.h b/examples/c/linked_list/linked_list.h similarity index 100% rename from examples/c/linked_list.h rename to examples/c/linked_list/linked_list.h diff --git a/examples/c/malloc_aligned.c b/examples/c/malloc/malloc_aligned.c similarity index 100% rename from examples/c/malloc_aligned.c rename to examples/c/malloc/malloc_aligned.c diff --git a/examples/c/malloc_freelist.c b/examples/c/malloc/malloc_freelist.c similarity index 100% rename from examples/c/malloc_freelist.c rename to examples/c/malloc/malloc_freelist.c diff --git a/examples/c/malloc_freelist.h b/examples/c/malloc/malloc_freelist.h similarity index 100% rename from examples/c/malloc_freelist.h rename to examples/c/malloc/malloc_freelist.h diff --git a/examples/c/malloc_test.c b/examples/c/malloc/malloc_test.c similarity index 100% rename from examples/c/malloc_test.c rename to examples/c/malloc/malloc_test.c diff --git a/examples/c/malloc_threadx.c b/examples/c/malloc/malloc_threadx.c similarity index 100% rename from examples/c/malloc_threadx.c rename to examples/c/malloc/malloc_threadx.c diff --git a/examples/c/memory.h b/examples/c/malloc/memory.h similarity index 100% rename from examples/c/memory.h rename to examples/c/malloc/memory.h diff --git a/examples/c/malloc/meson.build b/examples/c/malloc/meson.build new file mode 100644 index 0000000..69b4956 --- /dev/null +++ b/examples/c/malloc/meson.build @@ -0,0 +1,21 @@ +memory_inc = include_directories('.') + +libmalloc_threadx = static_library('malloc_threadx', + 'malloc_threadx.c', + c_args: '-fno-builtin', + dependencies: threadx_dep +) + +executable('malloc_aligned', + 'malloc_aligned.c', + c_args: '-DCOMPILE_AS_EXAMPLE', +) + +executable('malloc_freelist', + [ + 'malloc_freelist.c', + 'malloc_test.c' + ], + dependencies: linked_list_dep, + c_args: '-DCOMPILE_AS_EXAMPLE', +) diff --git a/examples/c/meson.build b/examples/c/meson.build index 6262b68..eb45599 100644 --- a/examples/c/meson.build +++ b/examples/c/meson.build @@ -1,57 +1,64 @@ # C examples Meson Build File +linked_list_dep = declare_dependency( + include_directories: 'linked_list' +) + subdir('fixed_point') +subdir('malloc') + +############# +# Libraries # +############# static_library('interrupt_latency', 'interrupt_latency.c' ) +############### +# Executables # +############### + executable('refactoring_global_data', 'refactoring_global_data.c' ) -executable('circular_buffer', - [ - 'circular_buffer_test.c', - 'circular_buffer/circular_buffer.c' - ], - include_directories: include_directories('circular_buffer'), - c_args: '-DCOMPILE_AS_EXAMPLE' -) +################### +# Circular Buffer # +################### -executable('circular_buffer_no_modulo', - [ - 'circular_buffer_test.c', - 'circular_buffer/circular_buffer_no_modulo.c' - ], - include_directories: include_directories('circular_buffer'), - c_args: '-DCOMPILE_AS_EXAMPLE' +circular_buffer_test_dep = declare_dependency( + sources: files( + 'circular_buffer/circular_buffer.c', + 'circular_buffer_tests/circular_buffer_tests.c' + ), + include_directories: [ + include_directories('.'), + include_directories('circular_buffer_tests'), + ] ) -executable('circular_buffer_no_modulo_threadsafe', - [ - 'circular_buffer_test.c', - 'circular_buffer/circular_buffer_no_modulo_threadsafe.c' - ], - include_directories: include_directories('circular_buffer'), - c_args: '-DCOMPILE_AS_EXAMPLE' -) +cmocka_test_deps += circular_buffer_test_dep -executable('malloc_aligned', - 'malloc_aligned.c', - c_args: '-DCOMPILE_AS_EXAMPLE', +circular_buffer_no_modulo_test_dep = declare_dependency( + sources: files( + 'circular_buffer/circular_buffer_no_modulo.c', + 'circular_buffer_tests/circular_buffer_tests.c' + ), + include_directories: [ + include_directories('.'), + include_directories('circular_buffer_tests'), + ] ) -executable('malloc_freelist', - [ - 'malloc_freelist.c', - 'malloc_test.c' +circular_buffer_no_modulo_threadsafe_dep = declare_dependency( + sources: files( + 'circular_buffer/circular_buffer_no_modulo_threadsafe.c', + 'circular_buffer_tests/circular_buffer_tests.c' + ), + include_directories: [ + include_directories('.'), + include_directories('circular_buffer_tests'), ], - c_args: '-DCOMPILE_AS_EXAMPLE', -) - -libmalloc_threadx = static_library('malloc_threadx', - 'malloc_threadx.c', - c_args: '-fno-builtin', - include_directories: include_directories('../rtos/threadx') + compile_args: '-DTEST_WITH_REDUCED_CAPACITY' ) diff --git a/examples/cpp/circular_buffer.cpp b/examples/cpp/circular_buffer.cpp index c9eeb3c..f603674 100644 --- a/examples/cpp/circular_buffer.cpp +++ b/examples/cpp/circular_buffer.cpp @@ -1,158 +1,71 @@ +// Copyright 2021 Embedded Artistry LLC + #include +#include +#include "circular_buffer/circular_buffer.hpp" -#include -#include +TEST_CASE("Create circular buffer") +{ + circular_buffer cbuf(10); + CHECK(cbuf.size() == 0); + CHECK(cbuf.capacity() == 10); + CHECK(cbuf.full() == false); + CHECK(cbuf.empty() == true); +} -template -class circular_buffer +TEST_CASE("Circular buffer operations") { - public: - explicit circular_buffer(size_t size) : buf_(std::unique_ptr(new T[size])), max_size_(size) - { - } + circular_buffer cbuf(10); - void put(T item) + SECTION("Check empty") { - std::lock_guard lock(mutex_); - - buf_[head_] = item; + CHECK(cbuf.empty() == true); - if(full_) + for(uint32_t i = 0; i < cbuf.capacity(); i++) { - tail_ = (tail_ + 1) % max_size_; + cbuf.put(i); + CHECK(cbuf.empty() == false); } - - head_ = (head_ + 1) % max_size_; - - full_ = head_ == tail_; } - T get() + SECTION("Check Full") { - std::lock_guard lock(mutex_); - - if(empty()) + for(uint32_t i = 0; i < cbuf.capacity(); i++) { - return T(); + CHECK(cbuf.full() == false); + cbuf.put(i); } - // Read data and advance the tail (we now have a free space) - auto val = buf_[tail_]; - full_ = false; - tail_ = (tail_ + 1) % max_size_; - - return val; - } - - void reset() - { - std::lock_guard lock(mutex_); - head_ = tail_; - full_ = false; - } - - bool empty() const - { - // if head and tail are equal, we are empty - return (!full_ && (head_ == tail_)); + CHECK(cbuf.full() == true); + CHECK(cbuf.size() == cbuf.capacity()); } - bool full() const + SECTION("Fill and empty buffer") { - // If tail is ahead the head by 1, we are full - return full_; - } - - size_t capacity() const - { - return max_size_; - } - - size_t size() const - { - size_t size = max_size_; - - if(!full_) + for(uint32_t i = 0; i < cbuf.capacity(); i++) { - if(head_ >= tail_) - { - size = head_ - tail_; - } - else - { - size = max_size_ + head_ - tail_; - } + cbuf.put(i); } - return size; - } - - private: - std::mutex mutex_; - std::unique_ptr buf_; - size_t head_ = 0; - size_t tail_ = 0; - const size_t max_size_; - bool full_ = 0; -}; - -int main(void) -{ - circular_buffer circle(10); - printf("\n === CPP Circular buffer check ===\n"); - printf("Size: %zu, Capacity: %zu\n", circle.size(), circle.capacity()); - - uint32_t x = 1; - printf("Put 1, val: %d\n", x); - circle.put(x); - - x = circle.get(); - printf("Popped: %d\n", x); - - printf("Empty: %d\n", circle.empty()); - - printf("Adding %zu values\n", circle.capacity() - 1); - for(uint32_t i = 0; i < circle.capacity() - 1; i++) - { - circle.put(i); - } - - circle.reset(); - - printf("Full: %d\n", circle.full()); - - printf("Adding %zu values\n", circle.capacity()); - for(uint32_t i = 0; i < circle.capacity(); i++) - { - circle.put(i); - } - - printf("Full: %d\n", circle.full()); - - printf("Reading back values: "); - while(!circle.empty()) - { - printf("%u ", circle.get()); + for(uint32_t i = 0; i < cbuf.capacity(); i++) + { + CHECK(i == cbuf.get()); + } } - printf("\n"); - printf("Adding 15 values\n"); - for(uint32_t i = 0; i < circle.size() + 5; i++) + SECTION("Check overflow behavior") { - circle.put(i); - } + for(uint32_t i = 0; i < cbuf.capacity(); i++) + { + cbuf.put(i); + } - printf("Full: %d\n", circle.full()); + // Force an overflow + cbuf.put(cbuf.capacity()); - printf("Reading back values: "); - while(!circle.empty()) - { - printf("%u ", circle.get()); + for(uint32_t i = 0; i < cbuf.capacity(); i++) + { + CHECK(i + 1 == cbuf.get()); + } } - printf("\n"); - - printf("Empty: %d\n", circle.empty()); - printf("Full: %d\n", circle.full()); - - return 0; } diff --git a/examples/cpp/circular_buffer/circular_buffer.hpp b/examples/cpp/circular_buffer/circular_buffer.hpp new file mode 100644 index 0000000..5584590 --- /dev/null +++ b/examples/cpp/circular_buffer/circular_buffer.hpp @@ -0,0 +1,100 @@ +#ifndef CIRCULAR_BUFFER_HPP_ +#define CIRCULAR_BUFFER_HPP_ + +#include +#include + +template +class circular_buffer +{ + public: + explicit circular_buffer(size_t size) : buf_(std::unique_ptr(new T[size])), max_size_(size) + { + } + + void put(T item) + { + std::lock_guard lock(mutex_); + + buf_[head_] = item; + + if(full_) + { + tail_ = (tail_ + 1) % max_size_; + } + + head_ = (head_ + 1) % max_size_; + + full_ = head_ == tail_; + } + + T get() + { + std::lock_guard lock(mutex_); + + if(empty()) + { + return T(); + } + + // Read data and advance the tail (we now have a free space) + auto val = buf_[tail_]; + full_ = false; + tail_ = (tail_ + 1) % max_size_; + + return val; + } + + void reset() + { + std::lock_guard lock(mutex_); + head_ = tail_; + full_ = false; + } + + bool empty() const + { + // if head and tail are equal, we are empty + return (!full_ && (head_ == tail_)); + } + + bool full() const + { + // If tail is ahead the head by 1, we are full + return full_; + } + + size_t capacity() const + { + return max_size_; + } + + size_t size() const + { + size_t size = max_size_; + + if(!full_) + { + if(head_ >= tail_) + { + size = head_ - tail_; + } + else + { + size = max_size_ + head_ - tail_; + } + } + + return size; + } + + private: + std::mutex mutex_; + std::unique_ptr buf_; + size_t head_ = 0; + size_t tail_ = 0; + const size_t max_size_; + bool full_ = 0; +}; + +#endif diff --git a/examples/cpp/meson.build b/examples/cpp/meson.build index 5cc1a6b..fd1446a 100644 --- a/examples/cpp/meson.build +++ b/examples/cpp/meson.build @@ -2,6 +2,12 @@ subdir('driver_abstraction') +catch2_tests_dep += declare_dependency( + sources: files( + 'circular_buffer.cpp' + ) +) + no_braces = meson.get_compiler('cpp').get_supported_arguments('-Wno-missing-braces') executable('variant_message', @@ -9,10 +15,6 @@ executable('variant_message', cpp_args: no_braces ) -executable('circular_buffer', - 'circular_buffer.cpp', -) - executable('assembly_source_location', 'assembly_source_location.cpp' ) @@ -30,6 +32,7 @@ executable('aligned_ptr', 'smart_ptr_aligned.cpp', '../libc/malloc_aligned.c' ], + include_directories: memory_inc ) executable('array_demo', diff --git a/examples/cpp/smart_ptr_aligned.cpp b/examples/cpp/smart_ptr_aligned.cpp index 0b8ffc1..84ca78e 100644 --- a/examples/cpp/smart_ptr_aligned.cpp +++ b/examples/cpp/smart_ptr_aligned.cpp @@ -2,7 +2,7 @@ #include #include #include -#include "../c/memory.h" +#include "memory.h" static void aligned_free_wrapper(void* ptr) { diff --git a/examples/meson.build b/examples/meson.build index d1575a2..5eb4e74 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -1,7 +1,4 @@ -# Examples Meson Build File - -rtos_includes = include_directories('rtos', is_system: true) - +subdir('rtos') # Has dependencies used elsewhere subdir('c') subdir('cpp') subdir('libc') diff --git a/examples/rtos/meson.build b/examples/rtos/meson.build new file mode 100644 index 0000000..fee9bf4 --- /dev/null +++ b/examples/rtos/meson.build @@ -0,0 +1,6 @@ + +rtos_includes = include_directories('.', is_system: true) + +threadx_dep = declare_dependency( + include_directories: include_directories('threadx') +) diff --git a/meson.build b/meson.build index caca55e..256f116 100644 --- a/meson.build +++ b/meson.build @@ -42,9 +42,10 @@ endif subdir('build/linker/linker-map') subdir('build/test/cmocka') -# Pre-declare this variable here so that we can add files to the list +# Pre-declare these variables here so that we can add files to the list # throughout the source tree, passing them to the test tree later. cmocka_test_deps = [] +catch2_tests_dep = [] ####################### # Process source tree # @@ -54,6 +55,10 @@ subdir('examples') subdir('interview') subdir('test') +# Defined after source folders so catch2_dep is fully populated +# when creating the built-in targets +subdir('build/test/catch2') + ################### # Tooling Modules # ################### diff --git a/subprojects/catch2.wrap b/subprojects/catch2.wrap new file mode 100644 index 0000000..2e20085 --- /dev/null +++ b/subprojects/catch2.wrap @@ -0,0 +1,10 @@ +[wrap-file] +directory = Catch2-2.11.3 + +source_url = https://github.com/catchorg/Catch2/archive/v2.11.3.zip +source_filename = Catch2-2.11.3.zip +source_hash = c5a0a7510379c6f37f70b329986a335a7b8489d67ac417ce8f4262d0cae4cc5d + +patch_url = https://wrapdb.mesonbuild.com/v1/projects/catch2/2.11.3/1/get_zip +patch_filename = catch2-2.11.3-1-wrap.zip +patch_hash = 63c09cb68280435040ad304b3dd87ecfe69dbc216608991d0a82569a63119e57 diff --git a/test/main.c b/test/main.c index d20e898..792206e 100644 --- a/test/main.c +++ b/test/main.c @@ -12,12 +12,14 @@ // clang-format on #include +#include int main(void) { int overall_result = 0; overall_result |= simple_fixed_point_test_suite(); + overall_result |= circular_buffer_test_suite(); return overall_result; } diff --git a/test/main_circular_buffer_no_modulo.c b/test/main_circular_buffer_no_modulo.c new file mode 100644 index 0000000..523e351 --- /dev/null +++ b/test/main_circular_buffer_no_modulo.c @@ -0,0 +1,23 @@ +/* + * Copyright © 2021 Embedded Artistry LLC. + * See LICENSE file for licensing information. + */ + +// CMocka needs these +// clang-format off +#include +#include +#include +#include +// clang-format on + +#include + +int main(void) +{ + int overall_result = 0; + + overall_result |= circular_buffer_test_suite(); + + return overall_result; +} diff --git a/test/main_circular_buffer_no_modulo_threadsafe.c b/test/main_circular_buffer_no_modulo_threadsafe.c new file mode 100644 index 0000000..523e351 --- /dev/null +++ b/test/main_circular_buffer_no_modulo_threadsafe.c @@ -0,0 +1,23 @@ +/* + * Copyright © 2021 Embedded Artistry LLC. + * See LICENSE file for licensing information. + */ + +// CMocka needs these +// clang-format off +#include +#include +#include +#include +// clang-format on + +#include + +int main(void) +{ + int overall_result = 0; + + overall_result |= circular_buffer_test_suite(); + + return overall_result; +} diff --git a/test/meson.build b/test/meson.build index c26526a..3970235 100644 --- a/test/meson.build +++ b/test/meson.build @@ -27,6 +27,28 @@ embedded_resources_tests = executable('embedded_resources_tests', native: true ) +circular_buffer_no_modulo_tests = executable('circular_buffer_no_modulo_tests', + 'main_circular_buffer_no_modulo.c', + dependencies: [ + circular_buffer_no_modulo_test_dep, + cmocka_native_dep, + ], + link_args: native_map_file.format(meson.current_build_dir() + '/circular_buffer_no_modulo_tests'), + c_args: test_suite_compiler_flags, + native: true +) + +circular_buffer_no_modulo_threadsafe_tests = executable('circular_buffer_no_modulo_threadsafe_tests', + 'main_circular_buffer_no_modulo_threadsafe.c', + dependencies: [ + circular_buffer_no_modulo_threadsafe_dep, + cmocka_native_dep, + ], + link_args: native_map_file.format(meson.current_build_dir() + '/circular_buffer_no_modulo_threadsafe_tests'), + c_args: test_suite_compiler_flags, + native: true +) + ############################# # Register Tests with Meson # ############################# @@ -40,6 +62,20 @@ test('embedded_resources_tests', cmocka_test_output_dir ]) +test('circular_buffer_no_modulo_tests', + circular_buffer_no_modulo_tests, + env: [ + 'CMOCKA_MESSAGE_OUTPUT=XML', + cmocka_test_output_dir + ]) + +test('circular_buffer_no_modulo_threadsafe_tests', + circular_buffer_no_modulo_threadsafe_tests, + env: [ + 'CMOCKA_MESSAGE_OUTPUT=XML', + cmocka_test_output_dir + ]) + run_target('embedded-resources-tests', command: [embedded_resources_tests] )