Merge branch 'develop-v1.x' into master-v1.x

This commit is contained in:
Tilen Majerle 2021-12-19 14:26:37 +01:00
commit b4e672fb27
17 changed files with 73 additions and 52 deletions

2
.vscode/launch.json vendored
View File

@ -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",

View File

@ -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

View File

@ -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);

View File

@ -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 */

View File

@ -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])));
lwmem_assignmem_ex(NULL, regions, 0);

View File

@ -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]));
lwmem_assignmem_ex(&lw_custom, regions, 0);

View File

@ -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

View File

@ -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 {

View File

@ -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 {

View File

@ -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(&region, 1)) {
if (!lwmem_assignmem(regions, 0)) {
printf("Could not initialize LwMEM!");
return -1;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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(&region, 1)) {
if (!lwmem_assignmem(regions, 0)) {
printf("Could not initialize LwMEM!");
return -1;
}

View File

@ -23,10 +23,12 @@
"platforms": "*",
"export": {
"exclude": [
".github",
"dev"
"docs",
"**/.vs",
"**/Debug",
"third_party/embedded-libs/st_hal/CMSIS/Lib/ARM"
"build",
]
}
}

View File

@ -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))

View File

@ -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;

View File

@ -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... */