Avatar billede mathilde2003 Nybegynder
09. maj 2003 - 14:33 Der er 3 kommentarer og
1 løsning

Programmering til seriel port under Linux

Hej,

Jeg skriver et program i C++ hvor jeg gerne vil sende karakterer ud på en seriel port.
Jeg kan åbne porten med open(), men når jeg skriver til den med write() får jeg en segmentation fault! Hvorfor?
Hvordan kan jeg få lov til at skrive til porten fra C++? Mangler jeg en opsætning af porten? Kodeeksempler velkomne!
Avatar billede disky Nybegynder
09. maj 2003 - 14:36 #1
Dette eksempel snakker med en Suunto Dykkercomputer via Seriel porten:

/*
* vyperlink.c Downloads Profile data from Suunto Vyper and compatible
* computers.
*
* (c) 2002 Andreas Beck <becka@bedatec.de>
*
* Important bugfixes for cooperation with the original Suunto interface
* (c) 2002 Mike Brodbelt (mike@coruscant.demon.co.uk)
*
* This program is free software; you can redistribute it and/or modify it     
* under the terms of the GNU General Public License as published by the       
* Free Software Foundation; either version 2 of the License, or (at your     
* option) any later version.                                                 
*                                                                             
* This program is distributed in the hope that it will be useful, but         
* WITHOUT ANY WARRANTY; without even the implied warranty of                 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General   
* Public License for more details.                                           
*                                                                             
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,     
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA                       
*/

#include <fcntl.h>
#include <sys/termios.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <strings.h>
#include <string.h>
#include <limits.h>
#include <time.h>

#define _GNU_SOURCE
#include <getopt.h>

#include "rcfile.h"

static struct comm_pars {
    int extraanswertime;
    int ifacealwaysechos;
    int breakprofreadearly;
    struct termios old_termios;
} comm_pars= {
    1,
    0,
    1,    /* unset this if you are experiencing problems at the end of dives */
};

#define SETBIT(fd,bit)    \
    int bits=bit;        \
    if (ioctl(fd,TIOCMBIS,&bits)==-1) {    \
        fprintf(stderr,"%s:%d:Error setting bit "#bit".\n",__FILE__,__LINE__); \
        perror("Error");    \
        return -1;    \
    }

#define CLEARBIT(fd,bit)    \
    int bits=bit;        \
    if (ioctl(fd,TIOCMBIC,&bits)==-1) {    \
        fprintf(stderr,"%s:%d:Error clearing bit "#bit".\n",__FILE__,__LINE__); \
        perror("Error");    \
        return -1;    \
    }

static int set_dtr(int fd) {
    SETBIT(fd,TIOCM_DTR)
    return 0;
}

static int clear_dtr(int fd) {
    CLEARBIT(fd,TIOCM_DTR)
    return 0;
}

static int set_rts(int fd) {
    SETBIT(fd,TIOCM_RTS)
    return 0;
}

static int clear_rts(int fd) {
    CLEARBIT(fd,TIOCM_RTS)
    return 0;
}


int close_serial(int fd) {

    if (tcsetattr(fd,TCSANOW,&comm_pars.old_termios)==-1) {
        fprintf(stderr,"%s:%d:Failed to reset terminal attributes.\n",__FILE__,__LINE__);
        perror("Error");
        close(fd);
        return -1;
    }

    close(fd);

    return 0;
}

int open_serial(const char * device) {

    struct termios settings;
    int fd;

    fd=open(device, O_RDWR | O_NOCTTY | O_NDELAY);
    if (fd==-1) {
        fprintf(stderr,"%s:%d:Can't open serial port %s.\n",__FILE__,__LINE__,device);
        perror("Error");
        return -1;
    }

    if (!isatty(fd)) {
        fprintf(stderr,"%s:%d:Huh? %s is not a terminal-device.\n",__FILE__,__LINE__,device);
        close(fd);
        return -1;
    }

    fcntl(fd, F_SETFL, 0);    /* Restore block on read behaviour opened nonblocking to avoid
                  waiting for modem lines to come up*/

    if ((tcgetattr(fd, &comm_pars.old_termios)) == -1) {
        fprintf(stderr,"%s:%d:Can't save old termios for %s.\n",__FILE__,__LINE__,device);
        close(fd);
        return -1;
    }
    tcflush(fd, TCIFLUSH);
 
    settings.c_iflag=IGNBRK|IGNPAR;
    settings.c_oflag=0;
    settings.c_cflag= CS8    /* 8 bit */
            | CREAD  /* input on */
            | PARENB
            | PARODD
            | CLOCAL /* ignore modem status lines */;

    settings.c_lflag=0;        /* nothing special */ 

    settings.c_cc[VTIME]=0;  /* set timeout */
    settings.c_cc[VMIN]=0;  /* We do select() */
 
    if (cfsetspeed(&settings,B2400)!=0) {
        fprintf(stderr,"%s:%d:Failed to set baud rate for %s.\n", __FILE__, __LINE__, device);
        return -1;
    }

    /*Set parameters defined above to the serial device*/
    if (tcsetattr(fd,TCSANOW,&settings)==-1) {
        fprintf(stderr,"%s:%d:Failed to set terminal attributes on %s.\n",__FILE__,__LINE__,device);
        perror("Error");
        return -1;
    }

    if (set_dtr(fd)||clear_rts(fd)) {
        fprintf(stderr,"%s:%d:Error setting RTS/DTR state on %s.\n",__FILE__,__LINE__,device);
        return -1;
    }

    usleep(100000);    /* Give the interface 100ms to settle and draw power up. */

    return fd;
}


static int write_serial(int fd,unsigned char *buffer,int len) {

    int rc;
    set_rts(fd);
    rc=write(fd,buffer,len);
    tcdrain(fd);
    usleep(200000);
    clear_rts(fd);
    return rc;
}

static unsigned char mk_crc(unsigned char *buffer,int len) {

    unsigned char erg=0;
   
    while(len--) erg^=*buffer++;
    return erg;
}

#define TIMEOUT 500000

static int read_serial(int fd,int extratime) {

    unsigned char ret;
    fd_set fds;
    int rc;
    struct timeval tv;
   
    FD_ZERO(&fds);
    FD_SET(fd,&fds);
    tv.tv_sec=extratime;
    tv.tv_usec=TIMEOUT;
   
    rc=select(fd+1,&fds,NULL,NULL,&tv);
/*    fprintf(stderr,"select off at %d.%6d .\n",tv.tv_sec,tv.tv_usec); */
    if (rc!=1) return -1;
    read(fd,&ret,sizeof(ret));
    return ret;
}

static int send_testcmd(int fd,unsigned char *cmd) {

    int len=strlen(cmd);

    if (len!=write(fd,cmd,len)) {
        fprintf(stderr,"%s:%d:Trouble sending test sequence to interface.\n",__FILE__,__LINE__);
        perror("Error:");
        return -1;
    }
    tcdrain(fd);
    return 0;
}

int detect_interface(int fd) {

    int rc,detectmode_worked=1;

    set_rts(fd);    /* Charge power supply? */
    usleep(300000);
    clear_rts(fd);    /* Try detection mode first */
    if (send_testcmd(fd,"AT\r")) return -1;    /* Failed to send? Huh? */
    if ('A' !=read_serial(fd,0)||
        'T' !=read_serial(fd,0)||
        '\r'!=read_serial(fd,0)) {
            fprintf(stderr,"%s:%d:Interface not responding in probe mode.\n",__FILE__,__LINE__);
            detectmode_worked=0;
    }
    if (-1 !=(rc=read_serial(fd,0))) {
            fprintf(stderr,"%s:%d:Got extraneous character %02x in detection phase - maybe line is connected to a modem?\n",__FILE__,__LINE__,rc);
    }
    set_rts(fd);    /* Try transfer mode now */
    if (send_testcmd(fd,"AT\r")) return -1;    /* Failed to send? Huh? */
    clear_rts(fd);
    rc=read_serial(fd,0);
    if (rc==-1) {
        if (detectmode_worked) {
            fprintf(stderr,"%s:%d:Detected original sunnto interface with RTS-switching.\n",__FILE__,__LINE__);
        } else {
            fprintf(stderr, "%s:%d:Can't detect Interface.\n"
                    "Hoping it's an original sunnto interface with DC already attached.\n",__FILE__,__LINE__);
        }
        comm_pars.ifacealwaysechos=0;
        return 0;
    }

    if ('A' !=rc||
        'T' !=read_serial(fd,0)||
        '\r'!=read_serial(fd,0)) {
            fprintf(stderr,"%s:%d:Interface not responding when RTS is on. Strange.\n",__FILE__,__LINE__);
    }
    if (-1 !=(rc=read_serial(fd,0))) {
            fprintf(stderr,"%s:%d:Got extraneous character %02x in detection phase - maybe line is connected to a modem?\n",__FILE__,__LINE__,rc);
    }
    fprintf(stderr,"%s:%d:Detected clone interface without RTS-switching.\n",__FILE__,__LINE__);
    comm_pars.ifacealwaysechos=1;
    return 0;
}


static int vyper_send_command(int fd,unsigned char *commbuffer, int len) {

    int ret;

    usleep(500000);
    write_serial(fd,commbuffer,len);
    if (comm_pars.ifacealwaysechos) {
        while(len--) {
            ret=read_serial(fd,0);    /* these are echos - should be there instantly */
            if (ret==-1) {
                fprintf(stderr,"%s:%d:Timeout waiting for echos.\n",__FILE__,__LINE__);
                return -1;
            }
            if (ret!=*commbuffer++) {
                fprintf(stderr,"%s:%d:Echo incorrect. Expected %02x, got %02x.\nMaybe another device is listening on this port?",__FILE__,__LINE__,commbuffer[-1],ret);
                return -2;
            }
        }
    }
    return 0;
}

static int vyper_read_memory(int fd,int start,unsigned char *retbuffer,int len) {

    unsigned char command[]={0x05,
            0x00, /* high  */
            0x00, /* low  */
            0x01, /* count */
            0x00  /* CRC  */};
    unsigned char reply[4]={0,0,0,0};
    int i;
    unsigned char crc=0x00;

    command[1]=(start>>8)&0xff;
    command[2]=(start  )&0xff;
    command[3]=len;
    command[4]=mk_crc(command,4);


    if (vyper_send_command(fd,command,5)) {
        fprintf(stderr,"%s:%d:Error sending command.\n",__FILE__,__LINE__);
        return -1;
    }

    /* Give the DC extra answer time to send its first byte, then let the standard timeout apply  */
    if ((reply[0]=read_serial(fd,comm_pars.extraanswertime))!=command[0]||
        (reply[1]=read_serial(fd,0))!=command[1]||
        (reply[2]=read_serial(fd,0))!=command[2]||
        (reply[3]=read_serial(fd,0))!=command[3]) {
        fprintf(stderr,"%s:%d:Reply to read memory malformed (expected %02x%02x%02x%02x, got %02x%02x%02x%02x).\n",
            __FILE__,__LINE__,
            command[0],command[1],command[2],command[3],
            reply[0]  ,reply[1]  ,reply[2]  ,reply[3]);
        if (reply[0]==255) {
            fprintf(stderr,"%s:%d:Interface present, but DC does not answer. Check connection.\n",__FILE__,__LINE__);
        }
        return -1;
    }
    crc=command[0]^command[1]^command[2]^command[3];
    printf("VyperRead(0x%04x,%d)=\"",(command[1]<<8)|command[2],command[3]);
    for(i=0;i<len;i++) {
        retbuffer[i]=read_serial(fd,0);
        printf("%02x",retbuffer[i]);
        crc^=retbuffer[i];
    }
    printf("\"\n");
    if (crc!=read_serial(fd,0)) {
        fprintf(stderr,"%s:%d:Reply failed CRC check. Line noise?\n",__FILE__,__LINE__);
        return -1;
    }
    return 0;
}

static int vyper_prepare_write_memory(int fd) {

    unsigned char command[]={0x07,
            0xa5, /* Magic? */
            0x00  /* CRC  */};
    unsigned char reply[3]={0,0,0};
    command[2]=mk_crc(command,2);

    if (vyper_send_command(fd,command,3)) {
        fprintf(stderr,"%s:%d:Error sending command.\n",__FILE__,__LINE__);
        return -1;
    }

    /* Give the DC extra answer time to send its first byte, then let the standard timeout apply  */
    if ((reply[0]=read_serial(fd,comm_pars.extraanswertime))!=command[0]||
        (reply[1]=read_serial(fd,0))!=command[1]||
        (reply[2]=read_serial(fd,0))!=command[2]) {
        fprintf(stderr,"%s:%d:Reply to read memory malformed (expected %02x%02x%02x%02x, got %02x%02x%02x%02x).\n",
            __FILE__,__LINE__,
            command[0],command[1],command[2],command[3],
            reply[0]  ,reply[1]  ,reply[2]  ,reply[3]);
        if (reply[0]==255) {
            fprintf(stderr,"%s:%d:Interface present, but DC does not answer. Check connection.\n",__FILE__,__LINE__);
        }
        return -1;
    }
    printf("VyperPrepareWrite();\n");
    return 0;
}

static int vyper_write_memory(int fd,int start,unsigned char *retbuffer,int len) {

    unsigned char command[37]={0x06,
            0x00, /* high  */
            0x00, /* low  */
            0x01, /* count */
            0x00  /* data+CRC */};
    unsigned char reply[5]={0,0,0,0,0};
    int i;
    unsigned char crc=0x00;

    command[1]=(start>>8)&0xff;
    command[2]=(start  )&0xff;
    command[3]=len;
    for(i=0;i<len;i++) {
        command[4+i]=retbuffer[i];
    }
    command[4+i]=mk_crc(command,4+i);

    if (vyper_send_command(fd,command,5+i)) {
        fprintf(stderr,"%s:%d:Error sending command.\n",__FILE__,__LINE__);
        return -1;
    }

    printf("VyperWrite(0x%04x,%d,\"",(command[1]<<8)|command[2],command[3]);
    for(i=0;i<len;i++) {
        printf("%02x",command[4+i]);
    }
    printf("\");\n");

    /* Give the DC extra answer time to send its first byte, then let the standard timeout apply  */
    if ((reply[0]=read_serial(fd,2+comm_pars.extraanswertime))!=command[0]||
        (reply[1]=read_serial(fd,0))!=command[1]||
        (reply[2]=read_serial(fd,0))!=command[2]||
        (reply[3]=read_serial(fd,0))!=command[3]) {
        fprintf(stderr,"%s:%d:Reply to write memory malformed (expected %02x%02x%02x%02x, got %02x%02x%02x%02x).\n",
            __FILE__,__LINE__,
            command[0],command[1],command[2],command[3],
            reply[0]  ,reply[1]  ,reply[2]  ,reply[3]);
        if (reply[0]==255) {
            fprintf(stderr,"%s:%d:Interface present, but DC does not answer. Check connection.\n",__FILE__,__LINE__);
        }
        return -1;
    }
    crc=command[0]^command[1]^command[2]^command[3];
    if (crc!=read_serial(fd,0)) {
        fprintf(stderr,"%s:%d:Reply failed CRC check. Line noise?\n",__FILE__,__LINE__);
        return -1;
    }
    return 0;
}

static int vyper_get_profile(int fd,int start,unsigned char *retbuffer,int len) {

    unsigned char command[]={0x08,0xa5,
            0x00  /* CRC  */};
    int i,j,slen,rc,crc;

    if (start) command[0]=0x08;
    else      command[0]=0x09;
    command[2]=mk_crc(command,2);

    if (vyper_send_command(fd,command,3)) {
        fprintf(stderr,"%s:%d:Error sending get_profile command.\n",__FILE__,__LINE__);
        return -1;
    }

    for (i=0;i<len;) {
        /* Give DC extra time to start talking. */
        rc=read_serial(fd,comm_pars.extraanswertime);
        if (rc!=command[0]) {
            if (rc==-1) {
                break;
            }
            fprintf(stderr,"%s:%d:Unexpected get_profile answer start byte (%d).\n",__FILE__,__LINE__,rc);
            return -1;
        }
        crc=rc;
        slen=read_serial(fd,0);
        if (slen<0||slen>32) {
            fprintf(stderr,"%s:%d:Unexpected get_profile answer length (%d).\n",__FILE__,__LINE__,slen);
            return -1;
        }
        crc^=slen;
        for(j=0;j<slen&&i<len;j++,i++) {
            retbuffer[i]=rc=read_serial(fd,0);
            if (rc==-1) {
                fprintf(stderr,"%s:%d:Unexpected EOF in get_profile answer.\n",__FILE__,__LINE__);
                return -1;
            }
            crc^=retbuffer[i];
        }
        crc^=read_serial(fd,0);
        if (crc!=0) {
            fprintf(stderr,"%s:%d:Unexpected get_profile answer CRC (%d).\n",__FILE__,__LINE__,crc);
            return -1;
        }
        if (comm_pars.breakprofreadearly && slen!=32)
            break;    /* Last packet. */
    }

    for(j=0;j<i/2;j++) {
        unsigned char hlp;
        hlp=retbuffer[j];
        retbuffer[j]=retbuffer[i-1-j];
        retbuffer[i-1-j]=hlp;
    }

    printf("Vyper%sProfile=\"",command[0]==0x08 ? "First" :"");
    for(j=0;j<i;j++) {
        printf("%02x",retbuffer[j]);
    }
    printf("\"\n");

    return i;
}

struct configdata {
    char devicefile[PATH_MAX+1];
} config = {
    "/dev/vyper",
};

int read_config(void) {

    char *path,*optarg;
    char buffer[1024];
    FILE *in;

    path=findrc(NULL,"vyperlinkrc",R_OK);
    if (!path) return 1;
   
    in=fopen(path,"r");
    if (!in) {
        fprintf(stderr,"Warning: Cannot fopen(%s), though findrc() said read o.k.\n",path);
        return 1;
    }
    while(fgets(buffer,sizeof(buffer),in)) {

        if ((optarg=strchr(buffer,'\n')))
            *optarg='\0';    /* Strip newline */
        if (*buffer=='#'||*buffer=='\0')
            continue;    /* Strip comments*/

        if (NULL==(optarg=strchr(buffer,':'))) {    /* Find delimiter */
            fprintf(stderr,"Ignoring malformed line in config file %s:\n%s\n",path,buffer);
            continue;
        }
        *optarg++='\0';/* stop */
        while(isspace(*optarg)) optarg++;
        /*  */ if (0==strcasecmp(buffer,"devicefile")) {
            if (strlen(optarg)<sizeof(config.devicefile)) {
                strcpy(config.devicefile,optarg);
            } else {
                fprintf(stderr,"Devicefile: name too long.\nIgnoring.\n");
            }
        } else if (0==strcasecmp(buffer,"extraanswertime")) {
            comm_pars.extraanswertime=atoi(optarg);
        } else if (0==strcasecmp(buffer,"breakprofreadearly")) {
            comm_pars.breakprofreadearly=!!atoi(optarg);
        } else {
            fprintf(stderr,"Ignoring unknown option in %s:\n%s\n",path,buffer);
        }
    }
   
    fclose(in);
    return 0;
}

int main(int argc, char **argv) {
 
    int fd;
    unsigned char rc[16*1024];
    int len;
    char *model="unknown";
    int divecnt;
   
    enum DOWHAT { DW_GETLOG, DW_READ, DW_WRITE } dowhat=DW_GETLOG;
   
    struct adrdata {
        int adr;
        int len;
        unsigned char data[1024];
    } rw_data={
        0x002c,
        30,
        "VYPERLINK                    "
    };
   
    enum MODEL { M_UNKNOWN, M_VYPER, M_SPYDER_OLD, M_SPYDER_NEW } cmodel=M_UNKNOWN;

    read_config();

    while(1) {
   
        static struct option long_options[] = {
            { "device",1,0,'d' },
            { "read",1,0,'r' },
            { "write",1,0,'w' },
            { 0,0,0,0}
        };
        int c;
       
        c=getopt_long(argc,argv,"d:r:w:",long_options,NULL);
        if (c==-1) break;
       
        switch(c) {
       
            case 'd':
                if (strlen(optarg)>=sizeof(config.devicefile)) {
                    fprintf(stderr,"%s: Path to device file too long.\n",argv[0]);
                    return 1;
                }
                strcpy(config.devicefile,optarg);
                break;
            case 'r':
                if (2!=sscanf(optarg,"%i,%i",&rw_data.adr,&rw_data.len)||rw_data.len>sizeof(rw_data.data)) {
                    fprintf(stderr,"Parameter error for read request.\n");
                    return 1;
                }
                fprintf(stderr,"User requested to read %d values at 0x%04x.\n",rw_data.len,rw_data.adr);
                dowhat=DW_READ;
                break;
            case 'w': {
                int x;
                char *hlp;
                if (2!=sscanf(optarg,"%i,%i,",&rw_data.adr,&rw_data.len)||rw_data.len>sizeof(rw_data.data)) {
                    writeparmerr:
                    fprintf(stderr,"Parameter error for write request.\n");
                    return 1;
                }
                hlp=strchr(optarg,',');
                if (hlp) hlp=strchr(hlp+1,',');
                if (hlp) hlp++;
                for(x=0;x<rw_data.len;x++) {
                    switch(*hlp) {
                        case '0':case '1':case '2':case '3':case '4':
                        case '5':case '6':case '7':case '8':case '9':
                            rw_data.data[x]=*hlp-'0';
                            break;
                        case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':
                            rw_data.data[x]=*hlp-'a'+10;
                            break;
                        case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':
                            rw_data.data[x]=*hlp-'A'+10;
                            break;
                        default:
                            fprintf(stderr,"Byte %d malformed (%c).\n",x,*hlp);
                            goto writeparmerr;
                    }
                    hlp++;rw_data.data[x]<<=4;
                    switch(*hlp) {
                        case '0':case '1':case '2':case '3':case '4':
                        case '5':case '6':case '7':case '8':case '9':
                            rw_data.data[x]|=*hlp-'0';
                            break;
                        case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':
                            rw_data.data[x]|=*hlp-'a'+10;
                            break;
                        case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':
                            rw_data.data[x]|=*hlp-'A'+10;
                            break;
                        default:
                            fprintf(stderr,"Byte %d malformed (%c).\n",x,*hlp);
                            goto writeparmerr;
                    }
                    hlp++;
                }
                fprintf(stderr,"User requested to write %d values at 0x%04x.\nValues are: ",rw_data.len,rw_data.adr);
                for(x=0;x<rw_data.len;x++) {
                    fprintf(stderr,"%02x",rw_data.data[x]);
                }
                fprintf(stderr,"\n");
                dowhat=DW_WRITE;
                } break;
            default :
                fprintf(stderr,"Usage: %s [-d devicename] [-r adr,len]\n",argv[0]);
                return 1;
        }
    }   

    fd=open_serial(config.devicefile);
    if (fd<0) {
        fprintf(stderr,"%s:%d:Error opening serial port. Aborting.\n",__FILE__,__LINE__);
        return -1;
    }
    if (detect_interface(fd)) {
        fprintf(stderr,"%s:%d:Interface not found.\n",__FILE__,__LINE__);
        goto bailout;
    }

    printf("# generated by vyperlink (c) 2002 Andreas Beck [becka@bedatec.de]\n");
    if (vyper_read_memory(fd,0x24,rc,1)) {
        fprintf(stderr,"%s:%d:Cannot identify computer. Sorry.\n",__FILE__,__LINE__);
        goto bailout;
    }
    switch(rc[0]) {
        case 20:
        case 30:
        case 40:fprintf(stderr,"Probably Spyder. Checking further.\n");
            if (vyper_read_memory(fd,0x16,rc,2)) {
                fprintf(stderr,"%s:%d:Cannot identify Spyder. Sorry.\n",__FILE__,__LINE__);
                goto bailout;
            }
            if (rc[0]==0x01&&rc[1]==0x01) {
                cmodel=M_SPYDER_OLD;
                model="old Spyder";
                goto showmodel;
            } else if (rc[0]==0x01&&rc[1]==0x02) {
                cmodel=M_SPYDER_NEW;
                model="new Spyder";
                goto showmodel;
            } else {
                fprintf(stderr,"%s:%d:Cannot identify Spyder. Firmware:%02x.%02x. Sorry.\n",__FILE__,__LINE__,rc[0],rc[1]);
                goto bailout;
            }
            break;
        case 0x0c:
            model="old Cobra/Vyper";
            cmodel=M_VYPER;
            showmodel:
            fprintf(stderr,"Found %s.\n",model);
            break;
        case 0x0a:
            model="new Vyper";goto showmodel;
        case 0x03:
            model="Stinger";goto showmodel;
        case 0x04:
            model="Mosquito";goto showmodel;
        default:
            fprintf(stderr,"Unknown DC %02x detected. Aborting.\n",rc[0]);
            goto bailout;
    }
    if (dowhat==DW_READ) {
        int x;
        if (vyper_read_memory(fd,rw_data.adr,rw_data.data,rw_data.len)) {
            fprintf(stderr,"Cannot read memory. Sorry.");
            return 1;
        }
        printf("Read memory gives: 0x%x,%d,",rw_data.adr,rw_data.len);
        for(x=0;x<rw_data.len;x++) {
            printf("%02x",rw_data.data[x]);
        }
        printf("\n");
       
        return 0;
    }
    if (dowhat==DW_WRITE) {
        fprintf(stderr, "##############################################################\n"
                "# WRITING TO THE COMPUTER IS DANGEROUS !!!!!!!!!!!!!!!!!!!!! #\n"
                "##############################################################\n"
                "\a\n"
                "This functionality is untested and could damage the computer.\n"
                "It is possible that the computer might malfunction and thus\n"
                "you might endanger your health, if you rely on it for decompression\n"
                "and depth information.\n"
                "\n"
                "If you are not absolutely sure about what you are doing, please\n"
                "abort now by pressing Ctrl-C. If that doesn't work, remove the\n"
                "computer from the interface NOW.\n"
                "\n"
                "Writing will begin in 10 seconds.\n");
        sleep(10);
        if (vyper_prepare_write_memory(fd)) {
            fprintf(stderr,"Preparing memory for writing failed.Abort.\n");
            return 1;
        }
        if (vyper_write_memory(fd,rw_data.adr,rw_data.data,rw_data.len)) {
            fprintf(stderr,"Ouch - failed to write memory. Hope the DC is still alive.\n");
            return 1;
        }
        return 0;
    }

    /* This works generically on both DCs */
    fprintf(stderr,"Fetching additional Info.\n");
    if (vyper_read_memory(fd,0x2c,rc,30)) {
        fprintf(stderr,"Cannot read persinfo. Sorry.");
        goto bailout;
    }
    if (vyper_read_memory(fd,0x18,rc,18)) {
        fprintf(stderr,"Cannot read summary data. Sorry.");
        goto bailout;
    }
    divecnt=1;
    len=vyper_get_profile(fd,1,rc,sizeof(rc));
    while(len>14) {
        fprintf(stderr,"Processing Dive #%d.\r",divecnt++);
        fflush(stderr);
        len=vyper_get_profile(fd,0,rc,sizeof(rc));
    }
    printf("VyperEnd\n");

    bailout:
    fprintf(stderr,"\n");
    close_serial(fd);
    return(0);
}
Avatar billede mathilde2003 Nybegynder
12. maj 2003 - 09:23 #2
OK, det virker når jeg kopierer din kode fra open_serial! Kan du gi et link til hvor jeg finder overskuelig dokumentation på ting som termios, tcsetattr(), cfsetspeed(), tcflush() osv. da jeg ikke forstår din kode helt?
Avatar billede mickni33 Nybegynder
12. maj 2003 - 10:49 #3
prøv at skrive

$> man termios

i din prompt
Avatar billede disky Nybegynder
12. maj 2003 - 11:57 #4
desværre ikke :(

Jeg er selv lige begyndt med serial programmering fra linux, og under denne søgning fandt jeg ovenstående eksempel
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester