PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] Fehler = "undefined reference to `memcpy' - Array zu gross (STM32F103RB)?



arwar52
03.06.2019, 15:09
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????

34181

Ceos
04.06.2019, 09:52
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

arwar52
05.06.2019, 17:56
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.

Siro
05.06.2019, 18:41
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:

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

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.

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/08/11/run-c-program-bare-metal-on-arm-cortex-m3.html#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.

arwar52
10.06.2019, 19:12
. . . 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.