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.
strings einfach mit
1 | const char *string = "string im flash" |
ablegen
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.
Beitrag #6005334 wurde von einem Moderator gelöscht.
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.
Leider etwas offtopic, aber die Abbruchbedingung der Schleife sieht auch merkwürdig aus:
1 | void PotentiometerInit(void) |
2 | {
|
3 | uint16_t initval = (uint16_t) (((uint32_t) INITIAL_SPEED_IN_RPM / (uint32_t) MAXIMUM_SPEED_IN_RPM) * 0XFFFF); |
4 | |
5 | for(pot_buf_index = 0; pot_buf_index >= POT_BUF_SIZE; pot_buf_index++) // <--- wirklich >= ??? |
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.
der Motorcontroller ist doch nicht der F103 sondern der L0 irgendwas, der hat scheinbar nur 4 kB Ram, und das wird aufgebraucht. es geht wohl um diesen: Beitrag "Problem mit ST-Board zur BLDC-Ansteuerung" https://www.st.com/en/microcontrollers-microprocessors/stm32f031c6.html
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.
:
Bearbeitet durch User
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:
1 | RCC_OscInitTypeDef RCC_OscInitStruct = {0}; |
2 | RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; |
3 | RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; |
4 | |
5 | ADC_ChannelConfTypeDef sConfig = {0}; |
6 | |
7 | TIM_MasterConfigTypeDef sMasterConfig = {0}; |
8 | TIM_OC_InitTypeDef sConfigOC = {0}; |
9 | TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0}; |
10 | |
11 | usw... |
:
Bearbeitet durch User
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
1 | .data.pUSART 0x00000000200005e0 0x13c Application/User/mc_config.o |
2 | 0x00000000200005e0 pUSART |
und
1 | COMMON 0x0000000020000778 0x22c Application/User/main.o |
2 | 0x0000000020000778 hdma_tim1_ch4_trig_com |
3 | 0x00000000200007bc PotentiometerConv |
4 | 0x00000000200007c8 htim3 |
5 | 0x0000000020000808 huart1 |
6 | 0x0000000020000878 htim1 |
7 | 0x00000000200008b8 hdma_tim3_ch4_up |
8 | 0x00000000200008fc PotentiometerHandle |
9 | 0x0000000020000900 hdma_adc |
10 | 0x0000000020000944 hadc |
11 | 0x0000000020000990 pot_buf |
immerhin 872 byte insgesamt.
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.
:
Bearbeitet durch Moderator
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^^
Und andere, wie z.B. LPC, haben das Problem nicht? Oder M0,M3,Mx abhaengig? Wie kann man das testen?
Danke. Also einmal mit 8 bit und einmal mit 32 bit und das vergleichen?
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!
:
Bearbeitet durch User
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.
:
Bearbeitet durch Moderator
Gnorm schrieb: > Wie kann man das testen? Zum Beispiel so (Pseudocode):
1 | #include <stdint.h> |
2 | ...
|
3 | volatile uint8_t i, j, k, l; |
4 | |
5 | led_an (); |
6 | |
7 | for (i = 0; i < 255; i++) |
8 | {
|
9 | for (j = 0; j < 255; j++) |
10 | {
|
11 | for (k = 0; k < 255; k++) |
12 | {
|
13 | for (l = 0; l < 255; l++) |
14 | {
|
15 | }
|
16 | }
|
17 | }
|
18 | }
|
19 | |
20 | led_aus (); |
21 | ...
|
Wichtig ist das volatile, sonst optimiert der Compiler die Schleifen weg. Dann die Zeit stoppen, wie lange die LED leuchtet. Anschließend die Zeile
1 | volatile uint8_t i, j, k, l; |
durch
1 | volatile uint_fast8_t i, j, k, l; |
ersetzen und nochmal die Zeit stoppen.
Danke. Und dann das Ganze noch mal mit 32 bit, um die "Referenz" zu haben?
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.
Gnorm schrieb: > Danke. Und dann das Ganze noch mal mit 32 bit, um die "Referenz" > zu haben? nimmste uint32_t.
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"
:
Bearbeitet durch User
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 | volatile uint8_t i, 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.
:
Bearbeitet durch Moderator
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)
Nene das macht Frank M. schon ganz gut. W.S. fällt hier desöfteren durch Dummschwätzigkeit auf ;)
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.html http://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
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.