-
        

Ergebnis 1 bis 5 von 5

Thema: Problem mit Watchdog [gelöst]

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    06.08.2008
    Ort
    Graz
    Beiträge
    502

    Problem mit Watchdog [gelöst]

    Anzeige

    SMARTPHONES & TABLETS-bis zu 77% RABATT-Kostenlose Lieferung-Aktuell | Cool | Unentbehrlich
    Ich kämpfe jetzt gerade mit dem Watchdog, und zwar gibt es das Problem dass er, wenn er angeschlagen hat, in einer Endlos Reset Schleife gefangen ist.
    Ich hab den empfohlenen Code aus der AVR Lib eingefügt mit dem man den Watchdog schnell abschalten kann, nutzt aber nichts:
    Code:
    unsigned char 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();
        }
    Und am Anfang von main steht das:
    Code:
        if (mcusr_mirror & (1 << WDRF))
        {
        LED_gr_ein;LED_rot_ein;
        lcd_gotoxy(0,0);lcd_puts_p(PSTR("!WATCHDOG! "));
        Motor_li_stop();Motor_re_stop();Mower_faststop();
        while(1);
        }
    
        else wdt_enable(WDTO_1S);
    
    sei();
    Ist ein Atmega644 mit 16Mhz mit max Startup Zeit für den Quarz. Die Watchdog Fuse ist deaktiviert, habs auch schon mit und ohne Fuse getestet.

    Was kann man noch probieren?

    LG!
    alles über meinen Rasenmäherroboter (wer Tippfehler findet darf sie gedanklich ausbessern, nur für besonders kreative Fehler behalte ich mir ein Copyright vor.)

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    06.08.2008
    Ort
    Graz
    Beiträge
    502
    Hat da keiner eine Idee?

    Im AVR Studio mit Simulator 1 kommt es wie auch in der Realität zu endlosen Resets, mit Simulator 2 funktioniert der Code.

    Und warum will der Atmega644 nicht?

    LG!
    alles über meinen Rasenmäherroboter (wer Tippfehler findet darf sie gedanklich ausbessern, nur für besonders kreative Fehler behalte ich mir ein Copyright vor.)

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    29
    Beiträge
    4.545
    Kannst du den gesamten Code posten. Wäre leichter den Fehler zu finden.

    MfG Hannes

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    06.08.2008
    Ort
    Graz
    Beiträge
    502
    Ich glaube kaum dass 4500 Zeilen für mehr Übersicht sorgen, deshalb hier genau die Teile die das Programm beim Start durchläuft


    Code Anfang:
    Code:
    #ifndef F_CPU
    #define F_CPU 16000000
    #endif
    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <stdlib.h>
    #include <lcd.h>
    #include <math.h>
    #include <string.h>
    #include <avr/pgmspace.h> 
    #include <i2cmaster.h>
    #include <avr/eeprom.h>
    #include <avr/wdt.h> 
    
    
    unsigned char mcusr_mirror __attribute__ ((section (".noinit"))); // Watchdog ausschalten
    
    void get_mcusr(void) \
          __attribute__((naked)) \
          __attribute__((section(".init3")));
        void get_mcusr(void)
        { 
         mcusr_mirror = MCUSR;
         MCUSR = 0;
    	 wdt_disable();
        }
    
    #define LED_gr_ein	(PORTB &= ~(1<<PB0))
    #define	LED_gr_aus	(PORTB |= (1<<PB0))
    #define	LED_rot_ein	(PORTB &= ~(1<<PB1))
    #define	LED_rot_aus	(PORTB |= (1<<PB1))
    danach kommen defines und globale Variablen, kein setzen von Registern!

    Diese Interrupts sind definiert:
    Code:
    /* Interrupts */
    volatile unsigned char timecount;
    volatile short radcount,i_summe,v_alt;
    volatile unsigned char odo_messer,odo_m;
    
    ISR(ISR_Timer2)
    {
    timecount++; if (timecount>250) timecount=250;
    radcount++; if (radcount>10000) radcount=10000;
    
    //static short ;
    short v, mowersp;
    
    if (timecount==25)	
    	{timecount++;
    	odo_m=odo_messer;
    	odo_messer=0;
    
    		if (messer_aus==0)
    			{
    			v = (short)(drehzahl-odo_m);					//Vergleich
    			i_summe = i_summe + v;							//Integration I-Anteil //mit "vergessen": (i_summe*9)/10 + v;
    			if (i_summe < -1280) i_summe = -1280;	        //Begrenzung I-Anteil
    			if (i_summe > 1280) i_summe = 1280;
    
    		//	mowersp=1*v+3*(i_summe*25)/100+1*((v -v_alt)*100)/25;	// stabile Ausgangsbasis
    		//	mowersp=(3*v+5*((i_summe)/4)+3*((v -v_alt)*4)+320)/4; // 320 (320/4=80) als Startwert, alles /4 für geringe PWM Stufung
    			mowersp=(5*v+3*((i_summe)/4)+5*((v -v_alt)*4)+560)/7;
    			v_alt=v;
    
    			if (mowersp < 40) mowersp = 40;			//Begrenzung Stellgröße
    			if (mowersp >= 255) mowersp = 255;
    	
    			mowerspeed=(unsigned char)(mowersp);
    			Mower=mowerspeed;
    			}
    	}
    }
    
    
    
    
    ISR(INT2_vect)
    {odo_messer++;}
    
    
    ISR(PCINT0_vect)
    {
    radcount=0;
    }
    
    SIGNAL (__vector_default) // falsche Interrupt erkennen, abbrechen
    {cli();PORTC &= ~( (1<<PC2) | (1<<PC3) );PORTC &= ~( (1<<PC4) | (1<<PC5) );PORTC |= (1<<PC6) | (1<<PC7);
    lcd_gotoxy(0,0);lcd_puts_p(PSTR("Bad Interrupt "));
    while(1);
    }

    und hier der Anfang von main:

    Code:
    int main(void)
    {
    //char buffer[10];
    short richtung_temp, richtung_soll,x_temp,y_temp;
    char korr_l,korr_r, modus;
    unsigned short speed_li, speed_re, felder,speed_fakt;	//
    unsigned char x,y, z, sekunde, sekk, sekkk,sek_f, min,minstd,temp; //, odo_m, sek_gps 
    
    modus=0;
    
    richtung_soll=1;korr_l=0;korr_r=0;
    sekunde=0;sekk=0;sekkk=0;sek_f=0; min=0;minstd=0;
    radcount=0;odo_m=0;
    x_temp=0;y_temp=0;
    
    
    //odo_li=14;odo_re=4;pos_x=2000;pos_y=1800;richtung=4700;Pos_odo(0); // Odometrie Test für Simulator
    //pos_x=300;pos_y=1300;GotoXY(1000,1300,1); // Test Navi
    
    // Watchdog   
    	LED_rot_aus;LED_rot_aus; 
    
        // Watchdog-Reset 
        if (mcusr_mirror & (1 << WDRF))
        {
    	LED_gr_ein;LED_rot_ein;
    	while(1);
    	}
    
    	else wdt_enable(WDTO_1S);
    
    
    
    sei(); //Interupt ein
    
    while(1); //Test für Watchdog
    
    init(); //Porteinstellungen, PWM, LCD
    
     
    lcd_clrscr();
    i2c_init();
    Hier habe ich die Wachtdog Abfrage ganz am Anfang eingebaut, hier extra für den Test noch bevor die einzelnen Register für I/O, PWM, LCD, USART; TWI etc gesetzt werden.

    Und genau dieser Code funktioniert im Simulator, nach 1s schlägt der Watchdog an, beim Neustart erkennt er das WDRF gesetzt ist, "schaltet" die LED's ein und bleibt wie er soll dort in der while Schleife.

    Am Atmega funktioniert das nicht, sieht so aus als hängt er in endlosen Resets fest. Anscheinend wird der Watchdog am Anfang nicht ausgeschalten, aber das soll genau dieser Beispielcode aus der GCC lib erledigen.

    LG!
    alles über meinen Rasenmäherroboter (wer Tippfehler findet darf sie gedanklich ausbessern, nur für besonders kreative Fehler behalte ich mir ein Copyright vor.)

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    06.08.2008
    Ort
    Graz
    Beiträge
    502
    Hab den Fehler gefunden, weil es immer heisst die Watchdog Erkennung ganz am Anfang des Programmes einzubauen war er einfach zu weit vorne.
    alles über meinen Rasenmäherroboter (wer Tippfehler findet darf sie gedanklich ausbessern, nur für besonders kreative Fehler behalte ich mir ein Copyright vor.)

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •