www.mikrocontroller.net

Forum: Compiler & IDEs Empfangen mit Interrupt


Autor: Katia (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich versuche mit Interrupt über serielle Schnittstelle mehrere String zu 
empfangen. Das Programm läuft nicht gut.Ich kann das erte String ohne 
Problem empfangen aber mit dem zweiten String empfange ich nur die 2 
erste Buchstaben.
Sieht jemanden wo das Problem liegt?
Anbei meine Code für das Senden und Empfangen

Ich danke euch für alle Hilfe.

Katia

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na, das ist ja reichlich Kuddelmuddel.

> #include <avr/iocan128.h>
> #include <avr/iocanxx.h>
> #include <avr/io.h>

Wenn mcu richtig gesetzt ist, reicht das Includen von io.h.
Das Obige compiliert gar nicht.

> #include "receive.h"

Wo ist die?

> main.c:
char tempstr[200];
unsigned char nextCharPos;
volatile unsigned char stringReady;
//volatile unsigned char dekryptString[100];
char string[200];
int lendekryptString;
char receivedString[200];
//const char dekryptString[14][100];
int i=0;
const char dekryptString[200];
> receive.c:
char tempstr[200];
char string[200];
char buffer[200];
unsigned char nextCharPos;
int lendekryptString;
const char dekryptString[200];
volatile unsigned char stringReady;

Du definierst diverse Variablen mehrfach. Du kannst sie zwar beliebig 
oft deklarieren, aber nur einmal definieren. Nimm dein C-Buch zur Hand 
und schlag "extern" nach.

Autor: Katia (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe gelesen und auch korrigiert. Extern ist für "One definition 
rule" d.h jedes Teil, egal ob Variable oder Funktion nur ein einziges 
mal definiert werden darf.
Mit den Veänderungen bekomme ich immer das selbe Problem.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann poste bitte mal den korrigierten Code (bitte inklusive der 
receive.h).

Autor: Katia (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
Anbei die Code

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich sehe nicht, dass du bei den Variablen-Definitionen irgendetwas 
verändert hättest.

Autor: Katia (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,
wie soll ich es dann machen?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beispielsweise so, wenn du die angegeben Variaben als globale Variablen 
haben willst und wenn sie alle in main.v definiert werden sollen:

// > main.c:
char tempstr[200];
unsigned char nextCharPos;
volatile unsigned char stringReady;
//volatile unsigned char dekryptString[100];
char string[200];
int lendekryptString;
char receivedString[200];
//const char dekryptString[14][100];
int i=0;
const char dekryptString[200];

// > receive.c:
extern char tempstr[];
extern char string[];
extern char buffer[];
extern unsigned char nextCharPos;
extern int lendekryptString;
extern const char dekryptString[];
extern volatile unsigned char stringReady;

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich glaube, dass Problem liegt anders.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
kann niemanden mir wirklich helfen?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach jetzt raffe ich das erst.

Thomas = Katia.

Und ich dachte deine vorletzte Nachricht wäre ein hämischer Kommentar zu 
den intellektuellen Fähigkeiten der Katia.

Nee, bin ich blöd.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan "stefb" B. wrote:
> Ach jetzt raffe ich das erst.
>
> Thomas = Katia.
Ah, ein Zwitter... Welch seltene Ehre!

Autor: Katia (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Stefan,
es ist nicht was du denkst mein Freund heisst Thomas und  manchmal achte 
ich nicht darauf, welche Name steht, wenn ich einen neuen Beitrag 
schreiben will.
Wir benutzen den selben Rechner.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
1/ Kannst du ein Beispiel angeben, was das Programm machen soll und was 
es im Moment leider macht? Was geht ins Programm rein und was kommt 
raus?

2/ Hast du die Änderungen mit extern bereits eingebaut und getestet? 
Diese Änderungen sind essentiell, um doppelte Variablen zu vermeiden.

Ich verstehe nicht, dass du mit deinem Code überhaupt vom Kompiler ein 
lauffähiges Programm bekommst. Meine Kompiler würden sinngemäß mit 
"Fehler doppelte Symbole" kotzen und abbrechen.

3/ Du kannst in der Empfangsroutine eine Stelle verbessern:

ISR (SIG_UART0_RECV)
{
  unsigned char c = UDR0;

  if( c == '\r' )
  {  // ist der String vollständig?
    string[nextCharPos] = '\0';
    stringReady = 1;
    nextCharPos = 0;
  }
  else
  {
    string[nextCharPos] = c;
    nextCharPos++;

    //
    // Den string IMMER mit einem Nullbyte abschliessen!
    //
    string[nextCharPos] = '\0';
  }
}

Das ist aber mehr fürS gute Gefühl.

4/ In deinem Programm ist keinerlei Kotrolle, ob Puffergrössen 
überschritten werden.

Damit ist das Laufzeitverhalten extrem von den empfangenen Daten 
abhängig! Manche Daten können dem Programm den Todesstoss versetzen.

Beispiel
#define Ns 5
#define Nz 8

  char FrameFormat[Nz][Ns];
  char **test[50];
  char *result=NULL; // initialisieren des Pointers
  const char *delims= " ";

  result = strtok_r( dekryptString,delims,test); 
  while( result != NULL )
  {
    strcpy(FrameFormat[sPtr],result);
    result = strtok_r( NULL, delims,test );
        ...

Eine Eingabe "eine beliebige Eingabe" wird an den Leerzeichen in Würter 
aufgetrennt. Die Rückgabewerte im Beispiel sind Zeiger auf

"Eingabe"
"beliebige"
"eine"
NULL

Bereits der zweite Rückgabewert würde über die Grenzen von 
FrameFormat[1] hinausschreiben und was zerstören oder verstümmeln. Die 
Dimension Ns wird gesprengt.

Die Eingabe "eingabe mit mehr worten als in FrameFormat Platz ist" wird 
die Dimension Nz sprengen.

5/ Du musst aufpassen mit den Typen für die Variablen.

Das war, so wie die KOmmentare im Programm aussehen, anscheinend mal 
richtig und wurde dann geändert.

const char dekryptString[200];
...
strcpy( dekryptString, receivedString ); 

Passt nicht. const bedeutet fix, nicht veränderbar. Da darf man nichts 
reinkopieren (strcpy) und man darf darin nichts zerstückeln (strtok_r)!

Der Compiler sollte da eigentlich mosern. Überhaupt sollte der Compiler 
sejr oft mosern, weil das mit dem extern fehlt.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan "stefb" B. wrote:
> Überhaupt sollte der Compiler
> sejr oft mosern, weil das mit dem extern fehlt.

Naja, der Compiler bemerkt die redefinierten Symbole ja gar nicht, 
schließlich werden die C-Dateien unabhängig voneinander übersetzt. Und 
der gcc-Linker legt sie kommentarlos auf identische Adressen, so dass 
ihr Code diesbezüglich sogar funktionieren sollte. Trotzdem sollte das 
natürlich geändert werden.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich meine mich zu erinnern, die Fehlermeldung (oder Warnung?) mit 
doppelten Symbolen gesehen zu haben. Ich kann aber nicht 100% sicher 
sagen, ob es bei der GCC AVR Toolchain war.

Compiler hatte ich im Sinn Gesamtpacket/Toolchain geschrieben. Klar ist 
es so wie du schreibst, dass der Linker hier das Problem entdecken kann.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der GCC hat die Eigenart, daß man auf extern verzichten kann (ohne 
Warnung).
Alle anderen C-Compiler meckern aber darüber.

Um also portablen Code zu schreibe, sollte man es trotzdem verwenden.


Peter

Autor: Katia (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

im Moment versuche ich mehrere String an meinen Mikrocontroller über die 
serielle Schnittstelle zu senden.
ZB: string1:"SEND  AA BB CC "
    string2:"RECV  AA BB CC "

1)Ich kann der erste String sehr gut empfangen und in der Funktion 
Derypt_Data_Cpu bearbeiten.

2)Für der zweite String bekomme ich nur die  erste Buchstaben.
Im for schleife von Derypt_Data_Cpu habe ich nur FrameFormat[0]=RE\n und 
dann gehe ich züruck im Main Funktion

3)Ich habe die Änderungen mit extern gemacht. Mit dem Aktuelzustand 
bekomme ich keinen Fehler Meldung und Warnung

4)Ich benutze const damit die Variable im Programm nicht veändern wird. 
Ich vermute:Falls der zweite String angekommen ist, wird es im 
dekryptString gespeichert und weiter bearbeitet.

5)Im Sting gibt habe ich kein Wort länger als 5 Zeichen.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
1/ Oben hatte ich Quatsch zur Reihenfolge der Auswertung beim strtok_r 
geschrieben. Das fängt nicht "hinten" an, sondern "vorne".

2/ In dieser Zeile hast du ein Argument zuwenig, um das %d auszuwerten!
sprintf(tempstr," frame: %s\n, %d",FrameFormat[i]);
Das kann dir seltsame Laufzeitfehler bringen! Die tauchen dann auch nach 
dem ersten String auf... Wenn 3/ und 4 unten nicht zutreffen ist sprintf 
je der einzige Übeltäter, der ein \n in die Daten reinfutscheln kann.

3/ Du testest das Zeilenende des empfangenen Strings mit \r. Kann es 
sein, dass dir von der Gegenseite auch ein \n geschickt wird und dass 
das unglücklich im Empfangspuffer landet? Schon probiert in der 
Interruptroutine nix zu machen, wenn das  c == '\n' ist?

4/ Du sperrst die Interrupts IMHO zu lange. Es kann sein, dass noch die 
ersten zwei Zeichen der zweiten Zeile im UART stehen, wenn der 
Interrupts gesperrt wird. Dann gehen etliche Zeichen verloren, weil du 
lange auswertest. Dann ist der Interrupt frei, die Zeichen RE aus der 
UART werden herausgeholt aber inzwischen ist nur noch \n auf der Leitung 
(wenn ein \n geschickt wird). Was steht in dekryptString direkt wenn du 
in Dekrypt_Data_Cpu() ankommst und noch keine Auswertung gemacht hast?

5/ const ist an der Stelle falsch. Glaube es mir.

Autor: Katia (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,
immer ohne Erfolg hat jemanden zuverlässig ein anderer Vorshlag.

Katia

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
plonk

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.