A bit more data... with initial blocksize of 54000 it fails to use up all the RAM. With 55000 it works ok.
With 54000, I get the following (showing sbrk input and output; numbers on the left are a milliseconds counter)
10908: HEAP TEST
10910: malloc sbrk, incr=54024, ret=2000fb60
10912: malloc sbrk, incr=408, ret=2001ce68
10914: malloc good, bk=54000 addr=2000fb68
10926: malloc good, bk=54100 addr=2000fb68
10938: malloc good, bk=54200 addr=2000fb68
10950: malloc good, bk=54300 addr=2000fb68
10962: malloc good, bk=54400 addr=2000fb68
10974: malloc sbrk, incr=57344, ret=ffffffff
10976: malloc failed, bk=54500
With 55000 I get this
10908: HEAP TEST
10910: malloc sbrk, incr=55024, ret=2000fb60
10912: malloc sbrk, incr=3504, ret=2001d250
10914: malloc good, bk=55000 addr=2000fb68
10926: malloc good, bk=55100 addr=2000fb68
10938: malloc good, bk=55200 addr=2000fb68
10950: malloc good, bk=55300 addr=2000fb68
10962: malloc good, bk=55400 addr=2000fb68
10974: malloc good, bk=55500 addr=2000fb68
10986: malloc good, bk=55600 addr=2000fb68
10998: malloc good, bk=55700 addr=2000fb68
11010: malloc good, bk=55800 addr=2000fb68
11022: malloc good, bk=55900 addr=2000fb68
11034: malloc good, bk=56000 addr=2000fb68
11046: malloc good, bk=56100 addr=2000fb68
11058: malloc good, bk=56200 addr=2000fb68
11070: malloc good, bk=56300 addr=2000fb68
11082: malloc good, bk=56400 addr=2000fb68
11094: malloc good, bk=56500 addr=2000fb68
11106: malloc good, bk=56600 addr=2000fb68
11118: malloc good, bk=56700 addr=2000fb68
11130: malloc good, bk=56800 addr=2000fb68
11142: malloc good, bk=56900 addr=2000fb68
11154: malloc good, bk=57000 addr=2000fb68
11166: malloc good, bk=57100 addr=2000fb68
11178: malloc good, bk=57200 addr=2000fb68
11190: malloc good, bk=57300 addr=2000fb68
11202: malloc good, bk=57400 addr=2000fb68
11214: malloc good, bk=57500 addr=2000fb68
11226: malloc good, bk=57600 addr=2000fb68
11238: malloc good, bk=57700 addr=2000fb68
11250: malloc good, bk=57800 addr=2000fb68
11262: malloc good, bk=57900 addr=2000fb68
11274: malloc good, bk=58000 addr=2000fb68
11286: malloc good, bk=58100 addr=2000fb68
11298: malloc good, bk=58200 addr=2000fb68
11310: malloc good, bk=58300 addr=2000fb68
11322: malloc good, bk=58400 addr=2000fb68
11334: malloc good, bk=58500 addr=2000fb68
11346: malloc sbrk, incr=61440, ret=ffffffff
11348: malloc failed, bk=58600
I reckon it is obvious, but can't get my head around it

This is _sbrk
// This is used by malloc().
// The original Newlib version of this, on which the ST code was based
// https://github.com/zephyrproject-rtos/zephyr/blob/main/lib/libc/newlib/libc-hooks.c
// allowed the heap to go all the way up to the current SP value, which is stupid.
// This one sets the limit at the base (lowest memory address) of the stack area.
caddr_t _sbrk(int incr)
{
// These two are defined in the linkfile
extern char end asm("_end"); // end of BSS
extern char top asm("_top"); // base of the general stack
static char *heap_end; // this gets initialised to NULL by C convention
char *prev_heap_end; // this gets initialised on 1st call here
// This sets heap_end to end of BSS, on the first call to _sbrk
if (heap_end == NULL)
heap_end = &end;
prev_heap_end = heap_end;
// top = top of RAM minus size of stack
if ( (heap_end + incr) > &top )
{
errno = ENOMEM; // not apparently used by anything
prev_heap_end = -1;
}
else
{
heap_end += incr;
}
printf("malloc sbrk, incr=%d, ret=%08x",(int)incr, (int) prev_heap_end); // TODO
return (caddr_t) prev_heap_end;
}
If I start with a blocksize of 1000, we get a lot more output... sorry about that
10908: HEAP TEST
10910: malloc sbrk, incr=1024, ret=2000fb60
10912: malloc sbrk, incr=160, ret=2000ff60
10914: malloc good, bk=1000 addr=2000fb68
10926: malloc good, bk=1100 addr=2000fb68
10938: malloc sbrk, incr=4096, ret=20010000
10940: malloc good, bk=1200 addr=2000fb68
10952: malloc good, bk=1300 addr=2000fb68
10964: malloc good, bk=1400 addr=2000fb68
10976: malloc good, bk=1500 addr=2000fb68
10988: malloc good, bk=1600 addr=2000fb68
11000: malloc good, bk=1700 addr=2000fb68
11012: malloc good, bk=1800 addr=2000fb68
11024: malloc good, bk=1900 addr=2000fb68
11036: malloc good, bk=2000 addr=2000fb68
11048: malloc good, bk=2100 addr=2000fb68
11060: malloc good, bk=2200 addr=2000fb68
11072: malloc good, bk=2300 addr=2000fb68
11084: malloc good, bk=2400 addr=2000fb68
11096: malloc good, bk=2500 addr=2000fb68
11108: malloc good, bk=2600 addr=2000fb68
11120: malloc good, bk=2700 addr=2000fb68
11132: malloc good, bk=2800 addr=2000fb68
11144: malloc good, bk=2900 addr=2000fb68
11156: malloc good, bk=3000 addr=2000fb68
11168: malloc good, bk=3100 addr=2000fb68
11180: malloc good, bk=3200 addr=2000fb68
11192: malloc good, bk=3300 addr=2000fb68
11204: malloc good, bk=3400 addr=2000fb68
11216: malloc good, bk=3500 addr=2000fb68
11228: malloc good, bk=3600 addr=2000fb68
11240: malloc good, bk=3700 addr=2000fb68
11252: malloc good, bk=3800 addr=2000fb68
11264: malloc good, bk=3900 addr=2000fb68
11276: malloc good, bk=4000 addr=2000fb68
11288: malloc good, bk=4100 addr=2000fb68
11300: malloc good, bk=4200 addr=2000fb68
11312: malloc good, bk=4300 addr=2000fb68
11324: malloc good, bk=4400 addr=2000fb68
11336: malloc good, bk=4500 addr=2000fb68
11348: malloc good, bk=4600 addr=2000fb68
11360: malloc good, bk=4700 addr=2000fb68
11372: malloc good, bk=4800 addr=2000fb68
11384: malloc good, bk=4900 addr=2000fb68
11396: malloc good, bk=5000 addr=2000fb68
11408: malloc good, bk=5100 addr=2000fb68
11420: malloc good, bk=5200 addr=2000fb68
11432: malloc sbrk, incr=8192, ret=20011000
11434: malloc good, bk=5300 addr=2000fb68
11446: malloc good, bk=5400 addr=2000fb68
11458: malloc good, bk=5500 addr=2000fb68
11470: malloc good, bk=5600 addr=2000fb68
11482: malloc good, bk=5700 addr=2000fb68
11494: malloc good, bk=5800 addr=2000fb68
11506: malloc good, bk=5900 addr=2000fb68
11518: malloc good, bk=6000 addr=2000fb68
11530: malloc good, bk=6100 addr=2000fb68
11542: malloc good, bk=6200 addr=2000fb68
11554: malloc good, bk=6300 addr=2000fb68
11566: malloc good, bk=6400 addr=2000fb68
11578: malloc good, bk=6500 addr=2000fb68
11590: malloc good, bk=6600 addr=2000fb68
11602: malloc good, bk=6700 addr=2000fb68
11614: malloc good, bk=6800 addr=2000fb68
11626: malloc good, bk=6900 addr=2000fb68
11638: malloc good, bk=7000 addr=2000fb68
11650: malloc good, bk=7100 addr=2000fb68
11662: malloc good, bk=7200 addr=2000fb68
11674: malloc good, bk=7300 addr=2000fb68
11686: malloc good, bk=7400 addr=2000fb68
11698: malloc good, bk=7500 addr=2000fb68
11710: malloc good, bk=7600 addr=2000fb68
11722: malloc good, bk=7700 addr=2000fb68
11734: malloc good, bk=7800 addr=2000fb68
11746: malloc good, bk=7900 addr=2000fb68
11758: malloc good, bk=8000 addr=2000fb68
11770: malloc good, bk=8100 addr=2000fb68
11782: malloc good, bk=8200 addr=2000fb68
11794: malloc good, bk=8300 addr=2000fb68
11806: malloc good, bk=8400 addr=2000fb68
11818: malloc good, bk=8500 addr=2000fb68
11830: malloc good, bk=8600 addr=2000fb68
11842: malloc good, bk=8700 addr=2000fb68
11854: malloc good, bk=8800 addr=2000fb68
11866: malloc good, bk=8900 addr=2000fb68
11878: malloc good, bk=9000 addr=2000fb68
11890: malloc good, bk=9100 addr=2000fb68
11902: malloc good, bk=9200 addr=2000fb68
11914: malloc good, bk=9300 addr=2000fb68
11926: malloc good, bk=9400 addr=2000fb68
11938: malloc good, bk=9500 addr=2000fb68
11950: malloc good, bk=9600 addr=2000fb68
11962: malloc good, bk=9700 addr=2000fb68
11974: malloc good, bk=9800 addr=2000fb68
11986: malloc good, bk=9900 addr=2000fb68
11998: malloc good, bk=10000 addr=2000fb68
12010: malloc good, bk=10100 addr=2000fb68
12022: malloc good, bk=10200 addr=2000fb68
12034: malloc good, bk=10300 addr=2000fb68
12046: malloc good, bk=10400 addr=2000fb68
12058: malloc good, bk=10500 addr=2000fb68
12070: malloc good, bk=10600 addr=2000fb68
12082: malloc good, bk=10700 addr=2000fb68
12094: malloc good, bk=10800 addr=2000fb68
12106: malloc good, bk=10900 addr=2000fb68
12118: malloc good, bk=11000 addr=2000fb68
12130: malloc good, bk=11100 addr=2000fb68
12142: malloc good, bk=11200 addr=2000fb68
12154: malloc good, bk=11300 addr=2000fb68
12166: malloc good, bk=11400 addr=2000fb68
12178: malloc good, bk=11500 addr=2000fb68
12190: malloc good, bk=11600 addr=2000fb68
12202: malloc good, bk=11700 addr=2000fb68
12214: malloc good, bk=11800 addr=2000fb68
12226: malloc good, bk=11900 addr=2000fb68
12238: malloc good, bk=12000 addr=2000fb68
12250: malloc good, bk=12100 addr=2000fb68
12262: malloc good, bk=12200 addr=2000fb68
12274: malloc good, bk=12300 addr=2000fb68
12286: malloc good, bk=12400 addr=2000fb68
12298: malloc good, bk=12500 addr=2000fb68
12310: malloc good, bk=12600 addr=2000fb68
12322: malloc good, bk=12700 addr=2000fb68
12334: malloc good, bk=12800 addr=2000fb68
12346: malloc good, bk=12900 addr=2000fb68
12358: malloc good, bk=13000 addr=2000fb68
12370: malloc good, bk=13100 addr=2000fb68
12382: malloc good, bk=13200 addr=2000fb68
12394: malloc good, bk=13300 addr=2000fb68
12406: malloc good, bk=13400 addr=2000fb68
12418: malloc sbrk, incr=16384, ret=20013000
12420: malloc good, bk=13500 addr=2000fb68
12432: malloc good, bk=13600 addr=2000fb68
12444: malloc good, bk=13700 addr=2000fb68
12456: malloc good, bk=13800 addr=2000fb68
12468: malloc good, bk=13900 addr=2000fb68
12480: malloc good, bk=14000 addr=2000fb68
12492: malloc good, bk=14100 addr=2000fb68
12504: malloc good, bk=14200 addr=2000fb68
12516: malloc good, bk=14300 addr=2000fb68
12528: malloc good, bk=14400 addr=2000fb68
12540: malloc good, bk=14500 addr=2000fb68
12552: malloc good, bk=14600 addr=2000fb68
12564: malloc good, bk=14700 addr=2000fb68
12576: malloc good, bk=14800 addr=2000fb68
12588: malloc good, bk=14900 addr=2000fb68
12600: malloc good, bk=15000 addr=2000fb68
12612: malloc good, bk=15100 addr=2000fb68
12624: malloc good, bk=15200 addr=2000fb68
12636: malloc good, bk=15300 addr=2000fb68
12648: malloc good, bk=15400 addr=2000fb68
12660: malloc good, bk=15500 addr=2000fb68
12672: malloc good, bk=15600 addr=2000fb68
12684: malloc good, bk=15700 addr=2000fb68
12696: malloc good, bk=15800 addr=2000fb68
12708: malloc good, bk=15900 addr=2000fb68
12720: malloc good, bk=16000 addr=2000fb68
12732: malloc good, bk=16100 addr=2000fb68
12744: malloc good, bk=16200 addr=2000fb68
12756: malloc good, bk=16300 addr=2000fb68
12768: malloc good, bk=16400 addr=2000fb68
12780: malloc good, bk=16500 addr=2000fb68
12792: malloc good, bk=16600 addr=2000fb68
12804: malloc good, bk=16700 addr=2000fb68
12816: malloc good, bk=16800 addr=2000fb68
12828: malloc good, bk=16900 addr=2000fb68
12840: malloc good, bk=17000 addr=2000fb68
12852: malloc good, bk=17100 addr=2000fb68
12864: malloc good, bk=17200 addr=2000fb68
12876: malloc good, bk=17300 addr=2000fb68
12888: malloc good, bk=17400 addr=2000fb68
12900: malloc good, bk=17500 addr=2000fb68
12912: malloc good, bk=17600 addr=2000fb68
12924: malloc good, bk=17700 addr=2000fb68
12936: malloc good, bk=17800 addr=2000fb68
12948: malloc good, bk=17900 addr=2000fb68
12960: malloc good, bk=18000 addr=2000fb68
12972: malloc good, bk=18100 addr=2000fb68
12984: malloc good, bk=18200 addr=2000fb68
12996: malloc good, bk=18300 addr=2000fb68
13008: malloc good, bk=18400 addr=2000fb68
13020: malloc good, bk=18500 addr=2000fb68
13032: malloc good, bk=18600 addr=2000fb68
13044: malloc good, bk=18700 addr=2000fb68
13056: malloc good, bk=18800 addr=2000fb68
13068: malloc good, bk=18900 addr=2000fb68
13080: malloc good, bk=19000 addr=2000fb68
13092: malloc good, bk=19100 addr=2000fb68
13104: malloc good, bk=19200 addr=2000fb68
13116: malloc good, bk=19300 addr=2000fb68
13128: malloc good, bk=19400 addr=2000fb68
13140: malloc good, bk=19500 addr=2000fb68
13152: malloc good, bk=19600 addr=2000fb68
13164: malloc good, bk=19700 addr=2000fb68
13176: malloc good, bk=19800 addr=2000fb68
13188: malloc good, bk=19900 addr=2000fb68
13200: malloc good, bk=20000 addr=2000fb68
13212: malloc good, bk=20100 addr=2000fb68
13224: malloc good, bk=20200 addr=2000fb68
13236: malloc good, bk=20300 addr=2000fb68
13248: malloc good, bk=20400 addr=2000fb68
13260: malloc good, bk=20500 addr=2000fb68
13272: malloc good, bk=20600 addr=2000fb68
13284: malloc good, bk=20700 addr=2000fb68
13296: malloc good, bk=20800 addr=2000fb68
13308: malloc good, bk=20900 addr=2000fb68
13320: malloc good, bk=21000 addr=2000fb68
13332: malloc good, bk=21100 addr=2000fb68
13344: malloc good, bk=21200 addr=2000fb68
13356: malloc good, bk=21300 addr=2000fb68
13368: malloc good, bk=21400 addr=2000fb68
13380: malloc good, bk=21500 addr=2000fb68
13392: malloc good, bk=21600 addr=2000fb68
13404: malloc good, bk=21700 addr=2000fb68
13416: malloc good, bk=21800 addr=2000fb68
13428: malloc good, bk=21900 addr=2000fb68
13440: malloc good, bk=22000 addr=2000fb68
13452: malloc good, bk=22100 addr=2000fb68
13464: malloc good, bk=22200 addr=2000fb68
13476: malloc good, bk=22300 addr=2000fb68
13488: malloc good, bk=22400 addr=2000fb68
13500: malloc good, bk=22500 addr=2000fb68
13512: malloc good, bk=22600 addr=2000fb68
13524: malloc good, bk=22700 addr=2000fb68
13536: malloc good, bk=22800 addr=2000fb68
13548: malloc good, bk=22900 addr=2000fb68
13560: malloc good, bk=23000 addr=2000fb68
13572: malloc good, bk=23100 addr=2000fb68
13584: malloc good, bk=23200 addr=2000fb68
13596: malloc good, bk=23300 addr=2000fb68
13608: malloc good, bk=23400 addr=2000fb68
13620: malloc good, bk=23500 addr=2000fb68
13632: malloc good, bk=23600 addr=2000fb68
13644: malloc good, bk=23700 addr=2000fb68
13656: malloc good, bk=23800 addr=2000fb68
13668: malloc good, bk=23900 addr=2000fb68
13680: malloc good, bk=24000 addr=2000fb68
13692: malloc good, bk=24100 addr=2000fb68
13704: malloc good, bk=24200 addr=2000fb68
13716: malloc good, bk=24300 addr=2000fb68
13728: malloc good, bk=24400 addr=2000fb68
13740: malloc good, bk=24500 addr=2000fb68
13752: malloc good, bk=24600 addr=2000fb68
13764: malloc good, bk=24700 addr=2000fb68
13776: malloc good, bk=24800 addr=2000fb68
13788: malloc good, bk=24900 addr=2000fb68
13800: malloc good, bk=25000 addr=2000fb68
13812: malloc good, bk=25100 addr=2000fb68
13824: malloc good, bk=25200 addr=2000fb68
13836: malloc good, bk=25300 addr=2000fb68
13848: malloc good, bk=25400 addr=2000fb68
13860: malloc good, bk=25500 addr=2000fb68
13872: malloc good, bk=25600 addr=2000fb68
13884: malloc good, bk=25700 addr=2000fb68
13896: malloc good, bk=25800 addr=2000fb68
13908: malloc good, bk=25900 addr=2000fb68
13920: malloc good, bk=26000 addr=2000fb68
13932: malloc good, bk=26100 addr=2000fb68
13944: malloc good, bk=26200 addr=2000fb68
13956: malloc good, bk=26300 addr=2000fb68
13968: malloc good, bk=26400 addr=2000fb68
13980: malloc good, bk=26500 addr=2000fb68
13992: malloc good, bk=26600 addr=2000fb68
14004: malloc good, bk=26700 addr=2000fb68
14016: malloc good, bk=26800 addr=2000fb68
14028: malloc good, bk=26900 addr=2000fb68
14040: malloc good, bk=27000 addr=2000fb68
14052: malloc good, bk=27100 addr=2000fb68
14064: malloc good, bk=27200 addr=2000fb68
14076: malloc good, bk=27300 addr=2000fb68
14088: malloc good, bk=27400 addr=2000fb68
14100: malloc good, bk=27500 addr=2000fb68
14112: malloc good, bk=27600 addr=2000fb68
14124: malloc good, bk=27700 addr=2000fb68
14136: malloc good, bk=27800 addr=2000fb68
14148: malloc good, bk=27900 addr=2000fb68
14160: malloc good, bk=28000 addr=2000fb68
14172: malloc good, bk=28100 addr=2000fb68
14184: malloc good, bk=28200 addr=2000fb68
14196: malloc good, bk=28300 addr=2000fb68
14208: malloc good, bk=28400 addr=2000fb68
14220: malloc good, bk=28500 addr=2000fb68
14232: malloc good, bk=28600 addr=2000fb68
14244: malloc good, bk=28700 addr=2000fb68
14256: malloc good, bk=28800 addr=2000fb68
14268: malloc good, bk=28900 addr=2000fb68
14280: malloc good, bk=29000 addr=2000fb68
14292: malloc good, bk=29100 addr=2000fb68
14304: malloc good, bk=29200 addr=2000fb68
14316: malloc good, bk=29300 addr=2000fb68
14328: malloc good, bk=29400 addr=2000fb68
14340: malloc good, bk=29500 addr=2000fb68
14352: malloc good, bk=29600 addr=2000fb68
14364: malloc good, bk=29700 addr=2000fb68
14376: malloc good, bk=29800 addr=2000fb68
14388: malloc sbrk, incr=32768, ret=ffffffff
14390: malloc failed, bk=29900