diff --git a/.vscode/launch.json b/.vscode/launch.json index ee70253..8b95413 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,7 +6,7 @@ "configurations": [ { "name": "(Windows) Launch", - "type": "cppvsdbg", + "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}\\build\\LwLibPROJECT.exe", "miDebuggerPath": "c:\\msys64\\mingw64\\bin\\gdb.exe", diff --git a/CHANGELOG.md b/CHANGELOG.md index d307109..66a5336 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## Develop +- Make `len` parameter deprecated for memory assignment +- Prepare for version v2 + ## v1.6.0 - Add option to define regions with array only, setting length to `0` by default diff --git a/docs/examples_src/example_realloc_enlarge_full.c b/docs/examples_src/example_realloc_enlarge_full.c index 121eae0..2a2d973 100644 --- a/docs/examples_src/example_realloc_enlarge_full.c +++ b/docs/examples_src/example_realloc_enlarge_full.c @@ -20,7 +20,7 @@ main(void) { printf("Cannot allocate memory for regions for debug purpose!\r\n"); return -1; } - lwmem_assignmem(regions_used, regions_count); + lwmem_assignmem(regions_used, 0); printf("Manager is ready!\r\n"); lwmem_debug_print(1, 1); diff --git a/docs/examples_src/example_realloc_region.c b/docs/examples_src/example_realloc_region.c index 201b6d7..901bdaf 100644 --- a/docs/examples_src/example_realloc_region.c +++ b/docs/examples_src/example_realloc_region.c @@ -9,10 +9,11 @@ static unsigned char region_mem[128]; static lwmem_region_t regions[] = { /* Set start address and size of each region */ - { region_mem, sizeof(region_mem) } + { region_mem, sizeof(region_mem) }, + { NULL, 0 } }; /* Later in the initialization process */ /* Assign regions for manager */ -lwmem_assignmem(regions, sizeof(regions) / sizeof(regions[0])); +lwmem_assignmem(regions, 0); lwmem_debug_free(); /* This is debug function for sake of this example */ \ No newline at end of file diff --git a/docs/examples_src/example_regions_definitions.c b/docs/examples_src/example_regions_definitions.c index ec68105..adaaba5 100644 --- a/docs/examples_src/example_regions_definitions.c +++ b/docs/examples_src/example_regions_definitions.c @@ -1,8 +1,5 @@ #include "lwmem/lwmem.h" -/* Set to 1 to describe regions only with array */ -#define DESCRIBE_REGIONS_WITH_ARRAY_ONLY 1 - /* * \brief Define regions for memory manager */ @@ -12,13 +9,11 @@ lwmem_region_t regions[] = { { (void *)0x10000000, 0x00001000 }, { (void *)0xA0000000, 0x00008000 }, { (void *)0xC0000000, 0x00008000 }, -#if DESCRIBE_REGIONS_WITH_ARRAY_ONLY { NULL, 0}, -#endif }; /* Later in the initialization process */ /* Assign regions for manager */ -lwmem_assignmem(regions, DESCRIBE_REGIONS_WITH_ARRAY_ONLY ? 0 : (sizeof(regions) / sizeof(regions[0]))); +lwmem_assignmem(regions, 0); /* or */ -lwmem_assignmem_ex(NULL, regions, DESCRIBE_REGIONS_WITH_ARRAY_ONLY ? 0 : (sizeof(regions) / sizeof(regions[0]))); \ No newline at end of file +lwmem_assignmem_ex(NULL, regions, 0); \ No newline at end of file diff --git a/docs/examples_src/example_regions_definitions_custom.c b/docs/examples_src/example_regions_definitions_custom.c index 7d90f60..bfc4799 100644 --- a/docs/examples_src/example_regions_definitions_custom.c +++ b/docs/examples_src/example_regions_definitions_custom.c @@ -15,8 +15,9 @@ lwmem_region_t regions[] = { { (void *)0x10000000, 0x00001000 }, { (void *)0xA0000000, 0x00008000 }, { (void *)0xC0000000, 0x00008000 }, + { NULL, 0 } }; /* Later in the initialization process */ /* Assign regions for custom instance */ -lwmem_assignmem_ex(&lw_custom, regions, sizeof(regions) / sizeof(regions[0])); \ No newline at end of file +lwmem_assignmem_ex(&lw_custom, regions, 0); \ No newline at end of file diff --git a/docs/user-manual/how-it-works.rst b/docs/user-manual/how-it-works.rst index 540cf53..8b51dc2 100644 --- a/docs/user-manual/how-it-works.rst +++ b/docs/user-manual/how-it-works.rst @@ -16,10 +16,12 @@ For the sake of this understanding, application is using ``3`` regions * Region ``1`` memory starts at ``0x1000 0000`` and is ``0x0000 1000`` bytes long * Region ``2`` memory starts at ``0xA000 0000`` and is ``0x0000 8000`` bytes long * Region ``3`` memory starts at ``0xC000 0000`` and is ``0x0000 8000`` bytes long +* Entry ``4`` indicates end of regions array descriptor .. note:: Total size of memory used by application for memory manager is ``0x0001 1000`` bytes or ``69 kB``. This is a sum of all ``3`` regions. + Last entry indicates end of regions with start address set as ``NULL`` and size as ``0`` Example also assumes that: @@ -36,11 +38,6 @@ First step is to define custom regions and assign them to memory manager. .. note:: Order of regions must be lower address first. Regions must not overlap with their sizes. -.. tip:: - Regions could be defined with array descriptor only, where last entry must be set to `NULL` address and `0` size. - This is useful for dynamic length definition with single descriptor file/address. - It allows application to define regions by setting linker scripts when compiling the code. - When calling :c:macro:`lwmem_assignmem`, manager prepares memory blocks and assigns default values. .. figure:: ../static/images/structure_default.svg diff --git a/examples/stm32/lwmem_rtos_stm32l496_discovery/src/main.c b/examples/stm32/lwmem_rtos_stm32l496_discovery/src/main.c index 962cb90..6a29c0e 100644 --- a/examples/stm32/lwmem_rtos_stm32l496_discovery/src/main.c +++ b/examples/stm32/lwmem_rtos_stm32l496_discovery/src/main.c @@ -49,6 +49,7 @@ static lwmem_region_t regions[] = { { region1_data, sizeof(region1_data) }, /* Add more regions if needed */ + { NULL, 0 } }; static void app_thread(void* arg); @@ -68,7 +69,7 @@ main(void) { /* Initialize LwMEM */ printf("Initializing LwMEM...\r\n"); - if (!lwmem_assignmem(regions, sizeof(regions) / sizeof(regions[0]))) { + if (!lwmem_assignmem(regions, 0)) { printf("Cannot initialize LwMEM. Make sure your regions are not overlapping each other and are in ascending memory order\r\n"); while (1) {} } else { diff --git a/examples/stm32/lwmem_stm32l496_discovery/src/main.c b/examples/stm32/lwmem_stm32l496_discovery/src/main.c index b1af32f..b682a47 100644 --- a/examples/stm32/lwmem_stm32l496_discovery/src/main.c +++ b/examples/stm32/lwmem_stm32l496_discovery/src/main.c @@ -48,6 +48,7 @@ static lwmem_region_t regions[] = { { region1_data, sizeof(region1_data) }, /* Add more regions if needed */ + { NULL, 0 } }; /** @@ -65,7 +66,7 @@ main(void) { /* Initialize LwMEM */ printf("Initializing LwMEM...\r\n"); - if (!lwmem_assignmem(regions, sizeof(regions) / sizeof(regions[0]))) { + if (!lwmem_assignmem(regions, 0)) { printf("Cannot initialize LwMEM. Make sure your regions are not overlapping each other and are in ascending memory order\r\n"); while (1) {} } else { diff --git a/examples/win32/lwmem/main.c b/examples/win32/lwmem/main.c index e0b301b..56440d3 100644 --- a/examples/win32/lwmem/main.c +++ b/examples/win32/lwmem/main.c @@ -9,9 +9,9 @@ /* Define single region */ uint8_t region_data[1024]; -lwmem_region_t region = { - .start_addr = region_data, - .size = sizeof(region_data) +lwmem_region_t regions[] = { + { .start_addr = region_data, .size = sizeof(region_data) }, + { .start_addr = NULL, .size = 0 } }; int @@ -19,7 +19,7 @@ main(void) { void* ptr, *ptr2; /* Initialize default LwMEM instance with single region */ - if (!lwmem_assignmem(®ion, 1)) { + if (!lwmem_assignmem(regions, 0)) { printf("Could not initialize LwMEM!"); return -1; } diff --git a/examples/win32/lwmem_multi_ins_multi_region/main.c b/examples/win32/lwmem_multi_ins_multi_region/main.c index 47e3b59..23c81ee 100644 --- a/examples/win32/lwmem_multi_ins_multi_region/main.c +++ b/examples/win32/lwmem_multi_ins_multi_region/main.c @@ -13,7 +13,8 @@ uint8_t lw0_region1_data[1024]; uint8_t lw0_region2_data[256]; lwmem_region_t lw0_regions[] = { { .start_addr = lw0_region1_data, .size = sizeof(lw0_region1_data) }, - { .start_addr = lw0_region2_data, .size = sizeof(lw0_region2_data) } + { .start_addr = lw0_region2_data, .size = sizeof(lw0_region2_data) }, + { .start_addr = NULL, .size = 0 }, }; /* Define second LwMEM instance and multiple regions for new instance */ @@ -21,8 +22,9 @@ lwmem_t lw1; uint8_t lw1_region1_data[1024]; uint8_t lw1_region2_data[512]; lwmem_region_t lw1_regions[] = { - {.start_addr = lw1_region1_data, .size = sizeof(lw1_region1_data) }, - {.start_addr = lw1_region2_data, .size = sizeof(lw1_region2_data) } + { .start_addr = lw1_region1_data, .size = sizeof(lw1_region1_data) }, + { .start_addr = lw1_region2_data, .size = sizeof(lw1_region2_data) }, + { .start_addr = NULL, .size = 0 }, }; int @@ -45,14 +47,14 @@ main(void) { } /* Initialize default LwMEM instance with single region */ - if (!lwmem_assignmem(lw0_regions, LWMEM_ARRAYSIZE(lw0_regions))) { + if (!lwmem_assignmem(lw0_regions, 0)) { printf("Could not initialize default LwMEM instance!"); return -1; } printf("Default LwMEM instance initialized and ready to use!\r\n"); /* Initialize custom LwMEM instance with its custom regions */ - if (!lwmem_assignmem_ex(&lw1, lw1_regions, LWMEM_ARRAYSIZE(lw1_regions))) { + if (!lwmem_assignmem_ex(&lw1, lw1_regions, 0)) { printf("Could not initialize custom LwMEM instance!"); return -1; } diff --git a/examples/win32/lwmem_multi_region/main.c b/examples/win32/lwmem_multi_region/main.c index dc9d7e8..6f3990e 100644 --- a/examples/win32/lwmem_multi_region/main.c +++ b/examples/win32/lwmem_multi_region/main.c @@ -12,7 +12,8 @@ uint8_t region1_data[1024]; uint8_t region2_data[256]; lwmem_region_t regions[] = { { .start_addr = region1_data, .size = sizeof(region1_data) }, - { .start_addr = region2_data, .size = sizeof(region2_data) } + { .start_addr = region2_data, .size = sizeof(region2_data) }, + { .start_addr = NULL, .size = 0 }, }; int @@ -28,7 +29,7 @@ main(void) { } /* Initialize default LwMEM instance with single region */ - if (!lwmem_assignmem(regions, LWMEM_ARRAYSIZE(regions))) { + if (!lwmem_assignmem(regions, 0)) { printf("Could not initialize LwMEM!"); return -1; } diff --git a/examples/win32/lwmem_os/main.c b/examples/win32/lwmem_os/main.c index 344e49d..6227353 100644 --- a/examples/win32/lwmem_os/main.c +++ b/examples/win32/lwmem_os/main.c @@ -10,9 +10,9 @@ /* Define single region */ uint8_t region_data[1024]; -lwmem_region_t region = { - .start_addr = region_data, - .size = sizeof(region_data) +lwmem_region_t regions[] = { + { .start_addr = region_data, .size = sizeof(region_data) }, + { .start_addr = NULL, .size = 0 }, }; /* Thread declaration */ @@ -21,7 +21,7 @@ static int thread_func(void* arg); int main(void) { /* Initialize default LwMEM instance with single region */ - if (!lwmem_assignmem(®ion, 1)) { + if (!lwmem_assignmem(regions, 0)) { printf("Could not initialize LwMEM!"); return -1; } diff --git a/library.json b/library.json index c8f9c15..d869241 100644 --- a/library.json +++ b/library.json @@ -23,10 +23,12 @@ "platforms": "*", "export": { "exclude": [ + ".github", + "dev" "docs", "**/.vs", "**/Debug", - "third_party/embedded-libs/st_hal/CMSIS/Lib/ARM" + "build", ] } } \ No newline at end of file diff --git a/lwmem/src/include/lwmem/lwmem.h b/lwmem/src/include/lwmem/lwmem.h index 03835d6..bb115b0 100644 --- a/lwmem/src/include/lwmem/lwmem.h +++ b/lwmem/src/include/lwmem/lwmem.h @@ -116,10 +116,20 @@ size_t lwmem_get_size_ex(lwmem_t* const lw, void* ptr); * It operates in default LwMEM instance and uses first available region for memory operations * \param[in] regions: Array of regions with address and its size. * Regions must be in increasing order (start address) and must not overlap in-between. - * When `len` param is set to `0`, regions array must contain last entry with `NULL` address and `0` length + * When `len` param is set to `0`, regions array must contain last entry with `NULL` address and `0` length, + * indicating end of regions (similar to end of string) + * \code{.c} +lwmem_region_t regions[] = { + { addr1, size1 }, + { addr2, size2 }, + { addr3, size3 }, + { NULL, 0 } //Regions array termination = end of descriptor +} +\endcode * \param[in] len: Number of regions in array. - * Can be set to `0` to describe number of regions with `regions` parameter. - * Array must have last entry with `0` length and `NULL` address, indicating end of array (similar to end of string) + * Can be set to `0` to describe number of regions with `regions` parameter only. + * \note `len` is deprecated and will be removed in the future versions. + * Describe regions with `regions` parameter only instead * \return `0` on failure, number of final regions used for memory manager on success */ #define lwmem_assignmem(regions, len) lwmem_assignmem_ex(NULL, (regions), (len)) diff --git a/lwmem/src/lwmem/lwmem.c b/lwmem/src/lwmem/lwmem.c index 2da3712..048a531 100644 --- a/lwmem/src/lwmem/lwmem.c +++ b/lwmem/src/lwmem/lwmem.c @@ -662,10 +662,20 @@ prv_realloc(lwmem_t* const lw, const lwmem_region_t* region, void* const ptr, co * \param[in] lw: LwMEM instance. Set to `NULL` to use default instance * \param[in] regions: Array of regions with address and its size. * Regions must be in increasing order (start address) and must not overlap in-between. - * When `len` param is set to `0`, regions array must contain last entry with `NULL` address and `0` length + * When `len` param is set to `0`, regions array must contain last entry with `NULL` address and `0` length, + * indicating end of regions (similar to end of string) + * \code{.c} +lwmem_region_t regions[] = { + { addr1, size1 }, + { addr2, size2 }, + { addr3, size3 }, + { NULL, 0 } //Regions array termination = end of descriptor +} +\endcode * \param[in] len: Number of regions in array. - * Can be set to `0` to describe number of regions with `regions` parameter. - * Array must have last entry with `0` length and `NULL` address, indicating end of array (similar to end of string) + * Can be set to `0` to describe number of regions with `regions` parameter only. + * \note `len` is deprecated and will be removed in the future versions. + * Describe regions with `regions` parameter only instead * \return `0` on failure, number of final regions used for memory manager on success * \note This function is not thread safe when used with operating system. * It must be called only once to setup memory regions @@ -695,18 +705,13 @@ lwmem_assignmem_ex(lwmem_t* const lw, const lwmem_region_t* regions, size_t len) /* Process further checks of valid inputs */ if (regions == NULL || len == 0 #if LWMEM_CFG_OS - || lwmem_sys_mutex_isvalid(&(LWMEM_GET_LW(lw)->mutex)) /* Check if mutex valid already */ + || lwmem_sys_mutex_isvalid(&(LWMEM_GET_LW(lw)->mutex)) /* Check if mutex valid already = must not be */ + || !lwmem_sys_mutex_create(&(LWMEM_GET_LW(lw)->mutex)) /* Final step = try to create mutex for new instance */ #endif /* LWMEM_CFG_OS */ - ) { /* Check inputs */ + ) { return 0; } -#if LWMEM_CFG_OS - if (!lwmem_sys_mutex_create(&(LWMEM_GET_LW(lw)->mutex))) { - return 0; - } -#endif /* LWMEM_CFG_OS */ - /* Ensure regions are growing linearly and do not overlap in between */ mem_start_addr = (void*)0; mem_size = 0; diff --git a/tests/lwmem_test.c b/tests/lwmem_test.c index 62fe434..a5125bf 100644 --- a/tests/lwmem_test.c +++ b/tests/lwmem_test.c @@ -30,6 +30,7 @@ lw_regions[] = { { lw_mem3, sizeof(lw_mem3) }, { lw_mem2, sizeof(lw_mem2) }, { lw_mem1, sizeof(lw_mem1) }, + { NULL, 0 } }; /********************************************/ @@ -47,6 +48,7 @@ lw_c_regions[] = { { lw_c_mem3, sizeof(lw_c_mem3) }, { lw_c_mem2, sizeof(lw_c_mem2) }, { lw_c_mem1, sizeof(lw_c_mem1) }, + { NULL, 0 } }; /********************************************/ @@ -57,11 +59,11 @@ lwmem_test_run(void) { /* Initialize default lwmem instance */ /* Use one of 2 possible function calls: */ - lwmem_assignmem(lw_regions, sizeof(lw_regions) / sizeof(lw_regions[0])); - //lwmem_assignmem_ex(NULL, lw_regions, sizeof(lw_regions) / sizeof(lw_regions[0])); + lwmem_assignmem(lw_regions, 0); + //lwmem_assignmem_ex(NULL, lw_regions, 0); /* Initialize another, custom instance */ - lwmem_assignmem_ex(&lw_c, lw_c_regions, sizeof(lw_c_regions) / sizeof(lw_c_regions[0])); + lwmem_assignmem_ex(&lw_c, lw_c_regions, 0); /* Regions initialized... */