Hallo Leute,
ich habe momentan das Problem, dass der RAM-Speicher für die Firmware
für meinen STM32 nicht ausreicht.
Von der TrueStudio IDE bekomme ich die Meldung 'RAM overflowed by 24
bytes'.
Kann mir jemand weiterhelfen, wie ich evtl. genügend RAM einsparen kann?
Ist viel serielle Kommunikation drin?
Es gibt für den STM32 sicherlich so etwas wie PROGMEM, mit dem konstante
Strings nicht im RAM sondern im Flash gespeichert werden. Das wäre ein
Anfang, mal in die Richtung zu schauen.
Generell Konstanten ausm RAM ins Flash holen.
Hi,
Guck mal ins .map-file, an welcher Stelle wieviel RAM verbraten wird.
Ansonsten, wie schon gesagt, zur Compilezeit konstante Zeichenketten
bzw. konstante Arrays mit 'const' aus dem RAM ins Flash verschieben.
Tim K. schrieb:> Kann mir jemand weiterhelfen, wie ich evtl. genügend RAM einsparen kann?
Zuerst einmal ins map file und linker script gucken, wofür Du das RAM
verwendest. Wahrscheinlich fällt Dir da schon etwas auf...
Hast du vielleicht auch alles als "int" angelegt das sind beim STM32 32
Bit. Ich glaube kaum das du bei all deinen Variablen so eine große
Variable brauchts. Bei denen wo weniger reicht kannst du auch folgende
Typen benutzen:
uint8_t / int8_t
uint16_t / int16_t
uint32_t / int32_t
Guest schrieb:> uint8_t
Bremst den STM32 unter Umständen arg aus.
Der TO sollte erstmal schauen, was er mit Compiler-Optionen erreichen
kann. Da helfen zum Beispiel entsprechende Optimierung-Flags wie zum
Beispiel -Os. Auch FLTO (in Verbindung mit gcc) kann einiges an
RAM-Bedarf optimieren.
Natürlich ist es sinnvoll, String-Konstanten auch als solche zu
definieren, das wurde oben ja schon genannt.
Wenn man den Soure-Code nicht kennt, wird es schwierig, zielführende
Ratschläge zu geben. Vielleicht kann der TO ja Teile davon posten, wo er
meint, dass hier besonders viel RAM verbraten wird.
Eine Optimierung der Compiler-Einstellung hat bei mir nicht geholfen.
Die Firmware habe ich mit der MotorControl Workbench von ST für ein
Steval-Spin3202 Eval-Board erzeugt. Der Speicher ist bei der Firmware
schon ziemlich am Limit.
Ich habe jetzt noch einen Programmteil für einen Poti aus einem
Beispiel-Projekt in der main hinzugefügt. Dafür reicht der Speicher
jetzt aber nicht mehr aus.
Bitte lass uns doch nicht im Regen stehn.
Dein geposteter Quellcode ist unvollständig, die Definition von
POT_BUF_SIZE fehlt zum Beispiel.
Wie schon geschrieben wurde: lies dir das map File vom Compiler durch.
Mit dem main.c kann man nichts anfangen, das ist ja nur einen Ansammlung
schwarzer Kisten.
Daß eine Motorsteuernung satte 20kB an RAM gulpt, ist schon recht
strange.
Das map-File sollte die Ursache verraten.
Vielleicht ist auch die Compilerversion nur eine Demo mit limitiertem
RAM.
Heapsize auf 0 ( dyn. Allokation mit 'new' kommt nicht vor, oder ? )
und/oder Stacksie dezent verringern ( z.b. auf 768 ) sollten dich erst
einmal unter die 4k-Grenze bringen.
Rainer B. schrieb:> Heapsize auf 0 ( dyn. Allokation mit 'new' kommt nicht vor, oder ?> )> und/oder Stacksie dezent verringern ( z.b. auf 768 ) sollten dich erst> einmal unter die 4k-Grenze bringen.
Kannst du mir das genauer erklären?
Irgendwo in deiner Toolchain ( TrueStudio IDE ? ) sollte es
Einstellungen geben, in diesen Einstellungen sollten diese zwei
Parameter HEAPSIZE und STACKSIZE auftauchen. Die sind gegenwärtig mit
128 ( oder 0x80 ) bzw. 1024 ( oder 0x400 ) belegt. Ändere HEAPSIZE auf 0
und/oder STACKSIZE auf 768 ( 0x300 ) Evtl. heißen diese beiden
Einstellungen in deiner IDE nicht genau so, aber ähnlich.
HEAPSIZE=0 setzt jedoch voraus, dass keine dyn. Speicherallokatio mit
'new' gemacht wird. In deinem main.c hab ich keine gesehen, daher gehe
ich davon aus, dass das funzt. Guck sicherheitshalber nochmal, ob im
restlichen Quellcode auch kein 'new' vorkommt.
STACKSIZE: 1k erscheint mir ziemlich hoch, probier mal weniger. Wenn das
Programm dann unvermittelt und unvermutet abstürzt, wieder hochsetzten.
Sollte deine Toolchain die Einstellungen für HEAPSIZE und STACKSIZE
nicht kennen, dann guck mal nach einem File mit der Extension .ld. Da
könnte HEAPSIZE und STACKSIZE auch definiert sein.
Außerdem musst du noch den Fehler beheben, den Herrmann G. oben
angemerkt hat.
EDIT: Diese Einstellungen könnten auch in irgendwelchen
'Projekteinstellungen' oder 'Buildeinstellungen' versteckt sein, ich
kenn TureStudio IDE leider nicht.
Dazu kommt das der gcc den M0 grob vernachlässigt und deutlich
schlechter optimiert als bei >= M3. Der Keil Compiler holt da mehr raus,
bis 32k Codesize lief der auch in der kostenlosen Testversion.
Man könnte auch die HAL wegschmeissen und das vernünftig zu Fuss machen.
Allein die ganzen HAL Init Strukturen brauchen unnötigen Stack, den man
sparen könnte.
Will man unbedingt die HAL verwenden könnte man die Init structs ggf.
auch "const" machen (wenn die HAL das mag) und statisch initialisieren -
falls darüber keine Parameter zurückgeliefert werden.
Was allein hier schon verbraten wird in den unterschiedlichen Funktionen
muss alles auf dem Stack vorgehalten werden. Warscheinlich existieren
einige auch global:
Random .. schrieb:> muss alles auf dem Stack vorgehalten werden. Warscheinlich existieren> einige auch global:RCC_OscInitTypeDef RCC_OscInitStruct = {0};> RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};> RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};>> ADC_ChannelConfTypeDef sConfig = {0};>> TIM_MasterConfigTypeDef sMasterConfig = {0};> TIM_OC_InitTypeDef sConfigOC = {0};> TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};>> usw...
Das ist ephemer und verschwindet wieder, die 1k Stack kann man während
der Initialisierung ja getrost ausnutzen. "const" wird nichts bringen.
Dubios vom RAM Verbrauch her finde ich
Rainer B. schrieb:> Außerdem musst du noch den Fehler beheben, den Herrmann G. oben> angemerkt hat.
Mir ist noch nicht klar, wo da genau der Fehler liegt?
Frank M. schrieb:> Bremst den STM32 unter Umständen arg aus.
Warum sollte das den STM ausbremsen. Soweit mir bekannt ist können die
in Byte Blöcken auf den Speicher zugreifen. Hab mit dem F1 noch nicht
wirklich was gemacht aber F2,3,4,7 und H7 machen das Problemlos
Dieter schrieb:> Soweit mir bekannt ist können die in Byte Blöcken auf den Speicher> zugreifen.
Ja, können Sie, indem sie auf 4 Byte alignen, 4 Bytes einlesen und 3
Bytes davon durch Maskierung wieder verwerfen - stark vereinfacht
ausgedrückt. Beim Speichern kann das ebenso übel aussehen, wenn nicht
der Compiler durch Alignment für "3-Byte-Löcher" zwischen den
Variablen/Structelementen sorgt, um das Problem abzumildern. Packed
Structs mit ungünstigem Alignment bringen den STM32 dann mal richtig ins
Schwitzen. Das gilt übrigens nicht nur für den STM32F1xx, sondern
eigentlich für alle STM32.
Es gibt auch hier im Forum diverse Tests mit Benchmarks, die klar
zeigen, dass die Geschwindigkeit bei Verwendung von uint8_t statt
uint_fast8_t (welches für STM32 identisch zu uint32_t ist) richtig in
den Keller geht. Bei uint16_t ist der Geschwindigkeitseinbruch übrigens
wesentlich weniger spürbar.
bei den größeren M4/M7 mit cache ist das stark situaionsabhängig.
er liest dann zwar schnell die 4bytes ein
beim speichern rudert er aber stark umher
zumal man hier darauf achten muss das der cache 32byte aligned ist
Habe mir angewöhnt packed structs zu vermeiden und nutze fast nur noch
uint_32/int
hfhd schrieb:> bei den größeren M4/M7 mit cache ist das stark situaionsabhängig. er> liest dann zwar schnell die 4bytes ein beim speichern rudert er aber> stark umher
Deshalb schrieb ich ja ursprünglich "Bremst den STM32 unter Umständen
arg aus."
> Habe mir angewöhnt packed structs zu vermeiden und nutze fast nur noch> uint_32/int
Dito. Ich verwende aber auch gern uint_fast8_t bzw. uint_fast16_t, um
auszudrücken, dass hier eigentlich eine 8-Bit-Variable beabsichtigt ist
bzw. reichen würde, aber aus Performance-Gründen darauf verzichtet wird.
Das macht übrigens dann den Code portabler, wenn er für verschiedenste
Zielplattformen geschrieben ist, wie zum Beispiel IRMP, welches
unter anderem auf AVRs (8-Bit) und auch STM32 (32-Bit) und noch vielen
anderen µCs läuft.
Hier wird dann vom Compiler immer die optimale Speichergröße verwendet.
Man muss dabei aber höllisch aufpassen, hier keine Überläufe der
möglichen Wertebereiche zu produzieren. Während in einem uint_fast8_t
auf einem STM32 durchaus der Wert 256 gespeichert werden kann, ist dies
bei einem AVR dann durch Überlauf gleich 0.
vielleicht ist das auch der grund meines kompilerproblems...
V4.9.3 alles funktioniert und das schnell
Alle Versionen darüber verursachen bei bestimmten Programmteilen einen
langsameren Ablauf.
Ich nutze lwIP... und hier sind ja auch packed structs dabei.
Ich habe das Problem das die TCP Verbindung dann langsamer ist
Wenn jemand einen Tip hat ... sehr gern^^
Frank M. schrieb:> Dito. Ich verwende aber auch gern uint_fast8_t bzw. uint_fast16_t, um> auszudrücken, dass hier eigentlich eine 8-Bit-Variable beabsichtigt ist> bzw. reichen würde..> ...> Man muss dabei aber höllisch aufpassen, hier keine Überläufe der> möglichen Wertebereiche zu produzieren.
Tja. Und wo bleibt da der proklamierte Vorteil dieser Alias-Bezeichner?
Ich sehe da nur eines: daß nämlich mit diesem Workaround namens
"uint_irgendwas" mehr Probleme aufgerissen werden (insbesondere die
vielgelobte Portabilität), als man zu stopfen beabsichtigt hatte.
Frank M. schrieb:> Packed> Structs mit ungünstigem Alignment bringen den STM32 dann mal richtig ins> Schwitzen. Das gilt übrigens nicht nur für den STM32F1xx, sondern> eigentlich für alle STM32.
Ach nö. Sowas geht nur dann in die Hose, wenn man gedankenlos so einen
Struct konzipiert. Es ist wie immer: Wenn der Programmierer nicht
nachdenkt, dann schreibt er eben auch einen schlechten Code. Wer
nachdenkt und die Manuals gelesen hat, der weiß, ob man der
Zielplattform überhaupt unaligned Daten zumuten kann und ob man sich das
bei Plattformen, die sowas abkönnen, auch leisten kann/will.
ABER: Das Problem des TO liegt ganz woanders.
Lies mal:
RCC_OscInitStruct.OscillatorType = ...
RCC_OscInitStruct.HSIState = ...
usw.
Nun, kommt so langsam die Erleuchtung?
Der TO benutzt diesen Krempel von ST und pflastert sich damit ruckzuck
alle Ressourcen zu, die sein Chip beinhaltet. Wenn man schon mit seinen
Ressourcen ein wenig haushalten muß, dann verbietet sich sowas wie die
ST-Lib, printf und anderes Zeug quasi wie von selbst. Genau DAS ist
hier der Generalfehler. Wenn ich lesen muß "Von der TrueStudio IDE
bekomme ich die Meldung 'RAM overflowed by 24 bytes'. Kann mir jemand
weiterhelfen," dann sagt mir mein Inneres: der Junge ist für seinen Job
zu klein.
W.S.
W.S. schrieb:> Wenn man schon mit seinen> Ressourcen ein wenig haushalten muß, dann verbietet sich sowas wie die> ST-Lib, printf und anderes Zeug quasi wie von selbst. Genau DAS ist> hier der Generalfehler.
In dem Fall ist der Generalfehler überhaupt STM32 oder kompatible zu
benutzen anstatt lieber einen den man in völlig tiefenentspanntem
Zustand über die Register direkt programmieren kann während das Auge
wohlgefällig über die grüne Wiese wandert und die Vögel zwitschern so
wie das zum Beispiel bei Kinetis der Fall ist und nicht wie bei STM32 wo
man allein beim Gedanken daran schon einen Herzinfarkt erleidet! Das ist
der Gerelalfehler, wenn es überhaupt sowas gibt dann ist es das!
W.S. schrieb:> Tja. Und wo bleibt da der proklamierte Vorteil dieser Alias-Bezeichner?
Dass ich den Source nicht mit #ifdefs zukleistern muss, um portabel zu
bleiben. Überläufe zu missachten ist ein eklatanter Fehler des
Programmierers. Man sollte also seine eigene Unfähigkeit nicht mit so
einer Ausrede "uint_fast8_t ist schuld!" verdecken.
> Ich sehe da nur eines: daß nämlich mit diesem Workaround namens> "uint_irgendwas" mehr Probleme aufgerissen werden (insbesondere die> vielgelobte Portabilität), als man zu stopfen beabsichtigt hatte.
Unsinn, Du hast schon desöfteren gezeigt, dass Du von Programmieren
keine Ahnung hast, daher würde ich an Deiner Stelle nicht so großkotzig
daherkommen.
Mit Portabilität hast Du auch nichts am Hut. Deine Programme laufen
immer nur genau auf einem Prozessortypen. Das ist easy.
> Frank M. schrieb:> Packed> Structs mit ungünstigem Alignment bringen den STM32 dann mal richtig ins> Schwitzen. Das gilt übrigens nicht nur für den STM32F1xx, sondern> eigentlich für alle STM32.>> Ach nö. Sowas geht nur dann in die Hose, wenn man gedankenlos so einen> Struct konzipiert.
Hallo? Lies meinen Satz nochmal: "Structs mit ungünstigem Alignment
...". Das ist genau damit gemeint, nämlich dass der Programmierer nicht
aufgepasst hat. Du wiederholst hier nur noch mal schwülstig meine
Aussage.
Also: Mal wieder viel Wind um nichts. Alles schon durchgekaut.
Hauptsache, W.S. hat sich mal wieder gemeldet.
Frank M. schrieb:> Packed> Structs mit ungünstigem Alignment bringen den STM32 dann mal richtig ins> Schwitzen.
Normalerweise entwirft man seine structs deswegen ja von der Sortierung
der Datentypen von groß nach klein oder umgedreht. Dann sorgt der
Compiler selber dafür, daß alles richtig aligned wird.
W.S. schrieb:> Tja. Und wo bleibt da der proklamierte Vorteil dieser Alias-Bezeichner?
Beispielsweise für Schleifenzähler, die vom Wertebereich her klein
bleiben, aber je nach Plattform in 32 bit durchaus schneller sein können
als in 8 bit.
Verwendet man das in structs, muß man natürlich sauber programmieren,
anstatt sich auf implizite Datengrößen und Offsets zu verlassen. Das ist
aber ohnehin best practice.
Nop schrieb:> Normalerweise entwirft man seine structs deswegen ja von der Sortierung> der Datentypen von groß nach klein oder umgedreht. Dann sorgt der> Compiler selber dafür, daß alles richtig aligned wird.
Es wird immer alles richtig aligned solange man kein packed verwendet.
Dann werden halt hier und da unsichtbare Paddingbytes eingefügt.
Jedoch kann man auch so vorgehen (man muss nicht stur von groß nach
klein):
int64 immer an 8er Offset plazieren
int32 immer an 4er Offset plazieren
int16 immer an 2er Offset Plazieren
int8 an beliebiger Stelle
Also zum Beispiel 2 einzelne Bytes, dann ein int16, dann ein int32, dann
vielleicht wieder 2 einzelne Bytes, dann wieder ein int16, etc... wie
mit den Bauklötzchen früher, ist ganz einfach...
Dann ist es auch ohne packed genauso kompakt und es entsteht kein
Padding. Dazu braucht man nur 8 Finger um zu zählen und ein bisschen
Grundrechnen.
Vgl: ESR: "The Lost Art Of Structure Packing"
Frank M. schrieb:> Bremst den STM32 unter Umständen arg aus.
Diese Umstände muß man aber schon mit der Lupe suchen.
Z.B. bei einer Struct, die UART-Daten, ADC-Daten oder Tastendrücke
aufsammelt, wird man keinen merkbaren Laufzeitunterschied feststellen.
Es müssen schon Routinen sein, die exzessiv auf die Struktur zugreifen,
z.B. DSP-Funktionen (Audio- oder Bildverarbeitung).
Nop schrieb:> Normalerweise entwirft man seine structs deswegen ja von der Sortierung> der Datentypen von groß nach klein oder umgedreht. Dann sorgt der> Compiler selber dafür, daß alles richtig aligned wird.
Eben. Und daher benutzt man packed-Structs nur, wenn man explizit gegen
das Alignment verstoßen will. Es ist Quatsch, eine bereits manuell
ausgerichtete Struct noch mit dem Attribut "packed" zu versehen. Das ist
doppelt gemoppelt und bringt nichts.
Peter D. schrieb:> Diese Umstände muß man aber schon mit der Lupe suchen.
Teste einfach mal die obigen vier for-Schleifen - einmal mit uint8_t und
einmal mit uint32_t (oder uint_fast8_t).
> Z.B. bei einer Struct, die UART-Daten, ADC-Daten oder Tastendrücke> aufsammelt, wird man keinen merkbaren Laufzeitunterschied feststellen.
Ich habe anfangs auch gar nicht von Structs gesprochen. Das, was Du da
von mir zitiert hast, bezog sich auf die allgemeine Verwendung von
8-Bit-Variablen - egal wo.
Frank M. schrieb:> Es ist Quatsch, eine bereits manuell> ausgerichtete Struct noch mit dem Attribut "packed" zu versehen.
Naja man kann sich ein bißchen Verschnitt sparen. 32, 16 und 8 bit sind
64 bit normal und 56 bit packed.
Nop schrieb:> Naja man kann sich ein bißchen Verschnitt sparen.
Betonung liegt auf "bißchen" - nämlich am Ende :-)
Beim Zugriff auf den letzten uint8_t müssen dann aber wieder 3 Bytes vom
STM32 ausmaskiert werden - auch nicht so dolle.
Ich habe das Programm mal auf zwei STM32F4xx laufen lassen:
1
volatileuint8_ti,j,k,l;
2
3
led_an();
4
5
for(i=0;i<255;i++)
6
{
7
for(j=0;j<255;j++)
8
{
9
for(k=0;k<255;k++)
10
{
11
for(l=0;l<60;l++)
12
{
13
}
14
}
15
}
16
}
17
18
led_aus();
Die Variable l habe ich nur bis 60 laufen lassen, damit ich nicht so
lange warten muss.
Getestet auf einem STM32F401RE mit 84 MHz:
uint8_t: 160 sec
uint_fast8_t: 134 sec
-> Einbruch der Geschwindigkeit um 20% bei Verwendung von uint8_t.
Getestet auf einem STM32F407VET6 mit 168MHz:
uint8_t: 83 sec
uint_fast8_t: 77 sec
-> Einbruch der Geschwindigkeit um 8% bei Verwendung von uint8_t.
Warum der Unterschied beim STM32F407 geringer ist, ist mir schleierhaft.
(Edit: Vermutlich liegts an der höheren Zahl der Waitstates bei 168MHz,
die das Ergebnis relativieren).
Aber Geschwindigkeitseinbußen im 2-stelligen Prozentbereich muss man
nicht haben. Hier sprechen wir noch nichtmals über Alignment, sondern
nur über die Verwendung von 8-Bit-Variablen. Natürlich wurden dabei auch
die 4 lokalen uint8_t-Variablen vom Compiler aligned.
P.S.
Gestoppt wurde das mit einem Timer, nicht mit der Hand ;-)
Eingebaut wurde das aus Faulheit in eine bestehende Anwendung, bei der
die Timer-ISR auch noch andere Dinge erledigen musste, wie zum Beispiel
IRMP und andere Aufgaben. Bei einer nackten Timer-ISR würde das
Egebnis sogar noch etwas krasser ausfallen.
Frank M. schrieb:> Bei einer nackten Timer-ISR würde das> Egebnis sogar noch etwas krasser ausfallen.
Der Timerinterrupt wird selber <0,1% verbrauchen, d.h. 20% mehr von 0,1%
merkt niemand.
Man muß nicht überall die Gespenster unterm Bett suchen, d.h.
Mikrooptimierung betreiben.
Bernd K. schrieb:> In dem Fall ist der Generalfehler überhaupt STM32 oder kompatible zu> benutzen anstatt...
Ach, sieh das mal nicht gar so pessimistisch.
Aber so im Kern kristallisiert sich schon dabei heraus, daß ST mit
seinem Marketing zwar offensichtlichen Erfolg hatte, aber auf lange
Sicht ist es ein Tiefschlag gegen das Niveau der existierenden
Ingenieure. Stell dir mal vor, wenn es in 10 Jahren nur noch Ingenieure
gibt, die nichts anderes können als XYZ_InitStruct's zu befüllen.
Frank M. schrieb:> Dass ich den Source nicht mit #ifdefs zukleistern muss,
und:
Frank M. schrieb:> Unsinn, Du hast schon desöfteren gezeigt, dass Du von Programmieren> keine Ahnung hast
Zunächst mal herzlichen Dank für die Blumen.
Oh mann, ich wollte ja nicht unbedingt auf dein hier mal
veröffentlichtes Projekt zurückkommen. Aber da du es ja selbst
ansprichst: Ja, du bist in selbigem so ziemlich ertrunken in einer Flut
von #ifdef's. Das zeigt, wieviel Ahnung du vom Programmieren hast, so
daß du von oben herab auf Leute wie mich herabsehen kannst. Und dabei
hast du nicht einmal alle üblichen STM32Fxxx mit deinen #ifdef's
erfassen können. Geschweige denn Cortex-M Chips von anderen Herstellern
oder gar 32 Bit Controller, die zufälligerweise mal keine Cortex-M sind.
Nein, in einer sauberen Quelle braucht eigentlich fast NIE ein #ifdef
enthalten zu sein. Ausnahmen sind sowas wie void __irq XYZhandler(void),
wenn irgend ein Compiler sowas wie __irq nicht versteht. Man macht das
so, daß man sauber zwischen den Ebenen trennt, also plattformabhängiges
Zeugs in plattformspezifische Lowlevel-treiber und schon hat man direkt
oberhalb dieser Ebene keine (oder zumeist keine) Plattformabhängigkeit
mehr drin.
So herum geht das - du großer Programmierer.
Peter D. schrieb:> Diese Umstände muß man aber schon mit der Lupe suchen.
Ja, Peter. Auf diese Dinge trifft man nur gezwungenermaßen, z.B. wenn
man vorgegebene Strukturen wie Header in irgendwelchen üblichen
Dateiformaten oder Directory-Strukturen behandeln MUSS. Big- versus
Little-Endian oder FAT12 zum Beispiel oder SOL-Audio oder eben sowas.
Für alles, was man sich selber aussucht, trifft das nicht wirklich zu.
Der TO hat aber eher das mentale Problem, daß er offenbar auf die STM32
festgenagelt ist, ebenso auf die Verwendung von Cube und Konsorten und
insgesamt sich etwas vorgenommen hat, wofür er noch ein bissel zu klein
ist.
W.S.
Peter D. schrieb:> Frank M. schrieb:>> Bei einer nackten Timer-ISR würde das>> Egebnis sogar noch etwas krasser ausfallen.>> Der Timerinterrupt wird selber <0,1% verbrauchen, d.h. 20% mehr von 0,1%> merkt niemand.
So habe ich das nicht verstanden. Die Benchmark-Schleife lief
offensichtlich im Hauptprogramm, aber der Timer zum Stoppen hat außer
dem Stoppen noch andere Sachen gemacht. D.h. das Hauptprogramm hat
nichtmal die volle Rechenzeit bekommen, d.h. der Unterschied war etwas
kleiner als eigentlich möglich.
Nop schrieb:> Die Benchmark-Schleife lief offensichtlich im Hauptprogramm, aber der> Timer zum Stoppen hat außer dem Stoppen noch andere Sachen gemacht
So ist es. Natürlich lief die Benchmark-Schleife im Hauptprogramm.
Frank M. schrieb:> Unsinn, Du hast schon desöfteren gezeigt, dass Du von Programmieren> keine Ahnung hast, daher würde ich an Deiner Stelle nicht so großkotzig> daherkommen.> Du wiederholst hier nur noch mal schwülstig meine> Aussage.> Also: Mal wieder viel Wind um nichts. Alles schon durchgekaut.> Hauptsache, W.S. hat sich mal wieder gemeldet.
Interessante und souveräne Art der Moderation.
Du bekommst hiermit die Auszeichnung "Moderator des Monats".
https://de.wikipedia.org/wiki/Moderator_(Gespr%C3%A4chsleiter)
Gnorm schrieb:> Oder M0,M3,Mx abhaengig?
Jo, das ist recht stark davon welcher core eingesetzt wird (und weniger
davon welcher Hersteller den verbaut hat).
Zum einen sind die unterstützten Befehle durchaus unterschiedlich,
gerade bei Div/Mul.
https://en.wikipedia.org/wiki/ARM_Cortex-M#Instruction_sets
Und bei den Speicherzugriffen gibt es auch Unterschiede. Z.B.:
Cortex-M0 & Cortex-M0+
3.3.4. Address alignment
An aligned access is an operation where a word-aligned address is used
for a word, or multiple word access, or where a halfword-aligned address
is used for a halfword access. Byte accesses are always aligned.
There is no support for unaligned accesses on the Cortex-M0+ processor.
Any attempt to perform an unaligned memory access operation results in a
HardFault exception.
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/BABFAIGG.htmlhttp://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0662b/BABFAIGG.html
Cortex-M3
3.3.5. Address alignment
An aligned access is an operation where a word-aligned address is used
for a word, dual word, or multiple word access, or where a
halfword-aligned address is used for a halfword access. Byte accesses
are always aligned.
The Cortex-M3 processor supports unaligned access only for the following
instructions:
LDR, LDRT, LDRH, LDRHT, LDRSH, LDRSHT, STR, STRT, STRH, STRHT.
All other load and store instructions generate a UsageFault exception if
they perform an unaligned access, and therefore their accesses must be
address aligned. For more information about UsageFaults see Fault
handling.
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/BABFAIGG.html