Problem mit switch



  • Ich schreibe einen Treiber für die Schnittstellen bei einem Power Pc Evaluation Board. Jetzt habe ich bei einem dieser Module eine Switch anweisung um auf verschiedene Register aufzuspalten. Die Anweisung sieht so aus.

    switch (channel)
    {
    case 1:
    break;
    .
    .
    .

    default
    break;
    }

    In der Variable channel steht 16 Drinn und es ist natürlich ein case für 16 Vorhanden. Wenn ich statt der Variable channel die Zahl 16 reinschreibe läuft alles wunderbar, wenn ich aber die Variable drinnlasse hängt sich das Programm komplett auf, genau an der Switch Anweisung. In der Variable steht definitiv 16 drinn. Sie ist vom Typ unsigned short, also ein UINT16.

    Kennt jemand das Problem ?

    Ich hab mittlerweile die komplette code Optimization ausgeschaltet. Ach ja ich verwende den Diab5.0a kompiler für Power Pc.

    Danke

    Tom



  • @Tom555,

    kannst du deinen Code debuggen?
    Normalerweise kann bei soetwas kein Fehler auftreten.

    unsigned short iVal = 16;
    ...
    switch ( iVal )
    {
      case 16:
        /* [1] Mache irgendetwas */
        break;
      default:
        ...
    };
    

    Was steht bei dir nach case 16 ?.
    Ich vermute, dass der Fehler dort liegt.

    Bye Peter.



  • Nein der Fehler liegt definitiv nicht an dem was im Case ausgeführt wird, denn wenn ich statt der Variable die 16 gleich einsetze kommt er ja dorthin. Ausserdem habe ich eine Debugausgabe am Anfang vom Case stehen, dann würde er noch was ausgeben bevor er sich verabschiedet. Das komische darin ist das folgende. Ich habe in dem switch 21 cases stehen. Wenn ich die 5 cases hinter der 16 wegmache dann gehts. Wenn die wieder da sind schmiert er wieder ab.



  • dann mach uns ein minimalbeispiel



  • Hi

    Hast vielleicht nen break vergessen sodass er zum nächsten case weiter geht nach 16 ?



  • Ich poste euch mal den Code:

    /********************************************************************************************
    | Name:		      PWM_SET_SYNC
    | Called by:	  MIOS
    | Preconditions:  none
    | Period Type  :  none
    | Inputs:         PWM Channel, Dutycycle in Prozent
    | Return Value :  none
    | Description  :  This Function Sets the Duty Cycle for the specified Port
    *********************************************************************************************/
    
    void PWM_SetSync (IO_ChannelType channel, IO_ValueType dutycycle)
    {
    	/* Temp Variables for dutycycle Calculations */
    
    	UINT16 var1,var2;
    
    	/* Check for Invalid dutycycle value */
    	if ( dutycycle < 0 || dutycycle > 100)
    	{
    		ErrorHook(PWM,SET_ERROR,IO_E_INVALID_VALUE);
    
    	}
    	else
    	{
    		/* Set Dutycycle for specified channel or return Error for invalid Channel */
    		switch (channel)
    		{
    
    		case 0:
    		var1 = MIOS14.MPWMSM0PERR.R;
    		var2 = dutycycle * var1 / Exp (2,16);
    		MIOS14.MPWMSM0PULR.R = var2;
    		break;
    
    		case 1:
    		var1 = MIOS14.MPWMSM1PERR.R;
    		var2 = dutycycle * var1 / Exp (2,16);
    		MIOS14.MPWMSM1PULR.R = var2;
    		break;
    
    		case 2:
    		var1 = MIOS14.MPWMSM2PERR.R;
    		var2 = dutycycle * var1 / Exp (2,16);
    		MIOS14.MPWMSM2PULR.R = var2;
    		break;
    
    		case 3:
    		var1 = MIOS14.MPWMSM3PERR.R;
    		var2 = dutycycle * var1 / Exp (2,16);
    		MIOS14.MPWMSM3PULR.R = var2;
    		break;
    
    		case 4:
    		var1 = MIOS14.MPWMSM4PERR.R;
    		var2 = dutycycle * var1 / Exp (2,16);
    		MIOS14.MPWMSM4PULR.R = var2;
    		break;
    
    		case 5:
    		var1 = MIOS14.MPWMSM5PERR.R;
    		var2 = dutycycle * var1 / Exp (2,16);
    		MIOS14.MPWMSM5PULR.R = var2;
    		break;
    
    		case 16:
    		var1 = MIOS14.MPWMSM16PERR.R;
    		var2 = dutycycle * var1 / Exp (2,16);
    		MIOS14.MPWMSM16PULR.R = var2;
    		break;
    
    		case 17:
    		var1 = MIOS14.MPWMSM17PERR.R;
    		var2 = dutycycle * var1 / Exp (2,16);
    		MIOS14.MPWMSM17PULR.R = var2;
    		break;
    
    		case 18:
    		var1 = MIOS14.MPWMSM18PERR.R;
    		var2 = dutycycle * var1 / Exp (2,16);
    		MIOS14.MPWMSM18PULR.R = var2;
    		break;
    
    		case 19:
    		var1 = MIOS14.MPWMSM19PERR.R;
    		var2 = dutycycle * var1 / Exp (2,16);
    		MIOS14.MPWMSM19PULR.R = var2;
    		break;
    
    		case 20:
    		var1 = MIOS14.MPWMSM20PERR.R;
    		var2 = dutycycle * var1 / Exp (2,16);
    		MIOS14.MPWMSM20PULR.R = var2;
    		break;
    
    		case 21:
    		var1 = MIOS14.MPWMSM21PERR.R;
    		var2 = dutycycle * var1 / Exp (2,16);
    		MIOS14.MPWMSM21PULR.R = var2;
    		break;
    
    		default:
    		ErrorHook(PWM,SET_ERROR,IO_E_INVALID_CHANNEL_ID);
    		break;
    		}
    
    	}
    
    }
    

    Also ich hab vor dem Switch schon eine Debugausgabe gemacht, das Switch erreicht er auf jeden Fall. Wenn ich die Variable channel mit einer 16 austausche gehts auch, wenn die Variable drinnsteht semmelt er ab.



  • bitte ein beispiel, dass wir kompilieren und selber testen können...

    btw: bist du dir sicher, dass ein MIOS14.MPWMSM17PULR-Array nicht vielleicht besser wäre?



  • Nein, Arrays kann ich nicht nehmen, das sind direkt die namen der Register des Prozessors, dahinter verbirgt sich eine Speicheradresse. Das geht nicht mit arrays.

    Ein Beispiel zum kompilieren und ausprobieren wird schwer sein, ausser ihr habt ein MPC564EVB Evaluation Board von der Firma Axiom.



  • Hast du schon mal versucht channel in einen normalen integer umzuwandeln und dann abzufragen? (Nur mal so ne Idee)



  • @AJ:

    Ja hab ich auch schon, ich habs schon in einen char gecastet, in einen UIN16, in einen normalen int und in alle möglichen unsigned ints.



  • @Tom555,

    ich schlag vor du schreibst ein neues kleines
    Testprogramm indem nur diese switch-Konstrukt
    vorkommt. Auch ohne den Code innerhalb des switch.

    int main( void )
    {
      unsigned short iVal = 16;
    
      switch ( iVal )
      {
        case 16:
          iVal = 100;
          break;
        default:
          iVal = 0;
      };
    
      return 0;
    };
    

    Wenn diese Code bei dir läuft liegt es auf keinen Fall
    an deinem switch, sondern hakt an einer anderen Stelle
    in deinem Code.

    Bye Peter.



  • Ich hab grad mal noch mal geschaut und voller schrecken mitbekommen, das er mir auch bei einem anderen Switch aussteigt wenn ich das aufrufe. Genau die gleichen Symptome. Wenn ich eine Variable einfüge stürzt das switch ab, wenn ich dei Zahl direkt reinschreibe läuft es durch.



  • Hi ich hab da so ne Vermutung.

    MSDN schrieb:

    Microsoft C does not limit the number of case values in a switch statement. The number is limited only by the available memory. ANSI C requires at least 257 case labels be allowed in a switch statement.

    Wenn du dann einen festen wert in switch einträgs wird der Code optimiert und die also nur die eine Case anweisung kann ja ablaufen.

    Mfg TheBender



  • Naja da steht das im Case 257 Stück erlaubt sind, ich hab grad mal 20 drinn. Das mit dem optimieren könnt ich mir schon vorstellen, aber wenn er das case ausführt wenn ichs direkt anspreche, wieso nicht wenn ich ne Variable einsetze. Irgendwas muss mit der Variable schiefgehen.

    [EDIT]

    Ich hab jetzt mal Spaßeshalber die ganzen switch rausgekickt und alles mit einzelnen if Anweisungen gemacht, und sofort geht es auch. Nur ist das halt ein schlechter Stil und ich will es eigentlich nicht so lassen, aber mir fällt echt langsam nix mehr ein.



  • MSDN schrieb:

    Microsoft C does not limit the number of case values in a switch statement. The number is limited only by the available memory. ANSI C requires at least 257 case labels be allowed in a switch statement.

    Der Satz könnte noch wichtig sein. Hast du schon mal überprüft, wieviel Speicher du überhaupt noch zur Verfügung hast?



  • Der Speicher reicht locker, ich hab 512 K und mein Programm hat alles in allem vielleicht mal grad 50 K



  • Arbeitsspeicher oder "Festplatten"speicher?



  • Ich glaube manche haben mein erstes Posting nicht gelesen oder ? Ich schrieb da das es um einen Power Pc auf einem Evaluation Board geht ? Da gibts keine Festplatten. Das ist ein Microcontroler mit Flash Speicher.



  • Ich wollte mit meinem Posting nicht auf die größe des Arbeitsspeicher aufmerksam machen sondern auf deinen Compiler vielleicht hatt der bei Switch() ne begrenzung von 8 oder so.

    Du kannst ja mal probieren die switchanweisung zu begrenzen z.B:
    case 1:
    bla
    case 2:
    bla
    default:
    bla

    Mfg TheBender



  • @Tom
    Darum habe ich auch "Festplatte" in Anführungszeichen gesetzt. Ich meinte damit eigentlich deinen Speicher auf deinem Chip oder sonst was. Aber das ändert im Endeffekt nicht meine Frage. Meinst du nun mit den 512K deinen Flashspeicher oder deinen Arbeitsspeicher.



  • Ich würd mal nach Assembler compilieren und mir das angucken ...
    Wenn alles nichts hilft, würd ich mich mit Usern dieser Plattform zusammensetzen, gibt bestimmt ne Newsgroup oder Mailingliste zum Thema. Es ist anscheinend auf jeden Fall irgendwas faul, auf dass du rein mit C-Mitteln einen Einfluss hast.


Anmelden zum Antworten