www.elektronik.si Seznam forumov www.elektronik.si
Forum o elektrotehniki in računalništvu
 
 PomočPomoč  IščiIšči  Seznam članovSeznam članov  SkupineSkupine  StatisticsStatistika  AlbumAlbum  DatotekeFilemanager DokumentacijaDocDB LinksPovezave   Registriraj seRegistriraj se 
  PravilaPravila  LinksBolha  PriponkePriponke  KoledarKoledar  ZapiskiZapiski Tvoj profilTvoj profil Prijava za pregled zasebnih sporočilPrijava za pregled zasebnih sporočil PrijavaPrijava 

Linux C RS232 serial port neznanje
Pojdi na stran 1, 2  Naslednja
 
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Linux, unix razprave
Poglej prejšnjo temo :: Poglej naslednjo temo  
Avtor Sporočilo
vilko
Član
Član



Pridružen-a: Pet 13 Feb 2004 10:26
Prispevkov: 3351
Aktiv.: 15.09
Kraj: Dragomer

PrispevekObjavljeno: Ned Nov 06, 2011 2:39 pm    Naslov sporočila:  Linux C RS232 serial port neznanje Odgovori s citatom

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
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
sundancer
Član
Član



Pridružen-a: Ned 08 Avg 2004 22:30
Prispevkov: 374
Aktiv.: 1.68
Kraj: Ljubljana

PrispevekObjavljeno: Ned Nov 06, 2011 2:45 pm    Naslov sporočila:   Odgovori s citatom

Zivjo.

Malo pobrskaj za non-blocking I/O operacije. En link za zacetek:
http://www.kegel.com/dkftpbench/nonblocking.html

lp, Marko
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
sundancer
Član
Član



Pridružen-a: Ned 08 Avg 2004 22:30
Prispevkov: 374
Aktiv.: 1.68
Kraj: Ljubljana

PrispevekObjavljeno: Ned Nov 06, 2011 2:50 pm    Naslov sporočila:   Odgovori s citatom

Tudi tukaj najdes nekaj o asynchronus I/O: http://beej.us/guide/bgnet/output/html/singlepage/bgnet.htm
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
.
Član
Član



Pridružen-a: Pon 23 Avg 2004 16:16
Prispevkov: 16777190
Aktiv.: 75543.66

PrispevekObjavljeno: Ned Nov 06, 2011 2:57 pm    Naslov sporočila:   Odgovori s citatom

Brisana vsebina odstranjenega uporabnika.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
vilko
Član
Član



Pridružen-a: Pet 13 Feb 2004 10:26
Prispevkov: 3351
Aktiv.: 15.09
Kraj: Dragomer

PrispevekObjavljeno: Ned Nov 06, 2011 10:36 pm    Naslov sporočila:   Odgovori s citatom

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
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
chaos
Član
Član



Pridružen-a: Sob 16 Sep 2006 22:12
Prispevkov: 1063
Aktiv.: 4.98
Kraj: Zagorje ob Savi

PrispevekObjavljeno: Ned Nov 06, 2011 10:46 pm    Naslov sporočila:   Odgovori s citatom

Najlažje je takšne stvari delati z child procesi. Preberi si o unix standardni komandi fork, npr. tu

LP!
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
.
Član
Član



Pridružen-a: Pon 23 Avg 2004 16:16
Prispevkov: 16777190
Aktiv.: 75543.66

PrispevekObjavljeno: Ned Nov 06, 2011 10:53 pm    Naslov sporočila:   Odgovori s citatom

Brisana vsebina odstranjenega uporabnika.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
forest70
Član
Član



Pridružen-a: Ned 20 Jul 2008 1:00
Prispevkov: 588
Aktiv.: 3.08
Kraj: Koper

PrispevekObjavljeno: Pon Nov 07, 2011 2:57 am    Naslov sporočila:   Odgovori s citatom

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
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
vilko
Član
Član



Pridružen-a: Pet 13 Feb 2004 10:26
Prispevkov: 3351
Aktiv.: 15.09
Kraj: Dragomer

PrispevekObjavljeno: Pon Nov 07, 2011 9:13 am    Naslov sporočila:   Odgovori s citatom

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
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
rudiP
Član
Član



Pridružen-a: Tor 07 Avg 2007 15:30
Prispevkov: 1234
Aktiv.: 6.09
Kraj: KOPER

PrispevekObjavljeno: Pon Nov 07, 2011 9:39 am    Naslov sporočila:   Odgovori s citatom

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
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
.
Član
Član



Pridružen-a: Pon 23 Avg 2004 16:16
Prispevkov: 16777190
Aktiv.: 75543.66

PrispevekObjavljeno: Pon Nov 07, 2011 2:56 pm    Naslov sporočila:   Odgovori s citatom

Brisana vsebina odstranjenega uporabnika.


The.Art.of.Readable.Code.pdf.jpg
 Opis:
uploading.com / files / get / e285b1e8 /
 Velikost datoteke:  9.35 KB
 Pogledana:  20430 krat

The.Art.of.Readable.Code.pdf.jpg


Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
vilko
Član
Član



Pridružen-a: Pet 13 Feb 2004 10:26
Prispevkov: 3351
Aktiv.: 15.09
Kraj: Dragomer

PrispevekObjavljeno: Pon Nov 07, 2011 3:13 pm    Naslov sporočila:   Odgovori s citatom

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
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
vilko
Član
Član



Pridružen-a: Pet 13 Feb 2004 10:26
Prispevkov: 3351
Aktiv.: 15.09
Kraj: Dragomer

PrispevekObjavljeno: Pon Nov 07, 2011 3:15 pm    Naslov sporočila:   Odgovori s citatom

MarE69 je napisal/a:
Priporocam branje:

Priložene datoteke ne morem odpreti.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
chaos
Član
Član



Pridružen-a: Sob 16 Sep 2006 22:12
Prispevkov: 1063
Aktiv.: 4.98
Kraj: Zagorje ob Savi

PrispevekObjavljeno: Pon Nov 07, 2011 3:20 pm    Naslov sporočila:   Odgovori s citatom

fd je verjetno kazalec (* fd) in mora verjetno biti struktura tipa FILE - torej (FILE * fd)

LP!
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
vilko
Član
Član



Pridružen-a: Pet 13 Feb 2004 10:26
Prispevkov: 3351
Aktiv.: 15.09
Kraj: Dragomer

PrispevekObjavljeno: Pon Nov 07, 2011 3:23 pm    Naslov sporočila:   Odgovori s citatom

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
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Pokaži sporočila:   
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Linux, unix razprave Časovni pas GMT + 2 uri, srednjeevropski - poletni čas
Pojdi na stran 1, 2  Naslednja
Stran 1 od 2

 
Pojdi na:  
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