Bit-Frickelei, wie uC Abstürze beheben?

Der chaotische Hauptfaden

Moderatoren: Heaterman, Finger, Sven, TDI, Marsupilami72, duese

Antworten
Farbe
Beiträge: 410
Registriert: So 29. Sep 2013, 16:06

Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von Farbe »

Hallo Leute,


ich komme immer öfter dazu mithilfe von Arduino zu programmieren.
Leider kommt es ab und zu vor das ich irgendwelche seltsamen unerklärbaren Crashes hab.

Aktuell probiere ich mit Hilfe von MegaTinyCore einen Atmega3227 zu benutzen.
Klappt auch alles ganz wunderbar.

Das Programm ist recht klein, ca 10kb, Arduino bestätigt mir ca 3% dynamischen Speicher.
Kurzfassung: ADC auslesen (NTC), Lüftersteuerung (PWM), kleiner PID Regler (PWM), blinken mit ein paar LEDs (Status), Stundenzähler (+eeprom wearleveling).

Trotzdem stürzt der uC ab.
Immer an der selben Stelle im Programm, kommentiere ich einen unabhängigen Teil aus, läuft alles super.

Als Beispiel für meinen Aktuellen Fehler:

Code: Alles auswählen

void setup() {
//initialisiere Outputs / Inputs, lese EEPROM
}

void loop() {
if(digitalRead(button) == HIGH){
debug = true;
}

if(debug == false){
ReadTemp();
ControlFan();
BlinkLED();
}else{
debug();
}

}

void debug() {
//read eeprom
//blink LEDs
debug = false;
}

Der Code oben funktioniert nicht.
Sobald der Knopf drückt wird und damit der debug loop gestartet wird, resettet sich der uC.
ReadTemp, ControlFan und BlinkLED funktionieren ohne Probleme.

Kommentiere ich jetzt z.b. den Inhalt von BlinkLED, ControlFan oder! ReadTemp aus, funktioniert der Debug Loop ohne Probleme.

Im Debug Loop gibts nur sowas wie "Blink without delay" das ein paar Statusvariablen mittels LED raus morst.

Da diese Programmteile komplett unabhängig sind und nicht aufeinander zugreifen schließe ich auf irgendeinen Overflow bei dem an die falsche Stelle geschrieben wird.

Wie Debugge ich das sinnvoll?
Arduino kann ja kein UPDI debugger.
Anse
Beiträge: 2309
Registriert: Mo 12. Aug 2013, 21:30
Wohnort: Bühl (Baden)

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von Anse »

Stürzt der µC ab oder resetet er sich?
Beim Reset kann man bei Start abfragen, was der Grund für den Reset war. Heist meistens MCUSR Oder MCUCSR.
Farbe
Beiträge: 410
Registriert: So 29. Sep 2013, 16:06

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von Farbe »

In dem fall sieht es nach Reset aus. Also er hängt nicht, er startet das Programm erneut, wie nach powerup.

IRS gibt es (in dem fall) keine außer die interne millis Funktion von Arduino, daher denke ich auch nicht das der Pointer dafür in eine falsche Richtung zeigt.

Da ich aber garkeinen Watchdog verwende, denke ich nicht das mir das wirklich hilft.
Reset Knopf wird auf jeden fall nicht gedrückt, denn es gibt keinen Pin dafür.

Das Problem hängt auch nicht mit Pins oder den anderen schleifen zusammen.
ReadTemp, ControlFan usw liefen schon Wochen durchgehen ohne Reset ohne Probleme.

Jetzt sollte nur noch die Maximale Temperatur mittels der Debug LED gemorst werden.
Die Debug Led morst im normalem Betrieb die Ist Temperatur aus.

D.h. Es werden auch nicht plötzlich andere Pins geschalten.

uC hab ich auch schon getauscht, ich dachte ich hab mir vielleicht den Flash/EEPROM zerschrieben.
andreas6
Beiträge: 4165
Registriert: So 11. Aug 2013, 15:09

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von andreas6 »

Ich glaube, hier fehlt die Struktur an sich. Es gibt zwar eine Routine namens loop, aber da loopt nichts. So ein simples Programm sollte eine Endlosschleife enthalten, in der es laufend kreiselt. Änderungen am Umfeld bewirken nur den zeitweisen Ausbruch daraus. Hier sehe ich so eine Schleife nicht.

MfG. Andreas
Jannyboy
Beiträge: 1419
Registriert: So 11. Aug 2013, 14:49
Wohnort: Kreis Augsburg

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von Jannyboy »

Farbe hat geschrieben: Mi 26. Jul 2023, 18:00 Das Programm ist recht klein, ca 10kb, Arduino bestätigt mir ca 3% dynamischen Speicher.
Die MCU hat keine MMU daher sollte man nur mit statischer Speicherzuweisung arbeiten.
Sonst macht der eine halbherzige MMU-Emulation.

Vielleicht liegt auch da der Fehler.
Was noch ein beliebter Fehler ist. Ist der Stack-Overflow. Also der freie Speicher des Stacks ist kleiner
Als der angeforderte Speicher.

Grüße Jan
Benutzeravatar
Finger
Administrator
Beiträge: 7486
Registriert: Di 12. Jun 2012, 20:16
Kontaktdaten:

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von Finger »

Der Coltroller verrät dir in irgendeinem Register die Resetquelle. Ausser du hast n Bootloader da drin laufen, dann ist das Register in aller Regel leer, wenn deine Applikation startet. Schau mal, was da drin steht bitte (welche Bits sind gesetzt). Ansonsten klingt das ganz stark nach einem Speicherüberlauf, dafür spricht das nicht deterministische Verhalten, wenn du Code auskommentierst. Das im System zu Debuggen ist auf der Plattform nicht sinnvoll möglich. Dein Linkerscript passt zum Controller?
Könntest du vielleicht deinen gesamten Code mal anhängen?
Silvio
Beiträge: 123
Registriert: Mi 21. Sep 2022, 03:18

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von Silvio »

Vielleicht ist deine Variable debug nicht deklariert und es beißt sich mit der gleichnamigen Funktion debug.
ch_ris
Beiträge: 3055
Registriert: Mo 30. Nov 2015, 10:08

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von ch_ris »

schlag mich gerade mit dem gleichen Problem herum. vielleicht.
Elektrik steht auch unter Verdacht.

MCUSR(ohne Bootloader) ist mir keine Hilfe , entweder ich bin zu doof das zu verstehen oder hab bei der Implementierung Fehler gemacht.
Das muss ich noch mal an einem blanken Stück Code probieren.

Speicher scheint genügend frei wenn ich 2 verschiedenen Funktionen glauben will.

Wegen Lesbarkeit habe ich einen CASE innerhalb eines SWITCH Blocks verschoben -> Peng, compiliert zwar aber Programm funktioniert gar nicht mehr bzw springt nicht in den CASE.
hab die Verzettelungs-tiefe als Ursache beschlossen, und rigoros Funktionen entfernt und IF IFs verflacht.
Das hatte Effekt, aber ob das letztlich die Ursache war...
Benutzeravatar
Tjareson
Beiträge: 362
Registriert: Fr 3. Jul 2015, 05:01

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von Tjareson »

Mein Tipp: einfach den kompletten Code in chatgpt kopieren und prüfen lassen. Hat mir in den letzten Monaten schon etliche mal direkt geholfen.
Am besten dazuschreiben, was das Problem ist. Da kommt nicht allzu selten eine relativ detaillierte Antwort raus.
ch_ris
Beiträge: 3055
Registriert: Mo 30. Nov 2015, 10:08

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von ch_ris »

Also,
ein blanker Nano, ohne Bootloader und Drähte, die fuses:
2023-07-27 11_23_28-ATmega328P Fuses.png
der code:

Code: Alles auswählen

#include <avr/wdt.h>

uint8_t mcusr_mirror __attribute__ ((section (".noinit")));

void get_mcusr(void) __attribute__((naked))
__attribute__((section(".init3")));
void get_mcusr(void) {
	mcusr_mirror = MCUSR;
	MCUSR = 0;
	wdt_disable();
}

void setup() {
//	wdt_disable() ;//kein Unterschied

	uint16_t mus = 0;
	if (mcusr_mirror & (1 << WDRF))
		mus += 1000; //Watchdog
	if (mcusr_mirror & (1 << BORF))
		mus += 100; //Brown-out
	if (mcusr_mirror & (1 << EXTRF))
		mus += 10; //Reset
	if (mcusr_mirror & (1 << PORF))
		mus += 1; //Power-on

	//manuell nullen weil .noinit ??? keine ahnung woher
//		mcusr_mirror = 0x00; // mus=0

	wdt_enable(WDTO_2S);
	Serial.begin(115200);
	Serial.println(mus);
}

void loop() {
	wdt_reset();
	delay(1500); // mus= 1111
//	delay(2500); // mus= 1111, reboot erfolgt
}
Brownout an, 4.3v, macht auch keinen Unterschied. Ergebnis ist stets 1111 oder 0
Was stimmt da nicht?

edit, hier noch die console:

Code: Alles auswählen

11:28:44 **** Incremental Build of configuration Release for project mcusr_test ****
"E:\\Tools\\eclipseSloeber4.4\\arduinoPlugin\\tools\\make\\make" all 
'Building file: ..\sloeber.ino.cpp'
'Starting C++ compile'
"E:\Tools\eclipseSloeber4.4\arduinoPlugin\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10812 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR     -I"E:\Tools\eclipseSloeber4.4\arduinoPlugin\packages\arduino\hardware\avr\1.8.5\variants\eightanaloginputs" -I"E:\Tools\eclipseSloeber4.4\arduinoPlugin\packages\arduino\hardware\avr\1.8.5\cores\arduino" -MMD -MP -MF"sloeber.ino.cpp.d" -MT"sloeber.ino.cpp.o" -D__IN_ECLIPSE__=1 -x c++ "..\sloeber.ino.cpp"   -o "sloeber.ino.cpp.o"
'Finished building: ..\sloeber.ino.cpp'
' '
'Starting combiner'
"E:\Tools\eclipseSloeber4.4\arduinoPlugin\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7/bin/avr-gcc" -w -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega328p   -o "D:\Eclipse_Workspaces\sloeber44\mcusr_test\Release/mcusr_test.elf"    .\sloeber.ino.cpp.o     D:\Eclipse_Workspaces\sloeber44\mcusr_test\Release/arduino.ar  "-LD:\Eclipse_Workspaces\sloeber44\mcusr_test\Release" -lm
'Finished building: mcusr_test.elf'
' '
'Do all objcopy commands'
"E:\Tools\eclipseSloeber4.4\arduinoPlugin\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7/bin/avr-objcopy" -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0  "D:\Eclipse_Workspaces\sloeber44\mcusr_test\Release/mcusr_test.elf" "D:\Eclipse_Workspaces\sloeber44\mcusr_test\Release/mcusr_test.eep"
"E:\Tools\eclipseSloeber4.4\arduinoPlugin\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7/bin/avr-objcopy" -O ihex -R .eeprom  "D:\Eclipse_Workspaces\sloeber44\mcusr_test\Release/mcusr_test.elf" "D:\Eclipse_Workspaces\sloeber44\mcusr_test\Release/mcusr_test.hex"
'Finished building: mcusr_test.hex'
' '
'Building target: mcusr_test'
'Printing size:'
"E:\Tools\eclipseSloeber4.4\arduinoPlugin\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7/bin/avr-size" -A "D:\Eclipse_Workspaces\sloeber44\mcusr_test\Release/mcusr_test.elf"
D:\Eclipse_Workspaces\sloeber44\mcusr_test\Release/mcusr_test.elf  :
section                     size      addr
.data                         22   8388864
.text                       1816         0
.bss                         166   8388886
.noinit                        1   8389052
.comment                      17         0
.note.gnu.avr.deviceinfo      64         0
.debug_aranges               240         0
.debug_info                 7056         0
.debug_abbrev               2868         0
.debug_line                 2893         0
.debug_frame                 536         0
.debug_str                  1875         0
.debug_loc                  2392         0
.debug_ranges                136         0
Total                      20082


'Finished building target: mcusr_test'
' '

11:28:46 Build Finished. 0 errors, 0 warnings. (took 2s.815ms)

virtexultra
Beiträge: 139
Registriert: So 9. Dez 2018, 11:30

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von virtexultra »

Ahh, etwas Code.

Mit Arduino IDE 2.1.1 landet folgender Code nicht im Flash:

Code: Alles auswählen

void get_mcusr(void) __attribute__((naked))
__attribute__((section(".init3")));
void get_mcusr(void) {
	mcusr_mirror = MCUSR;
	MCUSR = 0;
	wdt_disable();
}
D.h. es wird nie auf das Register 0x34 (MCUSR) zugegriffen.

Mit einem expliziten Aufruf:

Code: Alles auswählen

uint8_t mcusr_mirror __attribute__ ((section (".noinit"))); //Das noinit ist so aber egal. 
void get_mcusr(void) {
	mcusr_mirror = MCUSR;
	MCUSR = 0;
	wdt_disable();
}

void setup() {
  get_mcusr();
  [.........]
wird schon mal passender ASM-Code erzeugt.

Code: Alles auswählen

84 b7       	in	r24, 0x34	; 52
80 93 bc 01 	sts	0x01BC, r24
Jetzt bleibt nur die Frage ob irgendwas vor dem setup() Aufruf die Bits in MCUSR verändert.
Warum der Linker keine Lust hat __attribute__((section(""))); zu beachten kann ich dir so spontan nicht sagen.
Benutzeravatar
Finger
Administrator
Beiträge: 7486
Registriert: Di 12. Jun 2012, 20:16
Kontaktdaten:

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von Finger »

Warum überlässt man das an der Stelle nicht komplett dem Linker, lässt also Attribute weg?
ch_ris
Beiträge: 3055
Registriert: Mo 30. Nov 2015, 10:08

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von ch_ris »

steht so in der wdt.h.
es soll wohl nach init3 weil das vor dem Einstiegspunkt.... oder so...
keine ahnung schulterzuck
virtexultra
Beiträge: 139
Registriert: So 9. Dez 2018, 11:30

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von virtexultra »

Man möchte damit definieren wann der Code ausgeführt wird. Die .init3 Sektion ist vor dem allgemeinen Start Up Code und dem Init von RAM und den Konstruktoren. Es geht um das Verhindern von Informationsverlust aus dem MCUSR Register. Ob das notwendig ist bleibt zu klären.

Ich bin aber inzwischen schlauer. Der Compiler scheint mit der -flto Option die Funktion rauszuwerfen.
Mit
void get_mcusr(void) __attribute__((section(".init3"), naked, used));
wird passender ASM erzeugt.
ch_ris
Beiträge: 3055
Registriert: Mo 30. Nov 2015, 10:08

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von ch_ris »

!!!großartig!!!
reset=10
wdt timeout=1000

fettes Danke

edit und bei dem richtigen Programm
ebenso 10 beim reset.
101 oder 111 beim an- ab-stecken (brownout aktiv, 4.3v)
Benutzeravatar
Finger
Administrator
Beiträge: 7486
Registriert: Di 12. Jun 2012, 20:16
Kontaktdaten:

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von Finger »

Dann bleibt nur noch dein ursprünglicher Bug zu finden, oder?
ch_ris
Beiträge: 3055
Registriert: Mo 30. Nov 2015, 10:08

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von ch_ris »

ja, muss alles noch mal prüfen.stresstest, scope etc.
vielleicht wars wirklich zu tiefe verschachtelung. :?
bin gespannt ob der watchdog zuschlägt.
virtexultra
Beiträge: 139
Registriert: So 9. Dez 2018, 11:30

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von virtexultra »

Um ein Prinzip zur Ermittlung der Stackausnutzung (Stack Canary) zu zeigen habe ich folgenden Code mal von einer anderen Platform portiert. Ich denke auf einem Atmega328p sollte er laufen. Bei den anderen Platformen müssen evtl. die Symbole angepasst werden.

Code: Alles auswählen

#define STACK_CANARY_VALUE 0xDE
extern char *_end;
void _GetStackSizeActual(void){
  Serial.print("Stack size: ");  Serial.println(RAMEND - SP);
}

void _GetStackSizeMax(void){
  uint16_t size = _StackFreeChecker();
  Serial.print("Free stack size: ");  Serial.println(size);
}

void _StackPaint(void)  __attribute__((used)) __attribute__((naked)) __attribute__((optimize("O3"))) __attribute__((section (".init3")));
void _StackPaint(void)
{
uint8_t *ptr = (uint8_t *)&_end;  
while(ptr <= SP)
	*ptr++ = STACK_CANARY_VALUE;
}

uint16_t _StackFreeChecker(void) {
    const uint8_t *ptr = (uint8_t *)&_end;
    uint16_t cntFreeStack = 0;
     
    while(*ptr == STACK_CANARY_VALUE && ptr <= (uint8_t *)RAMEND) {
        ptr++;
        cntFreeStack++;
	}
	return cntFreeStack;
}
Der Code unterstützt aber keine Nutzung eines Heaps.
ch_ris
Beiträge: 3055
Registriert: Mo 30. Nov 2015, 10:08

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von ch_ris »

Hmm...
in das test programm eingebaut:

Code: Alles auswählen

	setup{
	zeuch...
	Serial.begin(115200);
	Serial.println(mus);
	_GetStackSizeMax();
	_GetStackSizeActual();

	overflow();
}
void overflow(){
	_GetStackSizeMax();
	_GetStackSizeActual();
	Serial.println(freeMemory());
	delay(50);
	overflow();
}
ergibt sich:
10 (reset)
Free stack size: 1752
Stack size: 8
Free stack size: 1751
Stack size: 8
1820
Free stack size: 1738
Stack size: 8
1820
Free stack size: 1738
Stack size: 8
1820
usw.
es ändert sich nix mehr.
soll das so? müsste das nicht explodieren?
Benutzeravatar
Mr_T
Beiträge: 101
Registriert: Di 13. Aug 2013, 20:55
Wohnort: SP

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von Mr_T »

ch_ris hat geschrieben: Fr 28. Jul 2023, 12:10 soll das so? müsste das nicht explodieren?
Sehr wahrscheinlich optimiert der Compiler den Funktionsaufruf zu einen einfachen Sprung zurück an den Anfang um. Stichwort: tail-call elimination
virtexultra
Beiträge: 139
Registriert: So 9. Dez 2018, 11:30

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von virtexultra »

Mit der Zeile

Code: Alles auswählen

void overflow()__attribute__((optimize("O0")));
als Deklaration wird ein Funktionsaufruf erzeugt.
ch_ris
Beiträge: 3055
Registriert: Mo 30. Nov 2015, 10:08

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von ch_ris »

probier ich.

zwischenzeitlich hab ich das in's richtige Programm eingebaut.
das Ergebnis vorweg:
Free stack size: 0
Stack size: 41

ich hab ziemlich viele F() macro verwendet, diese entfernt, gleiches Ergebnis.
spaßeshalber hab ich die Methode von init3 verschoben.
init8 führt zu:
Free stack size: 1527
Stack size: 41
und natürlich zum Absturz. es reicht gerade noch für die beiden aufrufe zu beginn von setup()

Ich hab die MStimer2 lib verwendet,
das wichtige raus geschrieben und ohne lib gemacht:
Free stack size: 0
Stack size: 27

tja, das Programm läuft scheinbar, kann aber Zufall sein deucht mich, wenn ich die null angucke.

ansonsten hab ich noch die EEPROM lib und eine eigene Klasse drumherum die das händelt.
in der setup() gutes duzend aufrufe die Variablen aus dem eeprom lesen.
Die Klasse hab ich jetzt auch direkt eingebunden und F() wieder eingebaut, macht keinen Unterschied beim stack.
Free stack size: 0
Stack size: 27

ist hier was auffällig?

Code: Alles auswählen

section                     size      addr
.data                         78   8388864
.text                      11402         0
.bss                         338   8388942
.noinit                        1   8389280
.comment                      17         0
.note.gnu.avr.deviceinfo      64         0
.debug_aranges               512         0
.debug_info                24427         0
.debug_abbrev               3984         0
.debug_line                 8307         0
.debug_frame                1792         0
.debug_str                  3948         0
.debug_loc                 11630         0
.debug_ranges                608         0
Total                      67108
Farbe
Beiträge: 410
Registriert: So 29. Sep 2013, 16:06

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von Farbe »

Oh wow, hier hat sich ja Ganz schön was getan.

Ich hab inzwischen meinen Code etwas vereinfacht und umgeschrieben.

Jetzt tritt der Fehler natürlich nicht mehr auf.

Logisch und funktionell ist der Code gleich, nur spar ich mir 3% Flash Speicher..

Aktuell bin ich noch am verzweifeln was das Wearleveling vom EEPROM angeht.
Ich brauche einen Betriebsstundenzähler.

Problem:
Ich kann das Schreiben beim Brownout nicht verhindern e.g. manchmal liegen Korrupte Daten im Speicher.
und ich hab nur 256byte.
Dazu kommt noch: ich hab keine RTC mit RAM.
(Ich weiß der interne Oszillator ist ungenau, die Abweichung ist aber egal, ich muss es nur auf 1000h genau wissen)

Ich brauch schon 4 Byte für die Manimale und Miximale Temperatur. Die müssen wenigstens nicht "gewearlevelt" werden.
Der Stundenzähler schon.

Um nicht zuviel bei jedem Ausschalten zu verlieren, würd ich gerne jede Minute Schreiben.
Eine 16 Bit Zahl reicht dann nicht, das sind nur 45 Tage maximal, 24 Bit sollten es schon sein.
Das sind zwar 32 Jahre = zuviel, eine 22 Bit Zahl sollte reichen (8 Jahre) bringt beim Speichern aber keinen Vorteil. (oder ich seh ihn nicht)

Ich dachte daran die Zahl direkt als long (4byte), da komme ich beim benutzen der vollen 250 bytes auf 12 Jahre bevor der EEPROM zerschrieben ist.
Das dumme ist, das ich noch keine vernünftige Idee hatte um den "ausschalten beim schreiben" case abzufangen.
Dafür müsste ich 3x speichern. Damit bin ich dann bei nur 4 Jahre und wenn es die Control Bytes trifft ist trotzdem aus.

Wenn ich als 3 Byte Zahl speichere, kann ich das MSByte 3x Speichern da das in den 31 Jahren ja nur 260x geschrieben wird.
Das nächste Byte wird noch 64000 mal in 31 Jahren geschrieben, reicht also auch 3x Speichern ohne Wearleveling aus.

Damit bleiben noch 243 Byte EEPROM fürs Wearleveling vom LSByte. Wenn ich da auch 3x Speichere komme ich immerhin auf 15 Jahre die das LSByte "hält"

Positiv wäre das ich da maximal 4,25h Betriebszeit verliere wenn das mal kaputt wäre. Die Betriebszeit ist meist länger als 5h und würde damit trotzdem noch ungefähr mitzählen.

Ich muss mir nur was überlegen wie ich das Wearleveling für das LSByte mache.
3x direkt hintereinander Schreiben (ohne Control Bits) und dann beim Start die höchste Adresse mit 2x dem selben Wert raussuchen?

Edit:
3x Schreiben fürs LSByte ist quatsch, ich weiß das die Zahl immer größer werden muss und damit sollte nacheinander Schreiben super funktionieren.
Ich kann beim Start dann einfach die höchste Zahl in der kleinsten Adresse suchen, bei der eine Adresse vorher der Wert um 1 kleiner ist.


Sollte gehen oder hab ich einen Denkfehler?
Benutzeravatar
sukram
Beiträge: 3119
Registriert: Sa 10. Mär 2018, 18:27
Wohnort: Leibzsch

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von sukram »

Du solltest zumindest bei dem Betriebsstundenzähler auch eine plausible Steigerung abprüfen. Nicht dass von einem Eintrag zum nächsten 10 Jahre Abstand drin sind.

Alternative: Alle Daten zusammen als Block schreiben. Der Datensatz mit dem höchsten plausiblen Betriebsstundenzähler gewinnt - damit musst du nicht mehrere Schreibstrategien einbauen. Und kannst den gesamten Eprom wie einen Ringspeicher beschreiben.
virtexultra
Beiträge: 139
Registriert: So 9. Dez 2018, 11:30

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von virtexultra »

ch_ris hat geschrieben: Fr 28. Jul 2023, 17:02 ich hab ziemlich viele F() macro verwendet, diese entfernt, gleiches Ergebnis.
spaßeshalber hab ich die Methode von init3 verschoben.
init8 führt zu:
Wichtig wäre zu prüfen ob der Code überhaupt funktioniert. Also ob der erste Aufruf von _GetStackSizeMax einen "sinnvollen" Wert zurückliefert.

Momentan klingt das nach: Irgendein Konstruktor/sonst was der nach init3 ausgeführt wird schreibt in den Bereich nach der Speichermarke __end. Also nach der Speichermarke befindet sich somit ein Wert der nicht STACK_CANARY_VALUE enstpricht. Somit ist das die falsche Speichermarke. Das könnte jetzt z.B. dynamische Allokation sein.
ch_ris
Beiträge: 3055
Registriert: Mo 30. Nov 2015, 10:08

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von ch_ris »

in einem blanken programm, hab zusätzlich einen Zähler eingebaut.
wenn die Rechnung so Sinn macht, es keinen heap noch nicht gibt bei init3,
dann müsste es ja erst mal stimmen.?
Stack+data+bss+noinit
2023-07-29 06_39_26-YAT - [[Terminal1 _] - COM1 - Open - Connected].png
edit
8-) Bösewicht waren 2 String Objekte in meinem EEprom wrapper.
ja nu, die ist von 2018, hab's übersehen.
durch char* ersetzt:

Free stack size: 1219
von 1273
Stack size: 41

ob das jetzt schlimm war,
oder nur der Speicher voll ausgenutzt während der Initialisierung?
ch_ris
Beiträge: 3055
Registriert: Mo 30. Nov 2015, 10:08

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von ch_ris »

habe die Sensor Ereignisse, auf die das normalerweise reagiert,
mittels Konsole simuliert.
Durch eine massive Maus Klick Attacke konnte ich einen Reboot provozieren.
Stack und Heap waren dabei scheinbar im grünen Bereich.
Nach/beim/vorm Reboot hats das eeprom zerschossen, so das keine Meldungen mit der Reboot Ursache geschrieben wurden.
komischerweise nur den unteren Bereich bis Byte ~18, da wo die Programm variablen stehen.

Nachdem ich das Problem beseitigt hab, klappts nicht mehr mit dem Reboot, hab schon einen Krampf im Finger.
Scheinbar wars das eeprom bzw das drumherum.
edit. obwohl der watchdog mit 30ms recht scharf gestellt ist, eeprom schreiben dauert 21ms. ich hab ein gutes Gefühl.
virtexultra
Beiträge: 139
Registriert: So 9. Dez 2018, 11:30

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von virtexultra »

Freut mich das es nun funktioniert. Es hätte mich gewundert wenn der Stack ursächlich gewesen wäre. Magst du uns noch verraten was die Problematik mit dem EEPROM war?
ch_ris
Beiträge: 3055
Registriert: Mo 30. Nov 2015, 10:08

Re: Bit-Frickelei, wie uC Abstürze beheben?

Beitrag von ch_ris »

ich hab einen zählerwert auf den eeprom bereich nicht auf Plausibilität geprüft. da stand dann 19564 drin oder so. schwierig bei max 1024.
:?: jedenfalls ist seit Änderung kein ungewollter reboot mehr passiert.
Antworten