Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
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 4458 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:

    Code:
    #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:

    Code:
    #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!!