- Akku Tests und Balkonkraftwerk Speicher         
Ergebnis 1 bis 5 von 5

Thema: Fehler = "undefined reference to `memcpy' - Array zu gross (STM32F103RB)?

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    05.10.2018
    Beiträge
    33

    Fehler = "undefined reference to `memcpy' - Array zu gross (STM32F103RB)?

    Anzeige

    Praxistest und DIY Projekte
    Hallo Kollegen. Da stehe ich mal wieder . . . auf dem Schlauch

    Also
    Olimex STM32 F103 RBT6 -> Flash 128k, SRAM 20k

    Aufgabe: Array mit 15 Zeilen x Struct a 31 Byte = ca 500Byte anlegen.

    Test-Struct siet so aus

    ___TasteNumber_____1 Byte
    ___PortAdresse______4
    ___PinNumber_______1


    Soll aber größer werden

    Struct Taster
    ___TasteNumber_____1 Byte
    ___PortAdresse______4
    ___PinNumber_______1
    ___StatusOld_______1
    ___StatusCurrent___1
    ___CanMessage_____8
    ___DispMessage____15 Bytes

    _________________31 Byte * 15 = 465 Byte

    Mit 3 Zeilen-Array wurde die Funktion zum Laufen gebracht.

    Array auf 15 Zeilen aufzustocken scheitert mit einem Fehler vom Compiler
    „undefined reference to `memcpy'“

    Meldung kommt wenn Array > als 4 Zeilen wird und dass beim Testen mit Test-Struct.

    Ich arbeite in einer eingeschränkten Umgebung. Somit fehlen schon mal ein Paar Standard Bibliotheken. Damit muss ich klar kommen.

    Jemand `ne Idee wie man den Fehler umgehen kann????

    Klicke auf die Grafik für eine größere Ansicht

Name:	memcpy.jpg
Hits:	4
Größe:	110,5 KB
ID:	34181
    Geändert von arwar52 (03.06.2019 um 16:30 Uhr)

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    39
    Beiträge
    3.416
    für memcpy musst du string.h includen ... es wird scheinbar implizit eingefügt weil du so eine ungewöhnlich große lokale Variable in einer Methode erstellst

    Tut es not, dass du so eine große lokale Variable innerhalb einer Methode erzeugst?

    Wäre es nicht einfacher deine Tabelle (die sogar statisch zu sein scheint) einfach als globale Variable oder sogar static const Variable anzulegen?

    Wichtiger Hinweis, je nach verwendetem Controller kann static const dazu führen dass Konstanten in den Flash geschrieben werden, das spart zwar RAM aber kann je nach Controller dafür eine recht heftige Verzögerung beim Zugriff darauf einhergeht.

    ein Worst Case Szenario hat bei mir dazu geführt, dass jeder Struct-Zugriff über die Array-Auflösung gelaufen ist, was im ASM pro Zeile jeweils zum Ausrechnen des Offset im Array plus Ausrechnen des Offset im Struct mit insgesamt glaube ich 4 maliger Verzögerung geführt hat und im normalen Programmablauf spürbar wurde ... danach habe ich einfach ein memcopy_P (Atmel Code) auf die Struktur gemacht und dann aus dem RAM darauf zugegriffen und beim nöchsten Zugriff aufs Array einfach nochmal kopiert
    Geändert von Ceos (04.06.2019 um 10:04 Uhr)
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    05.10.2018
    Beiträge
    33
    DANKE Ceos.

    Hab das Array (Tabelle) aus der Funktion in den globalen Bereich versetzt - jetzt geht's DANKE
    Wie es sich auf die Laufzeit auswirkt weiß ich noch nicht, aber dank Dir weiß ich das es dazu kommen kann.

    Die 2. Seite der Medaille - die Tabelle - Array - wird im globalen Bereich NICHT mit den gewünschten Daten initialisiert.
    Hab so was auch früher schon gemerkt, war aber nicht so schlimm.

    Gibt es eine elegante und kurze Methode die Daten ins Array zu laden?
    Einfach "einer Schleife" wird es wohl nicht gehen - jeder Datensatz ist anders.
    Leider muss ich OHNE Luxus wie `strtok', 'strcpy' und ähnliches auskommen
    Das ganze "zu Fuß" - Zeichen für Zeichen - aus einem String einzulesen scheint mir doch zu primitiv.

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Hallo
    Die Initialisierung sollte aber generell funktionieren.

    Es gibt einen sogenannten Startup Code bei "C" der sorgt dafür, dass die initialisierten Variablen auch entsprechend gesetzt werden.
    Bei meinem Compiler heisst die z.B. Datei cr_startup_lpc17x_6x.c

    Wie die bei Dir heisst, weis ich nicht,

    Eventuell ist es in deinem Projekt bei den Optionen des Compiler oder Linker ausgeschaltet.
    "Generate Startup Code" Häkchen draussen oder so.

    Bei mir sieht das in der Datei so aus:

    Die Funktion data_init sorgt für das kopieren der Startupdaten aus dem Flash in den RAM Bereich
    die untere Funktion bss_init setzt alle Variablen auf 0

    !!!! Nicht erschrecken, darum must Du Dich normalerweise NIE kümmern. Dieser Code für deine Controller
    wird normalerweise mitgeliefert und wird nur ähnlich aussehen:
    Code:
    Beispiel aus meinem Projekt: 
    
    //*****************************************************************************
    // Functions to carry out the initialization of RW and BSS data sections. These
    // are written as separate functions rather than being inlined within the
    // ResetISR() function in order to cope with MCUs with multiple banks of
    // memory.
    //*****************************************************************************
    __attribute__ ((section(".after_vectors")))
    void data_init(unsigned int romstart, unsigned int start, unsigned int len) {
        unsigned int *pulDest = (unsigned int*) start;
        unsigned int *pulSrc = (unsigned int*) romstart;
        unsigned int loop;
        for (loop = 0; loop < len; loop = loop + 4)
            *pulDest++ = *pulSrc++;
    }
    
    __attribute__ ((section(".after_vectors")))
    void bss_init(unsigned int start, unsigned int len) {
        unsigned int *pulDest = (unsigned int*) start;
        unsigned int loop;
        for (loop = 0; loop < len; loop = loop + 4)
            *pulDest++ = 0;
    }
    Ich habe grade mal folgendes probiert, OHNE string.h
    Code:
    typedef struct
    {
      char          name[10];
      unsigned char alter;
    } tPerson;
    
    tPerson person[3] =
    {
      { "Anton", 20 },
      { "Berta", 30 },
      { "Cesar", 187}
    };
    
    int main(void)
    {
      person[0].name[1] = 'X';   // testweise ändere ich hier den 2. Buchstaben in ein X
    Die Struktur wird ordnungsgemäß initialisiert.

    Das sehe ich jetzt am Debuggerfenster:
    Ich habe nur die eine Zeile ausgeführt, aber es ist schon alles richtig initialisiert. Aus "Anton" wurde "AXton"
    Die anderen Teile sind auch alle richtig inititialisert, habe ich mir grade angesehen.

    Klicke auf die Grafik für eine größere Ansicht

Name:	Anton.jpg
Hits:	9
Größe:	79,7 KB
ID:	34183

    Siro

    [EDIT]
    gefunden auf dieser Seite:
    http://stefanfrings.de/stm32/stm32f1.html
    Startup-Code

    Im Gegensatz zu allen mir bekannten Compilern für 8bit Mikrocontroller befindet sich der Startup-Code und die Interrupt-Vektor Tabelle in editierbaren Dateien (sysmem.c und startup_stm32.s). Der Projekt-Assistent in der IDE legt diese Dateien automatisch an. Für erste Versuche kann man sie unverändert benutzen.

    Dein Startup Code scheint in Assembler geschrieben zu sein und befindet sich wohl in der Datei startup_stm32.s

    ich habe aber auch noch diese hier gefunden, hier ist der Startup Code in "C"
    https://jacobmossberg.se/posts/2018/...c-startup-code

    Du must mal schauen wie das in deinem System/Entwicklngsumgebung gemacht wird.
    Ich vermute, dass bei Dir lediglich Einstellungen für das Projekt angepasst werden müssen.
    Geändert von Siro (06.06.2019 um 00:56 Uhr)

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    05.10.2018
    Beiträge
    33
    . . . Ursache für die „stark eingeschränkte Umgebung“ – der Code wird manchmal an die Kunden weitergegeben und SOLL in JEDER Umgebung laufen.

    Hab mein Problem erstmal so gelöst.
    Die Tabelle in 2 geteilt.
    - 1. Tabelle mit FESTEN Einträgen wird als „const“ deklariert, wie üblich mit nötigen Werten belegt und wird auch initialisiert.
    - 2. Tabelle, deren Inhalt sich im Laufe des Programms ändert ist als „static“ deklariert.
    Die einzige Spalte"Status" mit „bool“ Variablen wird in einer Schleife initialisiert.

    Danke allen für die Mithilfe und bis zum nächsten Mal.

Ähnliche Themen

  1. undefined reference to `main' ?
    Von robots4-ever im Forum Arduino -Plattform
    Antworten: 4
    Letzter Beitrag: 15.04.2013, 11:02
  2. [ERLEDIGT] undefined reference to...
    Von lineage im Forum C - Programmierung (GCC u.a.)
    Antworten: 10
    Letzter Beitrag: 03.02.2011, 18:38
  3. Fehler beim linken "undefined reference to..."
    Von Befedo im Forum C - Programmierung (GCC u.a.)
    Antworten: 7
    Letzter Beitrag: 21.05.2010, 23:20
  4. undefined reference to ...
    Von Bääääär im Forum C - Programmierung (GCC u.a.)
    Antworten: 15
    Letzter Beitrag: 05.08.2007, 08:01
  5. "undefined reference" bei AVRStudio
    Von BlueEagle im Forum C - Programmierung (GCC u.a.)
    Antworten: 4
    Letzter Beitrag: 17.08.2006, 17:52

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiFePO4 Speicher Test