Leonhard1978
31.08.2017, 08:33
Guten Morgen,
auf dem XMC4700 Mikrocontroller von Infineon wird eine UART eingesetzt. Es sollen die ankommenden Daten von UDP über die UART an ein anderes Device gesendet werden.
Es kann nun passieren, dass die ankommenden UDP Daten schneller ankommen als die UART die Daten verarbeiten kann. Deshalb sollen Die Daten (Frames) in einen Ringpuffer abgelegt werden. Auf folgender Seite habe ich eine Implementierung gefunden https://www.google.de/url?sa=t&rct=j&q=&esrc=s&sou... die mein Problem eventuell lösen könnte.
Der folgende Quellcode habe ich auf dem PC mit Visual Studio erfolgreich getestet. Auf dem Mikrocontroller läuft dieser Quellcode nicht. Der Mikrocontroller bleibt hängen.
Wo könnte hier das Problem liegen?
#define BUFFER_SIZE 512
#define NUMBER_OF_FRAMES 10
//Struktur fuer die Daten
typedef struct
{
int length;
char data[BUFFER_SIZE];
} userdata_t;
//Struktur fuer einen Ringbuffer-Handler
//wird benoetigt, um mehrere Listen zu verwalten
typedef struct
{
//Index zum Lesen
int readIndex;
//Index zum Schreiben
int writeIndex;
//Platz fuer Speicherelemente, eigentlicher Buffer
userdata_t fifo[NUMBER_OF_FRAMES];
//Groesse des Buffers, d.h. Anzahl der Elemente
int size;
} ringbuffer_handler_t;
/*-------------------------------------------------------------------------*/
//eine Funktion, um einen Ringbuffer anzulegen
//Parameter size: Groesse des Buffers (Anzahl der Elemente)
//Rückgabewert: Zeiger auf Ringbuffer-Handler
ringbuffer_handler_t * createFIFO(int size)
{
static char Memory[6000];
ringbuffer_handler_t *buffer = (ringbuffer_handler_t *)Memory;
//Werte des Handler belegen
//readIndex und WriteIndex zu Anfang 0
//fuer fifo muss genuegend Speicher reserviert werden,
//um size Datenelemente aufnehmen zu koennen
//size gibt Anzahl der Elemente im Ringbuffer an (aus Parameter)
buffer->readIndex = 0;
buffer->writeIndex = 0;
buffer->size = size;
return buffer;
}
/*-------------------------------------------------------------------------*/
//eine Funktion, um Elemente anzuhaengen, d.h. in den Buffer zu schreiben
//Parameter data: Daten, die in den Buffer geschrieben werden sollen
//Parameter *buffer: Zeiger auf Ringbuffer-Handler
//kein Rueckgabewert
void appendFIFO(userdata_t data, ringbuffer_handler_t *buffer)
{
//Daten in den entsprechenden Platz im Buffer schreiben
//dafuer ist writeIndex da
buffer->fifo[buffer->writeIndex] = data;
//writeIndex wird fuer das naechste Schreiben auf den neuen Wert
//gesetzt
//Achtung: wenn der Buffer voll ist, wird wieder vorne hineinge-
//schrieben (deshalb RINGbuffer), Daten koennen verloren gehen,
//wenn nicht zwischendurch gelesen wird
buffer->writeIndex = buffer->writeIndex++ % (buffer->size + 1);
//an dieser Stelle ist es deshalb sinnvoll, den readIndex auf den
//letzen wahren Wert zu setzen, wenn NICHT zwischendurch gelesen
//wurde
if (buffer->readIndex == buffer->writeIndex)
buffer->readIndex = buffer->readIndex++ % (buffer->size + 1);
}
//eine Funktion, um Elemente aus dem Buffer zu lesen
//Parameter *data: Zeiger auf ein Datenelement, das die gelesenen Daten
//aufnehmen soll
//Parameter *buffer: Zeiger auf Ringbuffer-Handler
//Rueckgabewert -1, wenn nicht gelesen werden konnte
//Rueckgabewert 1, wenn gelesen werden konnte
int readFIFO(userdata_t *data, ringbuffer_handler_t *buffer)
{
//der writeIndex zeigt immer auf das naechste zu beschreibende Element,
//d.h. dieses Element ist noch nicht beschrieben worden und enthaelt
//deshalb keine gueltigen Daten
//wenn readIndex also gleich writeIndex, darf nicht gelesen werden
if (buffer->readIndex != buffer->writeIndex)
{
//Daten kopieren
*data = buffer->fifo[buffer->readIndex];
//readIndex fuer das naechste Lesen hochsetzen
buffer->readIndex = buffer->readIndex++ % (buffer->size + 1);
//Rueckgabewert 1, da gelesen wurde
return 1;
}
else
//es konnten keine Daten gelesen werden, da keine gueltigen Daten
//Rueckgabewert also -1
return -1;
}
void main (void)
{
ringbuffer_handler_t *local_buffer;
userdata_t write_data;
userdata_t read_data;
int ergebnis;
local_buffer = createFIFO(NUMBER_OF_FRAMES);
char DummyData[500];
memset(DummyData, 0x33, 500);
write_data.length = 101;
memcpy(write_data.data, DummyData, 101);
appendFIFO(write_data, local_buffer);
readFIFO(&read_data, local_buffer);
}
auf dem XMC4700 Mikrocontroller von Infineon wird eine UART eingesetzt. Es sollen die ankommenden Daten von UDP über die UART an ein anderes Device gesendet werden.
Es kann nun passieren, dass die ankommenden UDP Daten schneller ankommen als die UART die Daten verarbeiten kann. Deshalb sollen Die Daten (Frames) in einen Ringpuffer abgelegt werden. Auf folgender Seite habe ich eine Implementierung gefunden https://www.google.de/url?sa=t&rct=j&q=&esrc=s&sou... die mein Problem eventuell lösen könnte.
Der folgende Quellcode habe ich auf dem PC mit Visual Studio erfolgreich getestet. Auf dem Mikrocontroller läuft dieser Quellcode nicht. Der Mikrocontroller bleibt hängen.
Wo könnte hier das Problem liegen?
#define BUFFER_SIZE 512
#define NUMBER_OF_FRAMES 10
//Struktur fuer die Daten
typedef struct
{
int length;
char data[BUFFER_SIZE];
} userdata_t;
//Struktur fuer einen Ringbuffer-Handler
//wird benoetigt, um mehrere Listen zu verwalten
typedef struct
{
//Index zum Lesen
int readIndex;
//Index zum Schreiben
int writeIndex;
//Platz fuer Speicherelemente, eigentlicher Buffer
userdata_t fifo[NUMBER_OF_FRAMES];
//Groesse des Buffers, d.h. Anzahl der Elemente
int size;
} ringbuffer_handler_t;
/*-------------------------------------------------------------------------*/
//eine Funktion, um einen Ringbuffer anzulegen
//Parameter size: Groesse des Buffers (Anzahl der Elemente)
//Rückgabewert: Zeiger auf Ringbuffer-Handler
ringbuffer_handler_t * createFIFO(int size)
{
static char Memory[6000];
ringbuffer_handler_t *buffer = (ringbuffer_handler_t *)Memory;
//Werte des Handler belegen
//readIndex und WriteIndex zu Anfang 0
//fuer fifo muss genuegend Speicher reserviert werden,
//um size Datenelemente aufnehmen zu koennen
//size gibt Anzahl der Elemente im Ringbuffer an (aus Parameter)
buffer->readIndex = 0;
buffer->writeIndex = 0;
buffer->size = size;
return buffer;
}
/*-------------------------------------------------------------------------*/
//eine Funktion, um Elemente anzuhaengen, d.h. in den Buffer zu schreiben
//Parameter data: Daten, die in den Buffer geschrieben werden sollen
//Parameter *buffer: Zeiger auf Ringbuffer-Handler
//kein Rueckgabewert
void appendFIFO(userdata_t data, ringbuffer_handler_t *buffer)
{
//Daten in den entsprechenden Platz im Buffer schreiben
//dafuer ist writeIndex da
buffer->fifo[buffer->writeIndex] = data;
//writeIndex wird fuer das naechste Schreiben auf den neuen Wert
//gesetzt
//Achtung: wenn der Buffer voll ist, wird wieder vorne hineinge-
//schrieben (deshalb RINGbuffer), Daten koennen verloren gehen,
//wenn nicht zwischendurch gelesen wird
buffer->writeIndex = buffer->writeIndex++ % (buffer->size + 1);
//an dieser Stelle ist es deshalb sinnvoll, den readIndex auf den
//letzen wahren Wert zu setzen, wenn NICHT zwischendurch gelesen
//wurde
if (buffer->readIndex == buffer->writeIndex)
buffer->readIndex = buffer->readIndex++ % (buffer->size + 1);
}
//eine Funktion, um Elemente aus dem Buffer zu lesen
//Parameter *data: Zeiger auf ein Datenelement, das die gelesenen Daten
//aufnehmen soll
//Parameter *buffer: Zeiger auf Ringbuffer-Handler
//Rueckgabewert -1, wenn nicht gelesen werden konnte
//Rueckgabewert 1, wenn gelesen werden konnte
int readFIFO(userdata_t *data, ringbuffer_handler_t *buffer)
{
//der writeIndex zeigt immer auf das naechste zu beschreibende Element,
//d.h. dieses Element ist noch nicht beschrieben worden und enthaelt
//deshalb keine gueltigen Daten
//wenn readIndex also gleich writeIndex, darf nicht gelesen werden
if (buffer->readIndex != buffer->writeIndex)
{
//Daten kopieren
*data = buffer->fifo[buffer->readIndex];
//readIndex fuer das naechste Lesen hochsetzen
buffer->readIndex = buffer->readIndex++ % (buffer->size + 1);
//Rueckgabewert 1, da gelesen wurde
return 1;
}
else
//es konnten keine Daten gelesen werden, da keine gueltigen Daten
//Rueckgabewert also -1
return -1;
}
void main (void)
{
ringbuffer_handler_t *local_buffer;
userdata_t write_data;
userdata_t read_data;
int ergebnis;
local_buffer = createFIFO(NUMBER_OF_FRAMES);
char DummyData[500];
memset(DummyData, 0x33, 500);
write_data.length = 101;
memcpy(write_data.data, DummyData, 101);
appendFIFO(write_data, local_buffer);
readFIFO(&read_data, local_buffer);
}