[Subject Prev][Subject Next][Thread Prev][Thread Next][Subject Index][Thread Index]

[linux-users:96629] シリアル通信中のRTS端子の制御


はじめまして、竹内 _at_ jornadaと申します。

 現在、シリアルポートで、とあるユニットとの通信を試みているのですが、
問題点が解決できません。どなたかよい知恵を授けて頂けませんでしょうか。


通信方式は簡単に言うと、

(1)TXD、RXD、制御線としてSYNという信号を使用
--->これは現在RTSに接続しています。
(2)送信コマンドは2バイトで、併せてSYN信号を以下のように送信する。

TXD              1バイト目   2バイト目
              _____________
SYN(=RTS) ____|            |_____________ (以降保持)


(3)コマンドを受信後、ユニットはACKデータを送信する(詳細省略)。

となっています。で、1バイト送信中の期間だけRTS端子を操作するようにした
いのですが、標準的なシリアルドライバと、ioctl関数の組み合わせを使った
ところ、以下のようになってしまいました。

TXD              1バイト目   2バイト
               _
SYN(=RTS) ____| |_____________ (以降保持)

 シリアルドライバがRTS信号を操作して、バイト送信時に戻されているよう
なので、ハードウェアフローを切ってみたりもしたのですが変化がありません
でした。

 そこで質問なのですが、このままシリアルドライバに手を入れずに、通信中
でもRTSをコントロールする方法というのはあるのでしょうか?

 ドライバの修正が必要な場合、どこか参考となるサイトがありましたら教え
て頂けると幸いです。

以上、よろしくお願いします。

----------< 以下概略ソース >----------
(*)削除修正等によるミスはご容赦ください。

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/io.h>
#include<sys/ioctl.h>
#include<sys/stat.h>
#include<sys/wait.h>
#include<fcntl.h>
#include<termios.h>
#include<string.h>
#include<time.h>
#include<unistd.h>
#include<errno.h>
#include<sys/resource.h>
#include<sys/ipc.h>
#include<sys/shm.h>

#define STANDBY 0x88
#define RETRY   50
#define E_COMMAND_NAK 0xe0000
#define E_SIO_FD      0xe0001
#define E_RETRY_OVER  0xe0002

unsigned int send_command(unsigned char c); /* command send */
unsigned int irt(void);    /* RTS OFF->ON->OFF */
unsigned int fnopenport(void); /* sio setting */
void exit_sio(void);
int put_sio(char buf[], unsigned int size); /* send data */
int get_sio1byte(char *buf); /* recv data */

int fd;            /* file discripter */

int main(void)
{
  char buf[255];       
  unsigned int modori;

  if(fnopenport()!=0){      /* sio port open */
    printf("sio port open error\n");
  }

  /*==================== INITIALIZE ====================*/
  /*---------- RESET ----------*/
  irt();    /* RTS OFF->ON->OFF */

  /*---------- STAND-BY SEND ---------*/
  modori=send_command(STANDBY);
  if(modori!=0){
    printf("command send error\n");
  }

  /*---------- ACK CHECK ----------*/
  if(get_sio1byte(buf)<0){             /* recv */
    printf("ack check error(recv fault)\n");
  }

  exit_sio();
  return 0;
}

unsigned int send_command(unsigned char c)
{
  int fd;
  unsigned int rts_bit=TIOCM_RTS;
  char buf[10];

  fd=open("/dev/ttyS0", O_RDWR);
  ioctl(fd, TIOCMBIS, &rts_bit);   /* RTS(=IRT) OFF */
  ioctl(fd, TIOCMBIC, &rts_bit);   /* RTS(=IRT) ON  */

  /*========== 1ST COMMAND(=c) SEND ==========*/
  buf[0]=c;
  if(put_sio(buf, 1)<0){
    return E_COMMAND_NAK;
  }

  /*========== SYN SIGNAL HSET ==========*/
  ioctl(fd, TIOCMBIS, &rts_bit);   /* RTS(=IRT) OFF */

  /*========== 2ND COMMAND(=~c) SEND ==========*/
  buf[0]=~c;
  if(put_sio(buf, 1)<0){
    return E_COMMAND_NAK;
  }

  return 0;
}

unsigned int irt(void)
{ /* unit init */
  int fd;
  unsigned int rts_bit=TIOCM_RTS;

  /* reset signal */
  fd=open("/dev/ttyS0", O_RDWR);
  ioctl(fd, TIOCMBIS, &rts_bit);    /* RTS(=IRT) OFF */
  ioctl(fd, TIOCMBIC, &rts_bit);   /* RTS(=IRT) ON = RESET */
  sleep(1);
  ioctl(fd, TIOCMBIS, &rts_bit);   /* RTS(=IRT) OFF */

  return 0;
}

unsigned int fnopenport(void)
{ /* sio setting */
  struct termios tio;

  if((fd=open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NONBLOCK))<0){ 
    return E_SIO_FD;
  }
  bzero(&tio, sizeof(tio));

  /* protocol set */
  tio.c_cflag=B4800 | CS8 | CLOCAL | CREAD | PARENB;
  tio.c_iflag=IGNPAR | INPCK;
  tio.c_oflag=ONLRET;
  tio.c_lflag=0;
  tio.c_cc[VTIME]=0;
  tio.c_cc[VMIN]=1;

  tcflush(fd, TCIFLUSH);
  tcsetattr(fd, TCSANOW, &tio);
  fcntl(fd, F_SETFL, FNDELAY);

  return 0;
}

int get_sio1byte(char *buf)
{ /* recv data */
  unsigned int retry;
  int i;

  for(retry=0;retry<RETRY;retry++){ /* data wait */
    i=read(fd, buf, 1);
    if(i>=0) /*  data input or file end ... exit retry loop */
      break;
    usleep(1500);
  }

  if(retry==RETRY){          /* retry over? */
    printf("RETRY OVER!\n");
    return E_RETRY_OVER;
  }
  return 0;
}

int  put_sio(char buf[], unsigned int size)
{ /* send data */
  int err;
  unsigned char data[1];
  int i;
  err=0;
  for(i=0;i<size;i++){
    data[0]=buf[i];
    err=write(fd, data, 1);
  }
  return err;
}

void exit_sio(void)
{
  close(fd);
}


--------------------
竹内 _at_ jornada
freedom _at_ grn.janis.or.jp

この情報があなたの探していたものかどうか選択してください。
yes/まさにこれだ!   no/違うなぁ   part/一部見つかった   try/これで試してみる

あなたが探していた情報はどのようなことか、ご自由に記入下さい。特に「まさにこれだ!」と言う場合は記入をお願いします。
例:「複数のマシンからCATV経由でipmasqueradeを利用してWebを参照したい場合の設定について」
Follow-Ups: