Guten Tag!
Ich habe eine Frage, ich arbeite mit dem uVision von Keil.
1
#define MAXVALCUR 700000
2
floatsave_currCW[MAXVALCUR]={0};
Error: L6406E: No space in execution regions with .ANY selector
matching.
Error: L6407E: Sections of aggregate size 0xaae600 bytes could not fit
into .ANY selector(s).
Wo ist die Grenze derPräprozessormakrogrösse. Oder bezieht sich der
Fehler auf das Array? Der Wertebereich reicht doch aus??
Vielen Dank!
M.B.
M. B. schrieb:> Wo ist die Grenze derPräprozessormakrogrösse.
nirgends
> Oder bezieht sich der Fehler auf das Array?
richtig erkannt.
> Der Wertebereich reicht doch aus??
welcher Wertebereich? Du hast einfach nciht genug RAM für
700000 * sizof(float)
Und du bist dir wirklich sicher, daß du ein Array mit 700.000 (in
Worten: Siebenhunderttausend) float-Werten anlegen willst, und das auch
benötigst?
Oliver
Der Fehler bezieht sich sehr wahrscheinlich auf die Arraygrösse. Typisch
der Index ein int sein, je nach Compiler und CPU ist das dann Maximal
32768.
Etwas seltsam: 700'000 = 0x00A'AE60, Der Compiler/Linker meckert aber
über einen 16 x höheren Wert: Sections of aggregate size 0x00AA'E600
bytes
Wenn `int' ein 16-bit-Typ ist, dann ist der größtmögliche
Array-Index 32767, da die Indizierung in C immer mit dem Typ `int'
erfolgt (und auch immer vorzeichenbehaftet ist, denn ptr[-1] ist
eine gültige Operation).
("Keil uVision" allein genügt nicht um festzustellen, welche
Datentypen die Zielplattform wirklich hat.)
Selbst für eine 32-bit-Plattform sind 700000 floats aber schon
heftig viel. Internen SRAM von mehr als 2 MiB dürfte kaum ein
Controller haben. Die Benutzung externen RAMs muss man dem Compiler
(bzw. Linker) sicher irgendwo anzeigen.
Ich mach eine Strommessung auf einer Länge von 3600mm, der Task wird
alle 70us durchlaufen. ergibt 680000 Messungen. Jetzt mach ich halt alle
150 zyklen eine Messung. Die Messung sollte einfach möglichst genau
sein.
M. B. schrieb:> Error: L6407E: Sections of aggregate size 0xaae600 bytes could not fit> into .ANY selector(s).
Die Zahl 0xaae600 (=4·700000·sizeof(float)) deutet darauf hin, dass du
nicht nur ein Float-Array mit 700000 Elementen angelegt hast, sondern
gleich vier davon. Wieviel RAM hast du denn insgesamt?
Andy D. schrieb:> @Jörg sicher dass es nicht size_t ist?
Ja, da size_t unsigned ist, die Array-Indizierung aber (wie oben
erläutert) vorzeichenbehaftet ist, bin ich mir da sehr sicher.
M. B. schrieb:> Ich mach eine Strommessung auf einer Länge von 3600mm, der Task wird> alle 70us durchlaufen. ergibt 680000 Messungen.
Kannst Du mal den Rechenweg erläutern, wie du Darauf kommst?
Auch wenn man aus der PC-Welt kommt, sollte man wissen, daß nicht jeder
MC mindestens 4GB RAM hat.
M. B. schrieb:> Die Messung sollte einfach möglichst genau> sein.
Durch Umwandeln in float bläht sich der Wert nur auf, die Genauigkeit
bleibt gleich. Wieviel Bit liefert denn Dein AD-Wandler.
Peter
Ja, und warum erfolgt die Umrechnung vom 12-Bit-Ergebnis in float
bereits während der Messung? Wie schon mehrfach angedeutet, ist das
nicht sinnvoll. Speichere direkt das ADC-Ergebnis (in einem Array aus
int16_t) und wandle das erst bei der abschließenden Auswertung in
float um.
ich bilde den Mittelwert direkt vom ADC Wert und übergebe einen int
Wert. Dann rechne ich das ganze in den Stromwert (float) um. Aber dann
lege ich ja wieder ein floatwert in ein Array?! einfach nur noch einmal
statt 2 mal! Das sehe ich ein. Aber dann speichere ich ja trotzdem ein
float in das Array!?
Das Ziel des ganzen ist ja, wenn der Strom ein gewisses Level erreicht
hat, muss ich den Motor abschalten. Ich habe den ADC Wert in ein
Stromwert umgerechnet, um es besser zu visualisieren. Du meinst jetzt
ich soll den ADC Wert nicht in einen Stromwert umrechnen und ihn mit
einem int Wert begrenzen? Das gebe viel weniger zu rechnen, es wäre aber
nicht auf einen Blick ersichtlich, also unübersichtlicher!?
Rufus Τ. Firefly schrieb:> Speichere direkt das ADC-Ergebnis (in einem Array aus> int16_t)
700000*2 byte sind 1,3MB. Das braucht immer noch einen ziemlich dicken
MC.
Oliver
Jörg Wunsch schrieb:> Wenn `int' ein 16-bit-Typ ist, dann ist der größtmögliche> Array-Index 32767, da die Indizierung in C immer mit dem Typ `int'> erfolgt (und auch immer vorzeichenbehaftet ist, denn ptr[-1] ist> eine gültige Operation).
welcher index ist damit gemeint, der absolute oder der relative.
int 16bit
int a[32001];
a[32000] = 0;
dann muss er ja intern a + 32000*sizoof(int) rechen. damit ist das
zwischenergebniss aber größer als int. Das ganze wird ja noch schlimmer
wenn das array nicht int sondern ein noch größere Datentype ist.
Oliver schrieb:> 700000*2 byte sind 1,3MB. Das braucht immer noch einen ziemlich dicken> MC.
Laut Datenblatt hat der STM32F103VC stolze 48kB RAM. Damit ist er schon
ein Bolide unter den MCs.
Da fehlen also noch einige Byte an 1,3MB.
Peter
M. B. schrieb:> Wert. Dann rechne ich das ganze in den Stromwert (float) um. Aber dann> lege ich ja wieder ein floatwert in ein Array?!
Wozu?
> Das Ziel des ganzen ist ja, wenn der Strom ein gewisses Level erreicht> hat, muss ich den Motor abschalten.
Dazu musst du aber nicht den ADC Wert in einen Strom umrechnen. Du
kannst ja auch diesen gewissen Level in den zugehörigen ADC Wert
umrechnen und damit den Vergleich machen.
> Ich habe den ADC Wert in ein> Stromwert umgerechnet, um es besser zu visualisieren.
Du du sowieso eine lineare Funktion hast, ist das doch im Grunde nichts
anderes als eine entsprechende Achsbeschriftung, wenn du die ADC Werte
hinmalst. Die Kurve ist ja vollständig identisch, egal ob du sie als
direkte ADC Werte oder als umgerechnete Stromwerte ausgibst. D.h. 'Ich
muss visualisieren' ist kein Grund für unnötige Speicherverschwendung.
> einem int Wert begrenzen? Das gebe viel weniger zu rechnen, es wäre aber> nicht auf einen Blick ersichtlich, also unübersichtlicher!?
Warum soll das unübersichtlich sein?
Alles nur eine Frage der Doku bzw. vernünftiger Variablennamen.
Peter Dannegger schrieb:> Laut Datenblatt hat der STM32F103VC stolze 48kB RAM.
Um das ganze dann mal umzudrehen: 48kB Ram sind ausreichen für um die
24000 16-bit-Werte, oder 12000 32-bit-Werte.
Das liegt nun doch um einiges unter den ursprüglichen 700000 Werten. Da
sollte man nochmals über das Konzept nachdenken.
Oliver
Karl Heinz Buchegger schrieb:
> Warum soll das unübersichtlich sein?> Alles nur eine Frage der Doku bzw. vernünftiger Variablennamen.
ja ich weiss jetzt wie ich es mache. Die Vorgabe ist, das auch die
Hardwareentwickler und Projektleiter auf einen Blick die Software
verstehen. Aber die sind ja auch nicht auf den Kopf gefallen. Wie Du
sagtest, eine Sache der richtigen Doku und Darstellung.
Danke für eure Antworten! Wieder etwas gelernt!
Gruss!
M.B.
M. B. schrieb:> ja ich weiss jetzt wie ich es mache. Die Vorgabe ist, das auch die> Hardwareentwickler und Projektleiter auf einen Blick die Software> verstehen.
Verpass allen Variablen einen postFix
current_adc ist der Messwert Strom-Messwert vom ADC
current_cur ist der zugehörige Messwert umgerechnet in einen
Strom
limit_adc ist der Grenzwert, ausgedrückt in ADC Einheiten
limit_cur dasselbe in Strom-Einheiten
Ein Code von
1
if(current_cur>limit_adc)
kann daher schon mal nicht richtig sein, weil hier falsche Einheiten
miteinander verrechnet werden. Das eine sind Milliampere, das andere
sind ADC Werte.
Wohingegen
1
if(current_cur>limit_cur)
oder
1
if(current_adc>limit_adc)
richtig sein kann. Links und rechts sind die gleichen 'Einheiten'.
Noch dokumentieren, dass im Variablennamen die 'Einheit' des Messwertes
enthalten sind, und schon versteht das jeder Techniker oder Ingenieur.
Vieleicht sollte man etwas weiter schauen. 680k Messwerte reinziehen ist
eine Sache. Und dadann ? alle Sekunden neu anzeigen ? Als Graph, als
Tabelle ? Auswerten ? Weitergeben ?