/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
Programmering af seriel-port i C.(Linux)
Fra : Martin Holm Pedersen


Dato : 10-05-04 21:27

Hejsa.. Jeg sidder og koger over et problem med seriel kommunikation. Jeg
skal modtage data fra en anden maskine der sender en char af gangen i en
forløkke.. Dvs. jeg skal modtage karakterer der ikke nødvendigvis kommer
helt optimalt. Dette er nødvendigt af grunde jeg ikke vil komme ind på. Jeg
vil gerne have en timeout på porten i tilfælde af jeg ikke modtager nogen
data. Jeg forsøgte mig med de to indstillinger tider VMIN og TIME "man
termios". Men det duer ikke, fordi der skal være modtaget data ind i
bufferen før timeout går igang. Jeg har også forsøgt mig med "select" der
kan sætte timeout op. Men af en eller anden mærkelig grund modtager jeg kun
8 eller i bedste fald 16 karakterer på den måde, selvom min buffer er 255
lang.. Håber nogen kan hjælpe.

VH
Martin Holm Pedersen

Porten er sat op som følger:
void InitSerialPort(PortDef *pSerPort)
{
pSerPort->fd = open(SERIALPORT, O_RDWR | O_NOCTTY );
if (pSerPort->fd < 0) {perror(SERIALPORT); exit(-1); }

tcgetattr(pSerPort->fd,&pSerPort->Oldtio); /* save current port settings
*/

memset(&pSerPort->Newtio, 0, sizeof(pSerPort->Newtio));
pSerPort->Newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;


pSerPort->Newtio.c_iflag = IGNPAR;


pSerPort->Newtio.c_oflag = 0;

/* set input mode (non-canonical, no echo,...) */
pSerPort->Newtio.c_lflag = 0;

tcflush(pSerPort->fd, TCIFLUSH);
tcsetattr(pSerPort->fd,TCSANOW,&pSerPort->Newtio);
}

Og jeg læser med:

void ReciveDataAndCheck(SlaveStatusDef *pSlaveStatus, PortDef *pSerPort,
PackageDef *pPackage){
int res=0, i=0, n=0;
unsigned short buf[25];

for(i=0;i<=25;i++){
buf[i]=0;
}

FD_ZERO(&pSerPort->rfds);
FD_SET(pSerPort->fd,&pSerPort->rfds);

/* Timeout defineres. */
pSerPort->tv.tv_sec=2;
pSerPort->tv.tv_usec=TIMEOUT;

/* Timeout sættes. */
res=select(pSerPort->fd+1,&pSerPort->rfds,NULL,NULL,&pSerPort->tv);
printf("%d\n",res);
if(res) {
n = read(pSerPort->fd,&buf,10);
buf[n] = 0;
}
if(res == 0) {
printf("Timeout!\n");
WriteToLog(pSlaveStatus,0);
}
}

 
 
Søren Hansen (11-05-2004)
Kommentar
Fra : Søren Hansen


Dato : 11-05-04 13:52

On Mon, 10 May 2004 22:27:09 +0200, Martin Holm Pedersen wrote:
> Jeg har også forsøgt mig med "select" der
> kan sætte timeout op. Men af en eller anden mærkelig grund modtager jeg kun
> 8 eller i bedste fald 16 karakterer på den måde, selvom min buffer er 255
> lang.. Håber nogen kan hjælpe.

Har du en anden buffer, eller er det buf, som kun er på 25 bytes, vi
snakker om?

Jeg er ikke helt sikker på, hvad problemet er.. Er du helt sikker på, at
der ikke kan gå to sekunder uden, der er data til rådighed?


> pSerPort->tv.tv_usec=TIMEOUT;

Hvad gør du her? Hvad er TIMEOUT?



Martin Holm Pedersen (11-05-2004)
Kommentar
Fra : Martin Holm Pedersen


Dato : 11-05-04 16:12

Søren Hansen wrote:

> On Mon, 10 May 2004 22:27:09 +0200, Martin Holm Pedersen wrote:
>> Jeg har også forsøgt mig med "select" der
>> kan sætte timeout op. Men af en eller anden mærkelig grund modtager jeg
>> kun 8 eller i bedste fald 16 karakterer på den måde, selvom min buffer er
>> 255 lang.. Håber nogen kan hjælpe.
>
> Har du en anden buffer, eller er det buf, som kun er på 25 bytes, vi
> snakker om?
>
> Jeg er ikke helt sikker på, hvad problemet er.. Er du helt sikker på, at
> der ikke kan gå to sekunder uden, der er data til rådighed?
>
>
>> pSerPort->tv.tv_usec=TIMEOUT;
>
> Hvad gør du her? Hvad er TIMEOUT?

Tak for svaret.

Problemet var og er sådan set stadig at jeg gerne vil teste om der er
forbindelse til en slave på vores serielle bus. Det skulle så gøres med en
timeout som skulle ske ved TIMEOUT sekunder uden data på porten. Men VTIME
og TIME er afhængige af hinanden så det ikke umiddelbart kan lade sig gøre.

Men jeg har fundet en løsning. Jeg fandt ud af at hvis jeg bruger select til
at finde ud af om der er data på porten og åbnede og lukkede porten hver
eneste gang jeg skriver til den bliver det stabilt. Det er nok ikke den
mest elegante løsning. Men det virker..hver gang. Der er lidt med hvor
hurtigt det kan gå pga. det ekstra arbejde hver gang der skal skrives. Jeg
åbner og lukker porten for hver karakter. Det skyldes at jeg skal tvinge
pariteten til en bestemt setting [Even/Odd] hver gang, idet vi tester på
den i den anden ende. Addressebit.. Men nu vil jeg så godt prøve at finde
ud af hvor lang tid det egentlig tager at sende mine data ud på sub-second
niveau. Det virker ikke til det er muligt med time.h..

- Martin

Søren Hansen (12-05-2004)
Kommentar
Fra : Søren Hansen


Dato : 12-05-04 09:42

On Tue, 11 May 2004 17:12:25 +0200, Martin Holm Pedersen wrote:

>>> pSerPort->tv.tv_usec=TIMEOUT;
>> Hvad gør du her? Hvad er TIMEOUT?
> Problemet var og er sådan set stadig at jeg gerne vil teste om der er
> forbindelse til en slave på vores serielle bus. Det skulle så gøres med en
> timeout som skulle ske ved TIMEOUT sekunder uden data på porten.

Det er såmænd fint nok, men det, du i virkeligheden skriver i din kode,
er at du gerne vil vente 2 sekunder og TIMEOUT millisekunder..



Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408917
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste