Mein erstes STM32 Programm läuft (Hurra!) allerdings ist es unerwartet
groß.
Und zwar habe ich in SW4STM32 ein neues Projekt mit der StdPeriph
Library erstellt. Zielplattform ist das Nucleo-64 Board mit STM32F103RB.
Das Programm belegt 2808 bytes Flash. Ich hatte weit unter 1kB erwartet.
Was mache ich falsch?
1
#include"stm32f10x.h"
2
#include"stm32f1xx_nucleo.h"
3
#include<stdint.h>
4
5
voiddelay(uint16_tmsec)
6
{
7
for(uint32_tj=0;j<500000;j++)
8
{
9
asmvolatile("nop");
10
}
11
}
12
13
intmain(void)
14
{
15
STM_EVAL_LEDInit(LED2);
16
while(1)
17
{
18
STM_EVAL_LEDOn(LED2);
19
delay(100);
20
STM_EVAL_LEDOff(LED2);
21
delay(100);
22
}
23
}
Das die delay Routine doof ist, möchte ich hier nicht diskutieren. Es
sei denn, die ist Ursache für die Programmgröße.
Stefan U. schrieb:> STM_EVAL_LED_irgendwas()
Diese unschuldig aussehenden Funktionen (fast könnte man meinen es sind
nur kleine Makros, aber es sind Funktionen, klick mal drauf wo die
hingehen) ziehen das ganze monströse gpio-Treibergelumpe rein.
Das gezeigte LED-Blinken ließe sich auch mit 3 oder 4 Schreibzugriffen
in die entsprechenden Register erledigen, dann würden die nicht mehr so
viele Controller mit zwei Nummern zuviel Flash verkaufen wenn sich das
herum spräche.
Realistische Größe für obiges Programm ohne den ganzen Bloat wäre etwa
geschätzte 716 Byte (und das größte daran wäre die Vektortabelle und der
Startup/Systeminit code, um den kommt man aber schwerlich herum)
Hier ist ein Beispiel auf nem Nucleo-Board das fast das selbe macht aber
ohne irgendwelche libs, erzeugt 716 Byte und blinkt:
https://github.com/prof7bit/bare_metal_stm32f401xe
und davon abgeleitet für nen stm32f103c8:
https://github.com/ChristianRinn/bare_metal_stm32f103c8
Stefan U. schrieb:> Ich hatte weit unter 1kB erwartet.
Das wird wohl nicht funktionieren.
Allein die Vektortabelle ist bereits ohne ein einziges Byte Code größer.
> Optimierung eingeschaltet?
Gute Frage, das hätte ich selbst erstmal prüfen sollen. Es war der Debug
Build mit -O0. Jetzt habe ich mal den Release Build mit -O3 probiert und
komme auf 3184 Bytes. Huch, das ist ja noch mehr! Warum?
Mit -Os sind es 2376 Bytes. Ist mir immer noch viel zu groß.
Bewege ich mich denn hier in einer normalen Größenordnung oder mache ich
was falsch? Ich bin von AVR's gewohnt, dass solche LED-Blinker
Anwendungen viel viel kleiner sind.
STM STM STM schrieb:> Genau das fehlt mir in seiner Source. Wird dieses Leben> da irgendwo implizit aufgerufen?
Vom startup code aus (meist in Assembler geschrieben) werden noch einige
Dinge initialisiert und dann erst mehr oder weniger indirekt in die
main() verzweigt.
Dem kannst Du folgen indem Du besagte startup Assemblerdatei findest und
dort mal im Code des Reset-vektors einen Breakpoint setzt (oder den
Debugger so einstellst daß er im angehaltenen Zustand startet) und dann
durchsteppst wohin Dich das überall herumführt bevor es in der main()
ankommt.
> Diese unschuldig aussehenden Funktionen ... ziehen das> ganze monströse gpio-Treibergelumpe rein.
Das hatte ich befürchtet. ist wohl der gleiche Rotz, wie bei Arduino.
Und diese komische HAL Library von CubeMX ist noch schlimmer.
Ich denke, damit steht für mich fest, dass ich gleich zu beginn lernen
will, ohne diese Libraries auszukommen.
> -ffunction-sections und -gc-sections
Ist beides schon aktiviert. Diese Optionen kenne ich auch schon vom
avr-gcc. Sie können den Code unter Umständen erheblich verkleinern.
Stefan U. schrieb:> Bewege ich mich denn hier in einer normalen Größenordnung oder mache ich> was falsch? Ich bin von AVR's gewohnt, dass solche LED-Blinker> Anwendungen viel viel kleiner sind.
Wie oben schon geschrieben. Du willst irgendwelche monströse Libs
verwenden anstatt wie man es früher gemacht hat einfach kurzerhand die
gpio- und sonstige Register direkt zu schreiben.
Ich weiß nicht wer das Gerücht aufgebracht hat das ginge plötzlich nicht
mehr anders (obwohl es jahrelang problemlos ging) und jeder glaubt es
unbesehen, diese kleinen Cortexe sind auch nicht nennenswert komplexer
als sagen wir mal zwei AVRs zusammen, die Manuals sind alle in der
selben Sprache und im selben Stil geschrieben, ähnlich aufgebaut und
genauso schwer oder einfach zu lesen wie früher.
> Du willst irgendwelche monströse Libs verwenden
Nee, will ich nicht. STM nennt diese Lib "schlank". Nach deren
Sichtweise bin cih dann wohl sportlich mit Idealgewicht :-)
> Ich weiß nicht wer das Gerücht aufgebracht hat das ginge> plötzlich nicht mehr anders
Steht in praktisch jedem Tutorial. Ich bin drauf reingefallen, aber ich
erkenne, dass dies der falsche Weg ist - jedenfalls für meinen
Geschmack. Da ist ja sogar Arduino noch besser (und Arduino ist schon
mies, finde ich).
Markus F. schrieb:> Stefan U. schrieb:>> Ich hatte weit unter 1kB erwartet.>> Das wird wohl nicht funktionieren.>> Allein die Vektortabelle ist bereits ohne ein einziges Byte Code größer.
Erzähl doch keinen Unsinn, die Vektortabelle ist beim F103 etwa 65
Einträge a 4 Byte lang. Startup-Code samt Blinky bräuchten ungefähr
nochmal 320 Byte, macht zusammen 580 Byte.
Hier hab ich ein kompiliertes Blinky für nen F401, der hat geschätzt 100
Vektoren, so sieht das Speicherabbild aus:
Bernd K. schrieb:> Erzähl doch keinen Unsinn, die Vektortabelle ist beim F103 etwa 65> Einträge a 4 Byte lang.
Meine Vektortabelle (kein STM32, Kinetis M4 MK20) hat 0x410 Bytes. Ich
bin einigermaßen erstaunt, wie stark die sich unterscheiden.
Und wenn man wie bei diesem Blinky keine Interrupts nutzt kann man die
auch noch alle weglassen (bis auf die ersten 2 Einträge), das ist zwar
für ne normale Anwendung eher unbrauchbar, aber zum Beispiel für
Bootloader interessant wenn man unter einer Sektorgrenze bleiben will
und um jedes einzelne Byte hart kämpfen muss.
Markus F. schrieb:> Meine Vektortabelle (kein STM32, Kinetis M4 MK20) hat 0x410 Bytes.
Nein hat sie nicht, die ist auch nur ein paar hundert Byte lang, aber
zwischen 0x400 und 0x40f liegen die Flash-Config- und Security Bytes.
Davor sind noch ~700 Bytes verschwendete "Luft".
Schau mal mit nem Hex-Editor ins .bin-File und staune über die
Verschwendung.
Mit Linkerscript und geeigneten Attributen lege ich bei mir dort die
SystemInit() hin und andere kleine Funktionen bis der Platz fast voll
ist, das mach ich aber auch nur bei meinen Bootloadern um damit
insgesamt unter der nächsten Sektorgrenze (z.B. 2kB) zu bleiben.
Zusätzlich lass ich im Bootloader auch noch alle Vektoren weg die ich
nicht brauche (also alle bis auf Reset), das bringt auch nochmal ein
bisschen zusätzliche Luft.
In der vom Bootloader geladenen Anwendung lasse ich die Flash-config
bytes einfach ersatzlos weg, dann verschwindet das häßliche Loch
zumindest dort komplett.
Bernd K. schrieb:> Nein hat sie nicht, die ist auch nur ein paar hundert Byte lang, aber> zwischen 0x400 und 0x40f liegen die Flash-Config- und Security Bytes.> Davor sind noch ~700 Bytes verschwendete "Luft".
Du hast recht, ist mir bislang nie aufgefallen. 700 sinds nicht ganz
(648 Bytes genau, SWI_IRQHandler ist der letzte benutzte Vektor). Gut zu
wissen, daß da noch ein bißchen Luft ist, wenn's eng wird.
Ich werd' jetzt aber trotzdem nicht gleich meinen Startupcode ändern
(wenigstens solange "hinten" noch Platz ist). Bei der nächsten
Chipgeneration hängen die da fünf neue Vektoren dran und dann kann man
wieder von vorne anfangen.
Hm, bin ja auch immer ein Feind der Verschwendung - aber du hast 128kB
Flash und jammerst, dass 3kB weg sind?? Die anderen 125kB muss man erst
mal vollbekommen, für leergelassenen Flash gibts keinen Bonus.
Interessant wird doch sowas nur, wenn es einfach nicht mehr reinpasst
oder knapp der nächstkleinere MC knapp nicht reicht.
> du hast 128kB Flash und jammerst, dass 3kB weg sind??
Wenn es bei den 3kB Overhead bleibt, ist alles ok. Ich habe nur tewas
Angst, dass meine Programme jetzt alle um Faktor 10 größer werden, als
bisher (verglichen mit 8bit AVR).
Andererseits möchte ich aber nicht völlig "zu fuß" programmieren, sonst
käme ich mir vor, wie in den 80ern, als ich noch mit dem Taschenrechner
Hex Codes assembliert hatte.
Vielleicht ist Dir das nützlich:
Vor Jahren erstellte ich ein in C geschriebenes Testprogram für
Schaltungsentwickungszwecke Für verschiedenen uC (PIC,AVR,AT90LP51,Zilog
Z8). Bei den 8-Bittern wurden dafür immer an ca 10KB an Flash
verbraucht. Später portierte ich dasselbe Program auf einen STM32 und
LPC2103 mit den dafür notwendigen Anpassungen und kam dann auf knapp
29KB. Allerdings musste ich beim STM32 ein externes I2C EEPROM
miteinbeziehen was bei den meisten 8-Bittern nicht notwendig war. Die
I2C Bib stammte von ST nach einer App Note. Die I2C HW im F103 ist etwas
gewöhnungsbedürftig und nicht sehr ausführlich im Datenblatt
beschrieben.
Die meisten SFRs programmierte ich in üblicheweise selber. Ich
verwendere nur ein paar StdLib Initialisierungen(Clock/Pll) ausser dem
vorgeschriebenem Startup Code.
Danach arbeitete es sich genau so leicht wie mit den 8-Bittern.
Beim STM32 gab es immer den von Dir erwähnten "Overhead". Auch eine
leere main() produzierte immer einen ähnliche Flash Bedarf. Danach
allerdings hielt sich der Verbrauch in proportionalen Grenzen.
Ein Program mit ca 35000 Source Lines verbrauchte beim STM32F103 nur um
110KB.
Deine Angst ist unbegründet.
Ja, sie werden insgesamt grösser, aber ganz bestimmt nicht in dem Mass,
wie du jetzt vielleicht befürchtest. 128kB ist ne ganze Menge.
Ok, dankeschön.
Auch an bernd K, diese Bare-Metal Codebeispiele habe ich mir angesehen.
Mit solchen Vorlagen möchte ich tatsächlich anfangen, nur fehlt mir noch
die headerdatei mit den Definitionen der ganzen Register.
Ich werde mal versuchen, mir das aus den ST Libs heraus zu kopieren. mal
sehen, wie klein/groß mein Programm ohne deren Initialisierungsroutinen
wird.
Letztendlich möchte ich sowieso alle Register selbst beschreiben, damit
ich weiss, was ich da tue.
Kann man alles machen.
Interessant wird es dann bei USB, Eth usw. auf Registerebene.
Dann kannst du dir für alles eigene Vorlagen anlegen, ist klar,
musst aber natürlich alles aktuell halten.
Viel Spass dabei :)
Ich bevorzuge da die HAL Luxus Variante und tauche nur in die Register
ab wenn irgend etwas nicht so läuft wie es soll.
Aber jeder wie er mag.
Wenn man keine Libs nutzt werden die Programme sogar kleiner.
Ich habe eine Drucker-Firmware auf den STM32F411 portiert. Die Größe ist
um Faktor 2 (AVR->STM) kleiner bei mir.
Stefan U. schrieb:> Ich habe nur tewas> Angst, dass meine Programme jetzt alle um Faktor 10 größer werden, als> bisher (verglichen mit 8bit AVR).
Der Startup-Code und die Vektortabelle kostet nur einmal Flash. Das kann
man also nicht linear hochrechnen. Und auch jede Lib-Funktion kostet nur
beim ersten Aufruf.
Je größer Dein eigener Code wird, umso günstiger wird es also.
Ein kurzes Blinkprogramm ist dagegen völlig untauglich für Vergleiche.
Bernd K. schrieb:> Das gezeigte LED-Blinken ließe sich auch mit 3 oder 4 Schreibzugriffen> in die entsprechenden Register erledigen, dann würden die nicht mehr so> viele Controller mit zwei Nummern zuviel Flash verkaufen wenn sich das> herum spräche.
Das gilt aber nur für sehr kleine Projekte.
Bei sehr großen, umfangreichen Projekten relatviert sich das schnell.
Wenn du meinst, das sei viel, dann schau dir an, was an Code durchlaufen
wird, bevor ein Raspberry-PI eine LED blinken lässt.
Um das mal mit einem Autovergleich zu garnieren:
Überleg dir, welchen Mehaufwand es bedeutet (in Punkto Technologie) ein
Holzscheit um 50m zu transportieren.
Variante1 : zu Fuß (enspricht dem µC)
Variante2 : mit dem Auto (enspricht dem Raspi)
Und dann überleg dir, was es bedeutet 50 Hozscheite über 50km zu
transportieren
Variante1 : zu Fuß
Variante2 : mit dem Auto
Du siehst den Unterschied ?
Willst du weniger Flash, nimm eine Blinkled. Oder einen 8-Bitter.
Stefan U. schrieb:> Wo bekomme ich denn die stm32f10x.h her, wenn ich weder CubeMX noch die> StdPeriph Library verwende?
Hmm, das verstehe ich nicht ganz.
In den Header-Dateien im CMSIS-Bereich (z.B. stm32f0xx.h,
system_stm32f0xx.h, core_cm0.h für die F0-Serie) findest Du doch
praktisch nur Defines und Strukturdefinitionen. Auf diese Bezeichner
wird auch in den Registerbeschreibungen der Referenz-Handbücher Bezug
genommen wird. Damit kannst Du die Register direkt ansprechen, so wie Du
es von den AVR gewohnt bist (und das ist dann auch nicht schwieriger).
Durch dessen Verwendung blähst Du den Code natürlich auch nicht auf.
Aufgebläht bzw. langsam wird das Ganze erst mit der StdLib/Cube.
Ich sehe keinen wirklichen Sinn darin, das alles nochmal selbst genau so
zu definieren.
Oder stört Dich die Lizenz?
Zum Startup-Code hat Peter ja schon das Richtige geschrieben. Den hat
man nur einmal, danach "wächst" die Codegröße nur noch langsam. Je nach
Anwendung (bspw. viele 32-Bit-Operationen) kann er dann sogar kleiner
als bei AVRs werden.
> Wenn es bei den 3kB Overhead bleibt, ist alles ok. Ich habe nur tewas> Angst, dass meine Programme jetzt alle um Faktor 10 größer werden, als> bisher (verglichen mit 8bit AVR).
Kann aus Erfahrung auch bestätigen, dass die Programme nicht größer
werden als beim AVR. Teilweise sogar kleiner. Mit dem Offset an
Speicherverbrauch musst du halt leben.
> Oder stört Dich die Lizenz?
Nein. Die Header aus der CMSIS hängen allerdings wiederum von den
Dateien der StdPeriph Library ab, und die installiert den großen
Startup-Code.
Wenn ich Platz sparen will, muss ich das wohl alles zusammen raus
werfen.
Oder mich mit der Programmgröße abfinden, sich sich aus der
CMSIS+StdPeriph Library ergibt.
Stefan U. schrieb:> Nein. Die Header aus der CMSIS hängen allerdings wiederum von den> Dateien der StdPeriph Library ab
Nein, es ist genau umgekehrt. Die stm32f***.h kann man isoliert
benutzen, man braucht nur noch die core_**.h und cmsis_**.h Header von
ARM dazu. Die HAL/SPL basiert darauf, aber die kann man weglassen.
Mithilfe diese Header kann man also ohne irgendwelchen Overhead direkt
auf die Register zugreifen. Ja, in den Headern sind ein paar
Hilfsfunktionen drin (wie __enable_irq), aber solange man die nicht
aufruft kosten die gar nichts. Es ist somit vergebliche Arbeit, sich
eigene Register-Definitionen zu bauen, wenn man nicht wie genannt ein
Problem mit der Lizenz hat oder die Definition komplett anders aufbauen
möchte (ohne fiese Makros und Speicher-Aliasing oder so).
Stefan U. schrieb:> und die installiert den großen> Startup-Code.
Nein, den Startup-Code kopiert man sich separat manuell ins Projekt. Tut
man das nicht, hat man keinen Startup-Code. Ohne den startet allerdings
das Programm nicht, weswegen man den vielleicht doch braucht. Wenn man
ihn selber schreibt, wird es nur unwesentlich kleiner.
Kleines Beispiel: Ich habe einen CAN-Bootloader für STM32F373
geschrieben, welcher zunächst seinen eigenen Startupcode inkl.
Takt-Initialisierung und CAN-Initialisierung durchläuft, sich selbst in
den RAM kopiert und von dort weiter läuft, dann mit einer asynchronen
FSM per Interrupts den eigentlichen Flash-Prozess durchläuft (inkl.
CRC-Prüfung) und schließlich die Anwendung startet. Das passt alles
genau in die 2048 Bytes, die eine Flash-Page ausmachen - also wesentlich
mehr Komplexität als der LED-Blinker, aber nicht linear mehr
Speichernutzung, und das trotz Nutzung der "stm32f37x.h" von ST.
@Niklas: anke für die Klarstellung.
>Und später auf HAL umsteigen
Im Wiki steht, dass HAL die SPL ablösen wird. Nun stellt sich für mich
die Frage, ob ich dann überaupt noch mit der SPL beschäftigen sollte.
Auf das erlernen von zwei Libraries habe ich keine Lust (es ist ja nur
ein Hobby).
Was mein ihr?
Stefan U. schrieb:>> Oder stört Dich die Lizenz?>> Nein. Die Header aus der CMSIS hängen allerdings wiederum von den> Dateien der StdPeriph Library ab
Inwiefern?
Die Header enthalten erstmal nur Definitionen. Die kannst Du ganz ohne
StdLib verwenden. Wenn Du möchtest, kannst Du auch die Takterzeugung
(üblicherweise in der system_stm32fxxxx.c unter CMSIS zu finden) selbst
stricken, allerdings halte ich das für sinnlos investierte Zeit. Viel
kleiner wird es nicht werden.
> und die installiert den großen> Startup-Code.
Man kann natürlich alles einschrumpfen (ISR-Vektortabelle usw.), aber
dann wird das Teil ziemlich unbenutzbar.
> Wenn ich Platz sparen will, muss ich das wohl alles zusammen raus> werfen.
Die Frage ist doch: musst Du überhaupt Platz sparen?
Dieser "Minimalplatzbedarf" tut bei den heutigen Flash-Größen wirklich
nicht weh, lässt einen aber komfortabel mit ISRs usw. arbeiten. Und
danach steigt die Codegröße nur noch sehr langsam an.
Die Zeiten, wo man auf Biegen und Brechen Bytes einsparen musste, sind
glücklicherweise für die meisten vorbei. Ich habe dieses Hineinpressen
damals einmal mit einem AVR8535 gehabt - das muss ich mir nicht mehr
geben :-)
> Oder mich mit der Programmgröße abfinden, sich sich aus der> CMSIS+StdPeriph Library ergibt.
Die ergibt sich nur aus der CMSIS + Startup-Code. Die StdLib spielt da
noch gar nicht rein.
Edit: ah, der Erlkönig war schneller :-}
> Die Frage ist doch: musst Du überhaupt Platz sparen?
Eigentlich nicht. Wir reden hier ja von vielleicht +/- 1kB und die
werden bei größeren Programmen auch nicht wesentlich mehr (soweit ich
verstanden habe).
Mit eurer Hilfe habe ich das nun verstanden. Nun habe ich noch die Frage
HAL oder SPL? Was sollte ich lernen? Konkrete Anforderungen habe ich gar
keine. Ich gehe allerdings davon aus, dass ich die komplexeren Treiber
für USB, Netzwerk, etc in absehbarer Zeit nicht brauche.
Darauf wirst du wohl keine einheitliche Antwort bekommen.
Ich finde CubeMX + SW4STM32 für meine Hobby Bedürfnisse perfekt.
Selbst USB-CDC war eine Angelegenheit von nur ein paar Minuten.
PWM war auch sehr übersichtlich zu erzeugen.
Sogar NF-PWM moduliertes HF-PWM.
Danke. Dann mache ich meine ersten Lernschritte erstmal nur mit den
Registerdefinitionen. Und wenn ich mich sicher fühle und was größeres
machen will, wo die HAL einen Mehrwert bringt, dann verwende ich sie.
Ich habe gerade eine Weile herumgegoogelt, demnach scheint die SPL
wirklich deprecated zu sein.
Stefan U. schrieb:> Nein. Die Header aus der CMSIS hängen allerdings wiederum von den> Dateien der StdPeriph Library ab, und die installiert den großen> Startup-Code.
Nein, das ist nicht der Fall.
Stefan U. schrieb:> Jetzt habe ich mal einen Versuch nur mit CMSIS gemacht. Hat geklappt und> belegt 2052 Bytes.
Da ist immer noch was faul. Die zu erwartende Größe für den Blinker auf
Deiner MCU sollte so zwischen 500 bis 700 Byte liegen.
Der Flash hört ja laut .map-File bei 0x3d8 auf, was 984 Byte sind und
soweit Pi mal Daumen passen sollte. Das Ding ist allerdings, das er da
noch irgendwas aus der libc reinlinkt und es in .data packt, also nicht
zu Null initialierter RAM:
> .data.impure_data> 0x20000000 0x428> d:/stm32/systemworkbench/plugins/fr.ac6.mcu.externaltools.arm-> none.win32_1.13.2.201703061525/tools/compiler/bin/../lib/gcc/arm-none-> eabi/5.4.1/../../../../arm-none-eabi/lib/armv7-m\libc.a(lib_a-impure.o)> 0x20000428 . = ALIGN (0x4)
Da gehen dir 0x428, also 1064 Byte an RAM flöten und natürlich auch an
Flash. Es geht bei der lib_a-impure.o soweit ich weiß darum bestimmte
Dinge in der newlib threadsafe zu machen. Ich vermute mal du linkst
gegen die newlib. Wie sieht der Linkeraufruf bei dir aus? Ein
"--specs=nano.specs" als Linkerargument linkt gegen die newlib-nano und
sollte dir das ersparen.
Christopher, du bist ein Schatz. Vielen vielen Dank!
Diese Linker Option war tatsächlich des Rätsels Lösung. Ich habe das
Programm inzwischen um eine Konfiguration der Taktfrequenz erweitert,
dennoch ist es jetzt nur noch 800 Bytes klein.
Warum willst Du denn die wenigen Bytes sparen? Dass 32 Bit Prozessoren
i.a. Maschinencode haben, der länger ist, ist eben so. Er ist allerdings
nicht 4x so lang, bestenfalls 1.5x. Dafür gibt es dann auch so schöne
Sachen wie Multiplikation/Division als Maschinenbefehl und vielleicht
sogar ein Floatingpoint Unit.
Du kannst ja als Übung mal ein minmales Programm schreiben, das eine LED
zum leuchten bringt. ;-) Das sollte so 20-30 Bytes verbrauchen?
Vektortabelle mit Stackinit und Resethandler und im Resethandler Clock
für den GPIO ein und Bit setzen. Danach abstürzen. ;-)
STM32 haben bis zu 2MB Flash, da passt einiges hinein. Meiner Meinung
nach gibt es nur drei Gründe, heute noch einen 8-Bitter zu
programmieren:
a) Aus Spass, man nimmt einen Arduino und lässt LEDchen blinken.
b) Aus beruflicher Notwendigkeit, weil man "geerbten" Code hat, bei 5
Millionen Waschmaschinen die Einsparung von 30 Cent lohnend ist, oder
die Aufgabe so einfach ist, dass es ein ATTiny auch tut.
TMK schrieb:> Warum willst Du denn die wenigen Bytes sparen?
Ich vermute damit er versteht was drin ist, was rein muß, was raus kann
und wie alles zusammenhängt. Und warum.
Diese kleinen ARMs sind immer noch so einfach gestrickt daß es ohne
weiteres möglich sein sollte nach etwas tieferem Einstieg jedes einzelne
Byte im Flash und jedes Register beim Namen zu kennen.
Diese intensive Beschäftigung mit Details die anderen unwichtig
erscheinen mögen vermittelt auch Grundlagenwissen welches sich mühelos
auf andere Hersteller übertragen lässt, teilweise sogar auf andere
Architekturen. Wenn er sich in ein paar Wochen bis auf den tiefsten
Grund und wieder zurück durchgegraben haben wird dann wird er mit diesem
Controller Dinge bewirken können bei denen gefühlte 95% der übrigen
Anwender (STM32-Cube-Klicker und HAL-Code-Abschreiber) nur noch mit den
Ohren schlackern können.
Und Aufmerksamkeit zum kleinsten Detail ist auch eine Eigenschaft die
einen befähigt Dinge zu erschaffen die in ihrer Qualität überragend und
einzigartig sein können. Diese Arbeitseinstellung ist stellenweise auch
heute noch gefragt. Das schafft kein Lego-Zusammenstecker.
Bernd K. schrieb:> Und Aufmerksamkeit zum kleinsten Detail ist auch eine Eigenschaft die> einen befähigt Dinge zu erschaffen die in ihrer Qualität überragend und> einzigartig sein können. Diese Arbeitseinstellung ist stellenweise auch> heute noch gefragt. Das schafft kein Lego-Zusammenstecker.
Ich gebe Dir in allem Recht und fühle mich an eine Zeit erinnert, wo ein
knapp 20-jähriger einen mühsam ersparten Original-IBM-PC gekauft hat.
Der hatte ein Manual mit kommentiertem BIOS-Listing in Assembler. Das
muss mich wohl zum Informatik-Studium gebracht haben... ;-)
Dein "stellenweise heute noch gefragt" hat mich etwas wehmütig
gemacht...
Trotzdem gebe ich zu bedenken, dass wir nun eine andere Zeit in der
Computertechnik erreicht haben, während wir als Menschen uns nicht
verändert haben. Nach wie vor gibt es eine gewisse "Maximalkomplexität"
die ein System haben darf, damit EIN Mensch es komplett verstehen kann.
Leider verdoppelt sich meine Speicherkapazität nicht alle 2 Jahren und
auch mein Gehirn hat noch denselben Takt wie damals. Deswegen habe ich
mich damit abfinden müssen, einem
SUPERHAL_Tut_Tolles(Pointer_auf_Was_Weiss_ich_strct ptr, 12345);
einfach zu glauben, dass es das tut, was ich will.
Viele Grüße
Thomas
Im Prinzip haben wir uns doch alle schon lange gelöst vom "bis ins
kleinste verstehen". Das kann man gar nicht mehr leisten (vielleicht als
Autist in einigen kleinen Spezialfällen) - wer es versucht, vertrödelt
Unmengen Zeit unproduktiv.
Wer in der Lage ist, einen TCP-Stack bis auf die Byte-Ebene zu verstehen
und das dann ohne Notwendigkeit auch tut (aus Prinzip) ist eigentlich
nur ein armer Tropf, denn er könnte mehr aus seinen Fähigkeiten machen.
Es geht aber noch viel früher los, ich sage jetzt einfach mal so
einfache Sachen wie CAN oder ein HART-Stack. Ich muss nicht verstehen,
wie das genau funktioniert, mir reicht eine gut dokumentierte und
funktionierende Blackbox völlig. Man kann das Verständnis auch noch eine
Ebene tiefer ansiedeln - wen ausser Chipdesignern interessiert es, wie
eine ALU oder ein Microprogramm funktioniert? Oder noch tiefer - ein
einzelnes läppisches Gatter oder Flipflop?
Wo ist die Grenze, was man genau verstehen sollte? Schwer zu sagen...
Die heutige Technik (besonders in der Softwaretechnik) haben wir nur
erreicht, weil immer mehr Leute die Vorarbeit anderer unbesehen nutzen.
Zu wissen, dass es funktioniert reicht.
Sollte es Probleme irgendwelcher Art geben, kann man sich damit genauer
beschäftigen.
So ganz einfach darf man sich die direkte Manipulation von SFRs bei
gewissen STM32 Peripherien nicht unbedingt machen, finde ich.
Das I2C H.W. Interface ist dafür ein gutes Beispiel. Einfach zugehörende
I2C SFRs zu beschreiben und Lesen geht dort nicht unbedingt alleine weil
die I2C HW aus einer semi-autonomen State Machine besteht die nur dann
korrekt mit den Bustransaktionen funktioniert wenn gewisse
dazugehörenden SFRs zur rechten Zeit und Umständen von der
Steuersoftware gelesen/geschrieben und bearbeitet werden damit die State
Machine korrekt weiter funktioniert. Das ist übrigens in einer App Note
von ST ausführlich beschrieben. Die freie Interaktion mit SFRs wie bei
einfacheren uC geht hier nicht. Auch der Startup anderer Peripherien und
auch der PLL benötigt genau vorgeschriebene Methoden.
Aus diesem Grund finde ich daß das Studium der StdPeripherie Bibliothek
am Anfang sehr nützlich ist um notwendige Initialisierungen korrekt zu
übersehen und mögliche Vereinfachungen zu erkennen und dort verwendete
Methoden beizubehalten wo es zwingend notwendig ist. Das STM32
Datenblatt ist nicht in allen Fällen unbedingt sehr ausführlich und
Manches ist eher inkomplett dokumentiert.
H.Joachim S. schrieb:> Man kann das Verständnis auch noch eine> Ebene tiefer ansiedeln - wen ausser Chipdesignern interessiert es, wie> eine ALU oder ein Microprogramm funktioniert? Oder noch tiefer - ein> einzelnes läppisches Gatter oder Flipflop?
Es gibt immer für jede Ebene Leute die es verstehen müssen, sonst würde
bald alles zusammenbrechen.
> wer es versucht, vertrödelt Unmengen Zeit unproduktiv.
Seit wann muss das Hobby produktiv sein?
> vertrödelt
Man eignet sich Kenntnisse und Fähigkeiten an die man in Bereichen in
denen solche Kenntnisse erforderlich oder vorteilhaft sind auch zum
beruflichen Vorteil nutzen kann.
Bernd K. schrieb:> Und Aufmerksamkeit zum kleinsten Detail ist auch eine Eigenschaft die> einen befähigt Dinge zu erschaffen die in ihrer Qualität überragend und> einzigartig sein können. Diese Arbeitseinstellung ist stellenweise auch> heute noch gefragt. Das schafft kein Lego-Zusammenstecker.
Stimmt, aber ich werde dafür bezahlt, dass ich in vertretbarer Zeit ein
vernünftiges Ergebniss abliefern kann.
Wenn ich ein (aus technischer Sicht) optimales Ergebniss nach 10 Jahren
Arbeit abliefern würde, dann wäre das leider unbezahlbar und schon bei
der Auslieferung veraltet.
In dem Sinne werde ich weder die Ansteuerungsroutinen für das Display
noch den Wlan-Stack nebst Webserver selber schreiben. Den manchmal
(leider) benötigten Software-USB-Stack ebenfalls nicht. Das alles läuft
und damit bin ich zufrieden.
Und wenn der Controller halt einen halben Euro teurer und eine Nummer zu
groß ist, dann ist das bei den Stückahlen immer noch egal. Eine
zusätzliche Woche Arbeitszeit zur Codeoptimierung wäre deutlich teurer!
Und wenn alles nichts hilft, dann werden manche Probleme gleich mit
einem der üblichen Linux-Boards erschlagen. Läuft da halt ein voll
aufgeblasener Apache-Server nebst MySQL-Datenbank nur um eine Webseite
auszuliefern.
Mir doch egal, ob da jetzt mit Kanonen auf Spatzen geschossen wird, ich
will fertig werden!
Schreiber schrieb:> Stimmt, aber ich werde dafür bezahlt, dass ich in vertretbarer Zeit ein> vernünftiges Ergebniss abliefern kann.
Das kommt auf die Definition von "vernünftig" an. Wenn Deine Geräte
immer doppelt so groß und doppelt so teuer wie die der Mitbewerber sein
dürfen kannst Du Arduino-Libs auf überdimensionierten Riesencontrollern
nutzen oder überall Raspis verbauen, die funktionieren sicher
Vernünftig.
Es gibt aber auch Extremsituationen da gibt es zum Beispiel im Innern
einer M8-Hülse nur noch zwei Zustände: unmöglich oder doch irgendwie
machbar.
Bernd K. schrieb:> H.Joachim S. schrieb:>> Man kann das Verständnis auch noch eine>> Ebene tiefer ansiedeln - wen ausser Chipdesignern interessiert es, wie>> eine ALU oder ein Microprogramm funktioniert? Oder noch tiefer - ein>> einzelnes läppisches Gatter oder Flipflop?>> Es gibt immer für jede Ebene Leute die es verstehen müssen, sonst würde> bald alles zusammenbrechen.
Richtig, aber da muss man nicht zwingend dazugehören.
>>> wer es versucht, vertrödelt Unmengen Zeit unproduktiv.>> Seit wann muss das Hobby produktiv sein?
Muss nicht, und ich hatte das nicht aufs Hobby beschränkt. Hat man das
eine schnell erledigt, hat man mehr Zeit für anderes. Sehe da nicht den
grossen Unterschied zwischen Arbeit und Hobby
>> vertrödelt>> Man eignet sich Kenntnisse und Fähigkeiten an die man in Bereichen in> denen solche Kenntnisse erforderlich oder vorteilhaft sind auch zum> beruflichen Vorteil nutzen kann.
Die gibts sicher, aber je spezialisierter, desto schwieriger wird es,
den passenden Gegenpart zu finden, der das zu würdigen weiss und auch
noch irgendwie gewinnbringend nutzen kann (nur dann ist es ein
beruflicher Vorteil). Im Einzelfall können Spezialkenntnisse allerdings
sprichwörtlich Gold wert sein. Ist aber eben genau wie Gold waschen -
alle haben von den grossen Nuggets gehört und geträumt, tatsächlich
gefunden haben die dicken Dinger nur sehr wenige.
Das ganze ist und bleibt ein Spagat.
Mir persönlich sind schnell funktionierende Lösungen lieber als ein hart
erarbeiteter Erkenntnisgewinn, der schon morgen nichts mehr wert ist.
Denn das darf man auch nicht aus den Augen verlieren. Früher (tm) war
man nach einem langen Arbeitsleben ein Meister seines Fachs, weil man
fast alles darüber wusste und von der Pieke auf gelernt hatte. Heute
kommen Neuigkeiten schneller dazu, als man das wirklich realisieren
kann. Sprich, wenn man sich in Kleinigkeiten verzettelt, verliert man
genau deswegen den Anschluss.
Bernd K. schrieb:> Das kommt auf die Definition von "vernünftig" an. Wenn Deine Geräte> immer doppelt so groß und doppelt so teuer wie die der Mitbewerber sein> dürfen kannst Du Arduino-Libs auf überdimensionierten Riesencontrollern> nutzen oder überall Raspis verbauen, die funktionieren sicher> Vernünftig.
Vernünftig = tut was es soll und das ganze zu einem vertretbaren Preis.
So groß ist die Konkurenz auch nicht, 1000 Stück sind in dem Bereich
schon Großserie. Wenn der überdimensioneite Riesencontroller 1€ zu teuer
ist, dann sind das maximal 1000€, meist aber weniger. Ob ich da wirklich
eine Woche Arbeitszeit in Codeoptimierung investieren will?!
Beim Raspberry das gleiche. Eine eigene Datenbank und einen Webserver
mit SSL (damit nicht jeder mitlesen kann) auf Schmalspurhardware zu
implementieren werde ich mir nicht antun. Das lohnt bei meinen
Stückzahlen einfach nicht.
Speicher und Rechenleistung sind mittlerweile einfach spottbillig
geworden, hier noch lange rumzulaborieren ist für mich nicht sinnvoll.
Bernd K. schrieb:> Es gibt aber auch Extremsituationen da gibt es zum Beispiel im Innern> einer M8-Hülse nur noch zwei Zustände: unmöglich oder doch irgendwie> machbar.
An dem "doch irgendwie möglich" hängt dann aber auch ein entsprechendes
Preisschild!
>> Warum willst Du denn die wenigen Bytes sparen?> Ich vermute damit er versteht was drin ist, was rein muß, was raus> kann und wie alles zusammenhängt. Und warum.
Ja genau.
> Einfach zugehörende I2C SFRs zu beschreiben und Lesen geht dort nicht> unbedingt alleine weil die I2C HW aus einer semi-autonomen State Machine> besteht
Na und? Das bin ich von den kleinen 8 bittern auch nicht anders gewohnt.
> Wer in der Lage ist, einen TCP-Stack bis auf die Byte-Ebene zu verstehen> und das dann ohne Notwendigkeit auch tut (aus Prinzip) ist eigentlich> nur ein armer Tropf
Warum das denn? Irgendwer muss diese Basis-Libraries auch entwickeln
oder zumindest Bugs beheben können. Ich kann das - habe ich schon
gemacht, das Resultat wird seit ein paar Jahren gewinnbringend verkauft.
> Man eignet sich Kenntnisse und Fähigkeiten an die man in Bereichen> in denen solche Kenntnisse erforderlich oder vorteilhaft sind auch> zum beruflichen Vorteil nutzen kann.
Die ganze µC Programmierung mit ihren sehr begrenzten Ressourcen
befähigt mich dazu, im Java Umfeld als Experte für
Performanceoptimierung tätig zu sein. Sie schäft den Sinn für die
relevanten Details. So wirft das Hobby nebenbei auch was für den Beruf
ab.
Es macht wenig Sinn, wenn hier die Hobbyprogrammierer mit den
Berufsprogrammierern über Effizienz der Arbeit streiten. Diese beiden
Seiten haben ziemlich unterschiedliche Anforderungen, die wird man
niemals unter einen Hut bekommen.
Stefan U. schrieb:>> Wer in der Lage ist, einen TCP-Stack bis auf die Byte-Ebene zu verstehen>> und das dann ohne Notwendigkeit auch tut (aus Prinzip) ist eigentlich>> nur ein armer Tropf>> Warum das denn? Irgendwer muss diese Basis-Libraries auch entwickeln> oder zumindest Bugs beheben können. Ich kann das - habe ich schon> gemacht, das Resultat wird seit ein paar Jahren gewinnbringend verkauft.
Schön, aber dafür werde ich von meinen Kunden nicht bezahlt .Die wollen
eine funktionsfähige Lösung für ihr Problem sehen. Und fertig werden
soll es am besten schon vorgestern...
Wenn ich denen eine Woche nach Auftragserteilung ein funktionsfähiges
Labormuster auf den Tisch stellen kann, freuen die sich. Wenn einen
Monat später die Serienproduktion anläuft ebenfalls.
Ich überlasse das Basislibaries entwickeln gerne denen die sich darauf
spezialisiert haben.
Stefan U. schrieb:> Es macht wenig Sinn, wenn hier die Hobbyprogrammierer mit den> Berufsprogrammierern über Effizienz der Arbeit streiten. Diese beiden> Seiten haben ziemlich unterschiedliche Anforderungen, die wird man> niemals unter einen Hut bekommen.
Gut. Auch bei den Berufprogrammieren gibts aber unterschiede. Von "so
billig wie möglich" über "maximale Performance mit gegebener Hardware
für ein gegebenes Problem" bis hin zu "brauchbare Lösung, aber zeitnah
und bezahlbar" gibts da alle Abstufungen.
Ich arbeite zu 99% an letzterem.
> Schön, aber dafür werde ich von meinen Kunden nicht bezahlt.> Ich überlasse das Basislibaries entwickeln gerne denen die sich> darauf spezialisiert haben.
Das ist völlig richtig so. Es gibt nicht "Den Programmierer", so wie es
auch nicht "Den Handwerker" gibt. Es gib viele Fachrichtungen, und man
tut gut daran, sich die heraus zu suchen, die man besser beherrscht als
andere, damit man eine Chance auf gute bezahlung hat.
Schnell sein ist sicher auch gefragt. Auf der Arbeit programmiere ich in
java mit ganzen Stapeln von Frameworks. Für meine Hobbyprojekte meide
ich diese Herangehensweise aber. Das sind eben zwei ganz
unterschiedliche Welten.