[elektro] Soros-USB atalakito Linuxon

Bánhidi István banhidi.istvan at gmail.com
Wed Aug 13 05:30:11 CEST 2014


Szia,

Most nincs időm átnyálazni a kódodat, de itt van a biztosan működő sajátom
a header fájlokat majd csupáld meg, mert egy nagyobb projektből ollóztam a
kód részletet:

#include <stdio.h>   /* Standard input/output definitions */
#include <stdlib.h>
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <termios.h> /* POSIX terminal control definitions */
#include <errno.h>   /* Error number definitions */
#include <sys/time.h>
#include <sys/types.h>
#include <locale.h>
#include <syslog.h>

#ifdef DEBUG
    #define PORT "/tmp/ttyV0"
#else
    #define PORT "/dev/ttyS0"
#endif

#define BAUDRATE 19200

FILE *serial_port;
struct termios old_tios, new_tios;
struct timeval timeout;
struct timeval start;

int portopen(void) {

    speed_t speed;

    serial_port = open(PORT, O_RDWR | O_NOCTTY | O_NDELAY);
    if (serial_port == -1) {
            fprintf(stderr, "ERROR: Can't open the device\n");
        return -1;
    }

    tcgetattr(serial_port, &old_tios);

    bzero(&new_tios, sizeof(struct termios));

    switch (BAUDRATE) {
    case 2400:
        speed = B2400;
        break;
    case 4800:
        speed = B4800;
        break;
    case 9600:
        speed = B9600;
        break;
    case 19200:
        speed = B19200;
        break;
    case 38400:
        speed = B38400;
        break;
    case 57600:
        speed = B57600;
        break;
    case 115200:
        speed = B115200;
        break;
    default:
        speed = B19200;
    }

    if ((cfsetispeed(&new_tios, speed) < 0) || (cfsetospeed(&new_tios,
speed) < 0)) {
        close(serial_port);
        serial_port = -1;
            fprintf(stderr, "ERROR: Can't set the baudrate\n");
        return -1;
    }

    new_tios.c_cflag |= (CREAD | CLOCAL);

    new_tios.c_cflag &= ~CSIZE;
    new_tios.c_cflag |= CS8;

    new_tios.c_cflag &= ~CSTOPB;

    new_tios.c_cflag &= ~CRTSCTS;

    new_tios.c_cflag &= ~PARENB;

    new_tios.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

    new_tios.c_iflag &= ~INPCK;

    new_tios.c_iflag &= ~(IXON | IXOFF | IXANY);

    new_tios.c_oflag &= ~OPOST;

    new_tios.c_cc[VMIN] = 0;
    new_tios.c_cc[VTIME] = 0;

    if (tcsetattr(serial_port, TCSANOW, &new_tios) < 0) {
        close(serial_port);
        serial_port = -1;
            fprintf(stderr, "ERROR: Can't set the port parameters\n");
        return -1;
    }
    fcntl(serial_port, F_SETFL, 0);
    return 0;
}

void portclose(void) {
    tcsetattr(serial_port, TCSANOW, &old_tios);
    close(serial_port);
}

int portflush(void) {
    return tcflush(serial_port, TCIOFLUSH);
}

int portsend(const unsigned char *req, const unsigned char req_length) {
    return write(serial_port, req, req_length);
}

int portread(unsigned char *rsp, const unsigned int rsp_length, const
unsigned long long int read_timeout) {
    unsigned char pos = 0;
    struct timeval start, now;

    gettimeofday(&start, NULL);

    while (1) {
        //onebyte_time_in_us = (1000 * 1000) * (1 + data_bit + (parity ==
'N' ? 0 : 1) + stop_bit) / baud;
        int n = read(serial_port, &rsp[pos], rsp_length - pos);

        if (n < 0) {
            //read failed
            return 1;
        }
        if (n == 0) { //nincs olvasott adat
            gettimeofday(&now, NULL);
            if ((now.tv_sec - start.tv_sec) * 1000 * 1000 + now.tv_usec -
start.tv_usec > read_timeout) {
                //túlléptük a teljes olvasásra szánt időt
                return 2;
            }
            usleep(1000); //várunk egy kicsit
            continue;
        }
        pos += n;
        if (pos == rsp_length) {
            break;
        }
    }
    return 0;
}

int main() {
    unsigned char buffer[256];
    unsigned int hany_bajtot_kuldok;
    unsigned int hany_bajtot_olvasok;
    unsigned long long int timeout_us_ben;
    unsigned char i;

    if (portopen() < 0) {
        return -1;
    }
    hany_bajtot_kuldok = 30;
    portsend("ezt kuldom ki a soros portra\r\n", 30);

    hany_bajtot_olvasok = 12;
    timeout_us_ben = 1000 * 1000; //1 sec
    i = portread(buffer, hany_bajtot_olvasok, timeout_us_ben);

    portflush();
    portclose();
    return 0;
}


üdv.
Steve



2014. augusztus 13. 2:28 Gergely Vakulya írta, <antiemes at gmail.com>:

> Udvozletem!
>
> Remelhetoleg elektro-kozeli a tema. Mindenesetre kellett hozza szkop...
>
> Soros portra valo irassal szenvedek. A soros portot egy soros-USB
> atalakito testesiti meg. A gondom az, hogy mig a write fuggveny vigan
> visszaadja, hogy kiirta az osszes byte-ot, valojaban azok nem jelennek
> meg a porton. Ez a kod:
> #include <sys/time.h>
> #include <sys/types.h>
> #include <unistd.h>
> #include <termios.h>
> #include <stdio.h>
> #include <fcntl.h>
> #include <sys/signal.h>
> #include <stdlib.h>
> #include <string.h>
>
> #define BAUDRATE B300
> #define MODEMDEVICE "/dev/ttyUSB0"
> #define _POSIX_SOURCE 1 /* POSIX compliant source */
> #define FALSE 0
> #define TRUE 1
>
> int main()
> {
>   int    fd_serial;
>   struct termios oldtio,newtio;
>
>   fd_serial = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_SYNC);
>   if (fd_serial <0)
>   {
>     perror(MODEMDEVICE);
>     exit(-1);
>   }
>
>   tcgetattr(fd_serial,&oldtio); /* save current port settings */
>
>   bzero(&newtio, sizeof(newtio));
>   //newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
>   newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
>   newtio.c_iflag = IGNPAR;
>   newtio.c_oflag = 0;
>
>   /* set input mode (non-canonical, no echo,...) */
>   newtio.c_lflag = 0;
>
>   newtio.c_cc[VTIME]    = 0;   /* inter-character timer unused */
>   newtio.c_cc[VMIN]     = 1;   /* blocking read until 1 chars received */
>
>   tcflush(fd_serial, TCIFLUSH);
>   tcsetattr(fd_serial,TCSANOW,&newtio);
>
>
>   int fd_file;
>   int rbyte;
>   char rbuf[64];
>   int cum=0;
>
>   fd_file=open("transdisklong", O_RDONLY);
>   while ((rbyte=read(fd_file, rbuf, 1))>0)
>   {
>     int x;
>     printf("Elotte\n");
>     x=write(fd_serial, rbuf, rbyte);
>     printf("Utana %d\n", x);
>     cum+=rbyte;
>     printf("%d\n", cum);
>     usleep(100000);
>   }
>
>   tcsetattr(fd_serial,TCSANOW,&oldtio);
>   close(fd_serial);
>   close(fd_file);
>
>   return 0;
> }
>
> Az x valtozoba kerul bele elvileg az, hogy hany byte-ot ir ki. Ott
> mindig annyi van, amennyit kiiratok. Ha mondjuk kiszedem az usleepet
> es nem 1 byte-ot irok ki, hanem 64-et, akkor az elso csomag kimegy,
> majd a program oruletes sebesseggel vegez. Ha a csomagok kozott
> varakozok, akkor latszolag minden rendben, de igy is maradnak ki
> csomagok. De persze a program azt jelzi, hogy kiment az osszes byte.
>
> Ami meg erdekesebb, hogy ha kiveszem a kesleltetest, akkor tobbet mar
> egyaltalan nem is megy ki adat a porton. Kezdek megorulni, hogy egy
> ilyen ver primitiv dolog nem megy.
>
> 73/DX
> HA4UC Gergo
>
> -----------------------------------------
>           elektro[-flame|-etc]
>


More information about the Elektro mailing list