mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik RST bei Buffernutzung


Autor: Timo P (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

ich bekomme immer einen RST, mehr kann mein code nicht...?!?
ATMEGA32 mit WINAVR, AVRStudio 4

#define BUFFER_SIZE 70  //buffergröße in Byte
volatile unsigned char buffer[BUFFER_SIZE] = "";

void kill_buffer()
{
  pread = 0;
  pwrite = 0;
  for(int ui1=0;ui1<BUFFER_SIZE;ui1++)
  {
    buffer[ui1]="";
    _delay_us(1000);
  }
}

int main()
{
  uart_puts("RST\r\n");
  kill_buffer();
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei aller Liebe.

Aber was ist jetzt die Frage?

Autor: Timo P (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"" entspricht doch '\0' was einem C-String-Ende entspricht. warum kann 
ich das nicht auch an alle stellen schreiben?

Autor: Bohrer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Liegt am ungüstigen Variablennamen -> der Compiler optimiert die 
weiteren Durchläufe weg!

ändere "ui1" zb. zu "dhka"

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timo P schrieb:
> int main()
> {
>   uart_puts("RST\r\n");
>   kill_buffer();

  while(1)
    {
    }

> }

Da fehlt die abschließende Endlosschleife, da sonst das weitere 
Verhalten des uC nicht definiert ist (Reset, Programmneustart,...)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timo P schrieb:
> "" entspricht doch '\0' was einem C-String-Ende entspricht. warum kann

Nein das tut es nicht.
"" enstpricht an dieser Stelle der Startadresse eines leeren Strings, 
der irgendwo im Speicher liegt.

Strings kann man nicht einfach so zuweisen.


Die Frage ist aber eigentlich:
Was ist eigentlich genau deine Frage?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Floh schrieb:
> Timo P schrieb:
>> int main()
>> {
>>   uart_puts("RST\r\n");
>>   kill_buffer();
>
>   while(1)
>     {
>     }
>
>> }
>
> Da fehlt die abschließende Endlosschleife, da sonst das weitere
> Verhalten des uC nicht definiert ist (Reset, Programmneustart,...)

Im Grunde hast du recht.
Allerdings schickt die gcc-Runtime nach einem return von main() den µC 
in eine Endlosschleife. So gesehen ist das Verhalten (beim gcc) 
definiert.

Autor: Timo P (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
meine Frage ist, warum ich einen Reset bekomme ab einer Buffergröße 
größer als 60

Autor: Timo P (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ps:

mein main hat eine for(;;) schleife in der der UART-RX-buffer abgefragt 
wird

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timo P schrieb:
> ps:
>
> mein main hat eine for(;;) schleife in der der UART-RX-buffer abgefragt
> wird

Dann zeig bitte das richtige Programm. OK?

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Allerdings schickt die gcc-Runtime nach einem return von main() den µC
> in eine Endlosschleife. So gesehen ist das Verhalten (beim gcc)
> definiert.

Wieder was gelernt :-)

Timo P schrieb:
> mein main hat eine for(;;) schleife in der der UART-RX-buffer abgefragt
> wird

davon seh ich nichts im Programmausschnitt??

Wie wärs wenn du mal genau beschreibst, was du erreichen willst, und 
dann, was stattdessen passiert?

Autor: Timo P (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok....
int main( void )
{
  DDRA |= (1<<PIN);
  char s[22];
  unsigned char flag1,flag2,flag3,flag4;
    DDRC |= 0x01;
  PORTC |= 0x01;
  DDRB &= ~(1<<1);               // Conf. pin for recv. control signal 
  DDRD &= ~(1<<LIMIT_SWITCH_IN_PIN);  // Conf. pin for limit switch
  DDRD &= ~(1<<LIMIT_SWITCH_OUT_PIN);  // Conf. pin for limit switch
  DDRD |=  (1<<INSERT_PIN);        // Conf. pin for inserting "Falle"
  DDRD |=  (1<<RELEASE_PIN);        // Conf. pin for releasing "Falle"
    send = 0;
    _delay_ms(100);
    uart_init(BAUD);
  _delay_ms(100);
  strcpy(buffer, "");
    sei();
  uart_puts("RST\r\n");        // Reset of Hardware
  sprintf(s,"Buffersize:%d\r\n",BUFFER_SIZE);
  uart_puts(s);
  kill_buffer();
  
  unsigned char trigger = 0;
  unsigned char tmp = EEPReadByte(IS_CONFIGERD);
  //sprintf(s,"IS_CONFIGERD:%X\t\r\n",tmp);     // EEPROM-Wert von Adresse 0x20 lesen 
  //uart_puts(s);

    for(;;)
    {
    //if(RESET_PORT&(1<<RESET_PIN))EEPWriteByte(IS_CONFIGERD, 0x01);
    _delay_ms(10);
    sprintf(s,"<%s> \r",buffer);uart_puts(s);

    
     if(strstr(buffer,"\n"))    // command oder command-artiges erhalten
     {
       cli();
      if(strstr(buffer,"config:start\n"))  
        {
        kill_buffer();
        uart_puts("config:start:OK\n");
        sei();

      }
      else if(strstr(buffer,"config:end\n"))    // Request Pin switchen
        {
        kill_buffer();
        uart_puts("\t\t\t\tconfig:end:OK\n");
        EEPWriteByte(IS_CONFIGERD, 0x01);   // write Flag if configuration ist set
        sei();
      }      
       else if(strstr(buffer,"00T\n"))      // Anfrage Pin switchen
        {
        kill_buffer();
        PORTA ^= (1<<PIN);
//*****************************************************************************************************************
//PORTD ^= (1<<6);         // Insert "Falle"
//*****************************************************************************************************************
        if(trigger == 1)trigger = 0;
        if(trigger == 0)trigger = 1;
        uart_puts("00TOK\n");
        
      }
      else if(strstr(buffer,"00S\n"))      // Statusanfrage
        {
        kill_buffer();
        if(PORTA&(1<<PIN))uart_puts("00S1\n");
        if((PORTA&(1<<PIN)) == 0)uart_puts("00S0\n");
        
      }
      else if(strstr(buffer,"PING\n"))
        {  
        kill_buffer();
        uart_puts("PONG\n");      
      }
      else if(strstr(buffer,"set:ssid\t"))  // set:ssid\ta1b2c3d4\t\n
        {  
        int i = 9,j = 0;
        
        while(buffer[i] != '\t')
        {
          ssid[j] = buffer[i];
          i++;
          j++;
        }
        kill_buffer();
        sprintf(s,"<%s>",ssid);  uart_puts(s);
        uart_puts("set:ssid:OK\n");            
      }
      else if(strstr(buffer,"set:key\t"))  // set:ssid\ta1b2c3d4\t\n
        {  
        int i = 8,j = 0;
        
        while(buffer[i] != '\t')
        {
          key[j] = buffer[i];
          i++;
          j++;
        }
        kill_buffer();
        sprintf(s,"<%s>",key);  uart_puts(s);
        uart_puts("set:key:OK\n");            
      }

      else kill_buffer();
  
      sei();  
    } //if(strstr(buffer,"\n"))





//*****************************************************************************************************************
//* auskommentiert für manuelle Fallenkontrolle in eine Richtung, siehe oben PORT..^=...
//*****************************************************************************************************************

    if(trigger && open_signal == 0)
    {
      open_signal = 1;   // For remaining control signal
      uart_puts("open_signal =1\r\n");
      }
    if(open_signal && !flag1 && !flag2 && !flag3)
    {
      PORTD |= (1<<6);         // Insert "Falle"
      uart_puts("insert an D6\r\n");
      flag1 = 1;
    }  
    if(open_signal && flag1 && (PIND & (1<<5)))    // reaching limit switch
    {
      uart_puts("insert stop, release an D7\r\n");
      PORTD &= ~(1<<6);      // Einfahrt stoppen
      _delay_ms(100);
      PORTD |=  (1<<7);      // Ausfahrt starten
      flag2 = 1;
      flag1 = 0;
    }

    if(open_signal && (PIND & (1<<4)) && flag2)// reaching limit switch
    {
      PORTD &= ~(1<<RELEASE_PIN);
      flag1 = 0;
      flag2 = 0;
      open_signal = 0;
      uart_puts("release_pin aus, open_signal aus\r\n");
    }


//*****************************************************************************************************************

    } // for(;;)

  return(0);
}    // main()



Autor: Timo P (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ floh:

passiert:
Ständiger Reset! sehe ich an meiner RST\r\n Ausgabe

soll passieren:
µC resettet nicht in einer Tour, ohne überhaupt in meine foreverschleife 
zu gelangen...., da vor dem for(;;) der Code den µC zum Reset zwingt...

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich sehe keine Interrupt-Routinen, warum aktivierst du über sei() die 
Interrupts?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dein Absturz wird höchst wahrscheinlich hier seinen Ursprung nehmen

    sprintf(s,"<%s> \r",buffer);uart_puts(s);

dein killBuffer hinterlässt nun mal in buffer keinen leeren String. 
Damit knallst du mit Sicherheit zuallererst einmal weit über die Grenzen 
von s drüber.

Das es mit Buffergrößen kleiner 60 scheinbar(*) funktioniert ist Zufall. 
Da erwischt du nur einfach nicht das richtige Byte um das komplette 
System zum Crashen zu bringen.

Um einen Buffer, der sowieso nur einen String aufnehmen kann zu löschen, 
vulgo den String auf einen Leerstring zu setzen, genügt es das erste 
Byte davon auf '\0' zu setzen. Man muss nicht durch das Array durchgehen 
und jedes einzelne Byte auf '\0' setzen.


(*) wie gesagt: scheinbar
Du hast trotzdem einen Fehler. Du siehst ihn nur nicht, weil du zufällig 
die falschen Bytes im Speicher zerstörst.

Autor: Timo P (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
weil ich die Interrupts nutzen möchte, aktiviere ich sie auch. Die ISR 
arbeitet wunderbar, wenn ich die Buffersize kleiner als 61 wähle!

Falls es interessiert hier die ISR für den uart-empfang:

ISR (USART_RXC_vect)
{
  buffer[pwrite]=UDR;
  pwrite++;
  if(pwrite >= BUFFER_SIZE) pwrite=0;
}

Autor: Timo P (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Um einen Buffer, der sowieso nur einen String aufnehmen kann zu löschen,
> vulgo den String auf einen Leerstring zu setzen, genügt es das erste
> Byte davon auf '\0' zu setzen. Man muss nicht durch das Array durchgehen
> und jedes einzelne Byte auf '\0' setzen.

ich überprüfe, ob ich ein config:start\n empfangen habe. dazu nutze ich 
strstr(). Wenn ich aber nun den Buffer nur an [0] auf '\0' setze, sind 
die anderen Zeichen nicht automatisch weg oder?

Oder sucht die Funktion strstr() nur bis zum \0 Zeichen?
Dann wäre das eine Lösung, mit kill_buffer nur die erste Stelle auf das 
Stringendezeichen zu setzen...

THX für weitere antwort

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timo P schrieb:
> Karl heinz Buchegger schrieb:
>> Um einen Buffer, der sowieso nur einen String aufnehmen kann zu löschen,
>> vulgo den String auf einen Leerstring zu setzen, genügt es das erste
>> Byte davon auf '\0' zu setzen. Man muss nicht durch das Array durchgehen
>> und jedes einzelne Byte auf '\0' setzen.
>
> ich überprüfe, ob ich ein config:start\n empfangen habe. dazu nutze ich
> strstr(). Wenn ich aber nun den Buffer nur an [0] auf '\0' setze, sind
> die anderen Zeichen nicht automatisch weg oder?

Richtig - Sind sie nicht.
Aber wen kümmerts?

Ein String ist mit dem ersten '\0' Zeichen zu Ende. Was dann noch 
dahinter kommt interessiert keinen. Auch die str... Funktionen wissen 
das und halten sich daran. So sind Strings in C nun mal definiert.

> Oder sucht die Funktion strstr() nur bis zum \0 Zeichen?

An dieser Stelle ist dann der Hinweis auf ein C-Buch angebracht

> Dann wäre das eine Lösung, mit kill_buffer nur die erste Stelle auf das
> Stringendezeichen zu setzen...

Und mach dein s größer!
Wenn im Extremfall dein Buffer voll ist, dann ist da ein String der 
Länge 70 drinnen. Der wird aber kaum in s (mit 22 Zeichen) reinpassen!

Autor: Timo P (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok, s ist vergrößert.
ich habe nun in der kill_buffer() nur noch buffer[0] = '\0' gesetzt.

Nun empfange ich nur noch Müll! wenn ich per Terminalprogramm Zeichen 
eintippe, empfange ich sie nur noch einzeln wenn ich mal ein \n drin 
hatte....

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh Himmel
      while(buffer[i] != '\t')
        {
          ssid[j] = buffer[i];
          i++;
          j++;
        }
        kill_buffer();
        sprintf(s,"<%s>",ssid);  uart_puts(s);

Da fehlts ja an allen Ecken und Enden in der Stringverarbeitung

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timo P schrieb:
> ok, s ist vergrößert.
> ich habe nun in der kill_buffer() nur noch buffer[0] = '\0' gesetzt.
>
> Nun empfange ich nur noch Müll!

Aber du hast keinen Absturz mehr.

Also: -> nächsten Fehler suchen! UNd du hast noch viele im Programm.

Autor: Timo P (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mein Programm hat ja mal gelaufen, als die Buffer kleiner waren!
Ich konnte z.B. erfolgreich eine ssid, die übergeben wurde, 
interpretieren.

denken kann ich mir aber, dass hier gemeint ist, dass ich die 
string-token funktion nutzen soll...

Wo hab ich denn noch Fehler?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timo P schrieb:

> ISR (USART_RXC_vect)
> {
>   buffer[pwrite]=UDR;
>   pwrite++;
>   if(pwrite >= BUFFER_SIZE) pwrite=0;
> }

Das ist deine Empfangsfunktion?

Dann kannst du das hier
    for(;;)
    {
    //if(RESET_PORT&(1<<RESET_PIN))EEPWriteByte(IS_CONFIGERD, 0x01);
    _delay_ms(10);
    sprintf(s,"<%s> \r",buffer);uart_puts(s);

nicht machen. In buffer ist zu diesem Zeitpunkt kein gültiger String.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timo P schrieb:
> mein Programm hat ja mal gelaufen, als die Buffer kleiner waren!

Dein Programm hat höchstens zufällig keinen Absturz produziert.
Korrekt gelaufen ist das nie. Zumindest nicht solange, solange du keine 
korrekt terminierten Strings hast.

Autor: Timo P (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
die kommands, die ich übermittelt bekomme, werden durch ein \n 
terminiert.

die ausgabe ..<%s>\r... in der for(;;) ist nur zu debugzwecken gedacht.

Autor: Ago (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timo P schrieb:
> {
...
>         if(trigger == 1)trigger = 0;
>         if(trigger == 0)trigger = 1;
>         uart_puts("00TOK\n");

Ähm.. ist das so gewollt, das trigger nicht 0 werden kann?

Oder wolltest du vielleicht schreiben

if (trigger == 1) then
  trigger == 0;
else
  trigger == 1;

Oder, kurzform:
trigger = (trigger) ? 0 : 1;

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Als Quick-Fix ändere das mal
ISR (USART_RXC_vect)
{
  buffer[pwrite]=UDR;

  pwrite++;
  if(pwrite >= BUFFER_SIZE)
    pwrite=0;

  buffer[pwrite] = '\0';
}

damit hast du zumindest im Input-Buffer ständig einen insofern gültigen 
C-String, als das er nach dem zuletzt empfangenen Zeichen 0-terminiert 
ist.

Autor: Timo P (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
DANKE!
Genau das war mein Fehler, falls ich in der kill_buffer() Fkt. 
ausschließlich buffer[0]= '\0' setzen wollte..

Autor: Ago (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Karl heinz Buchegger schrieb:
> damit hast du zumindest im Input-Buffer ständig einen insofern gültigen
> C-String, als das er nach dem zuletzt empfangenen Zeichen 0-terminiert
> ist.

hat er nicht (glaube ich... ;-)

Wenn USART_RXC_vect hier wieder das erste Zeichen des Buffers mit einem 
gültigen Zeichen überschreibt, sieht jede String-Funktion in C wieder 
den gesamten Buffer, plus das was dahinter im Speicher folgt (wenn nicht 
irgendwo im Buffer wieder ein /0 steht).

Wenn man es schon so machen muß wie der TE dann vllt. so:

#define BUFFER_SIZE 70  //buffergröße in Byte
volatile unsigned char buffer[1 + BUFFER_SIZE];
...
buffer[BUFFER_SIZE] == 0;

Damit wäre der Buffer immer NULL-Terminiert.

Autor: Ago (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Argh ich nehm das zurück.. hat er doch, hab nicht aufgepasst. Sorry :)

Autor: Timo P (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hab ich wohl, denn, wenn der RX-Interrupt das erste Zeichen 
überschreibt, hängt er automatisch ein '\0' an dank shiften des writer 
pointers um genu diese Bitbreite, die die Bufferelemente auch 
besitzen.....

so läuft es perfekt!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ago hat sich ins Boxhorn jagen lassen durch deine Variablen und der 
Tatsache dass du den Index am Ende des Buffers wieder auf 0 setzt. Er 
dachte das wäre ein Ringbuffer. Das ist er aber nicht. Sieht nur auf den 
ersten Blick so aus.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ago schrieb:

> Ähm.. ist das so gewollt, das trigger nicht 0 werden kann?
>
> Oder wolltest du vielleicht schreiben
>
> if (trigger == 1) then
>   trigger == 0;
> else
>   trigger == 1;

mit dem else hat ers nicht so

       if(PORTA&(1<<PIN))uart_puts("00S1\n");
        if((PORTA&(1<<PIN)) == 0)uart_puts("00S0\n");

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was passiert eigentlich, wenn der Benutzer
      else if(strstr(buffer,"set:ssid\t"))  // set:ssid\ta1b2c3d4\t\n
        {  
        int i = 9,j = 0;
        
        while(buffer[i] != '\t')
        {
          ssid[j] = buffer[i];
          i++;
          j++;
        }

auf den Tab bei der Eingabe vergisst?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dir ist auch klar, dass der Eingabetext

reset::ssid\t

(für \t drück ich natürlich den Tabulator)

auf diese Abfrage
     else if(strstr(buffer,"set:ssid\t"))  
passt?

strncmp eignet sich für solche Auswertungen besser als strstr
   else if( strncmp( buffer, "set::ssid\t", 10 ) == 0 )
jetzt muss der String mit "set::ssid\t" anfangen, nur dann gilt der Text 
als erkannt. reset::ssid\t passt jetzt nicht mehr.

Vielleicht hängt ja am anderen Ende der Leitung kein Mensch, aber die 
Sache mit dem \t würde ich mir insgesammt nochmal überlegen. Es sei denn 
natürlich, das da ein anderes Programm deinen µC füttert und dort ist 
das schon so festgelegt.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Was passiert eigentlich, wenn der Benutzer
> auf den Tab bei der Eingabe vergisst?

dann wird der Ram umsortiert...

Autor: Timo P (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
aus if...if ist längst ein if else geworden.

Mir ist auch bewusst, dass ich ein Bit aus einem 8-Bit char einzeln 
toggeln könnte.

Dann müsste ich aber wieder die Bitmasken nutzen, sowohl bei der 
Zuweisung, als auch bei der Abfrage des Flags...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timo P schrieb:
> aus if...if ist längst ein if else geworden.
>
> Mir ist auch bewusst, dass ich ein Bit aus einem 8-Bit char einzeln
> toggeln könnte.

Eine Schreibweise, die mir persönlich gut gefällt

   trigger = 1 - trigger;

keine Ahnung warum, aber ich finde das hat was :-)

> Dann müsste ich aber wieder die Bitmasken nutzen, sowohl bei der
> Zuweisung, als auch bei der Abfrage des Flags...

na, na

    trigger ^= 0x01;

so schlimm ist das auch wieder nicht.
Besser als
        if(trigger == 1)trigger = 0;
        else if(trigger == 0)trigger = 1;
ist es allemal.

Autor: Timo P (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dann frage ich aber auch das "0-te" Bit ab.... Dann gehts....

Oder ich hab mal was von Bitmasken gesehen, ein Strukt, in dem 8 Bits 
sind. Diese kann ich dann über ein define nutzen, quasi ein eigenes sbit 
für die AVRs, die ja keine bitadressierung haben.....

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timo P schrieb:
> dann frage ich aber auch das "0-te" Bit ab.... Dann gehts....

kannst du natürlich machen.
Aber bei all den Alternativvorschlägen ging es bisher immer nur darum, 
trigger zwischen 0 und 1 hin und her wechseln zu lassen. Das machen alle 
bisher hervorgebrachten Alternativen. Manche der Alternativen haben noch 
einen zuätzlichen Nebeneffekt bzw. zusätzliche Eigenschaften, der/die 
hier bei dir nicht zum tragen kommt, da trigger offenbar sowieso nur 0 
und 1 sein kann und auch das auch so sein soll.

Autor: Timo P (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier habe ich genug speicher und nutze ein komplettes byte als flag aus.
Missbrauch?!? ok, soll jeder so sehen, wie er es möchte.

Im übrigen sind alle commands, die hier zum tragen kommen, von einer GUI 
am PC über USB zum µC übertragen.

Daraus erzeuge ich dann andere Commands, die ich an ein WLAN-Modul 
übertrage.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timo P schrieb:
> Hier habe ich genug speicher und nutze ein komplettes byte als flag aus.
> Missbrauch?!? ok, soll jeder so sehen, wie er es möchte.

Darum gehts nicht.

Das hier
    if(trigger == 1)trigger = 0;
    else if(trigger == 0)trigger = 1;
ist für deinen µC so ziemlich die aufwändigste Methode, das Gewünschte 
zu erreichen.

>
> Im übrigen sind alle commands, die hier zum tragen kommen, von einer GUI
> am PC über USB zum µC übertragen.

ok. nehm ich zur Kentniss. Also musst du nicht besondere Sorgfalt in der 
Auswertung walten lassen. Du kannst davon ausgehen, dass der String 
immer vollständig und wohl geformt ist (abgesehen von 
Übertragungsfehlern natürlich)

Autor: Timo P (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ist gemeint, dass die Übertragungsfehler mindestens mit genau der selben 
Entgegnung/Auswertung optimiert werden sollen, wie Fehleingaben?

Oder hieß das, dass ich drauf vertrauen könnte? Wenn die GUI mir

set:ssid\thier_die_ssid\t\n

sendet, ich aber nicht mit einem

set:ssid:OK\n

antworte, weiß die Gui, dass sie erneut senden muss. Selbstverständlich 
versucht sie es nicht hunderte mal....

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timo P schrieb:
> ist gemeint, dass die Übertragungsfehler mindestens mit genau der selben
> Entgegnung/Auswertung optimiert werden sollen, wie Fehleingaben?

nein, das nicht. Aber dein Programm macht nach den vergessenen tab 
nichts mehr sinnvollens. Du musst also den µC neu starten.

Autor: Timo P (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist doch mal nen Argument...

strstr hätte den vorteil:

&$?=config:start\n wird von mir auch interpretiert, falls sich diese 
Zeichen vor config:start\n einschleichen sollten.

das strncmp klingt auch gut. (Welcher Vorteil ergibt sich praktisch 
durch das n, also die Angabe der Anzahl der zu prüfenden zeichen?)

Autor: Timo P (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
für die \t\t fehlerabfrage würde ich eine mindestgröße von sagen wir 1 
zeichen festlgegen, bei der mein code ein ...OK zurücksendet und die 
Daten in das entsprechende array schreibt.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timo P schrieb:
> Das ist doch mal nen Argument...
>
> strstr hätte den vorteil:
>
> &$?=config:start\n wird von mir auch interpretiert, falls sich diese
> Zeichen vor config:start\n einschleichen sollten.

die Frage ist ob du das überhaupt willst.
Falls sich da vor config::start\n ein paar Zeichen eingeschlichen haben, 
die da eigentlich nicht hingehören, woher willst du dann wissen, dass 
dieses config::start nicht eigentlich auch fehlerhaft ist und eigentlich 
gar nicht da hingehört?

> das strncmp klingt auch gut. (Welcher Vorteil ergibt sich praktisch
> durch das n, also die Angabe der Anzahl der zu prüfenden zeichen?)

Ich muss meinen String nicht in Einzelteile zerlegen
Dieser strncmp ist das Equivalent zu: Wenn die ersten n Buchstaben 
(sofern es überhaupt n gibt) diesen Text hier bilden, dann ist alles 
gut.

Autor: Timo P (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> dann ist alles
> gut.

klingt doch super ;)

nein im Ernst, Danke für die Anregungen zu meinem code. Sicher, man kann 
leute auf ein C-Buch verweisen. Aber irgendwie schreibt man dann doch 
auch mal mist zusammen. Sehen wir ja hier. Danke für eure Anregungen, 
nur so kann ich mich ja verbessern!

Weiter so im Forum!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timo P schrieb:

> auch mal mist zusammen. Sehen wir ja hier. Danke für eure Anregungen,
> nur so kann ich mich ja verbessern!

Das allerwichtigste bei der Arbeit mit Strings in C:

Du musst dir bei jeder Aktion immer im klaren sein, dass es kein 
Fangnetz gibt. Wenn du, aus welchem Grund auch immer, versuchst 20 
Zeichen in ein char-Array der Länge 10 zu quetschen, dann wird das 
grauslich schief gehen. Nicht nur das, es werden unter Umständen 
seltsame Phenomäne in deinem Programm auftauchen, Dinge die bisher schon 
funktioniert haben werden plötzlich nicht mehr funktionieren, 
Berechnungen liefern falsche Ergebnisse, Funktionsreturns landen 
plötzlich nicht mehr an der Stelle an der die Funktion aufgerufen wurde 
etc.

Daher: Bei jeglicher Stringaktion lieber konservativ arbeiten. Was kann 
schief gehen? Wenn du den String von einem Benutzer hast: Nicht darauf 
verlassen, dass der alles richtig eingibt. Wenn Strings über eine 
Leitung übertragen werden: Auch wenn es mitlerweile selten vorkommt, 
aber es gibt sie noch, die Übertragungsfehler.

Das mindeste, was man immer tun sollte, so lange man im Programm nicht 
sicher gestellt hat, das der String nicht zu lang sein kann:
Wenn man einen String (oder Teilstring) in ein anderes Array umkopiert, 
immer die Länge des Zielarrays im Auge behalten und notfalls das 
Umkopieren abwürgen, wenn man das Ziel überläuft!

Nicht wenige der frühen Hacker-Angriffe auf andere Rechner sind genau 
über solche Schlupflöcher gelaufen: Man hat ins Programm einen sehr 
langen String eingespielt, weil man genau wusste das dort und dort in 
der Umkopierschleife keine Sicherung gegen Überlaufen enthalten ist. 
Damit hat das Programm selber den Schadcode an die richtige Stelle im 
Speicher kopiert und das Tor aufgemacht.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.