Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[STM32][CodeSourcery] Skrypt linkera lub pomoc z _sbrk

Mess-gd 03 Oct 2009 13:14 4515 3
  • #1
    Mess-gd
    Level 14  
    Witam,

    Zasiadłem do STM32 i zaczynam implementować coraz kolejne funkcjonalności do mojego projektu. Napotkałem jednak problem. Chodzi tu o używanie funkcji malloc() lub printf(). Chodzi o to, że program się nie kompiluje ponieważ brak jest referencji do _sbrk. Przeszukałem Google i znalazłem przykładową funkcję. Funkcja ta potrzebuje dodatkowych informacji ze skryptu linkera (heap_end itp.). Ja w swoim skrypcie nie posiadam takich wpisów. Prośba jest taka. Czy ktoś jest w posiadaniu skryptu linkera dla stm32, który posiada wpisy dotyczące HEAP? (najlepiej do wersji HD - 512kB flash, 64kB RAM).

    Pozdrawiam,
    P. M.
  • #2
    Freddie Chopin
    MCUs specialist
    W każdym temacie odpowiadam to samo ostatnio, to pewnie dlatego, że nikt nie szuka przed zapytaniem.

    https://www.elektroda.pl/rtvforum/topic1339518.html

    Jeden i drugi przykład zawiera stosowne definicje dla heap - __heap_start, __heap_end oraz __heap_size.

    malloc() z newlib jest niezbyt dobry dla mikrokontrolerów moim skromnym zdaniem - zajmuje ~1.2kB pamięci RAM i ~2.5kB kodu.

    funkcje _sbrk() które są w necie też są głupawe lekko, bo po co sprawdzać zawsze, czy heap jest już zainicjalizowane, skoro można je zainicjalizować raz?

    Tak wygląda (moim zdaniem) wersja trochę lepsza:

    #include <sys/types.h>
    #include <errno.h>
    
    caddr_t _sbrk (int size)
    {
    	extern char __heap_start;
    	extern char __heap_end;
    	static char *current_heap_end = &__heap_start;
    	char *previous_heap_end;
    
    	previous_heap_end = current_heap_end;
    
    	if (current_heap_end + size > &__heap_end)
    	{
    		errno = ENOMEM;
    		return (caddr_t) -1;
    	}
    	
    	current_heap_end += size;
    	
    	return (caddr_t) previous_heap_end;
    }
    


    4\/3!!
  • #3
    Mess-gd
    Level 14  
    Udało się. Skrypt linkera skopiowałem z przykładu z diodami. Musiałem pozmieniać tylko kilka zmiennych w moim pliku startupa.

    Udało mi się odpalić moją funkcje printf, ale z 10k kodu zrobiło mi się 32k :|
    Trochę przesada. Mója funkcja printf wygląda następująco:

    #include <stdarg.h>
    #include <stdio.h>
    #include "lcd.h"
    
    int _printf(const char *fmt, ... )
    {
        va_list args;
        int tmp;
        char buffer[1000];
    
        va_start(args,fmt);
        tmp=vsprintf(buffer, fmt, args);
        va_end(args);
    
        LCDStr(0, buffer, 0);
    
        return tmp;
    }
  • #4
    Freddie Chopin
    MCUs specialist
    Nie dziw się, printf i malloc właśnie tyle zajmują [;

    Z tego właśnie powodu mam swojego printfa, który obsługuje tylko kilka najpotrzebniejszych specyfikatorów. Nie wiem czy zajmuje choć 500B <:
    ______________

    Zauważyłem właśnie to:
    char buffer[1000];
    Uwierz - to nie jest dobry pomysł, chyba że w ustawieniach w skrypcie linkera dałeś na stos główny z 5kB. Tak duże tablice albo globalne, albo dynamicznie...

    4\/3!!