|
www.elektronik.si Forum o elektrotehniki in računalništvu
|
Poglej prejšnjo temo :: Poglej naslednjo temo |
Avtor |
Sporočilo |
vilko Član
Pridružen-a: Pet 13 Feb 2004 10:26 Prispevkov: 3351 Aktiv.: 15.09 Kraj: Dragomer
|
Objavljeno: Ned Nov 06, 2011 2:39 pm Naslov sporočila: Linux C RS232 serial port neznanje |
|
|
Pozdravljeni,
Nekaj časa sem bil 'na bolniški', sedaj spet prihajam pred vas z problemi.
Okolje: Linux, Beagleboard povezan preko RS232 z Windows PC-jem na katerem poganjam Brayev terminal emulator.
Na Linuxu prevedem in poženem program, ki vsake 4 sekunde napiše sporočilo na RS232, a vmes ne gre v komo, temveč lahko izvaja karkoli drugega. To sem realiziral tako:
Koda: |
{
open_port ();
int n;
char sporocilo[BUFS+1];
while (1) // for ever
{
// neprestano:
// in stalno nadziramo pretečeni čas:
time_t seconds;
seconds = time (NULL);
if (seconds > sekunde ) // če je pretečeni čas (recimo 10 sekund) potekel
{
sekunde = seconds + 4; // ponastavimo čas za sledečo periodo
// in ta del programa se bo izvajal samo periodično
printf ("To se izvaja samo na 4 sekunde.\n");
stevec++;
char niz[40] = "Abefabedomine.\n";
sprintf(niz, "Abefabedomine %d\n",stevec);
n = strlen(niz);
printf ("BB Posiljam %s dolg %d\n",niz,n);
printf ("%d\n",n);
n = write(fd, niz, n);
if (n < 0) printf ("write() failed!\r\n");
} // end of if seconds
// tukaj je lahko koda, ki se stalno odvija, program 'ne spi'
}
|
To deluje.
Problem nastopi, če v zanko dodam branje informacije, ki pride po RS232. Kaj bi rad? Če informacija pride, naj jo program obdela, če pa ne naj ne visi v read, naj nadaljuje delo. A nažalost se v mojem programu ravno to dogaja. Program je sledeč:
Koda: |
{
open_port ();
int n;
char sporocilo[BUFS+1];
while (1) // for ever
//
// to ne dela dobro, izvisi v read, in dokler ne dobi nečesa,
// ===========================================================
{
if( ( n=read(fd, sporocilo, BUFS )) > 0)
{
sporocilo[n]='\0';
printf ("%s",sporocilo);
}
// neprestano:
// in stalno nadziramo pretečeni čas:
time_t seconds;
seconds = time (NULL);
if (seconds > sekunde ) // če je pretečeni čas (recimo 5 sekund) potekel
{
sekunde = seconds + 5; // ponastavimo čas za sledečo periodo
// in ta del programa se bo izvajal samo periodično
printf ("To se izvaja samo na 5 sekund.\n");
stevec++;
} // end of if
}
|
Če nič ne vtipkam v terminal emulator, program ne daje vsakih 5 sekund sporočilo.
Kaj delam narobe?
Se priporočam
VS
|
|
Nazaj na vrh |
|
|
sundancer Član
Pridružen-a: Ned 08 Avg 2004 22:30 Prispevkov: 374 Aktiv.: 1.68 Kraj: Ljubljana
|
|
Nazaj na vrh |
|
|
sundancer Član
Pridružen-a: Ned 08 Avg 2004 22:30 Prispevkov: 374 Aktiv.: 1.68 Kraj: Ljubljana
|
|
Nazaj na vrh |
|
|
. Član
Pridružen-a: Pon 23 Avg 2004 16:16 Prispevkov: 16777190 Aktiv.: 75543.66
|
Objavljeno: Ned Nov 06, 2011 2:57 pm Naslov sporočila: |
|
|
Brisana vsebina odstranjenega uporabnika.
|
|
Nazaj na vrh |
|
|
vilko Član
Pridružen-a: Pet 13 Feb 2004 10:26 Prispevkov: 3351 Aktiv.: 15.09 Kraj: Dragomer
|
Objavljeno: Ned Nov 06, 2011 10:36 pm Naslov sporočila: |
|
|
Ja, to je verjetno res, a mi smrdi, ker potem moram sam sestavljati sporočilo bajt po bajt, prestreči tudi kake 'backspace' znake, a če ne bo šlo drugače, bo to edini izhod.
Hvala.
|
|
Nazaj na vrh |
|
|
chaos Član
Pridružen-a: Sob 16 Sep 2006 22:12 Prispevkov: 1063 Aktiv.: 4.98 Kraj: Zagorje ob Savi
|
Objavljeno: Ned Nov 06, 2011 10:46 pm Naslov sporočila: |
|
|
Najlažje je takšne stvari delati z child procesi. Preberi si o unix standardni komandi fork, npr. tu
LP!
|
|
Nazaj na vrh |
|
|
. Član
Pridružen-a: Pon 23 Avg 2004 16:16 Prispevkov: 16777190 Aktiv.: 75543.66
|
Objavljeno: Ned Nov 06, 2011 10:53 pm Naslov sporočila: |
|
|
Brisana vsebina odstranjenega uporabnika.
|
|
Nazaj na vrh |
|
|
forest70 Član
Pridružen-a: Ned 20 Jul 2008 1:00 Prispevkov: 588 Aktiv.: 3.08 Kraj: Koper
|
Objavljeno: Pon Nov 07, 2011 2:57 am Naslov sporočila: |
|
|
Uporabi opcijo O_NONBLOCK pri funkcijo open ....
Citiram man open
When opening a block special or character special file that supports non-blocking opens:
* If O_NONBLOCK is set, the open() function shall return without blocking for the device to be ready or available. Subsequent behavior of the device is device-spe-cific.
* If O_NONBLOCK is clear, the open() function shall block the calling thread until the device is ready or available before returning.
|
|
Nazaj na vrh |
|
|
vilko Član
Pridružen-a: Pet 13 Feb 2004 10:26 Prispevkov: 3351 Aktiv.: 15.09 Kraj: Dragomer
|
Objavljeno: Pon Nov 07, 2011 9:13 am Naslov sporočila: |
|
|
Citiram: |
Uporabi opcijo O_NONBLOCK pri funkcijo open .... |
A veš, da sem,
Koda: |
fd = open("/dev/ttyS2", O_RDWR | O_NOCTTY | O_NONBLOCK); |
a pri meni ni bilo nobene razlike, kot da ne bi le tega naredil.
Hvala Mare, tvojo kodo bom kopiral in testiral.
Citiram: |
Najlažje je takšne stvari delati z child procesi. |
Ja, to je verjetno res. Child procesi nekako simulirajo tisto, kar pri mikroprocesorjih delamo z interupt podprogrami, a potem je pri linuxu potrebno še naštudirati prenašanje podatkov med procesi. Seveda, vse to gre, a sem že v letih in študiranje novitet mi ne gre preveč dobro.
|
|
Nazaj na vrh |
|
|
rudiP Član
Pridružen-a: Tor 07 Avg 2007 15:30 Prispevkov: 1234 Aktiv.: 6.09 Kraj: KOPER
|
Objavljeno: Pon Nov 07, 2011 9:39 am Naslov sporočila: |
|
|
Citiram: |
To je pa ja enostavno.
|
Je enostavno ko bereš lepo napisano kodo kot je priložena, če pa si začetnik v c-ju
je pa zložit tako kodo manj enostavno. S tvojo podporo Mare in ostalih poznavalcev je učenje C-ja lažje. Hvala.
_________________ Lep pozdrav iz Kopra Rudi |
|
Nazaj na vrh |
|
|
. Član
Pridružen-a: Pon 23 Avg 2004 16:16 Prispevkov: 16777190 Aktiv.: 75543.66
|
Objavljeno: Pon Nov 07, 2011 2:56 pm Naslov sporočila: |
|
|
Brisana vsebina odstranjenega uporabnika.
Opis: |
uploading.com / files / get / e285b1e8 / |
|
Velikost datoteke: |
9.35 KB |
Pogledana: |
20430 krat |
|
|
|
Nazaj na vrh |
|
|
vilko Član
Pridružen-a: Pet 13 Feb 2004 10:26 Prispevkov: 3351 Aktiv.: 15.09 Kraj: Dragomer
|
Objavljeno: Pon Nov 07, 2011 3:13 pm Naslov sporočila: |
|
|
Mare, še te potrebujem, getc mi ne dela, gotovo delam nekaj narobe.
Da bi izoliral sam getc, sem iz tutoriala prekopiral programček:
Koda: |
int main(int argc, char *argv[])
{
open_port ();
char ch;
while((ch=getc(fd))!=EOF)
{
printf("%c", ch);
}
fclose(fd);
return 0;
} |
Seveda sem spredaj deklariral vse mogoče biblioteke in definicije datoteke:
Koda: |
#include <stdio.h> /* Standard input/output definitions */
#include <string.h> /* String function definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include <fcntl.h> /* File control definitions */
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
#include <time.h>
#include <stdlib>
#define BUFS 45 // maksimalna dolžina sporočila
#define LF 0x0A
#define CR 0x0D
long sekunde = 0;
int stevec = 0;
int fd; /* File descriptor for the port */
int open_port(void)
{ struct termios options;
/* Get the current options for the port... */
tcgetattr(fd, &options);
/* * Set the baud rates to 9600... */
cfsetispeed(&options, B9600);
cfsetospeed(&options, B9600);
/* * Enable the receiver and set local mode... */
options.c_cflag |= (CLOCAL | CS8 | CREAD); /* 8 bit, no parity, one stop */
options.c_lflag |= (ICANON | ECHO | ECHOE); /* canonical (line oriented) input - must terminate with LF or CR */
options.c_iflag &= ~(IXON | IXOFF | IXANY); /* disable SW flow control */
/* * Set the new options for the port... */
tcsetattr(fd, TCSANOW, &options);
fd = open("/dev/ttyS2", O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
if (fd == -1)
{
/* * Could not open the port. */
perror("open_port: Unable to open /dev/ttyS0 - ");
}
else fcntl(fd, F_SETFL, 0);
return (fd);
} |
Na tiste 'flag.e v opcijah se ne spoznam, a tam verjetno tiči zajec. Tam je še vedno kot komentar
Citiram: |
options.c_lflag |= (ICANON | ECHO | ECHOE); /* canonical (line oriented) input - must terminate with LF or CR */ |
in mi je sumljiv.
Kaj se dogaja, ko prevedem program? Sledeče:
Citiram: |
a.c: In function 'main':
a.c:49: warning: passing argument 1 of '_IO_getc' makes pointer from integer without a cast
a.c:53: warning: passing argument 1 of 'fclose' makes pointer from integer without a cast
|
Pri izvajanju pa
Citiram: |
Cannot open file.
|
|
|
Nazaj na vrh |
|
|
vilko Član
Pridružen-a: Pet 13 Feb 2004 10:26 Prispevkov: 3351 Aktiv.: 15.09 Kraj: Dragomer
|
Objavljeno: Pon Nov 07, 2011 3:15 pm Naslov sporočila: |
|
|
MarE69 je napisal/a: |
Priporocam branje: |
Priložene datoteke ne morem odpreti.
|
|
Nazaj na vrh |
|
|
chaos Član
Pridružen-a: Sob 16 Sep 2006 22:12 Prispevkov: 1063 Aktiv.: 4.98 Kraj: Zagorje ob Savi
|
Objavljeno: Pon Nov 07, 2011 3:20 pm Naslov sporočila: |
|
|
fd je verjetno kazalec (* fd) in mora verjetno biti struktura tipa FILE - torej (FILE * fd)
LP!
|
|
Nazaj na vrh |
|
|
vilko Član
Pridružen-a: Pet 13 Feb 2004 10:26 Prispevkov: 3351 Aktiv.: 15.09 Kraj: Dragomer
|
Objavljeno: Pon Nov 07, 2011 3:23 pm Naslov sporočila: |
|
|
chaos je napisal/a: |
fd je verjetno kazalec (* fd) in mora verjetno biti struktura tipa FILE - torej (FILE * fd)
|
Pri branju cele vrstice se ni pritoževal in je delal, le blokiral je, če ni bilo stavka, tako da mislim, da je zajec nekje drugje.
|
|
Nazaj na vrh |
|
|
|
|
Ne, ne moreš dodajati novih tem v tem forumu Ne, ne moreš odgovarjati na teme v tem forumu Ne, ne moreš urejati svojih prispevkov v tem forumu Ne, ne moreš brisati svojih prispevkov v tem forumu Ne ne moreš glasovati v anketi v tem forumu Ne, ne moreš pripeti datotek v tem forumu Ne, ne moreš povleči datotek v tem forumu
|
Uptime: 49 dni
Powered by phpBB © 2001, 2005 phpBB Group
|