ATmega128 mit C++ programmieren - was muss man beachten?



  • Ich möchte einen Microcontroller Atmel ATmega128 mit C++ programmieren. Da ich bisher nur Erfahrung mit C++-Programmen auf PCs habe, die Frage an erfahrene µC-Programmierer in C++, auf was man beim ATmega128 (128K Speicher, Harvard Architektur) achten muss? Kann mir da jemand mit Tipps unter die Arme greifen? Ich möchte C++ verwenden, um vorhandene Klassen für schwache KI (FSM, NN, genet. Algos, Kohonen Maps, ...) einsetzen zu können.

    Man hätte natürlich gerne den Komfort einer STL oder boost library. Gibt es hier Äquivalente C++-Bibliotheken für die AVR? Ich habe mir schon eine eigene String-Klasse geschrieben, das fehlende new/delete hierbei z.B. durch malloc/free ersetzt.

    // Ersatz für new, new[], delete und delete[] der fehlenden C++-Standard-Bibliothek
    void* operator new      (size_t size) { return malloc(size); }
    void* operator new[]    (size_t size) { return malloc(size); }
    void  operator delete   (void* ptr)   { free(ptr); }
    void  operator delete[] (void* ptr)   { free(ptr); }
    


  • also mit ner neuen Compilerversion vom AVR-GCC kriegst du sogar new und delete dabei^^

    STL und boost vermisse ich auch schmerzlich - es gibt sie, ja, aber ich habe sie bisher nur kostenpflichtig gesehen. Daher habe ich mir das was ich brauchte selber zusammengebastelt.

    Sonst ist's eigtl. net so viel anders, als für n PC zu programmieren ...
    wir haben für das Board das wir verwenden ne Lib geschrieben mit den Basisfunktionen quasi als Schnittstelle zwischen Board und Priogramm, die die Register liest und schreibt und den hardwarenahen Kram erledigt, (rein funktional in nem Namespace) und halt außenrum ein "ganz normales" C++-Programm.



  • also mit ner neuen Compilerversion vom AVR-GCC kriegst du sogar new und delete dabei^^

    Jetzt bin ich aber baff! Mit WinAVR 25-05-2007 geht es noch nicht. Das ist GCC 4.1.2 und avr-libc 1.4.6. Bei Sourceforge ist dies die letzte Version.

    Ab welcher Version des AVR-GCC funktioniert new/delete? 😕



  • hmm eigtl. hab ich auch 4.1.2 ...

    /edit:

    hmm hmm mal eben für Mega128 compiliert - es funktioniert nicht 😞
    beim Mega32 Projekt funktioniert es aber - sehr komisch - mal kurz schauen, ob wir sie vielleicht doch auch selber überladen haben



  • gehen bei AVR auch abstrakte Basisklassen, virtuelle Funktionen?



  • Ja



  • Erhard Henkes schrieb:

    ...auf was man beim ATmega128 (128K Speicher, Harvard Architektur) achten muss? Kann mir da jemand mit Tipps unter die Arme greifen, damit ich den Ruf von C++ nicht demoliere?

    er hat nur 4K RAM. wenn du 'grösseres' vor hast, würde ich auf malloc/free sowie new/delete verzichten.
    🙂



  • er hat nur 4K RAM. wenn du 'grösseres' vor hast, würde ich auf malloc/free sowie new/delete verzichten. 🙂

    4096 Bytes SRAM sind wahrlich nicht allzu viel, wobei dies in der 8-bit-Klasse sogar imposant ist! Da zählt leider jedes Byte.
    Wie kann man für new/delete (genau genommen malloc/free) den Flash-Speicher (stolze 128 KB) anstelle des knappen SRAM dynamisch nutzen? Wie macht ihr das genau?



  • Erhard Henkes schrieb:

    er hat nur 4K RAM. wenn du 'grösseres' vor hast, würde ich auf malloc/free sowie new/delete verzichten. 🙂

    4096 Bytes SRAM sind wahrlich nicht allzu viel, wobei dies in dieser Klasse sogar imposant ist! Da zählt leider jedes Byte.
    Wie kann man für new/delete (genau genommen malloc/free) den Flash-Speicher /128 KB) anstelle des SRAM dynamisch nutzen? Wie macht ihr das genau?

    flash-speicher kann man nicht wie RAM nutzen. das ist so gut wie unmöglich. 😉
    ausserdem bezweifle ich, dass der ATmega zur laufzeit sein eigenes flash beschreiben kann. flash ist in blöcke organisiert. lesezugriffe funktionieren zwar sequenziell aber beim schreiben muss man erst einen kompletten block löschen und ihn dann neu programmieren d.h. in's flash gehören programmcode und anderes 'non volatile' zeug...

    bei so wenig RAM schaden new/delete und malloc/free mehr, als dass sie helfen. besser ist man dran, wenn man den speicher manuell aufteilt, d.h. du arbeitest mit globalen und statischen variablen und der linker sorgt dafür, dass das RAM gut ausgenutzt wird.
    und für den stack musst du ja auch noch etwas RAM spendieren (vielleicht 256 bytes oder so?), denn du willst sicher auch mit funktionsaufrufen und interrupts arbeiten.
    🙂



  • Danke für die Infos! Hier habe ich auch noch eine interessante Forumsdiskussion gefunden: http://www.mikrocontroller.net/topic/52866



  • @Checker...:
    StateDrive.o:(.data+0x12): undefined reference to \_\_cxa\_pure_virtual' StateMoveAway.o:(.data+0x12): undefined reference to__cxa_pure_virtual'
    Roboter.o:(.data+0x8): undefined reference to `__cxa_pure_virtual'

    Bei googlen finde ich dies:
    __cxa_pure_virtual is in libstdc++

    Dies fehlt aber doch bei C++ auf AVR. 🙄

    Gehen solche abstrakte Basisklassen bei AVR oder doch nicht?

    #ifndef STATE_H
    #define STATE_H
    
    class Bot;
    
    class State // abstrakte Klasse
    {
    public:
      virtual ~State(){}
      virtual void Execute(Bot*) = 0;
    };
    
    #endif
    




  • class Roboter;
    
    class State
    {
    public:
      virtual ~State(){}
      virtual void Execute(Roboter*){};
    };
    

    ... geht. Also liegt es wirklich an den abstrakten Klassen.



  • So geht es doch!!! Die Sprungmarke muss existieren, damit im Falle eines verbotenen Aufrufs der nichtexistierenden Funktion "irgendetwas" aufgerufen wird.
    Ob das sauber ist, weiß ich nicht, aber es geht. 😃

    // Hilfskonstruktionen
    extern "C"
    void __cxa_pure_virtual() {}
    

Anmelden zum Antworten