Skip to content

Provide multiple RAM region support for the heap when using GCC #9518

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
marcuschangarm opened this issue Jan 28, 2019 · 6 comments
Closed

Comments

@marcuschangarm
Copy link
Contributor

marcuschangarm commented Jan 28, 2019

Description

Some MCUs, like the STM32L475, have multiple discrete RAM regions. Accessing memory across these boundaries will cause a hard fault. The current sbrk implementation for GCC only allocates heap from one of these regions, leaving unused memory in other regions unavailable.

With a custom sbrk implementation it is possible to allocate heap from multiple regions (see #9441), but the current Mbed OS tests for stack and heap make assumptions that prevent users from mainlining these changes.

It would be useful if Mbed OS defined linker names for multiple regions, e.g., __mbed_sbrk_start_0, __mbed_sbrk_start_1, etc. and provided sbrk functions that took advantage of these. It would then just be a matter of linker script and target configuration for each target instead of each target providing its own sbrk.

Issue request type

[ ] Question
[x] Enhancement
[ ] Bug
@ciarmcom
Copy link
Member

Internal Jira reference: https://jira.arm.com/browse/MBOCUSTRIA-807

@cmonr
Copy link
Contributor

cmonr commented Jan 30, 2019

@ARMmbed/mbed-os-core

@deepikabhavnani
Copy link

deepikabhavnani commented Feb 14, 2019

@marcuschangarm - I did some experimentation with linker scripts and _sbrk over here deepikabhavnani@7c13576
and tested it with stack heap test in mbed-os deepikabhavnani@0ec2f31

GCC memory allocator does not support non-contiguous heap allocations. See commit messages for more info,

It would be useful if Mbed OS defined linker names for multiple regions, e.g., __mbed_sbrk_start_0, __mbed_sbrk_start_1, etc. and provided sbrk functions that took advantage of these.

Split heap may work if memory is contiguous. Also for now it is __end and __heaplimit symbols are used for default _sbrk implementation, but it is weak so targets can have custom _sbrk implementation in target specific folder, it need not be generic. Only few targets have this requirement for now, so instead of updating all linker files with *sbrk and *krbs symbols, target specific implementation of _sbrk will be preferred

@deepikabhavnani
Copy link

Similar experiment was done with K64F, since its memory map is contiguous, but RAM banks are physically separate, changes here: deepikabhavnani@da428a1

Code for main

#include "mbed.h"

extern uint32_t _sbrk_case;
extern int _sbrk_incr;
extern unsigned char *_sbrk_prev_heap;
extern unsigned char *_sbrk_new_heap;

extern unsigned char *mbed_heap_start;
extern uint32_t mbed_heap_size;
const uint32_t size = 800;
uint32_t max_mbed_heap_size = 0;

int main()
{
	void *data = NULL;

	printf("*** main begin ***\r\n");
	printf("\r\n");
	printf("_sbrk_incr: %i  ", _sbrk_incr);
	printf("_sbrk_case: %lu  ", _sbrk_case);
	printf("prev_heap: %X  ", _sbrk_prev_heap);
	printf("new_heap: %X \n", _sbrk_new_heap);

	printf("*** test begin ***\r\n");
    
	while(1)
	{
        _sbrk_incr = 0;
        _sbrk_case = 99;
        _sbrk_prev_heap = NULL;
        _sbrk_new_heap =  NULL;
    
        void *tmp_data = malloc(size);

        //if ((NULL != _sbrk_prev_heap ) && (NULL != _sbrk_new_heap)) {
         if (1) {
            printf("_sbrk_incr: %i  ", _sbrk_incr);
            printf("prev_heap: %X  ", _sbrk_prev_heap);
            printf("new_heap: %X ", _sbrk_new_heap);
            printf("_sbrk_case: %i ", _sbrk_case);

			data = tmp_data;
            // memset((void *)data, 0x10, size); - Hardfault when boundary crossed
            printf("data: %p ", data);
			printf("requested: %lu\n", size);
		}
        if (NULL == tmp_data) break;
	}
	printf("*** test end ***\r\n\r\n");
	printf("\r\n");
}

Output

*** main begin ***

_sbrk_incr: 2024  _sbrk_case: 5  prev_heap: 1FFFE818  new_heap: 1FFFF000
*** test begin ***

_sbrk_incr: 0  prev_heap: 0  new_heap: 0 _sbrk_case: 99 data: 0x1fffe810 requested: 800
_sbrk_incr: 0  prev_heap: 0  new_heap: 0 _sbrk_case: 99 data: 0x1fffeb38 requested: 800
_sbrk_incr: 4096  prev_heap: 1FFFF000  new_heap: 20000000 _sbrk_case: 2 data: 0x1fffee60 requested: 800
_sbrk_incr: 0  prev_heap: 0  new_heap: 0 _sbrk_case: 99 data: 0x1ffff188 requested: 800
_sbrk_incr: 0  prev_heap: 0  new_heap: 0 _sbrk_case: 99 data: 0x1ffff4b0 requested: 800
_sbrk_incr: 0  prev_heap: 0  new_heap: 0 _sbrk_case: 99 data: 0x1ffff7d8 requested: 800
_sbrk_incr: 0  prev_heap: 0  new_heap: 0 _sbrk_case: 99 data: 0x1ffffb00 requested: 800
_sbrk_incr: 4096  prev_heap: 20000000  new_heap: 20001000 _sbrk_case: 5 data: 0x1ffffe28 requested: 800
_sbrk_incr: 0  prev_heap: 0  new_heap: 0 _sbrk_case: 99 data: 0x20000150 requested: 800
_sbrk_incr: 0  prev_heap: 0  new_heap: 0 _sbrk_case: 99 data: 0x20000478 requested: 800
_sbrk_incr: 0  prev_heap: 0  new_heap: 0 _sbrk_case: 99 data: 0x200007a0 requested: 800
_sbrk_incr: 0  prev_heap: 0  new_heap: 0 _sbrk_case: 99 data: 0x20000ac8 requested: 800
_sbrk_incr: 4096  prev_heap: 20001000  new_heap: 20002000 _sbrk_case: 5 data: 0x20000df0 requested: 800
_sbrk_incr: 0  prev_heap: 0  new_heap: 0 _sbrk_case: 99 data: 0x20001118 requested: 800
_sbrk_incr: 0  prev_heap: 0  new_heap: 0 _sbrk_case: 99 data: 0x20001440 requested: 800
_sbrk_incr: 0  prev_heap: 0  new_heap: 0 _sbrk_case: 99 data: 0x20001768 requested: 800
_sbrk_incr: 0  prev_heap: 0  new_heap: 0 _sbrk_case: 99 data: 0x20001a90 requested: 800
_sbrk_incr: 4096  prev_heap: 20002000  new_heap: 20003000 _sbrk_case: 3 data: 0x0 requested: 800
*** test end ***


@deepikabhavnani
Copy link

deepikabhavnani commented Feb 15, 2019

image

Split heap support for GCC needs different memory allocator, it cannot be achieved with _sbrk and linker file modification.

@0xc0170
Copy link
Contributor

0xc0170 commented Aug 14, 2019

Resolved via #9944

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants