<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<p>Tahle promenna tj. kde zacina zasobnik neni standartizovana bych
rekl. Zname jen konec dat _ebss a konec zasobniku (<code>_estack </code>).
To, ze si ji da nejaky prekladac do linkeru nezamena, ze ji
standardni malloc pouzije. Ani ta metoda na dynamicke zjisteni
nepomuze na malem CPU, tam se sdili heap, takze dynamicke zjisteni
SP registru vrati nesmysl.<br>
</p>
<p>Jirka<br>
</p>
<p><br>
</p>
<p>Dne 3. 11. 2016 v 19:59 Jaroslav Buchta napsal(a):<br>
</p>
<blockquote
cite="mid:f3a1de29-554d-e316-358b-7c2c69c211b8@hascomp.cz"
type="cite">Ale ty fce malloc, free, ... je potreba resit pri
multi thread aplikacich, klasicke knihovny maji callback funkce, u
nano knihoven je to slozitejsi, musi se to resit nejak takto a
jeste jsou v tom nejake parametry linkeru, ktere se mi nechce
hledat:
<br>
<br>
size_t __malloc_margin = 256;
<br>
char *__brkval;
<br>
<br>
uint32_t maxHeap;
<br>
uint32_t minMSP = 0xffffffff;
<br>
<br>
void *__real__sbrk_r(
<br>
struct _reent *r,
<br>
ptrdiff_t incr);
<br>
<br>
void *__wrap__sbrk_r(
<br>
struct _reent *r,
<br>
ptrdiff_t incr)
<br>
{
<br>
extern char end; // provided by the linker script
<br>
<br>
if (__brkval == 0)
<br>
__brkval = &end;
<br>
#ifdef MMGMTDBG
<br>
DBGUSART_dbgSendStr("sbrk: ");
<br>
DBGUSART_dbgSendStrDec(incr);
<br>
DBGUSART_dbgSendStrNl("");
<br>
#endif
<br>
uint32_t mspCurr = __get_MSP();
<br>
if (mspCurr < minMSP) minMSP = mspCurr;
<br>
if (__brkval + incr > (char*)mspCurr - __malloc_margin)
<br>
{
<br>
r->_errno = ENOMEM;
<br>
return (void*)-1;
<br>
}
<br>
<br>
void *ret = __brkval;
<br>
__brkval += incr;
<br>
<br>
maxHeap = (uint32_t)__brkval;
<br>
return ret;
<br>
}
<br>
<br>
<br>
extern void *__real__malloc_r(
<br>
struct _reent *r,
<br>
size_t size
<br>
);
<br>
<br>
void *__wrap__malloc_r(
<br>
struct _reent *r,
<br>
size_t size
<br>
)
<br>
{
<br>
vPortEnterCritical();
<br>
void *ptr = __real__malloc_r(r, size);
<br>
#ifdef MMGMTDBG
<br>
DBGUSART_dbgSendStr("malloc: ");
<br>
DBGUSART_dbgSendStrDec(size);
<br>
DBGUSART_dbgSendStr(" at: ");
<br>
DBGUSART_dbgSendStrHex32((uint32_t)ptr);
<br>
DBGUSART_dbgSendStrNl("");
<br>
#endif
<br>
vPortExitCritical();
<br>
return ptr;
<br>
}
<br>
<br>
extern void __real__free_r(
<br>
struct _reent *r,
<br>
void *ptr
<br>
);
<br>
void __wrap__free_r(
<br>
struct _reent *r,
<br>
void *ptr
<br>
)
<br>
{
<br>
vPortEnterCritical();
<br>
#ifdef MMGMTDBG
<br>
DBGUSART_dbgSendStr("free at: ");
<br>
DBGUSART_dbgSendStrHex32((uint32_t)ptr);
<br>
DBGUSART_dbgSendStrNl("");
<br>
#endif
<br>
__real__free_r(r, ptr);
<br>
vPortExitCritical();
<br>
}
<br>
<br>
<br>
extern void *__real__realloc_r(
<br>
struct _reent *r,
<br>
void *ptr,
<br>
size_t size
<br>
);
<br>
<br>
extern void *__wrap__realloc_r(
<br>
struct _reent *r,
<br>
void *ptr,
<br>
size_t size
<br>
)
<br>
{
<br>
vPortEnterCritical();
<br>
void *newptr = __real__realloc_r(r, ptr, size);
<br>
vPortExitCritical();
<br>
return newptr;
<br>
}
<br>
<br>
<br>
<br>
Dne 03.11.2016 v 19:52 Miroslav Mraz napsal(a):
<br>
<blockquote type="cite">Pro lepší pochopení, jak to obvykle
funguje - do vlastního malloc() a free() v knihovně nemá cenu se
nějak vrtat. Vlastní přidělení paměti zajišťuje něco jako
_sbrk(), která je volána z vnitřku toho malloc(). A to je právě
to místo, kterým se můžete zabývat. Samotná tato funkce není
složitá, je to něco jako
<br>
<br>
// HEAP je definovan za .bss, stack jde proti heap dokud se
nepotkaji
<br>
extern char _end; // Defined by the linker.
<br>
//register char * stack_ptr asm ("sp"); // takhle je to v
newlib
<br>
static inline char * stack_ptr (void) { // pochopitelneji
<br>
register char * res;
<br>
asm volatile (
<br>
"mov %0,sp\r\n" // sp do vysledku
<br>
:"=r"(res) :: ); // standardni zapis
<br>
return res;
<br>
}
<br>
<br>
const char * _sbrk (int incr) {
<br>
static char * heap_end;
<br>
char * prev_heap_end;
<br>
if (heap_end == NULL) heap_end = & _end;
<br>
prev_heap_end = heap_end;
<br>
if (heap_end + incr > stack_ptr()) {
<br>
/*
<br>
No a tady si uděláte co je potřeba, když
<br>
už není dost paměti.
<br>
*/
<br>
return (char *) 0;
<br>
}
<br>
heap_end += incr;
<br>
return (const char *) prev_heap_end;
<br>
}
<br>
Takhle je to (přibližně) uděláno v newlib, ale samosebou si
můžete definovat vlastní oblast pro haldu jak chcete.
<br>
<br>
Mrazík
<br>
<br>
Dne 3.11.2016 v 19:04 Jan Waclawek napsal(a):
<br>
<blockquote type="cite">Ano a nie.
<br>
<br>
V principe by ste si mali to mnozstvo pamate vyhradenej ako
heap urcit Vy,
<br>
ci uz priamo v linker skripte alebo jeho obdobe, alebo u
klikatora na to
<br>
bude niekde nejake okno. Potom v runtime si mozete zistit ci
to tak naozaj
<br>
je, ale ci bude presne kod pana kolegu Nesvacila fungovat to
pochopitelne
<br>
zavisi od toho, ci budete mat tie iste symboly v tom linker
skripte atd.
<br>
<br>
*printf ma niekedy svoj vlastny alokator a vyhradzuje si
staticky cast
<br>
pamate (v ktorej si potom on sam pre seba dynamicky alokuje co
potrebuje,
<br>
to je pre Vas neviditelne a nezasahuje to do "vasho"
malloc()). Musite si
<br>
to zistit v dokumentacii ku kniznici, ktoru pouzivate (ja
viem, obvykle
<br>
nie je ziadna prip. zdrojaky ;-) ).
<br>
<br>
wek
<br>
<br>
</blockquote>
_______________________________________________
<br>
HW-list mailing list - sponsored by <a class="moz-txt-link-abbreviated" href="http://www.HW.cz">www.HW.cz</a>
<br>
<a class="moz-txt-link-abbreviated" href="mailto:Hw-list@list.hw.cz">Hw-list@list.hw.cz</a>
<br>
<a class="moz-txt-link-freetext" href="http://list.hw.cz/mailman/listinfo/hw-list">http://list.hw.cz/mailman/listinfo/hw-list</a>
<br>
</blockquote>
<br>
<br>
_______________________________________________
<br>
HW-list mailing list - sponsored by <a class="moz-txt-link-abbreviated" href="http://www.HW.cz">www.HW.cz</a>
<br>
<a class="moz-txt-link-abbreviated" href="mailto:Hw-list@list.hw.cz">Hw-list@list.hw.cz</a>
<br>
<a class="moz-txt-link-freetext" href="http://list.hw.cz/mailman/listinfo/hw-list">http://list.hw.cz/mailman/listinfo/hw-list</a>
<br>
</blockquote>
<br>
</body>
</html>