Hallo zusammen, leider ist diese Frage etwas vage gestellt, aber ich habe keinen Ansatz für eine exaktere Formulierung. Ich programmiere zur Zeit ein aufwändigeres Projekt für den Atmega328p in Atmel Studio 7 und es entstehen nun plötzlich vermehrt Fehler wie z.B. das Überschreiben von einzelnen Adressen im Speicher mit willkürlichen Werten, fehlerhafte Ausgaben über UART/USB oder das Hängenbleiben und endlose Ausführen von Funktionen. Die Fehler sind nur teilweise reproduzierbar und treten bei den selben Funktionen an anderer Stelle nicht auf. Aus diesem Grund kann ich auch kein bestimmtes Codesegment posten an dem der Fehler liegen könnte. Der Compiler liefert keine Fehlermeldung und nennt zum Speicher: Program Memory Usage : 10636 bytes 32,5 % Full Data Memory Usage : 651 bytes 31,8 % Full Kann es trotzdem am Speicher liegen, an der Taktung o.ä.? Welche Infos kann ich noch liefern die helfen könnten? Vielen Dank im Voraus!
Philipp H. schrieb: > Welche Infos kann ich noch liefern die helfen könnten? Dein Schaltplan und detaillierte Fotos vom Aufbau (Leiterplatten- Layout und tatsächliche Hardware). Deine Fehlerbeschreibung klingt sehr nach Macken in der Hardware. Aber Genaues weiss man jetzt noch nicht.
Philipp H. schrieb: > Ich programmiere zur Zeit ein aufwändigeres Projekt für den Atmega328p > in Atmel Studio 7 und es entstehen nun plötzlich vermehrt Fehler wie > z.B. das Überschreiben von einzelnen Adressen im Speicher mit > willkürlichen Werten, fehlerhafte Ausgaben über UART/USB oder das > Hängenbleiben und endlose Ausführen von Funktionen. Stack corruption. Irgendwo in deinem C-Code hast du einen Fehler gemacht und diese Drecks-Sprache hat es dir erlaubt, ihn zu machen. Relativ wahrscheinlich ein "off-by-one"-Fehler auf dem Stack. Also an irgendeiner Stelle schreibst du ein Byte über das Ende eines Puffers hinaus, der in einer Funktion deklariert ist.
Muss nix mit dem Stack zu tun haben... Irgendein Pointer, welcher in die Wiese zeigt, reicht schon, z.B. eine Arraygrenzen Überschreitung.
Bei der Hardware handelt es sich um einen Arduino Uno und ein LoRa Shield von Dragino, wobei ich mit der MCU das darauf befindliche RFM95W LoRa Modul ansteuere. Ich programmiere per AVRDUDE aber direkt mit Atmel Studio, das ganze soll erst später auf eine eigene Platine übertragen werden. Ich kann die Layouts gerne raussuchen, aber einen Hardwarefehler halte ich daher erstmal für unwahrscheinlich, zumal die Konfiguration bisher gut funktioniert hat. Stack/Pointer Fehler klingt plausibel, ich werde mal weiter danach suchen, vielen Dank!
Philipp H. schrieb: > Ich kann die Layouts gerne raussuchen, aber einen Hardwarefehler > halte ich daher erstmal für unwahrscheinlich, Gut, akzeptiert. Es stand aber auch nirgends, dass du einen fertigen Arduino verwendet hast, so bin ich mal davon ausgegangen, dass die HW selber gebaut wurde. Und da ist ein fehlender Block-C schon öfters als Ursache aufgetaucht ...
HildeK schrieb: > Gut, akzeptiert. > Es stand aber auch nirgends, dass du einen fertigen Arduino verwendet > hast, so bin ich mal davon ausgegangen, dass die HW selber gebaut wurde. > Und da ist ein fehlender Block-C schon öfters als Ursache aufgetaucht Joo, genau so isses. Deshalb fragen wir erst mal nach den Gesamt- Umständen. Zu viele Überraschungen kamen da schon oft daher.
Philipp H. schrieb: > Ich programmiere zur Zeit ein aufwändigeres Projekt für den Atmega328p > in Atmel Studio 7 Ich sags mal so: weil der nur 32k Speicher hat, kannst du damit gar kein wirklich "aufwändiges" Projekt machen. > wie z.B. das Überschreiben von einzelnen Adressen im Speicher mit > willkürlichen Werten Der klassische amoklaufende Pointer durch zu kleine oder sich überlappende Arrays. > Kann es trotzdem am Speicher liegen Ja, wenn du z.B. in einer Subroutine ein kleines Integer-Array mit 512 Werten im lokalen Speicher anlegen willst, dann ist die Speicherlatte trotz einer "Data Memory Usage" von 0% gerissen...
:
Bearbeitet durch Moderator
Lothar M. schrieb: > Ich sags mal so: weil der nur 32k Speicher hat, kannst du damit gar kein > wirklich "aufwändiges" Projekt machen. Schnacker!
Philipp H. schrieb: > aufwändigeres Projekt für den Atmega328p "aufwändigeres Projekt" ist schon ein heftiger Widerspruch bei so einem uralten vermurksten Steinzeit Krüppel:-) Dein Problem hört sich stark noch sowas hier an: https://de.wikipedia.org/wiki/Puffer%C3%BCberlauf
Moin, mir fallen eingentlich nur 2 Sachen ein, von denen 1 passiert und man das 2. nie machen sollte: 1. Pointer läuft zu weit. 2. Pointer in nen vector array gesetzt und läuft weiter. grüüßee (:
> von MaWin (Gast)10.03.2021 20:01
Der Psychopath, der seinen Namen vergessen hat und stattdessen MaWin ins
Namensfeld schreibt, vergreift sich mal wieder im Ton.
>Bei der Hardware handelt es sich um einen Arduino Uno und ein LoRa >Shield von Dragino, wobei ich mit der MCU das darauf befindliche RFM95W >LoRa Modul ansteuere. Hallo, auch mein erster Tipp wäre ein Stacküberlauf, vermutlich an mehreren Stellen. Zur Ansteuerung des RFM95 samt Umgebung ist die Tiefe der Unterprogramme vermutlich zu groß geworden. Also flacher programmieren. mfG
Dein Problem wirst du dann ernsthaft bemerken wenn du den Code auf einem ARM laufen lässt. Der zieht dann den Hard Fault.... Genau vor dem Problem stehen dann die meisten die vom AVR zum ARM wechseln. Was da noch durch rutschte wird jetzt zuverlässig durch die Hardware verhindert. Also musst du selber in deinen Programm suchen und das Problem beheben. Oder den Teil in dem du es vermutest hier veröffentlichen...
:
Bearbeitet durch User
Marco H. schrieb: > Der zieht dann den Hard Fault.... Seit wann das denn? Auch dem ARM ist es Schnuppe, wenn Du mit einem Arraypointer auf Variablen dahinter zugreifst. Die CPU kann nicht wissen, ob das beabsichtigt ist.
Marco H. schrieb: > Was da noch durch rutschte wird jetzt zuverlässig durch die > Hardware verhindert. Quak. 'Zuverlässig' gar nicht und verhindert wird da auch nischt. Man muss sich auch schon selber einen Überblick über lokale Variablen verschaffen, denn 'size' weiss davon nix.
:
Bearbeitet durch User
Er reicht vieleicht schon sich die Warnungen des Compilers anzuschauen.
Udo S. schrieb: > Er reicht vieleicht schon sich die Warnungen des Compilers > anzuschauen. Eben und diesen nachzugehen... Nö Auch bei Array Verletzungen landest du beim ARM im Hard Fault. Das kannst du gerne zuverlässig ausprobieren.
Marco H. schrieb: > Nö Auch bei Array Verletzungen landest du beim ARM im Hard Fault. Das > kannst du gerne zuverlässig ausprobieren. Wie soll das gehen? Der Compiler legt dazu keinerlei Verwaltungsstrukturen an. Die User-Applikation kann in ihrem RAM frei rumschreiben, wie sie lustig ist. Ansonsten müßtest Du ja für jede Variable definieren, welche Funktion darauf zugreifen darf und wie.
Marco H. schrieb: > Nö Auch bei Array Verletzungen landest du beim ARM im Hard Fault. Das > kannst du gerne zuverlässig ausprobieren. Das glaube ich nicht. Hier ein Beispiel:
1 | void foo () |
2 | {
|
3 | uint8_t bar1[100]; |
4 | uint8_t bar2[100]; |
5 | uint8_t i; |
6 | |
7 | for (i = 0; i < 150; i++) |
8 | {
|
9 | bar1[i] = 42; |
10 | }
|
11 | }
|
Und jetzt erkläre mir mal, wie ein ARM diesen Pufferüberlauf erkennen soll.
:
Bearbeitet durch Moderator
Fehler im Code muessten sich tendenziell nach jedem Hardreset in gleicher Weise bemerkbar machen. Vielleicht ist es doch ein Hardwareproblem. Ist das Netzteil in Ordnung?
Philipp H. schrieb: m.n. schrieb: > Stack vermutlich zu klein. Könnte gut sein. Einfach mal zu Programmstart per Debugger das geplante Ende vom Stack ein Test-Pattern schreiben z.B. den Affen 0xAFFE, das Programm laufen lassen und bei nach dem Auftreten des "ungewöhnlichen Verhaltens" wieder per Debugger auf die Speicherstellen schauen. Wenn dann nicht mehr 0xAFFE steht, ist wohl was falsch gelaufen... [ich weiß, theoretisch könnte bei 0xAFFE der Stack übergelaufen sein, weil es könnte ja genau 0xAFFE "regulär" an diese Stellen geschrieben worden sein. Aber die Wahrscheinlichkeit von 1:2^16 würde ich jetzt einfach mal vernachlässigen]. Ich bin im AVR-gcc nicht super fit, aber irgendwo wird in einem .lst/.asm/.map o.ä. file stehen wieviel Byte Stack jede Funktion/Interrupt benötigt. Da kann man schon mal eine Abschätzung machen, wie groß der Stack mindestens sein muß. Gruß Robert
Maxe schrieb: > Fehler im Code muessten sich tendenziell nach jedem Hardreset in > gleicher Weise bemerkbar machen. Leider nein! Denn es könnte ein von externer Quelle verursachter Interrupt dazwischen kommen, der den Fehler verursacht - das aber nur, wenn er der Interrupt einer bestimmten Stelle im Hauptprogramm auftritt. So kann das Fehlverhalten zu einem Zufallsgenerator werden.
Naja, zumindest der AVR GCC meldet das:
1 | E:\Programme\arduino\portable\sketchbook\sketch_mar11b\sketch_mar11b.ino:10:13: warning: iteration 100 invokes undefined behavior [-Waggressive-loop-optimizations] |
2 | 10 | bar1[i] = 42; |
3 | | ~~~~~~~~^~~~ |
4 | E:\Programme\arduino\portable\sketchbook\sketch_mar11b\sketch_mar11b.ino:8:17: note: within this loop |
5 | 8 | for (i = 0; i < 150; i++) |
6 | | ~~^~~~~ |
Unter anderem, um solche Böcke zu vermeiden, wurde sowas erfunden:
1 | for (uint8_t &value:bar1) |
2 | {
|
3 | value = 42; |
4 | }
|
Wo kein Index, da auch kein falscher möglich. Wird aber wohl noch was dauern bis das von der C++ Welt in der C Welt ankommt. Der Mangel an Iteratoren wirds bremsen. Aber schon wahr... Weder C, C++ noch ASM kennt da, von Hause, aus Schutzmaßnahmen. Außer: Sorgfalt und Disziplin.
Maxe schrieb: > Fehler im Code muessten sich tendenziell nach jedem Hardreset in > gleicher Weise bemerkbar machen. Ähhhh, ich hab mal Temp.Werte hingeschrieben wo sie nicht hingehören.....
Arduino Fanboy D. schrieb: > Naja, zumindest der AVR GCC meldet das: Mensch, das war doch nur ein exemplarisches Beispiel mit der fixen Grenze von 150 und ein Denkanstoß. Dann mach ichs halt anders:
1 | void foo (uint8_t limit) |
2 | {
|
3 | uint8_t bar1[100] = { 0 }; |
4 | uint8_t bar2[100] = { 0 }; |
5 | uint8_t i; |
6 | |
7 | for (i = 0; i < limit; i++) |
8 | {
|
9 | bar1[i] = 42; |
10 | }
|
11 | }
|
12 | |
13 | void bar () |
14 | {
|
15 | foo (rand() % 150); |
16 | }
|
Jetzt wird der Compiler nix mehr ausrichten können. Und schon gar nicht wird ein ARM einen Hardfault werfen. Solange man im verwendeten Adressraum bleibt, ist alles erlaubt. > Unter anderem, um solche Böcke zu vermeiden, wurde sowas erfunden: Reden wir von C oder von C++?
:
Bearbeitet durch Moderator
Soll ich noch ein Beispiel für den Z80 hinterherbringen? Das hilft dem TO bei Problemen mit dem Atmega328 bestimmt genau so viel, wie des Verhalten von ARM.
Oh,oh schrieb: > Das hilft dem TO bei Problemen mit dem Atmega328 bestimmt genau so viel, > wie des Verhalten von ARM. Es ging darum, dass dem TO erzählt wurde "Mit einem ARM wär das nicht passiert". Das ist aber ein Trugschluss. Wo ist denn Dein Beitrag zur Hilfe? Dieser war's jedenfalls nicht. Tipps wurden dem TO bereits genannt. Aber: Ohne Quellcode bleibt alles Spekulation. Solange der hier nicht präsentiert wird, kann man nur aus der Glaskugel lesen.
Ich wiederhole es noch einmal: die geschilderten Fehler treten immer dann zu Tage, wenn die Stackgröße zu klein gewählt ist. Die IDE gibt bei einem neuen Projekt einen kleinen Standardwert vor, der bei größer werdenden Programmen mit "verschachtelten" Funktionen und Interrupts irgendwann nicht mehr ausreicht. Der TO sollte die Größe testweise um 50% erhöhen. Dann braucht er sein Programm auch nicht auf einen ARM umzuschreiben. Frank M. schrieb: > Aber: Ohne Quellcode bleibt alles > Spekulation. Solange der hier nicht präsentiert wird, kann man nur aus > der Glaskugel lesen. An dem Quellcode kann man die Stackgröße nicht erkennen. Wenn ich in meine Glaskugel sehe, kann ich vieles wiedererkennen ;-)
m.n. schrieb: > Ich wiederhole es noch einmal: die geschilderten Fehler treten immer > dann zu Tage, wenn die Stackgröße zu klein gewählt ist. Sie kann nur das Problem der Stack/Heap Kollisionen mildern. Die Stackgröße hat keine Auswirkungen auf Pointer, welche ins Nirwana zeigen.
m.n. schrieb: > Der TO sollte die Größe testweise um 50% erhöhen. Beim AVR-GCC kann man den Stack nicht vergrößern. Er läuft immer bis RAM_END. Um ihn zu vergrößern, müßte man die globalen Variablen verkleinern.
Peter D. schrieb: > Beim AVR-GCC kann man den Stack nicht vergrößern. Er läuft immer bis > RAM_END. Um ihn zu vergrößern, müßte man die globalen Variablen > verkleinern. Eben.
Peter D. schrieb: > Beim AVR-GCC kann man den Stack nicht vergrößern. Er läuft immer bis > RAM_END. Von RAM_END! Man kann doch den Stackbereich einstellen? Wenn dann der Linker meckert, sieht man ob's RAM zu klein ist.
m.n. schrieb: > Wenn dann der Linker meckert, sieht man ob's RAM zu klein ist. Nö, der Stack läuft einfach in die globalen Variablen hinein.
Peter D. schrieb: > Nö, der Stack läuft einfach in die globalen Variablen hinein. Testbar z.B. mit https://www.mikrocontroller.net/attachment/highlight/15782 (Musste etwas suchen, bis ich die Original-PeDa-Version gefunden hab … Quelle Beitrag "ATMega32 Stack overflow. Wie vermeiden/analysieren?")
Frank M. schrieb: > Oh,oh schrieb: >> Das hilft dem TO bei Problemen mit dem Atmega328 bestimmt genau so viel, >> wie des Verhalten von ARM. > > Es ging darum, dass dem TO erzählt wurde "Mit einem ARM wär das nicht > passiert". Das ist aber ein Trugschluss. > > Wo ist denn Dein Beitrag zur Hilfe? Dieser war's jedenfalls nicht. Meinen Beitrag zu Hilfe wirst Du vergeblich suchen müssen, denn zuviele meiner Beiträge, die Hilfe brachten und teilweise ziemlichen Aufwand erforderten, wurden entfernt. Daraus schließe ich, daß man auf sinnvolle Mitarbeit keinen gesteigerten Wert legt und richte mich entsprechend darauf ein.
Peter D. schrieb: > m.n. schrieb: >> Wenn dann der Linker meckert, sieht man ob's RAM zu klein ist. > > Nö, der Stack läuft einfach in die globalen Variablen hinein. Na gut, dann bin ich zu sehr IAR-geschädigt. RAM kann man gut freibekommen, indem man konstante Strings (Texte) nicht in initialisierte Variablen kopieren läßt, sondern immer aus dem Flash liest.
m.n. schrieb: > Na gut, dann bin ich zu sehr IAR-geschädigt. Der IAR hat wohl 2 Stacks, einen für Calls/Register und einen für lokale Variablen. Daher hat der AVR auch das 3. Pointerset. m.n. schrieb: > RAM kann man gut freibekommen, indem man konstante Strings (Texte) nicht > in initialisierte Variablen kopieren läßt, sondern immer aus dem Flash > liest. Da ja nur 31,8% belegt sind, ist das nicht der Flaschenhals.
Erstmal danke für das reichliche Feedback, "aufwändig" war natürlich nur im Rahmen der gegebenen Hardware gemeint ;) Εrnst B. schrieb: > Testbar z.B. mit > https://www.mikrocontroller.net/attachment/highlight/15782 habe das mal eingebaut und frage an mehreren Stellen im Programm ab. Erwartungsgemäß sinkt der "unberührte" Stack nach den größeren Funktionen erheblich ab, z.B. auf 0x02FB von verfügbaren 0x059F, bei manchen Durchgängen noch niedriger. Bis er plötzlich wieder auf einen höheren Wert springt...? Zerschießt sich das Programm an diesem Punkt? Sind dann Fehler bei Pointern/Arrays erstmal unwahrscheinlicher wenn es wohl doch einfach am Stack liegt?
Philipp H. schrieb: > Bis er plötzlich wieder auf einen höheren Wert springt...? Zerschießt > sich das Programm an diesem Punkt? Beim Return aus einer Funktion mit größeren lokalen Variablen (Arrays) springt der Stackpointer auf einen (wesentlich) höheren Wert. Ohne den Quellcode kommen wir hier nicht weiter.
Frank M. schrieb: > Ohne den Quellcode kommen wir hier nicht weiter. Dann hier mal alle Dateien. lorawan.c ist mit der aktiven Session der kritische punkt, dort gehen die Funktionen am tiefsten, vor allem wenn frames zusammengesetzt und de/encrypted werden. aes und cmac stammen nicht von mir, funktionieren isoliert aber wie erwartet.
Philipp H. schrieb: > Dann hier mal alle Dateien. Ich finde beim Compilieren eine bedenkliche Warnung: ../LoraWAN.c:620: warning: array subscript is above array bounds die ich sehr ernst nehmen würde. Also wenn man so was nicht sieht bzw. ignoriert ....
Philipp H. schrieb: > Dann hier mal alle Dateien. Danke. Frage dazu:
1 | bool LorawanJoinDecrypt (uint8_t *firstElementOfData, uint8_t lengthOfMessage) |
Wie groß kann lengthOfMessage werden? Innerhalb dieser Funktion wird aufgerufen:
1 | aes_encrypt(joinAcceptMessageEnc, joinAcceptMessage, &aesContext); |
aes_encrypt() arbeitet nicht mit der Längeninformation lengthOfMessage, sondern mit einer festen Länge N_BLOCK bzw. Informationen aus aesContext. Ist sichergestellt, dass das gutgeht? aes_encrypt() benutzt zur Längenberechnung aesContext(), wobei sich mir nicht direkt auf den ersten Blick erschließt, ob und wie lengthOfMessage und aesContext korrelieren. P.S. Unschön:
1 | memset(aesContext.ksch, '\0', 240); |
Besser wäre:
1 | memset(aesContext.ksch, '\0', (N_MAX_ROUNDS + 1) * N_BLOCK): |
oder einfacher:
1 | memset(aesContext.ksch, '\0', sizeof (aesContext.ksch)): |
Ich habe nachgerechnet: Glücklicherweise stimmen die 240.;) Tipp: Suche nach weiteren Zahlenkonstanten im Source, überprüfe die Richtigkeit und ersetze diese maghischen Zahlen durch passende Preprozessor-Konstanten oder sizeofs. Eine falsch verwendete Zahl kann schon verheerende Auswirkungen haben.
:
Bearbeitet durch Moderator
Noch eine prüfenswerte Stelle in LorawanCreateFrame():
1 | k = i+fOptsLen; |
2 | while (i<k) |
3 | {
|
4 | message[i] = macPendingCommand[j]; |
Ist sichergestellt, dass i + fOptLen niemals größer gleich 127 wird?
Philipp H. schrieb: > Dann hier mal alle Dateien. Da geht's drunter und drüber .... - Öffentliche Funktionen nicht in <lorawan.h> definiert. Dadurch kommt es zu Fehlermeldungen des Compilers der eine Funktion vordefiniert (weil sie aufgerufen wird) bevor sie wirklich definiert wird. - Variablen in <lorawan.h> angelegt. Das tut man nicht! Nein das tut man nicht. Will nicht wissen was da noch alles im Argen ist. Und da soll ein Programm bei soviel Macken fehlerfrei laufen?
Philipp H. schrieb: > Dann hier mal alle Dateien Bitte -Wall einschalten und alle Warnungen bearbeiten - nicht durch Casts "wegschummeln"
Frank M. schrieb: > Bitte -Wall einschalten und alle Warnungen bearbeiten - nicht durch > Casts "wegschummeln" Plötzlich wird es hier im Thread ganz still .... wie seltsam.
Hard Worker schrieb: > Plötzlich wird es hier im Thread ganz still Naja, er hat jetzt erstmal eine Weile was zu tun.
c-hater schrieb: > Irgendwo in deinem C-Code hast du einen Fehler gemacht > und diese Drecks-Sprache hat es dir erlaubt, ihn zu machen. Diesen dummen Spruch kannst zurück haben. Deine "Drecks-Sprache" (Assembler) erlaubt diesen Fehler ebenfalls und noch viele weitere.
MaWin schrieb: > Der Psychopath, der seinen Namen vergessen hat und stattdessen MaWin ins > Namensfeld schreibt, vergreift sich mal wieder im Ton. Die Memme heult schon wieder. Registriere dich!
Es muss nicht, destotrotz, auf einen groben Klotz nicht immer nur ein grober Keil gehören ... H. v. Veen
Stefan ⛄ F. schrieb: > Die Memme heult schon wieder. Memme würde ich zuallererst mit dem weinerlichen Weichei stefanus assoziieren. Der originale (tm) MaWin kann gar nicht soviel vergessen, wie Du nie wissen wirst, also halte die Flossen still, wenn's um MaWin geht.
Philipp H. schrieb: > Die Fehler sind nur teilweise reproduzierbar Irgend W. schrieb: > uralten Massefehler. Philipp H. schrieb: > "aufwändig" war natürlich nur im Rahmen der gegebenen Hardware gemeint Scherzkeks.
Philipp H. schrieb: > Ich programmiere zur Zeit ein aufwändigeres Projekt für den Atmega328p > in Atmel Studio 7 Wenn man als einigermassen erfahrener Programmierer das so liest dann bekommt man solch einen Respekt vor den Fähigkeiten des TO, ganz im Kontrast zu dem was einem dann an Arbeit vorgelegt wird.
Ich bitte, hier beim Thema zu bleiben. Persönliche Anfeindungen helfen hier nicht weiter. Wenn jemand einen Kleinkrieg anzetteln will, ist er hier falsch am Platz.
Beitrag #6617422 wurde von einem Moderator gelöscht.
Stefan ⛄ F. schrieb: > Deine "Drecks-Sprache" (Assembler) erlaubt diesen Fehler ebenfalls und > noch viele weitere. Das stimmt natürlich. Aber von Assembler behauptet eben auch niemand, dass es eine Hochsprache wäre. Von einer Hochsprache kann man schon deutlich mehr erwarten als von einem Assembler, insbesondere bezüglich der Verhinderung von Fehlern und notfalls Möglichkeiten zu ihrer einfacheren Lokalisierung. Und genau das leistet C in keinster Weise. Ja klar, ein versehentliches R2 statt R22 kann da z.B. nicht passieren. Aber das wurde einfach nur durch andere Typo-Fehlerklassen ersetzt, z.B. "," statt ";" oder "=" statt "==". Ähnlich sieht das bezüglich viele anderer Standardfehlerklassen auch aus, das beschränkt sich also durchaus nicht auf die Typos. Mit extrem viel Syntax-Bombast (der zusätzliche Komplexität einführt) also bezüglich der Fehlervermeidung praktisch nix erreicht, so kann man das in etwa zusammenfassen.
c-hater schrieb: > Aber von Assembler behauptet eben auch niemand, dass es eine Hochsprache > wäre. Von einer Hochsprache kann man schon deutlich mehr erwarten als > von einem Assembler, insbesondere bezüglich der Verhinderung von Fehlern > und notfalls Möglichkeiten zu ihrer einfacheren Lokalisierung. Deine Erwartungshaltung ist defekt. Nirgendwo verspricht C oder C++ den totalen Schutz gegen Dummheit. Warnungen können etwas helfen.....
m.n. schrieb: > Peter D. schrieb: >> Beim AVR-GCC kann man den Stack nicht vergrößern. Er läuft immer bis >> RAM_END. > > Von RAM_END! Man kann doch den Stackbereich einstellen? Ja, der Bereich, der dafür vorgesehen ist, kann eingestellt werden. Das heißt aber nicht, dass dieser auch eingehalten wird. > Wenn dann der Linker meckert, sieht man ob's RAM zu klein ist. Woher soll denn der Linker wissen, wie viel Stack später zur Laufzeit tatsächlich verwendet wird? Der sagt dir nur, wie viel Platz deine statischen Variablen belegen, sonst nichts. Dass dann für den Stack noch genug Platz bleibt (wobei "genug" natürlich stark vom Programm abhängt), musst du selbst sicherstellen. c-hater schrieb: > Aber von Assembler behauptet eben auch niemand, dass es eine Hochsprache > wäre. Von einer Hochsprache kann man schon deutlich mehr erwarten als > von einem Assembler, insbesondere bezüglich der Verhinderung von Fehlern > und notfalls Möglichkeiten zu ihrer einfacheren Lokalisierung. An anderen Stellen beschwerst du dich regelmäßig, dass C-Code vermeintlich doch so viel größer und langsamer sei als dein handgestrickter Assembler-Code. Jetzt beschwerst du dich, dass fehlerhafte Zeigerzugriffe und Stacküberläufe zur Laufzeit nicht erkannt werden. Das könnte man schon machen, würde aber den Code deutlich größer und langsamer machen.
> Akausales Verhalten von Atmega328p
Akausal? Was man hier für wunderschöne Worte finden kann...
Nachdenklicher schrieb: >> Akausales Verhalten von Atmega328p > > Akausal? Was man hier für wunderschöne Worte finden kann... Vor allem wird das Verhalten durchaus kausal sein. Wenn man den Grund für das Verhalten nicht kennt, heißt das ja nicht, dass es keinen gibt.
Was sagt denn der Simulator im Studio? Ist schon einige Jahre her mit AVRs bei mir, aber konnte man da nicht sogar einen Alarmwert für den Stackpointer festlegen(In der Simulation)?
Hard Worker schrieb: > Philipp H. schrieb: >> Ich programmiere zur Zeit ein aufwändigeres Projekt für den Atmega328p >> in Atmel Studio 7 > > Wenn man als einigermassen erfahrener Programmierer das so liest > dann bekommt man solch einen Respekt vor den Fähigkeiten des TO, > ganz im Kontrast zu dem was einem dann an Arbeit vorgelegt wird. Ich habe vieles erst bei diesem Projekt gelernt und es ist alles sehr work in progress. Ich verstehe dass es jemandem mit mehr Erfahrung da grausen kann, aber jeder fängt mal klein an und der nächste Code wird mit Sicherheit deutlich schöner. Ich wollte nur den Verdacht zum Ausdruck bringen, dass ich den Chip in Sachen RAM etc. vielleicht an seine Grenzen bringe, gerade weil die Programmierung noch sehr holprig ist. Frank M. schrieb: > Bitte -Wall einschalten und alle Warnungen bearbeiten - nicht durch > Casts "wegschummeln" War bereits eingeschaltet, weshalb mich auch wundert, warum ich z.B. diese Warnung Hard Worker schrieb: > Ich finde beim Compilieren eine bedenkliche Warnung: > > ../LoraWAN.c:620: warning: array subscript is above array bounds nicht bekommen habe. Welche Option übersehe ich da?
uwe schrieb: > Was sagt denn der Simulator im Studio? Ist schon einige Jahre her mit > AVRs bei mir, aber konnte man da nicht sogar einen Alarmwert für den > Stackpointer festlegen(In der Simulation)? Zumindest AS 4 konnte bei bestimmten Kontrollertypen eine "data breakpoint", Zugriff r oder auch w auf eine "don't touch" Speicherstelle setzen, damit konnte man das abfangen. Ging im Memory-Fenster mittels Rechtsklick und Kontextmenue. Wenn man den Resetvektor abfängt - bei Stacküberlauf kann es zu falschen Returnadressen, damit Ausführung ungültiger Opcodes und nachfolgend Neustart kommen - dann kann man noch schnell einen Stack- und Registerdump rausschreiben.
ohne jetzt alle Beiträge gelesen zu haben, klingt es eher nach einem typischen C Problem. Daher besser auch Pascal setzen, wenn es zuverlässig laufen soll. Für Hobbyzwecke ist C aber vom Prinzip her völlig ok oder für einfache Consumerprodukte. Selbst Basci sollte hier besser geeignet sein
Philipp H. schrieb: > War bereits eingeschaltet, weshalb mich auch wundert, warum ich z.B. > diese Warnung Welche gcc-Version hast Du? Hast Du mal meinen Beitrag von gestern Beitrag "Re: Akausales Verhalten von Atmega328p" geprüft? Da wird aes_encrypt() mit 2 Arrays aufgerufen, die eine variable Länge haben, wobei aes_encrypt() hier zwei Array mit fixer Länge erwartet.
Pete34 schrieb: > ohne jetzt alle Beiträge gelesen zu haben, klingt es eher nach > einem > typischen C Problem. > Daher besser auch Pascal setzen, wenn es zuverlässig laufen soll. > Für Hobbyzwecke ist C aber vom Prinzip her völlig ok oder für einfache > Consumerprodukte. > > Selbst Basci sollte hier besser geeignet sein „Einfache Consumerprodukte“ wie Autos zum Beispiel? scnr
Philipp H. schrieb: > War bereits eingeschaltet, weshalb mich auch wundert, warum ich z.B. > diese Warnung > ............. > nicht bekommen habe. Naja, bist du in gewisser Weise selbst Schuld wenn du nur einzelne Sourcen lieferst statt einem vollständigen Projekt. So ist nicht einwandfrei nachvollziehbar was du machst.
Frank M. schrieb: > Welche gcc-Version hast Du? "AVR/GNU C Compiler : 5.4.0" Frank M. schrieb: > Da wird aes_encrypt() mit 2 Arrays aufgerufen, die eine variable Länge > haben, wobei aes_encrypt() hier zwei Array mit fixer Länge erwartet. Habe mich da an anderen Implementierungen der Funktionen orientiert, auch dort wird mit variablen Längen aufgerufen. So wie ich das verstanden habe werden nur die Blöcke gefüllt, für Nachrichten >16 müsste man also nochmal mit den restlichen Werten, also verschobenen Input/Output Buffern aufrufen. Da sollte durch längere Arrays eigentlich nichts in die Wildnis geschrieben werden, im früheren Verlauf haben die encrypt Funktionen auch noch kein unerwünschtes Verhalten verursacht. Aber ich werde nochmal genauer nachgucken um Fehler auszuschließen.
Hard Worker schrieb: > So ist nicht einwandfrei nachvollziehbar was du machst. Denn die Projekteinstellungen im Atmel Studio sind vielfältig, kompliziert und für den Anfänger sicherlich teilweise undurch- sichtig, unverständlich und auch fehleranfällig.
Nach der Korrektur der Variablen in der *.h Datei kompiliert es auch in der Arduino IDE. Die angegebenen Warnung Hard Worker schrieb: > ../LoraWAN.c:620: warning: array subscript is above array bounds Sehe ich auch mit -Wall nicht. Toolchain: avr-gcc-10.0.0_2019-12-16_-mingw32 Eine falsche Warnung taucht allerdings auf:
1 | E:\temp\Arduino\sketch\lorawan.c: In function 'LorawanReadFrame': |
2 | E:\temp\Arduino\sketch\lorawan.c:675:10: warning: variable 'fOpts' set but not used [-Wunused-but-set-variable] |
3 | 675 | uint8_t fOpts[15]; |
4 | | ^~~~~ |
Das genannte Array wird genutzt. Was allerdings wohl scheppern muss, ist dieses:
1 | uint8_t micBlock[16] = {0}; |
2 | // schnipp
|
3 | for (i=0; i<lengthOfMessage; i++) |
4 | {
|
5 | micBlock[(16+i)] = *(firstElementOfMessage+i); |
6 | }
|
Arduino Fanboy D. schrieb: > Was allerdings wohl scheppern muss, ist dieses: Genau da meckert "mein" Compiler. Dass es sich um die gleiche Stelle handelt hättest du an der Zeilennummer sehen können.
Arduino Fanboy D. schrieb: > Was allerdings wohl scheppern muss, ist dieses:uint8_t micBlock[16] = > {0}; > // schnipp > for (i=0; i<lengthOfMessage; i++) > { > micBlock[(16+i)] = *(firstElementOfMessage+i); > } Das war line 620, ist schon raus. Das mit fOpts ist ok, wird noch nicht weiter verwendet.
Philipp H. schrieb: > War bereits eingeschaltet, weshalb mich auch wundert, warum ich z.B. > diese Warnung > Hard Worker schrieb: > >> Ich finde beim Compilieren eine bedenkliche Warnung: >> ../LoraWAN.c:620: warning: array subscript is above array bounds > > nicht bekommen habe. Welche Option übersehe ich da? Manche Warnungen werden vom gcc erst ausgegeben, wenn der Optimizer eingeschaltet ist. Also solltest Du mindestens "-Os" setzen, vielleicht auch testweise mal mit "-O2" übersetzen.
Hard Worker schrieb: > Dass es sich um die gleiche Stelle handelt hättest du an der > Zeilennummer sehen können. Tja, so kann es kommen.... Die Zeilennummern sind bei mir anders, da ich die Variablen von der *.h, in die *.c transportiert habe. Ohne den Transport ist der Linker mit viel Geschrei (w.g. den Duplikaten) ausgestiegen. Frank M. schrieb: > Du mindestens "-Os" setzen, v Habe ich, trotzdem keine Meldung dazu.
Nach dem mit soviel verschiedenen Zungen gesprochen wird, darf ich mich noch mal wiederholen: Hard Worker schrieb: > Naja, bist du in gewisser Weise selbst Schuld wenn du nur > einzelne Sourcen lieferst statt einem vollständigen Projekt. > So ist nicht einwandfrei nachvollziehbar was du machst.
Frank M. schrieb: > Manche Warnungen werden vom gcc erst ausgegeben, wenn der Optimizer > eingeschaltet ist. Also solltest Du mindestens "-Os" setzen, vielleicht > auch testweise mal mit "-O2" übersetzen. Merci, mit o2 bekomme ich auch direkt die Meldung über einen anderen schön blöden Fehler. Ich Initialisiere Array[16] und schreibe danach in Array[16]. Das ist allerdings schon so grundlegend falsch dass ich mich frage wie das selbst bei o1 noch durchgehen kann? Ein Fehler bei dem eine Adresse ohne zutun neu beschrieben wird ist auch direkt weg, ich taste mich mal weiter voran und hoffe erstmal, dass das der Grund war, sollten die Fehler weiter auftauchen melde ich mich und lade das ganze Projekt nochmal hoch. Vielen Dank erstmal für die rege Beteiligung und die Hilfe, mit mehr Erfahrung kommen dann auch hoffentlich kompetentere Fragen!
Philipp H. schrieb: > sollten die Fehler weiter auftauchen melde ich mich und > lade das ganze Projekt nochmal hoch. Na das ist doch schon mal was. Ich hoffe dass du alle Aspekte die hier bisher genannt wurden auch umgesetzt hast. Oft fallen Warnings dadurch unter den Tisch dass ein Projekt teilweise korrekt compiliert wurde und man nur an der Stelle wo ein Fehler auftritt, eingreift. Um wirklich "alles" an Warnings zu sehen empfiehlt es sich dringend öfters mal ein Build-->CleanSolution zu machen um den Build Prozess ganz von vorne anzustossen.
Hard Worker schrieb: > Oft fallen Warnings dadurch unter den Tisch dass ein Projekt > teilweise korrekt compiliert wurde und man nur an der Stelle > wo ein Fehler auftritt, eingreift. Dem kann man mit -Werror vorbeugen. Dann muss man an jede Warnung ran und keine fällt unter den Tisch.
:
Bearbeitet durch Moderator
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.