W
Hi,
ich habe es jetzt so gelöst das ich ein struct mit einem 1k char Feld habe.
Ein Adressfeld mit 31 Adressen für dieses struct.
Und jedesmal wenn ich eine Adresse habe erzeuge ich mit malloc ein struct mit dem 1 k buffer.
Dies ist nicht ganz so dynamisch, (wenn ich weniger als 1k Daten habe, habe ich zu viel Speicher reserviert) aber es sollte so einfach funktionieren.
Nun habe ich aber das Problem das derv Compiler einmal
struct.feld und einmal struct->feld erwartet. Hier habe ich vermutlich zu wenig Ahnung warum das so ist.
Anbei mal die komplette main (ja ich weiß, es wird später in einzelne Funktionen zerlegt.)
#define max_adresse_mpi 31
datenkopfkopf fetchkopf = { 0 , 0 , 0 , 0 , 0 , 0 , 0xFF , 0xFF };
datenkopfkopf sendkopf = { 0 , 0 , 0 , 0 , 0 , 0 , 0xFF , 0xFF };
typedef struct
{
int mpi_adr;
char typ;
int db_nr;
int byte_nr;
int datenlaenge; /* in Worten */
int var_laenge; /* in Worten */
} block;
typedef struct
{
char data[1024];
} datenspeicher;
/*#############################################################################################################*/
int main(int argc, char *argv[])
{
FILE *fp;
int sst,v,z,y,x,blocknr, max_block;
//int akt_mpi = 0;
int zwischenspeicher;
char *lesen;
char zeile[255];
datenspeicher *ausgabepuffer[max_adresse_mpi] = {NULL};
block *blockkennung;
char dateipfad[255];
char dateiname[255];
/* Schnittstelle öffnen */
sst = init_SST("/dev/ttyS1"); /* 1. Schnittstelle (DOS Com:2) */
if (sst <= 0 )
{
printf("Fehler beim öffnen der Schnittstelle");
return 0;
}
/*--------------------------------------------------------------------------------------------*/
/* Parameter-Datei einlesen */
while (1)
{
if ((fp = fopen("/home/peter/projekte/visual_sst/visual_sst/parameter", "r")) == NULL)
{
/* ERROR */ ;
printf ("parameter-Datei konnte zum lesen für die Schnittstelle nicht geöffnet werden");
return -1;
}
max_block = 0; /* zeilenzähler aus der parameterdatei */
/* File komplett einlesen */
while ( fgets(zeile, sizeof(zeile), fp) )
{
if (zeile[0] == '#' || strlen(zeile) == 0)
{
continue;
}
if (blockkennung == NULL || max_block <= 0)
{
blockkennung = malloc(sizeof(block));
sscanf (zeile , "%i , %c , %i , %i , %i , %i" , &blockkennung[0].mpi_adr ,
&blockkennung[0].typ,
&blockkennung[0].db_nr,
&blockkennung[0].byte_nr,
&blockkennung[0].datenlaenge,
&blockkennung[0].var_laenge
);
max_block++;
}
else
{
blockkennung = realloc(blockkennung , ((max_block + 1) * sizeof(block)));
sscanf (zeile , "%i , %c , %i , %i , %i , %i" , &blockkennung[max_block].mpi_adr ,
&blockkennung[max_block].typ,
&blockkennung[max_block].db_nr,
&blockkennung[max_block].byte_nr,
&blockkennung[max_block].datenlaenge,
&blockkennung[max_block].var_laenge
);
max_block++;
}
}
fclose (fp);
/*--------------------------------------------------------------------------------------------*/
/* jeweiligen Block vorbereiten zum lesen */
for ( blocknr = 0 ; blocknr < max_block ; blocknr++)
{
if (blockkennung[blocknr].typ == 'D')
{
fetchkopf.db_nummer = blockkennung[blocknr].db_nr;
}
else
{
fetchkopf.db_nummer = 0;
}
/*--------------------------------------------------------------------------------------------*/
/* pro Adresse einen Ausgabepuffer anlegen */
if (ausgabepuffer[blockkennung[blocknr].mpi_adr] == NULL)
{
ausgabepuffer[blockkennung[blocknr].mpi_adr] = malloc (sizeof(datenspeicher));
}
/* Telegrammkopf vorbereiten */
fetchkopf.datentyp = blockkennung[blocknr].typ;
fetchkopf.wort_nummer = blockkennung[blocknr].byte_nr;
fetchkopf.anzahl = (blockkennung[blocknr].datenlaenge * blockkennung[blocknr].var_laenge) / 2;
fetchkopf.koordinierungsbyte = 0xFF;
fetchkopf.koordinierungsbit = 0xFF;
lesen = malloc(((fetchkopf.anzahl + 1) * 2 ) * sizeof(char));
if (NULL == lesen)
{
printf("Hoppla - nicht genug Speicher für Variable lesen\n");
exit(-1);
}
/* Daten von SPS holen */
y = Fetch_SST(sst , &fetchkopf , lesen);
/* 250ms */
usleep(250);
/*################ Zwischenspeichern in Buffer ###########################################################*/
for ( z = 0 ; z < (fetchkopf.anzahl + 1) ; )
{
switch (blockkennung[blocknr].var_laenge)
{
case 1: /* Byte */
zwischenspeicher = (int)(lesen[z]);
z++;
break;
case 2: /* Worte */
zwischenspeicher = (int)((lesen[z] << 8) + lesen[z + 1]);
z = z + 2;
break;
case 4: /* Doppelworte / Real */
zwischenspeicher = (int)( (lesen[z] << 24) + (lesen[z + 1] << 16) +
(lesen[z + 2] << 8) + lesen[z + 3]);
z = z + 4;
break;
default: /* kein korrektes Format */
printf ("Als Variablenlänge wurde in der Parameter-Datei ein falscher Wert angegeben\n");
printf ("Dieser darf nur 1,2,4 (Bytelänge) enthalten\n");
printf ("Bitte komplette Zeile überprüfen (DB-Nr muss wenn nicht benötigt wird 0 betragen\n");
break;
}
/*################ alle Daten aufsammeln ###########################################################*/
sprintf(zeile ,"%i\n" , zwischenspeicher);
strcat (ausgabepuffer[blockkennung[blocknr].mpi_adr]->data , zeile);
}
free(lesen);
}
/*################ AUSGABE in Datei ###########################################################*/
for ( v = 0 ; v < max_adresse_mpi ; v++)
{
if (strlen(ausgabepuffer[v]->data) > 0);
{
strcpy(dateipfad , "/srv/www/htdocs/data/");
sprintf(dateiname , "data_mpi_%i2",blockkennung[blocknr].mpi_adr);
strcat(dateipfad , dateiname);
if ((fp = fopen(dateipfad , "w+")) == NULL)
{
printf ("Das datafile %s konnte nicht geöffnet-erzeugt werden\n" , dateipfad);
return -1;
}
printf("%s",ausgabepuffer[v]->data);
fclose (fp);
}
}
/* Adressen der Ausgabepuffer löschen */
for ( v = 0 ; v < max_adresse_mpi ; v++)
{
if (ausgabepuffer[v] != NULL);
{
free(ausgabepuffer[v]);
ausgabepuffer[v] = NULL;
}
}
}
x = close_SST(sst);
return EXIT_SUCCESS;
}