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..b34703f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Develop +## v2.0.0 + +- Remove `len` parameter for regions definition. Affected functions: `lwmem_assignmem` and `lwmem_assignmem_ex` +- Create separate branch for v1.x, for critical maintenance purpose only + ## v1.6.0 - Add option to define regions with array only, setting length to `0` by default diff --git a/dev/VisualStudio/lwmem_opts.h b/dev/VisualStudio/lwmem_opts.h index 0925a5f..a03fa48 100644 --- a/dev/VisualStudio/lwmem_opts.h +++ b/dev/VisualStudio/lwmem_opts.h @@ -29,7 +29,6 @@ * This file is part of Lightweight dynamic memory manager library. * * Author: Tilen MAJERLE - * Version: v1.6.0 */ #ifndef LWMEM_HDR_OPTS_H #define LWMEM_HDR_OPTS_H diff --git a/docs/examples_src/example_minimal.c b/docs/examples_src/example_minimal.c index d6948b0..3d80f07 100644 --- a/docs/examples_src/example_minimal.c +++ b/docs/examples_src/example_minimal.c @@ -12,7 +12,7 @@ lwmem_region_t regions[] = { /* Later in the initialization process */ /* Assign regions for manager */ -lwmem_assignmem(regions, 0); +lwmem_assignmem(regions); /* Usage in program... */ diff --git a/docs/examples_src/example_realloc_enlarge_full.c b/docs/examples_src/example_realloc_enlarge_full.c index 121eae0..2cc8f74 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); 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..cca1fad 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); 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..6af4aba 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); /* 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); \ 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..4e1d4f0 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); \ 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/inc/lwmem_opts.h b/examples/stm32/lwmem_rtos_stm32l496_discovery/inc/lwmem_opts.h index c193d5e..0f929f3 100644 --- a/examples/stm32/lwmem_rtos_stm32l496_discovery/inc/lwmem_opts.h +++ b/examples/stm32/lwmem_rtos_stm32l496_discovery/inc/lwmem_opts.h @@ -29,7 +29,6 @@ * This file is part of LwMEM - Lightweight dynamic memory manager library. * * Author: Tilen MAJERLE - * Version: v1.6.0 */ #ifndef LWMEM_HDR_OPTS_H #define LWMEM_HDR_OPTS_H diff --git a/examples/stm32/lwmem_rtos_stm32l496_discovery/inc/main.h b/examples/stm32/lwmem_rtos_stm32l496_discovery/inc/main.h index 2ef3d4a..4bff3ec 100644 --- a/examples/stm32/lwmem_rtos_stm32l496_discovery/inc/main.h +++ b/examples/stm32/lwmem_rtos_stm32l496_discovery/inc/main.h @@ -27,7 +27,6 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Author: Tilen MAJERLE - * Version: v1.6.0 */ #ifndef __MAIN_H #define __MAIN_H diff --git a/examples/stm32/lwmem_rtos_stm32l496_discovery/src/main.c b/examples/stm32/lwmem_rtos_stm32l496_discovery/src/main.c index 962cb90..e36eb21 100644 --- a/examples/stm32/lwmem_rtos_stm32l496_discovery/src/main.c +++ b/examples/stm32/lwmem_rtos_stm32l496_discovery/src/main.c @@ -27,7 +27,6 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Author: Tilen MAJERLE - * Version: v1.6.0 */ #include "main.h" #include "cmsis_os.h" @@ -49,6 +48,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 +68,7 @@ main(void) { /* Initialize LwMEM */ printf("Initializing LwMEM...\r\n"); - if (!lwmem_assignmem(regions, sizeof(regions) / sizeof(regions[0]))) { + if (!lwmem_assignmem(regions)) { 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/inc/lwmem_opts.h b/examples/stm32/lwmem_stm32l496_discovery/inc/lwmem_opts.h index 2f031ac..1f94312 100644 --- a/examples/stm32/lwmem_stm32l496_discovery/inc/lwmem_opts.h +++ b/examples/stm32/lwmem_stm32l496_discovery/inc/lwmem_opts.h @@ -29,7 +29,6 @@ * This file is part of LwMEM - Lightweight dynamic memory manager library. * * Author: Tilen MAJERLE - * Version: v1.6.0 */ #ifndef LWMEM_HDR_OPTS_H #define LWMEM_HDR_OPTS_H diff --git a/examples/stm32/lwmem_stm32l496_discovery/inc/main.h b/examples/stm32/lwmem_stm32l496_discovery/inc/main.h index 2ef3d4a..4bff3ec 100644 --- a/examples/stm32/lwmem_stm32l496_discovery/inc/main.h +++ b/examples/stm32/lwmem_stm32l496_discovery/inc/main.h @@ -27,7 +27,6 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Author: Tilen MAJERLE - * Version: v1.6.0 */ #ifndef __MAIN_H #define __MAIN_H diff --git a/examples/stm32/lwmem_stm32l496_discovery/src/main.c b/examples/stm32/lwmem_stm32l496_discovery/src/main.c index b1af32f..0c47d50 100644 --- a/examples/stm32/lwmem_stm32l496_discovery/src/main.c +++ b/examples/stm32/lwmem_stm32l496_discovery/src/main.c @@ -27,7 +27,6 @@ * OTHER DEALINGS IN THE SOFTWARE. * * Author: Tilen MAJERLE - * Version: v1.6.0 */ #include "main.h" #include "lwmem/lwmem.h" @@ -48,6 +47,7 @@ static lwmem_region_t regions[] = { { region1_data, sizeof(region1_data) }, /* Add more regions if needed */ + { NULL, 0 } }; /** @@ -65,7 +65,7 @@ main(void) { /* Initialize LwMEM */ printf("Initializing LwMEM...\r\n"); - if (!lwmem_assignmem(regions, sizeof(regions) / sizeof(regions[0]))) { + if (!lwmem_assignmem(regions)) { 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/lwmem_opts.h b/examples/win32/lwmem/lwmem_opts.h index 2f031ac..1f94312 100644 --- a/examples/win32/lwmem/lwmem_opts.h +++ b/examples/win32/lwmem/lwmem_opts.h @@ -29,7 +29,6 @@ * This file is part of LwMEM - Lightweight dynamic memory manager library. * * Author: Tilen MAJERLE - * Version: v1.6.0 */ #ifndef LWMEM_HDR_OPTS_H #define LWMEM_HDR_OPTS_H diff --git a/examples/win32/lwmem/main.c b/examples/win32/lwmem/main.c index e0b301b..e1db8f1 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)) { printf("Could not initialize LwMEM!"); return -1; } diff --git a/examples/win32/lwmem_multi_ins_multi_region/lwmem_opts.h b/examples/win32/lwmem_multi_ins_multi_region/lwmem_opts.h index 2f031ac..1f94312 100644 --- a/examples/win32/lwmem_multi_ins_multi_region/lwmem_opts.h +++ b/examples/win32/lwmem_multi_ins_multi_region/lwmem_opts.h @@ -29,7 +29,6 @@ * This file is part of LwMEM - Lightweight dynamic memory manager library. * * Author: Tilen MAJERLE - * Version: v1.6.0 */ #ifndef LWMEM_HDR_OPTS_H #define LWMEM_HDR_OPTS_H diff --git a/examples/win32/lwmem_multi_ins_multi_region/main.c b/examples/win32/lwmem_multi_ins_multi_region/main.c index 47e3b59..bc14e9a 100644 --- a/examples/win32/lwmem_multi_ins_multi_region/main.c +++ b/examples/win32/lwmem_multi_ins_multi_region/main.c @@ -7,13 +7,15 @@ #include "lwmem/lwmem.h" #include +#include /* Define multiple regions for default instance */ 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 +23,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 +48,14 @@ main(void) { } /* Initialize default LwMEM instance with single region */ - if (!lwmem_assignmem(lw0_regions, LWMEM_ARRAYSIZE(lw0_regions))) { + if (!lwmem_assignmem(lw0_regions)) { 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)) { printf("Could not initialize custom LwMEM instance!"); return -1; } diff --git a/examples/win32/lwmem_multi_region/lwmem_opts.h b/examples/win32/lwmem_multi_region/lwmem_opts.h index 2f031ac..1f94312 100644 --- a/examples/win32/lwmem_multi_region/lwmem_opts.h +++ b/examples/win32/lwmem_multi_region/lwmem_opts.h @@ -29,7 +29,6 @@ * This file is part of LwMEM - Lightweight dynamic memory manager library. * * Author: Tilen MAJERLE - * Version: v1.6.0 */ #ifndef LWMEM_HDR_OPTS_H #define LWMEM_HDR_OPTS_H diff --git a/examples/win32/lwmem_multi_region/main.c b/examples/win32/lwmem_multi_region/main.c index dc9d7e8..50dca58 100644 --- a/examples/win32/lwmem_multi_region/main.c +++ b/examples/win32/lwmem_multi_region/main.c @@ -6,13 +6,15 @@ #include "lwmem/lwmem.h" #include +#include /* Define multiple regions */ 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 +30,7 @@ main(void) { } /* Initialize default LwMEM instance with single region */ - if (!lwmem_assignmem(regions, LWMEM_ARRAYSIZE(regions))) { + if (!lwmem_assignmem(regions)) { printf("Could not initialize LwMEM!"); return -1; } diff --git a/examples/win32/lwmem_os/lwmem_opts.h b/examples/win32/lwmem_os/lwmem_opts.h index f6429c7..8536f88 100644 --- a/examples/win32/lwmem_os/lwmem_opts.h +++ b/examples/win32/lwmem_os/lwmem_opts.h @@ -29,7 +29,6 @@ * This file is part of LwMEM - Lightweight dynamic memory manager library. * * Author: Tilen MAJERLE - * Version: v1.6.0 */ #ifndef LWMEM_HDR_OPTS_H #define LWMEM_HDR_OPTS_H diff --git a/examples/win32/lwmem_os/main.c b/examples/win32/lwmem_os/main.c index 344e49d..a1a4733 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)) { printf("Could not initialize LwMEM!"); return -1; } diff --git a/library.json b/library.json index c8f9c15..972dba8 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "LwMEM", - "version": "1.6.0", + "version": "2.0.0", "description": "Lightweight dynamic memory manager optimized for embedded systems", "keywords": "lwmem, memory, dynamic, heap, malloc, calloc, realloc, free, lightweight, manager, embedded, stm32, win32", "repository": { @@ -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..90c579a 100644 --- a/lwmem/src/include/lwmem/lwmem.h +++ b/lwmem/src/include/lwmem/lwmem.h @@ -29,7 +29,7 @@ * This file is part of LwMEM - Lightweight dynamic memory manager library. * * Author: Tilen MAJERLE - * Version: v1.6.0 + * Version: v2.0.0 */ #ifndef LWMEM_HDR_H #define LWMEM_HDR_H @@ -102,7 +102,7 @@ typedef struct { size_t size; /*!< Size of region in units of bytes */ } lwmem_region_t; -size_t lwmem_assignmem_ex(lwmem_t* const lw, const lwmem_region_t* regions, size_t len); +size_t lwmem_assignmem_ex(lwmem_t* const lw, const lwmem_region_t* regions); void* lwmem_malloc_ex(lwmem_t* const lw, const lwmem_region_t* region, const size_t size); void* lwmem_calloc_ex(lwmem_t* const lw, const lwmem_region_t* region, const size_t nitems, const size_t size); void* lwmem_realloc_ex(lwmem_t* const lw, const lwmem_region_t* region, void* const ptr, const size_t size); @@ -114,15 +114,21 @@ size_t lwmem_get_size_ex(lwmem_t* const lw, void* ptr); /** * \note This is a wrapper for \ref lwmem_assignmem_ex function. * 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. + * \param[in] regions: Pointer to array of regions with address and respective 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 - * \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) + * Last region entry must have address `NULL` and size set to `0` + * \code{.c} +//Example definition +lwmem_region_t regions[] = { + { (void *)0x10000000, 0x1000 }, //Region starts at address 0x10000000 and is 0x1000 bytes long + { (void *)0x20000000, 0x2000 }, //Region starts at address 0x20000000 and is 0x2000 bytes long + { (void *)0x30000000, 0x3000 }, //Region starts at address 0x30000000 and is 0x3000 bytes long + { NULL, 0 } //Array termination indicator +} +\endcode * \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)) +#define lwmem_assignmem(regions) lwmem_assignmem_ex(NULL, (regions)) /** * \note This is a wrapper for \ref lwmem_malloc_ex function. diff --git a/lwmem/src/include/lwmem/lwmem_opt.h b/lwmem/src/include/lwmem/lwmem_opt.h index fdc8ee5..8050d88 100644 --- a/lwmem/src/include/lwmem/lwmem_opt.h +++ b/lwmem/src/include/lwmem/lwmem_opt.h @@ -29,7 +29,7 @@ * This file is part of LwMEM - Lightweight dynamic memory manager library. * * Author: Tilen MAJERLE - * Version: v1.6.0 + * Version: v2.0.0 */ #ifndef LWMEM_HDR_OPT_H #define LWMEM_HDR_OPT_H diff --git a/lwmem/src/include/lwmem/lwmem_opts_template.h b/lwmem/src/include/lwmem/lwmem_opts_template.h index adb08cb..ccac00c 100644 --- a/lwmem/src/include/lwmem/lwmem_opts_template.h +++ b/lwmem/src/include/lwmem/lwmem_opts_template.h @@ -29,7 +29,7 @@ * This file is part of LwMEM - Lightweight dynamic memory manager library. * * Author: Tilen MAJERLE - * Version: v1.6.0 + * Version: v2.0.0 */ #ifndef LWMEM_HDR_OPTS_H #define LWMEM_HDR_OPTS_H diff --git a/lwmem/src/include/system/lwmem_sys.h b/lwmem/src/include/system/lwmem_sys.h index 8d295ab..9afb1e0 100644 --- a/lwmem/src/include/system/lwmem_sys.h +++ b/lwmem/src/include/system/lwmem_sys.h @@ -29,7 +29,7 @@ * This file is part of LwMEM - Lightweight dynamic memory manager library. * * Author: Tilen MAJERLE - * Version: v1.6.0 + * Version: v2.0.0 */ #ifndef LWMEM_HDR_SYS_H #define LWMEM_HDR_SYS_H diff --git a/lwmem/src/lwmem/lwmem.c b/lwmem/src/lwmem/lwmem.c index 2da3712..67f369e 100644 --- a/lwmem/src/lwmem/lwmem.c +++ b/lwmem/src/lwmem/lwmem.c @@ -29,7 +29,7 @@ * This file is part of LwMEM - Lightweight dynamic memory manager library. * * Author: Tilen MAJERLE - * Version: v1.6.0 + * Version: v2.0.0 */ #include #include @@ -660,60 +660,49 @@ prv_realloc(lwmem_t* const lw, const lwmem_region_t* region, void* const ptr, co /** * \brief Initializes and assigns user regions for memory used by allocator algorithm * \param[in] lw: LwMEM instance. Set to `NULL` to use default instance - * \param[in] regions: Array of regions with address and its size. + * \param[in] regions: Pointer to array of regions with address and respective 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 - * \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) + * Last region entry must have address `NULL` and size set to `0` + * \code{.c} +//Example definition +lwmem_region_t regions[] = { + { (void *)0x10000000, 0x1000 }, //Region starts at address 0x10000000 and is 0x1000 bytes long + { (void *)0x20000000, 0x2000 }, //Region starts at address 0x20000000 and is 0x2000 bytes long + { (void *)0x30000000, 0x3000 }, //Region starts at address 0x30000000 and is 0x3000 bytes long + { NULL, 0 } //Array termination indicator +} +\endcode * \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 */ size_t -lwmem_assignmem_ex(lwmem_t* const lw, const lwmem_region_t* regions, size_t len) { +lwmem_assignmem_ex(lwmem_t* const lw, const lwmem_region_t* regions) { uint8_t* mem_start_addr; - size_t mem_size; + size_t mem_size, len = 0; lwmem_block_t* first_block, *prev_end_block; - /* Check first entries */ - if (LWMEM_GET_LW(lw)->end_block != NULL /* Init function may only be called once per lwmem instance */ + /* Check first things first */ + if (regions == NULL + || LWMEM_GET_LW(lw)->end_block != NULL /* Init function may only be called once per lwmem instance */ || (((size_t)LWMEM_CFG_ALIGN_NUM) & (((size_t)LWMEM_CFG_ALIGN_NUM) - 1)) > 0) { /* Must be power of 2 */ return 0; } - /* - * When len == 0, number of regions is defined by pointer to regions. - * - * Last entry, indicating end of region, must have address and length to `NULL` and `0` respectively - */ - if (regions != NULL && len == 0) { - /* Go through array of regions */ - for (const lwmem_region_t* r = regions; r->size > 0 && r->start_addr != NULL; ++len, ++r) {} - } - - /* 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 */ -#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 */ + /* Check values entered by application */ mem_start_addr = (void*)0; mem_size = 0; - for (size_t i = 0; i < len; ++i) { - /* Make sure for valid entry */ + for (size_t i = 0;; ++i) { + /* + * Check for valid entry or end of array descriptor + * + * Invalid entry is considered as "end-of-region" indicator + */ if (regions[i].size == 0 && regions[i].start_addr == NULL) { len = i; + if (len == 0) { + return 0; + } break; } @@ -722,11 +711,21 @@ lwmem_assignmem_ex(lwmem_t* const lw, const lwmem_region_t* regions, size_t len) return 0; } - /* Save new values for next try */ + /* Save new values for next round */ mem_start_addr = regions[i].start_addr; mem_size = regions[i].size; } + /* 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 = 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 */ + ) { + return 0; + } + for (size_t i = 0; i < len; ++i, ++regions) { /* Get region start address and size */ if (!prv_get_region_addr_size(regions, &mem_start_addr, &mem_size)) { diff --git a/lwmem/src/system/lwmem_sys_cmsis_os.c b/lwmem/src/system/lwmem_sys_cmsis_os.c index 8d7997c..17bf646 100644 --- a/lwmem/src/system/lwmem_sys_cmsis_os.c +++ b/lwmem/src/system/lwmem_sys_cmsis_os.c @@ -29,7 +29,7 @@ * This file is part of LwMEM - Lightweight dynamic memory manager library. * * Author: Tilen MAJERLE - * Version: v1.6.0 + * Version: v2.0.0 */ #include "system/lwmem_sys.h" diff --git a/lwmem/src/system/lwmem_sys_win32.c b/lwmem/src/system/lwmem_sys_win32.c index f178131..5fdb647 100644 --- a/lwmem/src/system/lwmem_sys_win32.c +++ b/lwmem/src/system/lwmem_sys_win32.c @@ -29,7 +29,7 @@ * This file is part of LwMEM - Lightweight dynamic memory manager library. * * Author: Tilen MAJERLE - * Version: v1.6.0 + * Version: v2.0.0 */ #include "system/lwmem_sys.h" diff --git a/tests/lwmem_test.c b/tests/lwmem_test.c index 62fe434..e3b33d6 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); + //lwmem_assignmem_ex(NULL, lw_regions); /* 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); /* Regions initialized... */ @@ -148,7 +150,7 @@ lwmem_test_memory_structure(void) { * Assign memory for LwMEM. Set len parameter to 0 to calculate * Number of regions with regions pointer, with last entry being set to NULL and 0 */ - used_regions = lwmem_assignmem(regions_used, 0); + used_regions = lwmem_assignmem(regions_used); printf("Manager is ready with %d regions!\r\n", (int)used_regions); lwmem_debug_print(1, 1);