Morgen, wir haben die Aufgabe bekommen ein Programm (auf dem8051) von
Assembler in C zu übersetzen. Es geht dabei ums aus- und einlesen von
Daten aus einem Ringbuffer. Insbesondere ist mir nicht klar, wie ich die
Variablen initilisieren soll (siehe Funktion rbInit). Es wäre gut, wenn
ihr da mal drüberschauen konntet. Danke im Voraus.
Ich würde ja gerne das Assemblerprogramm sehen, das der Verwendung von
'struct' zu Grunde liegt.
Was funktioniert denn nicht?
Variablen initialisiert man vorzugsweise mit 0.
Ich würde die Variablen so initializieren wie oben in der Funktion
angegeben.
"SIZE" habe ich wie gesagt in der Header-Datei dekl.:
#define size 4
"rbstart" ist die Startadresses des Puffers und liegt an der
Anfangsadresse von Speicherbereich XDATA. Meine Frage ist nun wie ich
das deklariere. Wie unterscheide ich in C zwischen diesen
Speicherbereichen?
OK, "size" habe ich jetzt klein geschrieben Schreibefehler. Das habe ich
nicht beachtet, weil ich vorher mit VHDL rumgemacht habe und der Prof
schreibt Schlüsselworter und Konstneten immer groß. Ich versuche immer
alles klein zu schreiben.
BerndS wrote:
> Morgen, wir haben die Aufgabe bekommen ein Programm (auf dem8051) von> Assembler in C zu übersetzen.
Dann wirst Du hierfür wohl eine glatte "6" bekommen.
Du hast einfach ohne Nachzudenken von irgendwoher eine Lösung kopiert,
die für wesentlich größere Systeme ausgelegt sind, als für nen kleinen
8051.
Der MC wird sich erstmal schon dumm und dußlich ackern, ehe er überhaupt
die ganzen Indirektionen aufgelöst hat.
Und zu allem Übel wird er das mit generic Pointern machen müssen, d.h.
für jeden einzelnen Bytezugriff nen Funktionsaufruf. Es sind ja keine
Memory-Specifier angegeben.
Ich kann mir nicht vorstellen, daß der Assemblercode auch nur entfernt
ähnlich komplex ist.
Er wird wohl ganz einfach sein, ohne Strukturpointer, sondern mit
direktem Memoryzugriff für genau eine FIFO im IDATA-Bereich.
Zeig dochmal den Assemblercode, damit man weiß, was Du wirklich machen
sollst.
Peter
BerndS wrote:
> OK, "size" habe ich jetzt klein geschrieben Schreibefehler. Das habe ich> nicht beachtet, weil ich vorher mit VHDL rumgemacht habe und der Prof> schreibt Schlüsselworter und Konstneten immer groß. Ich versuche immer> alles klein zu schreiben.
Damit mans schlechter lesen kann? Nene die Konstanten-"Regel" gilt bei
ziemlich vielen Programmiersprachen. Ist kein schlechter Stil das
beizubehalten.
Peter, es ist eine Praktikumsaufgabe und die Funktionsrümpfe wurden
vorgegeben. Der Algorithmus für das Lesen und Schreiben eines Bytes
(generisch) wurde als Ablaufdiagramm (mit Variablen) im Heft für
Assemblerprogrammierung vorgegeben. Dort ist auch ein einfaches Beispiel
für die Programmierung eines Ringpuffers, was ich hier ja mal einstellen
kann.
Diese Lösung ist nicht optimal (weil generisch). Daher sollen wir uns ja
im nächsten Schritt überlegen, wie wir das Programm optimieren können.
Eine Lösung ist die generischen Zeiger durch spezifische Zeiger zu
ersetzen. Mir ist nur noch nicht klar wie...
#include "rbLIB.h"
extern void rbInit( struct STRUCT_RB_CTRL *prbCtrl, char *buffer,
unsigned char size )
{
prbCtrl->rbUsed = 0;
prbCtrl->rbStart = buffer;
prbCrl->rbSize = size;
prbCtrl->rbLast = size + buffer -1
}
extern char rbState( struct STRUCT_RB_CTRL *prbCtrl )
{
return prbCtrl->rbUsed;
}
extern char rbRead(struct STRUCT_RB_CTRL *prbCtrl, char *value)
{
char rc = ERR_BUF_EMPTY;
if (prbCtrl->rbUsed > 0) //Daten im Puffer verfügbar
{
*value = *prbCtrl->rbReadPos++; //Lesezeiger dekr. von aktuellen
Wert
if (prbCtrl->rbReadPos < prbCtrl->rbStart) //Untere Grenze des
Puffers erreicht
if (prbCtrl->rbReadPos < prbCtrl->rbLast) //Obere Grenze des
Puffers erreicht
{
prbCtrl->rbReadPos = prbCtrl->rbStart;
}
prbCtrl->rbUsed--;
rc = OK;
}
return rc;
}
extern char rbWrite( struct STRUCT_RB_CTRL *prbCtrl, char value )
{
char rc = ERR_BUF_FULL;
if( prbCtrl->rbUsed < prbCtrl->rbSize )
{
*prbCtrl->rbWritePos++ = value;
if( prbCtrl->rbWritePos > prbCtrl->rbLast )
{
prbCtrl->rbWritePos = prbCtrl->rbStart;
}
prbCtrl->rbUsed++;
rc = OK;
}
return rc;
}
// EOF rbLIB.c
BerndS wrote:
> Der Algorithmus für das Lesen und Schreiben eines Bytes> (generisch) wurde als Ablaufdiagramm (mit Variablen) im Heft für> Assemblerprogrammierung vorgegeben. Dort ist auch ein einfaches Beispiel> für die Programmierung eines Ringpuffers, was ich hier ja mal einstellen> kann.
Ja das wäre sinnvoll.
> Diese Lösung ist nicht optimal (weil generisch). Daher sollen wir uns ja> im nächsten Schritt überlegen, wie wir das Programm optimieren können.
Der 8051 ist nicht sonderlich optimiert auf Operationen mit Zeigern auf
Strukturen mit Zeigern (doppelte Indirektion).
Wenn der FIFO die gesamte Laufzeit gebraucht wird, ist es also
sinnvoller seine Struktur direkt im Memory zu plazieren.
Vielleicht ab 10 FIFOs ist die Pointervariante wieder günstiger im
Codeverbrauch.
> Eine Lösung ist die generischen Zeiger durch spezifische Zeiger zu> ersetzen.
Das kann auch noch etwas bringen, ist aber bei Strukturen ziemlich
haarig in der Syntax. Mal in der Keil Knowledgebase googlen.
> #include "rbLIB.h"
Wo ist denn die?
Wenn man Code postet, muß man auch alle darin verwendeten Definitionen
mitposten.
Er muß compilierbar sein, sonst ist es sinnlos.
Peter