Hallo,
aus irgendwelchen Gründen macht der avr-gcc 11.1.0 Mist. Ich habe
festgestellt das SPI mit Arduino IDE und Arduino Nano Every (ATmega4809)
nicht mit dem avr-gcc 11.1.0 funktioniert. Der Code wird nachweislich
ausgeführt und dennoch läuft dabei etwas schief. Ich habe die Methoden
mittels Pin Toggle "überwacht". Am Ende werden die CTRLA und CTRLB
Register der SPI Einheit nicht gesetzt. Obwohl wie gesagt der Code
nachweislich an den Stellen durchläuft.
Ein weiterer Beweis dafür ist folgender. Wenn ich die lokalen Member
ctrla und ctrlb in SPI.h Zeile 146 mit irgendeinem Wert initialisiere,
dann bleiben die Werte bestehen. Sie werden nicht geändert obwohl sie
von init_AlwaysInline() geändert werden müßten.
init_MightInline und init_AlwaysInline werden nachweislich durch Pin
Toggle ausgeführt.
Es funktionieren folgende Kombinationen:
Arduino IDE 1.8.15 + avr-gcc 10.3.0
Arduino IDE 1.8.15 + avr-gcc 11.1.0 + Arduino Mega2560 (ATmega2560)
Arduino IDE 1.8.15 + avr-gcc 11.1.0 + MCUdude MegaCoreX Package
(ATmega4809)
Arduino IDE 1.8.15 + avr-gcc 11.1.0 + SpenceKonde DxCore Package
(AVR128DB48)
Es funktioniert nicht:
Arduino IDE 1.8.15 + avr-gcc 11.1.0 + Arduino megaavr0 Package
(ATmega4809)
Ich erhalte keinerlei Warnungen oder Fehlermeldungen. Ich habe es auch
mit der Toolchain von Zakkemble gegen getestet. Gleiches Ergebnis.
Es gibt eine kleine Abhilfe. Wenn ich den Methodenaufruf
config(DEFAULT_SPI_SETTINGS) in der SPI.cpp Zeile 53 weglasse, dann
funktioniert SPI wieder. Aber das kann nicht die Endlösung sein. Das
deutet nur auf ein Problem hin. Nur welches?
Ich habe das Problem zuerst im Arduino Forum besprochen.
https://forum.arduino.cc/t/houston-spi-has-a-problem-with-avr-gcc-11-1-0/876291
Wir sind beide der Meinung das beim kompilieren etwas schief läuft. Wir
wissen nur noch nicht ob es am Quellcode liegt oder an der Compilierung.
Nur wenn es am Quellcode liegen würde sollte doch schon ein älterer gcc
meckern zudem der 11.1.0 keine Warnung/Fehler ausgibt. Was wir sehen
sind Unterschiede in den Adressen wenn man die Assembler Dumpfiles
vergleicht. Ist das ein Fehler im gcc oder in den Files des ATmega4809
oder ... ?
Kann jemand einen Fehler entdecken?
Kann es jemand nachvollziehen?
Alle Dateien zusammengefasst hängen oben dran.
Dein Klasse ist allerdings etwas merkwürdig: was sofort auffällt:
- warum Pin-Nummern angeben? Die liegen fest, auch bei Portmux sind sie
nicht frei wählbar.
- Du verwendest immer SPI0, es gibt aber beim DA zwei Instanzen. DAs
wird dann schon mal falsch.
- ...
Veit D. schrieb:> Arduino IDE 1.8.15 + avr-gcc 11.1.0 + MCUdude MegaCoreX Package> (ATmega4809)> Es funktioniert nicht:> Arduino IDE 1.8.15 + avr-gcc 11.1.0 + Arduino megaavr0 Package> (ATmega4809)
Wie kommst Du dazu, dass es der Compiler sein sollte. Was sich hier
unterscheidet sind diese Packages.
Hallo,
die SPI.h/cpp stammt nicht von mir. Das ist orignal Arduino Code.
> Wie kommst Du dazu, dass es der Compiler sein sollte. Was sich hier> unterscheidet sind diese Packages.
Egal was ich verwende, sobald ich für den ATmega4809 (Nano Every) den
avr-gcc 11.1.0 verwende funktioniert SPI nicht. Gleicher kurzer
Testcode, gleiche Lib, nur anderer avr-gcc -> andere Adressen. Worauf
lässt das schließen?
Veit D. schrieb:> Egal was ich verwende, sobald ich für den ATmega4809 (Nano Every) den> avr-gcc 11.1.0 verwende funktioniert SPI nicht. Gleicher kurzer> Testcode, gleiche Lib, nur anderer avr-gcc -> andere Adressen. Worauf> lässt das schließen?
Schau nochmal was Du oben geschrieben hast: da ist es derselbe Compiler.
Aber vielleicht ist Deine Auflistung auch falsch.
> warum Pin-Nummern angeben?
Weil die Lib auch Software SPI zulässt.
> Schau nochmal was Du oben geschrieben hast: da ist es derselbe Compiler.> Aber vielleicht ist Deine Auflistung auch falsch.
Lies nochmal bitte genau was ich aufgelistet und geschrieben habe.
Veit D. schrieb:>> Schau nochmal was Du oben geschrieben hast: da ist es derselbe Compiler.>> Aber vielleicht ist Deine Auflistung auch falsch.> Lies nochmal bitte genau was ich aufgelistet und geschrieben habe.
Vielleicht solltest du selbst nochmal nachschauen was du geschrieben
hast. Du hast 3 Kombinationen mit dem gcc 11.1.0 die funktionieren und
eine die nicht funktioniert. Warum glaubst du, dass es am Compiler liegt
und nicht an dem zusammengewürfelten Rest? Und kannst du nicht
nachgucken, was der Compiler für Code generiert?
Veit D. schrieb:> Es funktionieren folgende Kombinationen:> Arduino IDE 1.8.15 + avr-gcc 11.1.0 + MCUdude MegaCoreX Package> (ATmega4809)> Es funktioniert nicht:> Arduino IDE 1.8.15 + avr-gcc 11.1.0 + Arduino megaavr0 Package> (ATmega4809)
Und nocheinmal ... worin unterscheiden die sich: richtig, nicht im
Compiler.
Hallo,
Leute, der generierte Code hängt doch oben dran. Beide Dumpfiles mit
Arduino IDE 1.8.15 + Arduino megaavr0 Package (ATmega4809). Irgendwelche
Adressen unterscheiden sich. Ich bin aber kein Compilerguru.
Gegenfrage. Warum funktioniert
Arduino IDE 1.8.15 + avr-gcc 10.3.0 + Arduino megaavr0 Package
(ATmega4809)
und warum funktioniert nicht
Arduino IDE 1.8.15 + avr-gcc 11.1.0 + Arduino megaavr0 Package
(ATmega4809)
Worauf lässt das als Erstes schließen? Der erzeugte Code unterscheidet
sich jedenfalls.
Veit D. schrieb:> Leute, der generierte Code hängt doch oben dran.
Du hast nen zip hochgeladen. Um zu wissen was drin ist, müsste man die
Datei runterladen und öffnen. Ich traue dir nicht genug und bin zu faul
ne sichere Umgebung zu starten ...
Ich gehe auch davon aus, dass es sich nicht um ein minimales,
compilierbares und lauffähiges Beispiel handelt, das den Fehler
reproduziert.
Veit D. schrieb:> Irgendwelche> Adressen unterscheiden sich. Ich bin aber kein Compilerguru.
Man muss man kein "Compilerguru" sein, um nachvollziehen zu können, was
der Compiler generiert. Der AVR ist nun wirklich nicht kompliziert.
Veit D. schrieb:> Gegenfrage. Warum funktioniert> Arduino IDE 1.8.15 + avr-gcc 10.3.0 + Arduino megaavr0 Package> (ATmega4809)> und warum funktioniert nicht> Arduino IDE 1.8.15 + avr-gcc 11.1.0 + Arduino megaavr0 Package> (ATmega4809)
Weil megaavr0 nen Bug hat? Weil du etwas falsch bedienst, das du nicht
verstanden hast? Weil es eigentlich funktioniert und du interpretierst
etwas falsch?
// Clock settings are defined as follows. Note that this shows SPI2X
8
// inverted, so the bits form increasing numbers. Also note that
9
// fosc/64 appears twice. If FOSC is 16 Mhz
10
// PRESC[1:0] ~SPI2X Freq
11
// 0 0 0 fosc/2 8.00 MHz
12
// 0 0 1 fosc/4 4.00 MHz
13
// 0 1 0 fosc/8 2.00 MHz
14
// 0 1 1 fosc/16 1.00 MHz
15
// 1 0 0 fosc/32 500 kHz
16
// 1 0 1 fosc/64 250 kHz
17
// 1 1 0 fosc/64 250 kHz
18
// 1 1 1 fosc/128 125 kHz
19
20
// We find the fastest clock that is less than or equal to the
21
// given clock rate. The clock divider that results in clock_setting
22
// is 2 ^^ (clock_div + 1). If nothing is slow enough, we'll use the
23
// slowest (128 == 2 ^^ 7, so clock_div = 6).
24
uint8_tclockDiv;
25
26
// When the clock is known at compiletime, use this if-then-else
27
// cascade, which the compiler knows how to completely optimize
28
// away. When clock is not known, use a loop instead, which generates
29
// shorter code.
30
31
/* This is no longer the case since, F_CPU_CORRECTED is variable */
32
/* set at run time. */
33
34
uint32_tclockSetting=0;
35
36
clockSetting=F_CPU_CORRECTED/2;
37
clockDiv=0;
38
while((clockDiv<6)&&(clock<clockSetting)){
39
clockSetting/=2;
40
clockDiv++;
41
}
42
43
// Compensate for the duplicate fosc/64,
44
// should be fosc/128 if clockdiv 6.
45
if(clockDiv==6)
46
{
47
clockDiv++;
48
}
49
50
// Invert the SPI2X bit
51
clockDiv^=0x1;
52
53
/* Pack into the SPISettings::ctrlb class */
54
/* Set mode, disable master slave select, and disable buffering. */
55
/* dataMode is register correct, when using SPI_MODE defines */
56
ctrlb=(dataMode)|
57
(SPI_SSD_bm)|
58
(0<<SPI_BUFWR_bp)|
59
(0<<SPI_BUFEN_bp);
60
61
/* Get Clock related values.*/
62
uint8_tclockDiv_mult=(clockDiv&0x1);
63
uint8_tclockDiv_pres=(clockDiv>>1);
64
65
/* Pack into the SPISettings::ctrlb class */
66
/* Set Prescaler, x2, SPI to Master, and Bit Order. */
67
68
ctrla=(clockDiv_pres<<SPI_PRESC_gp)|
69
(clockDiv_mult<<SPI_CLK2X_bp)|
70
(SPI_ENABLE_bm)|
71
(SPI_MASTER_bm)|
72
((bitOrder==LSBFIRST)<<SPI_DORD_bp);
73
74
}
75
/* member variables containing the desired SPI settings */
76
uint8_tctrla;
77
uint8_tctrlb;
78
friendclassSPIClassMegaAVR;
79
};
Demzufolge müßte den Membern ctrla und ctrlb ein Wert zugewiesen werden.
Das funktioniert jedoch aus unbekannten Gründen nicht. Denn der Wert
dieser Member sollte in der Methode config() in SPI.cpp den Registern
SPI0.CTRLA und SPI0.CTRLB zugewiesen werden. Dort kommt jedoch kein Wert
an. In der begin Methode wird vorher noch SPI enable usw. gesetzt usw.
Auch das kommt nicht an. Die Register bleiben leer. Kommentiere ich den
config() Aufruf in der begin() Methode aus, dann funktioniert
komischerweise alles. Wenn das ansonsten funktioniert nur mit dem
avr-gcc 11.1.0 nicht, woran soll es dann liegen? Minimale Code
Änderungen führen zum funktionieren. Das ist aber für mich nicht
logisch. Es gibt ja auch nie ein Gemecker vom Compiler.
Übrigens Wilhlem, ich rede die ganze Zeit vom ATmega4809, der hat nur
eine SPI Hardwareeinheit.
Bei dem letzten Test ...
Veit D. schrieb:> Ganz schön starker Tobak. Ich verstehe dich so, du möchtest nur nörgeln> und wolltest niemals helfen.
Du kannst mich verstehen wie du willst, das steht dir frei. Was genau
ist starker Tobak?
- Störst du dich an meinem Unwillen, zip-Dateien mit unbekanntem Inhalt
von unbekannten Personen zu öffnen?
- Ist in der zip-Datei ein minimales, compilierbares und lauffähiges
Beispiel, das den Fehler reproduziert?
- Sind AVRs deiner Meinung nach so kompliziert, dass es im allgemeinen
unmöglich ist zu verstehen wie sie funktionieren?
- Deine Gegenfrage mit weiteren Gegenfragen "beantworten", die den
Fehler bei dir und nicht beim gcc vermuten?
Wo wird denn:
init_AlwaysInline(...)
aufgerufen? Das sieht man an Deinem Beispiel nicht.
Veit D. schrieb:> Demzufolge müßte den Membern ctrla und ctrlb ein Wert zugewiesen werden.> Das funktioniert jedoch aus unbekannten Gründen nicht.
Woher willst Du das wissen. Gibt die beiden doch mal aus.
Hallo,
init_AlwaysInline(...) wird in init_MightInline(...) aufgerufen.
init_MightInline(...) wird im Konstruktor SPISettingsMegaAVR(...)
aufgerufen.
Die beiden Methoden werden jeweils nur einmal aufgerufen. Das habe ich
mittels Pin Toggle geprüft.
Die Member ctrla und ctrlb direkt auszugeben ist nicht so einfach. Habe
ich wegen dem Datentyp noch nicht geschafft. Würde ich eine eigene
Instanz erzeugen hätte ich nicht mehr die "originalen Werte". Da ich
aber weiß wann sie den Registern zugewiesen werden, habe ich immer
zwischendurch die Register ausgelesen die diese Werte enthalten müssen.
Tun sie aber nicht. Siehe meiner vorherigen Antwort.
Veit D. schrieb:> Die Member ctrla und ctrlb direkt auszugeben ist nicht so einfach. Habe> ich wegen dem Datentyp noch nicht geschafft.
Oh ha, ein uint8_t ist auch echt schwierig auszugeben ;-)
Oder meinst Du, Du hast keinen Zugriff, weil sie private sind?
Veit D. schrieb:> Da ich> aber weiß wann sie den Registern zugewiesen werden, habe ich immer> zwischendurch die Register ausgelesen die diese Werte enthalten müssen.> Tun sie aber nicht. Siehe meiner vorherigen Antwort.
Woher willst Du das wissen. Wo passiert das?
0 - Man sollte nicht einfach eine ino ins Forum stellen und schreiben
"avr-gcc 11.1.0 defekt ?" Das ist viel zu pauschal.
Ein Versuch der Versachlichung:
A - in der AVR128DB-TCB32.ino steht
Das setzt unter ArduinoIDE voraus, dass der Boardmanager dieses Board
mit AVR128DB kennt und das setzt voraus, dass unter Preferences der Link
http://drazzy.com/package_drazzy.com_index.json eingetragen und
anschliessend der Boardmanager aufgerufen wird. Bei meiner ArduinoIDE
1.8.15 ist das jedenfalls so.
B - Die AVR-Toolchain 10.0.1 bzw. 11.0.1 müssen in der Lage sein den
entsprechenden Code für AVR128DB zu generieren. Das setzt voraus, dass
das entsprechenden Microchip.ATtiny_DFP.2.6.122.atpack vorhanden ist und
die notwendigen ioavr32dbnn.h, crtavr32dbnn.o, libavr32dbnn.a,
specs-avr32dbnn in die entsprechenden Verzeichnisse kopiert werden. Bei
meinen AVR-Toolchains 10.0.1/11.0.1 ist das jedenfalls so.
Nur unter diesen Voraussetzungen können Foristen das Problem
nachvollziehen und eventuell helfen heraus zu finden, was wo klemmt.
Unter diesen Voraussetzungen kompiliert das im
/home/ab/.arduino15/packages/DxCore/hardware/megaavr/1.3.6/libraries/SPI
/examples/DigitalPotControl vorhandene SPI-Beispiel unter
avr-gcc-10.1.0-x64-linux/
... bash -c "/home/ab/Installed/avr-gcc-10.1.0-x64-linux/bin/avr-nm
--numeric-sort --line-numbers --demangle --print-size --format=s
/home/ab/.arduino15/debug/DigitalPotControl.ino.elf >
/home/ab/.arduino15/debug/DigitalPotControl.ino.map"
Using library SPI at version 1.0.2 in folder:
/home/ab/.arduino15/packages/DxCore/hardware/megaavr/1.3.6/libraries/SPI
/home/ab/Installed/avr-gcc-10.1.0-x64-linux/bin/avr-size -A
/home/ab/.arduino15/debug/DigitalPotControl.ino.elf
Sketch uses 1500 bytes (1%) of program storage space. Maximum is 131072
bytes.
Global variables use 117 bytes (0%) of dynamic memory, leaving 16267
bytes for local variables. Maximum is 16384 bytes.
und unter avr-gcc-11.1.0-x64-linux/ kompiliert das Beispiel NICHT.
Die entscheidende Fehlermeldung unter avr-gcc-11.1.0-x64-linux/ lautet:
... /home/ab/Installed/avr-gcc-11.1.0-x64-linux/bin/avr-gcc-ar rcs
/home/ab/.arduino15/debug/core/core.a
/home/ab/.arduino15/debug/core/wiring_pulse.S.o
/home/ab/Installed/avr-gcc-11.1.0-x64-linux/bin/../lib/gcc/avr/11.1.0/..
/../../../avr/bin/ar:
error while loading shared libraries: libfl.so.2: cannot open shared
object file: No such file or directory
Using library SPI at version 1.0.2 in folder:
/home/ab/.arduino15/packages/DxCore/hardware/megaavr/1.3.6/libraries/SPI
exit status 127
/home/ab/Installed/arduino-1.8.15/arduino-builder returned 127
Error compiling for board AVR DB-series (no bootloader).
************************
Weshalb libfl.so.2 nicht vorhanden ist, habe ich noch nicht untersucht.
************************
Das Beispiel AVR128DB-TCB32.ino kompiliert unter meinen Randbedingungen
nicht, weil die #include <AVR128DB_PinLib.h> nicht
in/home/ab/.arduino15/packages/DxCore vorhanden ist.
https://blog.zakkemble.net/avr-gcc-builds/
Known Issues
Using avr-ar will return an error about libdep.dll.a not being designed
to run on Windows. To fix this error delete
avr-gcc-11.1.0-x64-windows/lib/bfd-plugins/libdep.dll.a
Korrigendum zu oben:
... entsprechenden Atmel.AVR-Dx_DFP.1.8.95.atpack vorhanden ist ...
Mitleserin (a.b.) schrieb:> Nur unter diesen Voraussetzungen können Foristen das Problem> nachvollziehen und eventuell helfen heraus zu finden, was wo klemmt.
Das Problem ist halt, daß die Schnittmenge derjenigen, die was zur
Problemlösung beitragen können und Arduino nutzen und das auch noch für
diesen Prozessor genau eine Person enthält: den TO selber.
Daher sind die Anfragen zu diesen Themen selten von Erfolg gekrönt.
Oliver
Hallo,
das hast du nett zusammengefasst Oliver. Es kommt jedoch noch ein
Problem hinzu was ich immer wieder feststelle. Das dem TO (in dem Fall
mir) immer wieder etwas vor die Füße geworfen wird, aber die angeblichen
Helfer selbst nicht lesen können. Anders kann ich mir die sinnfreien
provozierenden Nachfragen nicht erklären. Alles was nachgefragt wird
hatte ich schon geschrieben und zur Verfügung gestellt. Nachfragen wegen
unklaren Formulierungen sehen anders aus.
Und was hat ein Timercode vom AVR128DB48 hier zu suchen? Dazu das Ding
mit der Pin Lib. Das ist meine Lib. Wer die nicht hat kann nicht
kompilieren. Das ist völlig logisch. Ich habe jetzt in dessen älteren
Thread nicht nachgeschaut ob die bereit steht oder nicht. Aber selbst
wenn nicht kann man ja danach ganz normal fragen ob man die Lib bekommen
kann. Aber nein, wird gleich quer geschossen. Das Thema vom Thread hier
wurde demnach überhaupt nicht verstanden. Dabei ist der Thread noch
nicht lang sodass man alles lesen kann.
Auch der Vorwurf mit der Arduino IDE und dem avr-gcc kann ich nicht
verstehen. Wer die Arduino IDE nicht verwendet und keine aktuelle
Toolchain hinzufügen kann, der kann mir in dem konkreten Problem sowieso
nicht helfen. Gewisse Dinge setze ich einfach voraus.
Auch das man sich an der Betreffzeile aufhängt finde ich unmöglich.
Alles weitere steht im Text. Ein Betreff kann niemals alles
wiederspiegeln. Man hätte bei allen irgendwas zu meckern.
Das Problem tritt nur mit dem "Atmega4809", der Arduino SPI Lib und dem
avr-gcc 11.1.0 auf. Also eine spezielle Kombination. Der gcc 11 hat ein
neues Frontend und ein neues Backend. Kann ja durch im Rahmen des
Möglichen liegen das mit bestimmten Quellcode falsch kompiliert wird.
Das liegt für mich jedenfalls nicht vom Tisch wischbar nachwievor auf
der Hand.
Wenn jemand wirklich helfen möchte, dann klingen die Nachfragen
sicherlich anders und dem würde ich sogar erklären wie er eine aktuelle
Toolchain der IDE hinzufügt. Nur kamen dazu nie Nachfragen, sodass das
nie ein Thema war.
Ich weiß nicht was ich zu dem Threadverlauf noch sagen soll. Hatte ich
mir anders vorgestellt. Jedenfalls nicht so ein oberflächliches an der
Nase herumführen. Wer nicht helfen möchte der muss nicht helfen. Das ist
ganz einfach.
Nun ja, du bist lange genug dabei…
Bei solchen Problemen braucht es ein aufs wesentliche reduziertes
compilierbares Beispiel, das den angeblichen Fehler reproduzierbar
zeigt. Alles andere ist zwecklos.
Wenn das Problem halt nur bei mit völlig exotischen libs und völlig
exotischen Prozessoren auftritt, und das daher eh niemand compilieren
könnte, ist Hilfe kaum möglich.
Warum du dir allerdings die paar Zeilen Assembler, die da generiert
werden, nicht selber anschaust, ist schon komisch.
Oliver
Wilhelm M. schrieb:> Veit D. schrieb:>> Demzufolge müßte den Membern ctrla und ctrlb ein Wert zugewiesen werden.>> Das funktioniert jedoch aus unbekannten Gründen nicht.>> Woher willst Du das wissen. Gibt die beiden doch mal aus.Veit D. schrieb:> Die Member ctrla und ctrlb direkt auszugeben ist nicht so einfach. Habe> ich wegen dem Datentyp noch nicht geschafft.Wilhelm M. schrieb:> Oh ha, ein uint8_t ist auch echt schwierig auszugeben ;-)> Oder meinst Du, Du hast keinen Zugriff, weil sie private sind?
Darauf hast Du bisher gar nicht reagiert.
Hallo,
@ Wilhelm
Mit private und uint8_t habe ich kein Problem. Ich bekomme keinen
Zugriff durch die Verzwickung der verschiedenen Klassen die im Spiel
sind. Deswegen hatte ich erstmal den Umweg über die SPI Register
gemacht.
Ich muss von SPIClass:: eine Methode bauen um auf ctrla/ctrlb von
SPISettingsMegaAVR:: zuzugreifen. Ich meine die Klasse SPIClassMegaAVR
hat doch mittels friend class SPIClassMegaAVR; vollen Zugriff auf die
Member der Klasse SPISettingsMegaAVR. Klappt aber nicht. Alle 3 return
Varianten führen zur Meldung ctrla is not a member of ...
Veit D. schrieb:> Ich weiß nicht was ich zu dem Threadverlauf noch sagen soll. Hatte ich> mir anders vorgestellt. Jedenfalls nicht so ein oberflächliches an der> Nase herumführen. Wer nicht helfen möchte der muss nicht helfen. Das ist> ganz einfach.
Du hast als TO halt auch Pflichten. Zu diesen Pflichten gehört das
Darstellen des Problems in einem Format, so dass dir geholfen werden
kann. Das wird üblicherweise mit einem minimalen compilierbaren (und
wenn möglich lauffähigen) Beispiel, das den Fehler reproduziert. Wenn du
das nicht machst, musst du dich rechtfertigen. Wenn du deinen Pflichten
selbständig, oder auf Nachfrage nachkommst, wird dir geholfen, soweit es
möglich ist.
Was für bescheuerte Prinzipienreiter hier nur noch unterwegs sind.
Entwerft doch mal ein Formular welches jemand als Antrag auf die
Bearbeitung seines Anliegens ausfüllen muss. In dreifacher Ausführung
mit notarieller Beglaubigung natürlich.
Veit D. schrieb:> Hallo,>> @ Wilhelm> Mit private und uint8_t habe ich kein Problem.
Ja, warum schreibst Du es denn?
Das hast Du gesagt hier:
Veit D. schrieb:> Die Member ctrla und ctrlb direkt auszugeben ist nicht so einfach. Habe> ich wegen dem Datentyp noch nicht geschafft.> Ich bekomme keinen> Zugriff durch die Verzwickung der verschiedenen Klassen die im Spiel> sind. Deswegen hatte ich erstmal den Umweg über die SPI Register> gemacht.
Was ist denn daran verzwickt?
Du übergibt Deiner Funktion config(...) eine Instanz von
SPISettingsMegaAVR.
Dann für doch da zwei Beobachter-Funktionen ein oder mache testweise die
Elemente grad public.
> Ich muss von SPIClass:: eine Methode bauen um auf ctrla/ctrlb von> SPISettingsMegaAVR:: zuzugreifen. Ich meine die Klasse SPIClassMegaAVR> hat doch mittels friend class SPIClassMegaAVR; vollen Zugriff auf die> Member der Klasse SPISettingsMegaAVR. Klappt aber nicht. Alle 3 return> Varianten führen zur Meldung ctrla is not a member of ...>>
1
>uint8_tSPIClass::getCtrla(void)
2
>{
3
>returnSPISettingsMegaAVR::ctrla;
4
>returnSPIClassMegaAVR::ctrla;
5
>returnctrla;
6
>}
7
>
Das mit den Beobachtern hast Du immer noch nicht verstanden. Das hatten
wir schon mal in einem anderen Thread. Das Nachvollziehen der
Informationen anderer scheint für Dich schwierig zu sein bzw. Du gehst
darüber einfach hinweg, weil Du meinst es sei völlig unwichtig.
Zu der Funktion: ctrla/ctrlb sind doch keine statischen Datenelemente!
C++ lernt man nicht durch trial-n-error.
Mach Deine Debug-Ausgabe in der config(...)-Funktion. Dann siehst Du, ob
die aufgerufen wird und welche Werte in die beiden Register geschrieben
werden.
Hallo,
Danke Johannes für deine klaren Worte.
Die Klassennamen SPISettingsMegaAVR und SPIClassMegaAVR sind auch
Datentypen. Nur eben "selbst" gebaute. Diese meinte ich. Im Nachgang
betrachtet hätte ich das vielleicht näher beschreiben sollen. Gut. Warum
die Member ctrla/ctrlb für eigene Zugriffe statisch sein sollen kann ich
nicht nachvollziehen. Die Klassen haben doch mittels Vererbung Zugriff.
In der Theorie jedenfalls. Ich wollte mir jedenfalls eine eigene
Rückgabemethode bauen und bin daran gescheitert. Soweit so schlecht.
Jetzt lasse ich mir die Member in der config Methode direkt ausgeben.
Wie du vorgeschlagen hast. Damit passiert genau das was ich befürchtet
habe, jede Änderung führt zu anderen Ergebnissen. Vielleicht ist das
auch nicht verkehrt sieht man doch das da Einiges passiert. Der
komplette Testcode sieht so aus.
Die Ausgabe ist damit wie folgt. Mal abgesehen davon das die Werte nicht
stimmen, gehen Bits vom Member zum Register verloren. Das Bit 3 in CTRLA
fehlt.
1
µC Reset #### #### ####
2
SPI0 CTRLA: 0b0000'0000 0x08C0
3
SPI0 CTRLB: 0b0000'0000 0x08C1
4
5
begin
6
0
7
1
8
0
9
1
10
SPI0 CTRLA: 0b0000'0000 0x08C0
11
SPI0 CTRLB: 0b0000'0001 0x08C1
12
13
beginTransaction
14
1010
15
0
16
1010
17
0
18
SPI0 CTRLA: 0b0000'0010 0x08C0
19
SPI0 CTRLB: 0b0000'0000 0x08C1
20
21
endTransaction
22
SPI0 CTRLA: 0b0000'0010 0x08C0
23
SPI0 CTRLB: 0b0000'0000 0x08C1
Lässt man in der config() Methode die ersten beiden Ausgaben weg erhält
man andere Werte. Bei CTRLB gehen keine Bits verloren.
1
µC Reset #### #### ####
2
SPI0 CTRLA: 0b0000'0000 0x08C0
3
SPI0 CTRLB: 0b0000'0000 0x08C1
4
5
begin
6
0
7
1
8
SPI0 CTRLA: 0b0000'0000 0x08C0
9
SPI0 CTRLB: 0b0000'0001 0x08C1
10
11
beginTransaction
12
0
13
10000010
14
SPI0 CTRLA: 0b0000'0000 0x08C0
15
SPI0 CTRLB: 0b1000'0010 0x08C1
16
17
endTransaction
18
SPI0 CTRLA: 0b0000'0000 0x08C0
19
SPI0 CTRLB: 0b1000'0010 0x08C1
Lässt man in der config() Methode nur die letzten beiden Ausgaben weg
erhält man wieder andere Werte.
1
µC Reset #### #### ####
2
SPI0 CTRLA: 0b0000'0000 0x08C0
3
SPI0 CTRLB: 0b0000'0000 0x08C1
4
5
begin
6
0
7
1
8
SPI0 CTRLA: 0b0000'0000 0x08C0
9
SPI0 CTRLB: 0b0000'0001 0x08C1
10
11
beginTransaction
12
10
13
0
14
SPI0 CTRLA: 0b0000'0010 0x08C0
15
SPI0 CTRLB: 0b0000'0000 0x08C1
16
17
endTransaction
18
SPI0 CTRLA: 0b0000'0010 0x08C0
19
SPI0 CTRLB: 0b0000'0000 0x08C1
Lässt man die Ausgaben in der config() Methode komplett drin und nimmt
die "SPI Methoden" Textausgaben im setup() raus, erhält man wieder
andere Werte.
1
µC Reset #### #### ####
2
SPI0 CTRLA: 0b0000'0000 0x08C0
3
SPI0 CTRLB: 0b0000'0000 0x08C1
4
5
0
6
1
7
0
8
1
9
SPI0 CTRLA: 0b0000'0000 0x08C0
10
SPI0 CTRLB: 0b0000'0001 0x08C1
11
12
11001
13
1010110
14
11001
15
1010110
16
SPI0 CTRLA: 0b0001'0001 0x08C0
17
SPI0 CTRLB: 0b0100'0110 0x08C1
18
19
SPI0 CTRLA: 0b0001'0001 0x08C0
20
SPI0 CTRLB: 0b0100'0110 0x08C1
Das Kombinationsspiel könnte man fortsetzen, aber ich denke das Problem
ist erkennbar. Wenn ich das mit dem avr-gcc 10.3.0 mache erhalte ich
immer die gleichen korrekten Daten.
Veit D. schrieb:> Wie nun weiter?
Zunächst erst einmal alles Unnötige aus Deinem Beispiel heraus nehmen.
Schritt für Schritt, bis zu dem Punkt, wo es dann Deines Erachtens
wieder konsistent ist. Dann hast Du einen Ansatz gefunden. Könnte ja
auch ein Stack-Overflow sein ...
Im Moment muss man sich ja alles zusammen suchen. Es wurde ja schon
geschrieben, dass Du ein "minimum verifying complete example" erstellen
sollst.
Veit D. schrieb:> Warum> die Member ctrla/ctrlb für eigene Zugriffe statisch sein sollen kann ich> nicht nachvollziehen.
Ich auch nicht. Deswegen: warum versuchst Du auf ein nicht existierendes
statisches Element zuzugreifen. Das hast Du ins Spiel gebracht:
Veit D. schrieb:> uint8_t SPIClass::getCtrla (void)> {> return SPISettingsMegaAVR::ctrla;> return SPIClassMegaAVR::ctrla;> return ctrla;> }
Ich vermute, Du hast meine Bemerkung oben gar nicht verstanden.
Hallo,
aber soweit war ich doch schon einmal. Wie oft soll ich denn noch von
vorn anfangen? Ich kann die ewigen Vorwürfe nicht mehr hören zeige was
Komplettes. Wie kompletter als komplett soll es denn noch sein? Das
Gezeigte ist doch komplett. Ich verstehe das Problem nicht. Für den
Testcode liefere sich sogar frei Haus meine Lib mit. Damit ja niemand
seine Maus vom zu vielen klicken kaputt macht. Kann aber jeder auch ohne
machen wenn er auf die Formatierung verzichtet. Arduino IDE, ggf. mein
Lib importieren, den Sketch kopieren und schon kann es los gehen.
Einfacher gehts ja nun wirklich nicht. Was soll ich daran noch
vereinfachen? Das hätte ich gern einmal gewusst.
Wenn ich config() Methodenaufruf weglasse, leere Methode, stimmen alle
Registerwerte. Sobald die config aufgerufen wird kommt wieder Mist raus.
Hatte ich aber alles schon mehrfach geschrieben. Das ist der Punkt ab
der es schief läuft.
Warum sollte ein möglicher Stack Overflow ausgerechnet mit dem gcc 11
auftreten? Fakt ist doch das gcc 11 irgendwie anders kompiliert was zum
Fehler führt. Das kann man doch nicht ignorieren.
PS: Wegen Member ctrla/ctrlb. Ich vermute auch wir reden komplett
aneinander vorbei.
Veit D. schrieb:> Wenn ich config() Methodenaufruf weglasse, leere Methode, stimmen alle> Registerwerte. Sobald die config aufgerufen wird kommt wieder Mist raus.> Hatte ich aber alles schon mehrfach geschrieben. Das ist der Punkt ab> der es schief läuft.
Meine Güte, ist das so schwer zu verstehen? Koche das Beispiel so weit
herunter, dass es jeder - auch ohne diesen Arduino-Kram - nachvollziehen
kann. Du hast da mehrere Riesen-Klassen, von deren Inhalt 95% nicht
benötigt wird. Entkerne das soweit, bis der Fehler ggf. gar nicht mehr
auftritt, dann gehe einen Schritt zurück, und Du hast genau das, um
Hilfe zu bekommen.
Wie kommen denn die Registerinhalte in CTRLA, wenn config() gar nicht
aufgerufen wird? Oder meinst Du die Reset-Inhalte? Worher hast Du es
genau anders herum gesagt, ohne config() nur 0x00 drin. Was denn nun?
Veit D. schrieb:> PS: Wegen Member ctrla/ctrlb. Ich vermute auch wir reden komplett> aneinander vorbei.
Dann mache es klar. Jedenfalls hast Du einen stat. Elementzugriff
codiert, auf ein Element, das es nicht gibt. Das lese ich aus dem
Code-Schnipsel. Den Rest musst Du erklären.
Veit D. schrieb:> Wie oft soll ich denn noch von> vorn anfangen? Ich kann die ewigen Vorwürfe nicht mehr hören zeige was> Komplettes. Wie kompletter als komplett soll es denn noch sein?
Das Wort, dass du immer zu überlesen scheinst ist "minimal". Falls du es
noch nicht verstanden hast. Die Forderung nach einem minimalen,
compilierbaren und lauffähigen Beispiel, das den Fehler reporduziert hat
zwei Aspekte.
- Es ist deutlich einfacher für andere Personen zu überblicken.
- In 95% der Fälle findest du selbst auf dem Weg zu diesem Beispiel die
Ursache und eine Lösung (und meistens andere Probleme, von denen du bis
jetzt nichts wusstest).
Falls Du aber mit diesen Antworten hier nicht zufrieden bist, dann poste
das als gcc-bug (Du bist ja der Meinung, dass es einer ist) im
gcc-bugzilla. Wenn Du da dann kein "minimal verifying complete example"
lieferst, ist der Eintrag schneller zu, als Du ihn aufgemacht hast.
Gleiches gilt für Stack-Overflow. Also, versuche es doch dort einmal.
Veit D. schrieb:> aber soweit war ich doch schon einmal. Wie oft soll ich denn noch von> vorn anfangen? Ich kann die ewigen Vorwürfe nicht mehr hören zeige was> Komplettes. Wie kompletter als komplett soll es denn noch sein? Das> Gezeigte ist doch komplett. Ich verstehe das Problem nicht.
Das Problem fängt mit A… an und endet auf ...ino.
Kaum jemand hat große Lust, in dem wilden Mischmasch von Bibliotheken
und sonstigem Gedöns irgendwelche Fehler zu suchen.
Oliver
Veit D. schrieb:> Hallo
Hab mal in das Zip aus diesem Beitrag geschaut... Hat nichts mit dem
Problem zu tun, aber:
Du weisst was include macht und wie man das nutzt?
Da fehlen saemtliche includes in deiner tollen utilities.h. Wo kommt
Stream her? Wo kommt uint8_t her? Wo kommen byte und Serial in den
examples her? Warum sind die includes mit <> und nicht mit ""?
Wie soll man damit das Problem nachvollziehen?
Wie waere es, wenn du dir Register/Speicher/was auch immer einfach im
Debugger anschaust?
Wilhelm M. schrieb:> Wenn Du da dann kein "minimal verifying complete example"> lieferst, ist der Eintrag schneller zu, als Du ihn aufgemacht hast.> Gleiches gilt für Stack-Overflow. Also, versuche es doch dort einmal.
Da muss ich Wilhelm leider recht geben. Mit dem Beispiel wird das
nichts. Nach ueber 2700 eigenen Beitraegen in diesem Forum sollte der TO
das aber wissen.
Arduino ist nicht meine bevorzugte Umgebung, aber ich kann das Internet
bedienen und kann dem Problem folgen.
Stream und anderes Zeug kommt aus
https://github.com/arduino/ArduinoCore-API, was ist daran so schwierig?
Ein Debugger wäre tatsächlich ein feines Hilfsmittel, ein Grund warum
ich schon lange bei ARM CM gelandet bin. Trotzdem sollte sich auch
dieses Puzzle lösen lassen, und halte die Wahrscheinlichkeit für groß
das es tatsächlich ein gcc Problem ist weil im 10/11er einiges umgebaut
wurde.
Ich bin bei AVR Tools nicht mehr aktuell, kann man evtl. mit dem AVR
Studio Simulator da durch steppen? Das AVR Studio konnte Arduino
Projekte lesen und konvertieren, ich weiß nur nicht ob man dem einfach
die gcc11 unterjubeln kann.
Der Programablauf ist etwas tricky weil die SPISettings in
https://github.com/arduino/ArduinoCore-API/blob/master/api/HardwareSPI.h,
also in einem gemeinsamen core liegen. Diese Klasse ist nur ein Helfer
um die SPI Einstellungen zu halten.
Im
https://github.com/arduino/ArduinoCore-megaavr/blob/master/libraries/SPI/src/SPI.h
gibt es eine für den megaAVR angepasste Settings Klasse. Der Ablauf ist
dann:
config(DEFAULT_SPI_SETTINGS);
Makro expandiert zum default constructor für SPISettings im gemeinen
core
damit ruft config einen Konverter von SPISettings nach
SPISettingsMegaAVR auf, in
https://github.com/arduino/ArduinoCore-megaavr/blob/5717c2a3ac8ecc6e5f382715b7f6225e1c809007/libraries/SPI/src/SPI.h#L179-L181
Da werden mehrfach temporäre Objekte auf dem Stack erzeugt, aber die
paar Bytes sollte der µC mit 6 kB RAM schon packen.
Evtl. geht hier was schief wenn das temporäre SPISettings benutzt werden
soll?
https://github.com/arduino/ArduinoCore-megaavr/blob/5717c2a3ac8ecc6e5f382715b7f6225e1c809007/libraries/SPI/src/SPI.h#L69
Und dann bleibt schon die Frage, warum kommt eine ältere gcc damit klar
und eine neuere nicht?
noch ein Edit:
geht die Zeile im letzten Link nicht ins Leere? Im Konstruktor aus
SPISettings& wird der SPISettingsMegaAVR(,,) aufgerufen, aber damit wird
ja nix gemacht. Liegt auf dem Stack und wird wieder abgeräumt, und der
Konstruktor liefert ein leeres Objekt, also genau das was der TO
beobachtet.
Damit hätten die älteren gcc eher zufällig den initialisierten Stack
benutzt, bei anderem Speicherläyout geht es damit korrekterweise schief.
Johannes S. schrieb:> Arduino ist nicht meine bevorzugte Umgebung, aber ich kann das Internet> bedienen und kann dem Problem folgen.
Was niemandem einer Lösung näher bringt.
Johannes S. schrieb:> Und dann bleibt schon die Frage, warum kommt eine ältere gcc damit klar> und eine neuere nicht?
Selbst das ist doch eine reine Behauptung, die bisher noch gar nicht
nachgewiesen wurde.
Und ohne dem TO allzu nahe treten zu wollen, ist der gezeigte Code in
allen Belangen so weit weg von "solide" und "verstanden", daß es reiner
Zufall ist, ob da was funktioniert oder nicht.
Oliver
Oliver S. schrieb:> Was niemandem einer Lösung näher bringt.
ich habe nicht gelabert und genörgelt wie die anderen hier, ich habe die
Zeile mit dem Fehler lokalisiert.
also nochmal:
https://github.com/arduino/ArduinoCore-megaavr/blob/5717c2a3ac8ecc6e5f382715b7f6225e1c809007/libraries/SPI/src/SPI.h#L69
ist nicht korrekt. Projekt forken, branch mit fix erstellen, PR an den
Autor, das überlasse ich dem TO. So geht das, das ist ein OSS Community
Projekt und ob es gefällt oder nicht, es ist populär und so haben sich
Arduino und andere weiterentwickelt.
Johannes S. schrieb:> ich habe nicht gelabert und genörgelt wie die anderen hier, ich habe die> Zeile mit dem Fehler lokalisiert.
Ok, dein Edit hatte ich übersehen. Da sollte dann jemand das Thema
"delegating constructors" nochmals nachlesen.
Bedeutet das jetzt, daß alle Compiler vor gcc 11 fehlerhaft waren?
Oliver
Johannes S. schrieb:> noch ein Edit:> geht die Zeile im letzten Link nicht ins Leere? Im Konstruktor aus> SPISettings& wird der SPISettingsMegaAVR(,,) aufgerufen, aber damit wird> ja nix gemacht. Liegt auf dem Stack und wird wieder abgeräumt, und der> Konstruktor liefert ein leeres Objekt, also genau das was der TO> beobachtet.> Damit hätten die älteren gcc eher zufällig den initialisierten Stack> benutzt, bei anderem Speicherläyout geht es damit korrekterweise schief.
Oh wei, wieder eine Bestätigung dafür, dass die Code-Qualität der
Arduino-Sachen nicht die beste ist.
Ich hatte da schon nach dieser Zeile aufgehört zu lesen:
https://github.com/arduino/ArduinoCore-megaavr/blob/5717c2a3ac8ecc6e5f382715b7f6225e1c809007/libraries/SPI/src/SPI.cpp#L27
Glückwunsch an Johannes.
Johannes S. schrieb:> ich würde eher sagen es war Zufall das etwas funktioniert hat,Oliver S. schrieb:> Und ohne dem TO allzu nahe treten zu wollen, ist der gezeigte Code in> allen Belangen so weit weg von "solide" und "verstanden", daß es reiner> Zufall ist, ob da was funktioniert oder nicht.
Tja, ein Leben ohne Arduino ist nicht nur möglich, sondern tatsächlich
sinnvoll.
Oliver
Hallo,
wenn ich die Antworten hier lese weiß ich nicht mehr was ich sagen soll.
Das Beste ist, ich wundere mich einfach nur darüber. Alles andere führt
zu nichts.
Ein Einziger hat es richtig gemacht. Das ist Johannes. Aus der Kalten
heraus mitgemacht, umfangreichen fremden Code gelesen, ohne Theater
Problem analysiert und auf den Punkt gezeigt. Vor solchen Leuten ziehe
ich meinen Hut. Du hast meinen allertiefsten Respekt. Das kann ich dir
sagen.
Jetzt machen meine Beobachtungen auch Sinn, wenn man die Member ctrla,
cltrb selbst initialisiert, dann sieht man das genau die Werte in den
Registern landen. Ohne Initialisierung landen Zufallswerte (non static
Member) in den Registern, weil das mit dem Kontruktor selbst bzw.
überladen schief läuft. Soweit mein Verständnis zum Problem im Nachgang.
Einen konkreten Vorwurf an die Arduino Programmierer kann man auch nicht
machen. Ich jedenfalls nicht. Erstens wird die IDE "nur" mit avr-gcc
7.3.0 ausgeliefert und Zweitens kann man diesen Fehler ja nur finden
wenn ihn auch entdeckt. Wenn der Fehler bis 10.3.0 nicht auftaucht, weil
der gcc bis dahin scheinbar fehlertoleranter ist, tja dann kann man ihn
nicht finden. Codefehler findet man sicherlich nicht nur bei Arduino. Es
hat ja seinen Grund das gcc bzw. C++ weiterentwicklet wird und immer
strenger wird. Hier in dem Fall hätte ich mir irgendeine Warnung seitens
gcc gewünscht. Falls das überhaupt möglich ist. Wunschdenken. :-)
Diese Erkenntnis nehme ich mit ins Arduino Forum und dann kann das
sicherlich von "Arduino" gefixt werden. Ich werde auf den Thread
verweisen, vielleicht können von denen auch paar Leute deutsch falls
erforderlich.
Nochmals vielen Dank Johannes. Schön das es solche Menschen noch gibt.
Veit D. schrieb:> Wenn der Fehler bis 10.3.0 nicht auftaucht, weil> der gcc bis dahin scheinbar fehlertoleranter ist, tja dann kann man ihn> nicht finden.
Das hat mit Fehlertoleranz im Compiler nichts zu tun (die gibt es acuh
nicht). Das ist ein so grundlegender Fehler im Code, da müssen schon
sehr viele Zufälle zusammenkommen, daß das so aussieht, als ob es
funktioniert.
Das ist bisher nicht aufgefallen, weil es noch niemand ernsthaft benutzt
hat.
Oliver
Nanu, wo sind denn die Maulhelden, allen voran "Wilhelm", abgeblieben?
War wohl nichts -den TO für unfähig erklären, aber selbst nicht in der
Lage sein, das Problem auch nur im Ansatz zu erfassen.
So schön ruhig schrieb:> den TO für unfähig erklären, aber selbst nicht in der> Lage sein, das Problem auch nur im Ansatz zu erfassen
Bist du dir da sicher?
Das der TO unfähig ist, steht ja außer Frage - nur ein, sagen wir mal
höflich -untalentierter und suboptimal mit der Anlage zur Selbstkritik
Beschenkter- erklärt seine individuelle 'Programmierschnitzer' (wie
Verwendung unitialisierter Objekte) mit mangelnder 'Fehlertoleranz des
Compilers'.
Und möglicherweise liegt das angemoserte Ausbleiben einer 'Warning'
vielleicht auch am Unvermögen, die Generierung derselben einzuschalten
('-Wall').
So schön ruhig schrieb:> Nanu, wo sind denn die Maulhelden, allen voran "Wilhelm", abgeblieben?> War wohl nichts -den TO für unfähig erklären, aber selbst nicht in der> Lage sein, das Problem auch nur im Ansatz zu erfassen.
Zwischen "in der Lage sein" und "keine Lust den Haufen S******
durchzuarbeiten" besteht ein großer Unterschied. Und anders kann man das
was da auf github verlinkt ist nicht nennen. Schön für den TO, dass er
jemanden gefunden hat, der die Arbeit für ihn übernimmt. Allerdings hat
der TO nicht wirklich etwas gelernt und wird beim nächsten Mal
vermutlich auch nicht in der Lage sein den Fehler selbst zu finden. Und
wie sich herausgestellt hat, lagen alle Maulhelden im Recht. Denn der
gcc ist nicht defekt.
mh schrieb:> Schön für den TO, dass er> jemanden gefunden hat, der die Arbeit für ihn übernimmt.
Das ist jemand (Johannes), der mit dem Wort "helfen" etwas anzufangen
weiß.
Alle Achtung von mir dafür.
> Allerdings hat> der TO nicht wirklich etwas gelernt und wird beim nächsten Mal> vermutlich auch nicht in der Lage sein den Fehler selbst zu finden.
Der TO hat beschrieben, was er daraus gelernt hat.
> Und> wie sich herausgestellt hat, lagen alle Maulhelden im Recht. Denn der> gcc ist nicht defekt.
Wenn eine Version des Programmes nicht mehr das tut, was die
Vorgängerverion noch tat -woran liegt das dann?
Ich halte mich von diesem Zeug so fern, wie nur irgend möglich, denn es
hat sich (nicht nur hier und jetzt) gezeigt, daß das Programmieren damit
einem Würfelspiel gleicht.
So schön ruhig schrieb:> Wenn eine Version des Programmes nicht mehr das tut, was die> Vorgängerverion noch tat -woran liegt das dann?
Am Zufall aka undefined Behaviour.
Das ist so als wenn deine Jetzige Vormundschaftstussi achselzuckend
deinen Raum verlässt, obwohl Ihre Vormundschaftsvorgängerin auf die
selbe Aufforderung "Liess mir meine Wünschen von meinen geschlossenen
Lippen ab" wortlos den Fernseher einschaltete und eine Tüte Aldi-Popcorn
in die Blumenvase schüttete.
erarre humanum est schrieb:> Das ist so als wenn deine Jetzige Vormundschaftstussi achselzuckend> deinen Raum verlässt, obwohl Ihre Vormundschaftsvorgängerin auf die> selbe Aufforderung "Liess mir meine Wünschen von meinen geschlossenen> Lippen ab" wortlos den Fernseher einschaltete und eine Tüte Aldi-Popcorn> in die Blumenvase schüttete.
Findest Du das wirklich lustig? Dann wundert mich Deine Verteidigung
unbrauchbaren Mistes so gar nicht.
So schön ruhig schrieb:> Nanu, wo sind denn die Maulhelden, allen voran "Wilhelm", abgeblieben?> War wohl nichts -den TO für unfähig erklären, aber selbst nicht in der> Lage sein, das Problem auch nur im Ansatz zu erfassen.
Dann habe ich wohl Deinen sachdienlichen Hinweis überlesen? Hätte ich
gerne mal gesehen, "Gast".
So schön ruhig schrieb:> Der TO hat beschrieben, was er daraus gelernt hat.
In der Tat: der TO hat wie ein kleines Kind gelernt, dass man seinen
Mist nur anderen, sehr sehr netten Leuten vorwerfen muss, ohne sich auch
nur ein kleines bisschen Mühe zu geben. Mehr hat er leider nicht
gelernt!
In finde es auch toll, dass Johannes sich die Mühe gemacht hat - und
finde es eben aus o.g. Grund gleichzeitig auch schade, dass er es
gemacht hat.
Zu seiner Lösung habe ich ihm gratuliert, weil er sich durch diesen
Misthaufen durchgelesen hat.
Ja, das habe ich nicht getan, und werde es in Zukunft auch nicht tun,
wenn der Code bestimmte Merkmale aufweist und andere eben nicht
aufweist.
Warum ich mir den Code nicht weiter angesehen habe, steht weiter oben.
Wenn ich so etwas lese, ist es für mich nur Zeitverschwendung, die
tatsächliche Problemstelle zu suchen.
Stattdessen habe ich ganz oben begonnen, den TO auf mögliche Ursachen
hinzuweisen. Natürlich kann auch ein Compiler wie gcc oder clang Fehler
aufweisen, doch auch habe ich ganz oben begründet meine Zweifel daran
sofort geäußert. Stattdessen habe ich dem TO versucht Methodiken
aufzuzeigen, mit denen er selbst zum Ziel kommt - etwas ein MCVE zu
erstellen. Das ist übliche Praxis. Dazu war der TO nicht willens bzw. in
der Lage.
Sorry, aber dieser TO neigt dazu, alles das, was er nicht versteht, erst
einmal als unnötig oder falsch zu bezeichnen. Auch da haben wir hier ein
Beispiel: seine Beobachterfunktion. In seinen Augen ist
const-correctness unnötig. Das hatten wir in einem anderen Beitrag. Und
siehe da: wieder nichts gelernt.
Das nächste Beispiel ist die Unfähigkeit, die beiden Elemente ctrla /
ctrlb einfach mal auszugeben. Sorry, das ist C++ Grundschule. Kriegt er
nicht hin. Stattdessen murkst er da irgendwas mit Zugriff auf
nicht-existierende statische Elemente zurecht.
So nett Johannes auch war, es wird rein gar nichts helfen.
Was bin ich froh, auf solche "Helfer" wie Dich, Wilhelm nicht angewiesen
zu sein. 3 Kreuze mache ich dafür...
Es sind ja nicht die ersten Beiträge aus Deiner Feder, die mir sauer
aufstoßen, denn ALLE folgen dem gleichen Schema: Ich bin der Größte,
aber so abgehoben, daß ich mich nicht in die Niederungen von Quelltexten
anderer Leute begebe. Dafür spare ich dann nicht an wohlfeilen
Ratschlägen, die meterweit am Ziel vorbeigehen.
Braucht kein Mensch.
So schön ruhig schrieb:> Was bin ich froh, auf solche "Helfer" wie Dich, Wilhelm nicht angewiesen> zu sein. 3 Kreuze mache ich dafür...
Ja, dann ist es ja gut so.
BTW: was war nochmal Dein substantieller Beitrag für die Problemlösung
hier. Oder gibt Du nur Allgemeinplätze ab?
So schön ruhig schrieb:> Was bin ich froh, auf solche "Helfer" wie Dich, Wilhelm nicht angewiesen> zu sein. 3 Kreuze mache ich dafür...
Ich bin zwar nicht immer seiner Meinung, aber wenn es um Antworten auf
konkrete fachliche Fragen geht, kann man Wilhelm nicht wirklich etwas
vorwerfen.
Wilhelm M. schrieb:> So schön ruhig schrieb:>> Was bin ich froh, auf solche "Helfer" wie Dich, Wilhelm nicht angewiesen>> zu sein. 3 Kreuze mache ich dafür...>> Ja, dann ist es ja gut so.>> BTW: was war nochmal Dein substantieller Beitrag für die Problemlösung> hier. Oder gibt Du nur Allgemeinplätze ab?
Ich sage doch: Du liest zwar, begreifst aber das Gelesene offensichtlich
nicht. Ich zitiere mich deshalb selbst:
> Ich halte mich von diesem Zeug so fern, wie nur irgend möglich, denn es> hat sich (nicht nur hier und jetzt) gezeigt, daß das Programmieren damit> einem Würfelspiel gleicht.
Wie also sollte ich da einen "substanziellen Beitrag" leisten können,
wenn das selbst solchen Spezialisten wie Dir in keiner Weise gelingt?
Rechtsaussen als Linksabbieger schrieb:> Ich sage doch: Du liest zwar, begreifst aber das Gelesene offensichtlich> nicht. Ich zitiere mich deshalb selbst:>>> Ich halte mich von diesem Zeug so fern, wie nur irgend möglich, denn es>> hat sich (nicht nur hier und jetzt) gezeigt, daß das Programmieren damit>> einem Würfelspiel gleicht.>> Wie also sollte ich da einen "substanziellen Beitrag" leisten können,> wenn das selbst solchen Spezialisten wie Dir in keiner Weise gelingt?
Jetzt auch von Versteckspiel??? Traurig!
Hallo,
naja Wilhelm. Du musst schon zugeben das du so getan hast den SPI Lib
Code gelesen zu haben, mich von oben herab belehrend zu allen möglichen
behandelt hast, also wie immer und dich dann aber mit der Frage zur
config Methode blamiert hast. Denn in der begin Methode ist klar
ersichtlich womit die Register beschrieben werden um dann von der
Problem Methode config falsch überschrieben zu werden. Du hast demnach
nicht einmal den Code gelesen, bist aber immer schön brav darauf
rumgeritten. Mir aber keine angebliche Lesebereitschaft vorwerfen. Das
ist mehr als nur arrogant. Wie gesagt drehst du dir alles zurecht damit
alle anderen immer blöd aussehen. Das habe ich schon lange durchschaut.
Lesekompetenz und Pädagogik sieht anders aus. Wie man dich auf Studenten
loslassen kann verstehe ich bis heute nicht. Du magst in deiner eigenen
Programmierwelt bestens zurecht kommen. Aber mit fremden Code tust du
dich genauso schwer wie viele andere auch. Alles was nicht gefällt wird
als inkompetent abgestempelt.
Bei allen anderen Vorwürfen gegen mich kann ich nur sagen. Steck ich
weg. Ich weiß was ich kann und ich weiß was ich nicht kann. Und es
sollte sich jeder einmal Fragen wofür ein Forum da ist wenn man keine
Fragen zu Problemen stellen darf? Auch wenn es im nachhinein zu einem
unerwartenden Ergebnis führt. Das ist eben so. Die Vorarbeit habe ich
geleistet, Johannes hat es aufgegriffen und verstanden und wie gesagt
dankend das eigentliche Problem gezeigt. Hat von allen anderen ja auch
niemand fertig gebracht. Für seine Hilfsbereitschaft und unkomplizierte
Hilfe wird er jetzt noch angegangen. Also das kann es ja nun auch nicht
sein. Wirklich nicht.
Der Rest hier folgt wie immer dem gleichen Schema. Wenn das Problem
geklärt ist melden sich plötzlich alle zu Wort die es schon immer
gewusst haben.
Auch das Arduino Programmierer hier generell für blöd gehalten werden
darüber kann ich nur lachen. Da sind durchaus fähige Leute dabei.
Vorallendingen haben "wir" nicht das große Maul. Das muss ich auch
einmal klar sagen. Außerdem will ich mal jemanden sehen der so ein
Gesamtbauwerk wie Arduino programmiert ohne in Probleme zugeraten. Das
ist ein ständiges abwägen zwischen Kompatibilität zu alten Code und
Unterstützung für neue Controller. Wenn man eine gewisse Kompatibilität
über Board wirft und paar neue Features einbaut, dann kommen von fähigen
Arduino Programmiereren wie MCUdude und SpenceKonde (um mal 2 zu nennen)
Boarderweiterungen heraus. Sowas würde doch hier niemand freiwillig
machen und für alle bereit stellen. Das nennt sich Community. Wenn sich
hier alle auf ihre Kernkompetenz konzentrieren und nicht immer blind
austeilen würden, dann wäre das hier auch ganz dufte.
Damit beende ich den Thread für mich.
Veit D. schrieb:> Bei allen anderen Vorwürfen gegen mich kann ich nur sagen. Steck ich> weg. Ich weiß was ich kann und ich weiß was ich nicht kann.
Mit wegstecken meinst du Kritik ignorieren. So kommt es jedenfalls
rüber.
> Und es sollte sich jeder einmal Fragen wofür ein Forum da ist wenn man keine
Fragen zu Problemen stellen darf?
Du darfst fragen was immer und wie du willst. Du musst aber auch mit den
Antworten leben. Du solltest wirklich mal auf Stackoverflow nachlesen,
was da die Anforderungen an den Fragenden sind. Die FAQ:
https://meta.stackoverflow.com/questions/251225/faq-index-for-stack-overflow
Der erste Eintrag ist "What is the proper way to approach Stack Overflow
as someone totally new to programming?"
Die akzeptierte Antwort solltest du dir wirklich einmal genau
durchlesen.
Der zweite Eintrag ist "How much research effort is expected of Stack
Overflow users?"
Die Akzeptierte Antwort fängt an mit "A lot. Asking a question on Stack
Overflow should be the last step in your process for finding an
answer—if the information that you need already exists, then you should
be able to find it before asking."
> Auch wenn es im nachhinein zu einem unerwartenden Ergebnis führt. Das ist eben
so.
Das sollte aber nicht so sein. Warum hast du ein erwartetes Ergebnis?
Weißt du die Antwort oder hast du ein Vorurteil?
> Die Vorarbeit habe ich geleistet
Nein! Du hast ETWAS Vorarbeit geleistet, aber nicht genug und nicht die
richtige.
>Johannes hat es aufgegriffen und verstanden und wie gesagt dankend das >
eigentliche Problem gezeigt. Hat von allen anderen ja auch niemand fertig
gebracht.
Es sollte dir zu denken geben, dass dir nur EINE Person geholfen hat.
Hat das nur etwas mit uns zu tun oder hat das vielleicht doch etwas mit
dir zu tun? Warum haben wir all diese Beiträge geschrieben?
> Für seine Hilfsbereitschaft und unkomplizierte Hilfe wird er jetzt noch >
angegangen. Also das kann es ja nun auch nicht sein. Wirklich nicht.
Wo wird er angegangen? Beziehst du dich auf den Beitrag von Wilhelm?
Wilhelm M. schrieb:> In finde es auch toll, dass Johannes sich die Mühe gemacht hat - und> finde es eben aus o.g. Grund gleichzeitig auch schade, dass er es> gemacht hat.
Da hat dich kritisiert und nicht Johannes ...
IMHO wird hier auch ein konzeptuelles Problem sichtbar, das
SPI-Peripheral wird nicht übern einen Treiber angesprochen (als mit dem
Treiberfunktionen Config, read,write) sondern wie ein Speicherobjekt
über Con- und Destruktoren.
Ein sauber geschriebener Treiber testet beim config ab, ob überhaupt die
kompatible Hardware vorliegt (HardwareID o.ä. auslesen) und meldet das
Ergebnis der Prüfung mit einem Returnwert zurück.
PS:
@Moderator: Da es offensichtlich kein Compiler-Problem war, sollt man
diesen Thread in die passende Gruppe:
https://www.mikrocontroller.net/forum/mikrocontroller-elektronik
verschieben
Fpgakuechle K. schrieb:> IMHO wird hier auch ein konzeptuelles Problem sichtbar, das> SPI-Peripheral wird nicht übern einen Treiber angesprochen (als mit dem> Treiberfunktionen Config, read,write) sondern wie ein Speicherobjekt> über Con- und Destruktoren.
Das Problem liegt m.E. auch an anderer Stelle wie schon oft hier gesagt:
werden Laufzeitobjekte benutzt für HW-Abstraktionen, müssten sie alle
als Monostate geschrieben werden. Fehler können erst zur Laufzeit
entdeckt werden.
Fast alle Abstraktionen von Peripherie sollte m.E. durch statische
Instanziierung (in C++ aka template-Instanziierung) durchgeführt werden.
So können alle Prüfungen bzgl. der HW schon zur Compilezeit ausgeführt
werden. Dies ist m.E. beim Arduino-SW-Framework im Ansatz falsch.
> Ein sauber geschriebener Treiber testet beim config ab, ob überhaupt die> kompatible Hardware vorliegt (HardwareID o.ä. auslesen) und meldet das> Ergebnis der Prüfung mit einem Returnwert zurück.
Genau, und das bitte zur Compilezeit. Das geht in C++ durch
Meta-Funktionen bzw. durch immediate-functions zur Compilezeit. Damit
spart man sich sehr(!) viel Debugging auf der Zielplattform.
das ist schon traurig hier das man sich rechtfertigen muss geholfen zu
haben.
Wenn man zu einem Thema nicht helfen will oder kann, dann einfach mal
die Fresse halten, frei nach Nuhr. Das macht die Threads übersichtlicher
als wenn jeder schreibt das er etwas nicht will oder kann.
Die Diskussion um das Arduino API ist da genauso müssig, das ist
mittlerweile über 10 Jahre alt. Es ist einfach gestrickt und aus
Processing entstanden das bewusst auf OO verzichtet hatte. Es ist auf
viele Plattformen portiert worden, also benutzen 'as is' oder nicht.
Die Konfiguration der SPI halte ich auch für kompliziert gelöst, das
könnte der Autor dieses Arduino Core vielleicht etwas vereinfachen, da
hänge ich mich aber nicht rein. Es ging nur darum zu sehen ob es ein gcc
oder Code Problem war, das ist ja nun geklärt. Mit dem Testcode und den
verwendeten Versionen hatte der TO alle Informationen geliefert um das
Problem nachzuvollziehen. Sogar mit dem Tablet auf der Couch beim
Fußball gucken.
Johannes S. schrieb:> das ist schon traurig hier das man sich rechtfertigen muss geholfen zu> haben.
Du kannst das gerne weiterhin behaupten, dadurch wird es nicht wahr.
Johannes muss sich nicht rechtfertigen und wurde nicht kritisiert. Es
sieht langsam so aus, als würdest du alle Kritik auf ihn ablenken wollen
;-)
Ich frag mich ja auch, wie das geforderte Minimalbeispiel hätte aussehen
sollen. Problem war ja, dass bestimmte SFRs nicht initialisiert
wurden, und egal wieviel und welchen Code man auch entfernt, wird sich
daran nix ändern. Das Minimalbeispiel wäre also einfach ein leeres
Programm gewesen...
Nicht ganz. Das Problem ist, daß die älteren Compiler Code erzeugen, der
nicht ganz zufälligen Werten in die Register schreibt, der aktuelle aber
nicht.
Oliver
Johann L. schrieb:> Ich frag mich ja auch, wie das geforderte Minimalbeispiel hätte aussehen> sollen. Problem war ja, dass bestimmte SFRs nicht initialisiert> wurden, und egal wieviel und welchen Code man auch entfernt, wird sich> daran nix ändern. Das Minimalbeispiel wäre also einfach ein leeres> Programm gewesen...
Das Minimalbeispiel ist der Konstruktoraufruf, der das Register nicht
setzt, das er setzen sollte.
Johann L. schrieb:> Man muss den Fehler also schon kennen, um das "Minimalbeispiel" zu> konstruieren.
Nein, man erreicht diesen Punkt, wenn man den existierenden Code
rediziert. Der TO wusste schon im ursprünglichen Beitrag, dass die
SPI-Register nicht wie erwartet gesetzt werden wie erwartet. Der erste
Schritt sollte also sein alles rauszuwerfen, was nicht "Register setzen"
ist. In diesem Fall ist dazu wohl der Aufruf dieses Konstruktors nötig.
Hallo,
ich melde mich doch nochmal zu Wort.
> Der erste Schritt sollte also sein alles rauszuwerfen, was nicht "Register> setzen" ist. In diesem Fall ist dazu wohl der Aufruf dieses Konstruktors> nötig.
Genau das hatte ich gemacht indem ich die config() Methode nicht
aufgerufen habe innerhalb der begin() Methode. Ohne config() passte
alles. Das Problem hatte also mit der config() Methode und der Klasse
SPISettingsMegaAVR zu tun. Hatte ich beschrieben. Und genau ab dem Punkt
kam ich nicht weiter. Tja und dann muss es ja erlaubt sein im Forum zu
fragen.
Hätte ich einfach geschrieben "Geht nicht, wer kümmert sich darum?"
hätte ich die Aufregung verstanden. Aber so war es ja nicht.
mh ich empfehle dir einfach mal weniger aufplustern. Man muss nicht
immer perfekt sein.
Wilhelm M. schrieb:> Fpgakuechle K. schrieb:>> Ein sauber geschriebener Treiber testet beim config ab, ob überhaupt die>> kompatible Hardware vorliegt (HardwareID o.ä. auslesen) und meldet das>> Ergebnis der Prüfung mit einem Returnwert zurück.>> Genau, und das bitte zur Compilezeit. Das geht in C++
Wenn der Code diese Information erst zur Laufzeit erhält, also welche
Chips physisch verbaut sind, liegt das zur Compilezeit nichtmal vor. Für
eine funktionierende Glaskugel wären die Lottozahlen von nächster Woche
die naheliegendere Anwendung.
Hallo,
ne ne, dass ist schon zur Compilezeit möglich, da muss ich Wilhelm und
Fpgakuechle schon recht geben. Nur muss man das für sich selbst
schreiben. Arduino wird das nicht mehr bei sich ändern. Dafür ist das
Gesamtbauwerk schon zu weit fortgeschritten über die Jahre. Das würde
einer kompletten Neuprogrammierung gleichkommen. Mit dem Rattenschwanz
der da dranhängt.
Veit D. schrieb:> ne ne, dass ist schon zur Compilezeit möglich
Hardware-ID auslesen ist zur Compilezeit nicht möglich, weil die
Information nicht vorliegt. Genau das ist aber der Sinn eines Treibers
mit so einer Fähigkeit.
Was man natürlich machen kann, ist die Firmware für die
unterschiedlichen Versionen des PCB zu bauen und dann mehrere Hexfiles
zu haben.
Hallo,
okay, ich hatte beim lesen HardwareID schon mit Controller define für
mich korrigiert. Das wäre zur Compilezeit möglich. Eine echte HardwareID
Auswertung ist natürlich nur zur Laufzeit möglich. Da muss ich dir
wiederum zustimmen.