【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※返信付き投稿の削除は禁止!
 ※マルチポスト(多重投稿)は慎んで!

 詳しくはこちら


本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール掲示板2こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.21270

Linux上でRS232Cプログラム
投稿者---ccc(2005/06/08 15:20:36)


LinuxでRS232Cのプログラムを作っているのですが、
コンパイル後、実行すると以下のエラー文がでます。

  /dev/ttys1: Input/output error

プログラムはコンパイルできるのでいいと思うし、
シリアルポートにケーブルを指し、データを受信できる状態に
セッティングできています。

プログラムは以下のです。一応、データ受信タイプのプログラムです。

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>

#define BAUDRATE B38400
#define MODEMDEVICE "/dev/ttys0"

#define FALSE 0
#define TRUE 1

volatile int STOP = FALSE;

int main()
{
  int fd, c, res;
  struct termios oldtio, newtio;
  char buf[255];
  
  if((fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY )) == -1){
    perror(MODEMDEVICE);
    exit(-1);
  }
     
     tcgetattr(fd, &oldtio);
     bzero(&newtio, sizeof(newtio));
     newtio.c_cflag = (BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD);
     
     newtio.c_iflag = (IGNPAR | ICRNL);
     
     newtio.c_oflag = 0;

     newtio.c_lflag = ICANON;
     
     tcflush(fd, TCIFLUSH);

     tcsetattr(fd, TCSANOW, &newtio);

     while(STOP == FALSE){
       res = read(fd, buf, 255);
       buf[--res] = 0;
       printf(":%s:%d\n", buf, res);
       if(buf[0] == 'z') STOP = TRUE;
     }
     tcsetattr(fd, TCSANOW, &oldtio);
     close(fd);
     return(0);
}


どなたか、ご指摘お願いします。


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:Linux上でRS232Cプログラム 21272 もぐりん 2005/06/08 16:57:11


No.21272

Re:Linux上でRS232Cプログラム
投稿者---もぐりん(2005/06/08 16:57:11)


>LinuxでRS232Cのプログラムを作っているのですが、
>コンパイル後、実行すると以下のエラー文がでます。
>
>  /dev/ttys1: Input/output error
>

WindowsでいうところのCOM1は/dev/ttys0なんでは?

こちらにRS232Cのテスト用のソースがあります。
http://natsci.kyokyo-u.ac.jp/~takasima/LHCfile/com1.c
/dev/ttyS0をつかってwindowsマシンとつないでみたところ、8bit偶数パリティ9600bpsで接続できているそうです。



この投稿にコメントする

削除パスワード

No.21288

Re:Linux上でRS232Cプログラム
投稿者---ccc(2005/06/08 23:20:12)


お返事ありがとうございます。
テスト用のプログラム試して見ます。

こちらに載せていただいたプログラムなんですが、
/dev/ttyS0 
と記入しても同じエラーがでます。

PCを2つ繋げて、両機に記載させていただいた、
プログラムを実行しても、意味ないのでしょうか?
送信するという文は付けていないのですが。

そしてもう一つ、RS232Cの送信できる
プログラムを作っているのですが、
下記の記載させていただいたプログラムに
間違っているところはあるのでしょうか?

一応コンパイルは通るのですが、実行時に同じエラーがでるので
分からなくて困っています。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>

#define BAUDRATE B38400
#define MODEMDEVICE "/dev/ttys0"

#define FALSE 0
#define TRUE 1

volatile int STOP = FALSE;

int main()
{
  int fd, c, res;
  struct termios oldtio, newtio;
  char buf[255];
  char wbuf[255] = "hoge\r\n";


  if((fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY )) == -1){
    perror(MODEMDEVICE);
    exit(-1);
  }

  tcgetattr(fd, &oldtio);
  bzero(&newtio, sizeof(newtio));
  newtio.c_cflag = (BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD);
  newtio.c_oflag = (IGNPAR | ICRNL);
  newtio.c_lflag = ICANON;

  tcflush(fd, TCIFLUSH);
  tcsetattr(fd, TCSANOW, &newtio);

  while(STOP = FALSE){
    write(fd, wbuf, 255);
    read(fd, buf, 255);
  }
  func(buf);

  tcsetattr(fd, TCSANOW, &oldtio);
  close(fd);
  return(0);
} 
 




この投稿にコメントする

削除パスワード

No.21296

Re:Linux上でRS232Cプログラム
投稿者---もぐりん(2005/06/09 10:24:47)


まずは、Linuxにてシリアルポート(ttyS0)が使用できるのか確認してますか?
こちらのホームページを見ながら設定を確認してください。
http://www.shoshin.co.jp/computer/lsi/scs/faqlinux.html
また、そのPCのBIOSの設定でcom1がdisableになっていたら、enableに変更する必要があります。(要は物理的に無効になっていないかの確認)
その辺を全てクリアしてからサンプルソースを試してみるなり、Windowsのハイパーターミナルで接続してみてください。
ちなみにクロスケーブルですよね?
モデムと接続するためのストレートケーブルでは、他のPCとは接続できません。



この投稿にコメントする

削除パスワード

No.21466

Windows上でRS232Cプログラム
投稿者---ccc(2005/06/16 13:26:38)


いろいろご指摘ありがとうございました。

BIOSとか見てCOMポートを使えるように設定していると思うのですがなかなかうまくいきません。

Windows上でも新しくプログラムを作って試しているのですが、やはりポートの部分でエラーが出ます。ちなみに、シリアルポートを使うほかのソフトウェアを使用してみるときちんと起動します。
どうやらプログラムがおかしいのだと思うのですが、本を見てきちんと作っているのですがなぜでしょうか。

CreateFileを使った部分がうまくいかなくて、hComの値が-1になり、エラーが出ます。何か間違っているのでしょうか。
ちなみにこちらのプログラムは、読み込み専用です。

#include <windows.h>
#include <iostream>
#include <stdio.h>

using namespace std;

int main()
{
    HANDLE hCom;
    char buf[16];
    DWORD size;
    BOOL          Ret;            // 関数戻り値
    
    //ポートの初期化
    hCom = CreateFile("\\\\.\\COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    printf("%d  \n",hCom);
    if(hCom  == INVALID_HANDLE_VALUE){
        printf("port could not open \n");
        exit(0);
    }

        // 送受信バッファ初期化
    Ret = SetupComm(hCom, 4096, 4096);
    if(Ret == FALSE){
        printf("SetupComm failed.\n");
        CloseHandle(hCom);
        exit(0);
    }   
    Ret = PurgeComm(hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
    if(Ret == FALSE){   
        printf("PurgeComm failed.\n");
        CloseHandle(hCom);
            exit(0);
        }
    
    ReadFile(hCom, buf, strlen("Hello World"), &size, NULL);
    
    
    cout << buf << endl;
    
    getchar();
    
    CloseHandle(hCom);

    return 0;

}




この投稿にコメントする

削除パスワード

No.21467

Re:Windows上でRS232Cプログラム
投稿者---おでん(2005/06/16 17:14:12)


win32sdk.hlp:[Win32 Developer's Referenses]の
Configuring a Communications Resourceに使い方が書いてあります。

GetCommState(hCom, &dcb);あたりをキーに確認してみてください。


この投稿にコメントする

削除パスワード

No.21546

Re:Windows上でRS232Cプログラム
投稿者---ccc(2005/06/22 12:16:47)


GetCommStateを参考にしてつくり変えてみたのですが、ポートは開放されるのにデータの受信ができません。
[受信プログラム]
//通信設定
Ret = GetCommState(hCom, &dcb);

if(Ret == FALSE){
printf("GetCommState error\n");
CloseHandle(hCom);
exit(0);
}


dcb.BaudRate = 9600;
dcb.Parity = 0;
dcb.StopBits = ONESTOPBIT;
dcb.ByteSize = 8;

//通信デバイス構成の初期化
Ret = SetCommState(hCom, &dcb);

if(Ret == FALSE){
printf("SetCommState error\n");
CloseHandle(hCom);
exit(0);
}

for(n=0; n<256; n++)
ReadBuf[n] = n;

ReadFile(hCom, ReadBuf, 256, &Readsize, NULL);

cout << ReadBuf << endl;

getchar();

CloseHandle(hCom);



一応送信のプログラムの一部も張っておきます。
送信データ作成の部分で作ったデータを送っているのですが。
[送信プログラム]
//通信設定
Ret = GetCommState(hCom, &dcb);

if(Ret == FALSE){
printf("GetCommState error\n");
CloseHandle(hCom);
exit(0);
}


dcb.BaudRate = 9600;
dcb.Parity = 0;
dcb.StopBits = ONESTOPBIT;
dcb.ByteSize = 8;

//通信デバイス構成の初期化
Ret = SetCommState(hCom, &dcb);

if(Ret == FALSE){
printf("SetCommState error \n");
CloseHandle(hCom);
exit(0);
}


//送信データ作成
for(n=0; n<256; n++)
SendBuf[n] = n;

//デバイス拡張設定
Ret = EscapeCommFunction(hCom, SETRTS);
if(Ret == FALSE){
printf("EscapeCommFunction  error\n");
CloseHandle(hCom);
exit(0);
}

//データ送信
Ret = WriteFile(hCom, SendBuf, 256, &SendSize, NULL);

if(Ret == FALSE){
printf("WriteFile error \n");
CloseHandle(hCom);
exit(0);
}

CloseHandle(hCom);



おかしな点や間違っている点があればアドバイスお願いします。
よろしくお願いします。


この投稿にコメントする

削除パスワード

No.21605

Re:Windows上でRS232Cプログラム
投稿者---ccc(2005/06/24 14:09:00)


送信のエラーは出ていないので、WriteFileではきちんと送れているんだと思います。
しかし、受信の方でデータが読み込まれません。ReadFileでエラーが出ているわけではないのですが。

自分でもいろいろ調べているのですが、何が問題なのかがわかりません。


この投稿にコメントする

削除パスワード

No.21609

Re:Windows上でRS232Cプログラム
投稿者---tetrapod(2005/06/24 15:41:17)


思うだけでは何の役にも立ちませんよ。

こーいうハードウェア絡みのプログラムは、ハードソフトどちらに問題があってもうまく動きません。
地道に確実に1つづつ動作確認を取っていきましょう。

1.確実に動くプログラムを用意し、ハードウェア的問題があるかどうか確認。
例えば両方のマシンで HyperTerminal を起動します。
片方で入力した文字が相手に正しく送られるかを確認。
HyperTerminal すらうまく動かないのであれば、ハードウェア的問題があります。

2.ハードウェア的問題が無いことを確認した上で、確実に動くプログラム+自作プログラムで確認
片方を自作、片方を HyperTerminal にします。
自作プログラムが送信した結果を HyperTerminal が受信するか確認。
HyperTerminal が送信した結果を自作プログラムが受信するか確認。

そのくらいは確認してあるのですか?

3.最後に自作プログラム同士で動作確認。



この投稿にコメントする

削除パスワード

No.21610

Re:Windows上でRS232Cプログラム
投稿者---ccc(2005/06/24 17:19:58)


>1.確実に動くプログラムを用意し、ハードウェア的問題があるかどうか確認。
>例えば両方のマシンで HyperTerminal を起動します。
>片方で入力した文字が相手に正しく送られるかを確認。
>HyperTerminal すらうまく動かないのであれば、ハードウェア的問題があります。

HyperTerminalは通信できます。

>2.ハードウェア的問題が無いことを確認した上で、確実に動くプログラム+自作プログラムで確認
>片方を自作、片方を HyperTerminal にします。
>自作プログラムが送信した結果を HyperTerminal が受信するか確認。
>HyperTerminal が送信した結果を自作プログラムが受信するか確認。


自作で作ったプログラムでHyperTerminal上に
 //送信データ作成
  for(n=0; n<256; n++)
   SendBuf[n] = n;

で作ったデータを送ると文字化けして表示されますが、何らかのデータは送れました。
文字化けしているということはきちんとデータが送れていないのでしょうか?
それとも、送信したデータはHyperTerminalでは違った表示方法なので、おかしくなっているのでしょうか?


この投稿にコメントする

削除パスワード

No.21611

Re:Windows上でRS232Cプログラム
投稿者---おでん(2005/06/24 17:35:24)


>自作で作ったプログラムでHyperTerminal上に
> //送信データ作成
>  for(n=0; n<256; n++)
>   SendBuf[n] = n;
>
>で作ったデータを送ると文字化けして表示されますが、何らかのデータは送れました。
>文字化けしているということはきちんとデータが送れていないのでしょうか?

>  for(n=0; n<256; n++)
>   SendBuf[n] = n;
>
って、制御コードも送ってますがいいのですか?


この投稿にコメントする

削除パスワード

No.21766

Re:Windows上でRS232Cプログラム
投稿者---ccc(2005/07/04 16:43:12)


一応、同期のプログラムでは通信することができました。

次は、非同期でスレッドを使ったプログラムを作ろうと思っています。
スレッドとかを使ったことがないので悩んでいるのですが、どういったことを勉強すればいいのでしょうか。

スレッドの形としては、Mainに大きなメモリバッファを用意しといて、スレッドの中にあるReadFileでデータを読み込みそのメモリバッファに書き込んでいくという形にしたいのです。
メモリバッファはリングバッファの形にします。

スレッドを使った、部分部分のサンプルはあるのですが、それでは、Mainからどういった形でスレッドに飛んで値を返すのかということがわかりません。
参考になるサンプルコードがあれば紹介してもらいたいのですが。


この投稿にコメントする

削除パスワード

No.21767

Re:Windows上でRS232Cプログラム
投稿者---おでん(2005/07/04 17:58:09)


>スレッドを使った、部分部分のサンプルはあるのですが、それでは、
>Mainからどういった形でスレッドに飛んで値を返すのかということが
>わかりません。

スレッドは関数ではありませんから呼び出したり、値を返したりする
ことは出来ません。また、スレッドから外部の領域(今回の場合は
リングバッファです)にアクセスするには、排他制御が必須となります。

スレッド側
1.シリアルポートからデータを読む。
2.リングバッファ更新のために排他をかける。
3.リングバッファにデータを書き込む。
4.排他を解除する。
5.1に戻る。

main側

1.リングバッファ更新のために排他をかける。
2.リングバッファにデータがあるか確認する。
データなし→4へ
データなし→リングバッファからデータを読み出す
4.排他を解除する。

大体このようになると思います。

#上記処理の間にsleep()等を入れて、スレッドを休止させることを
#忘れないように。

>参考になるサンプルコードがあれば紹介してもらいたいのですが。

検索した結果なので詳しくは読んでいませんので、
お勧めというわけではありませんが・・・

http://www.ncad.co.jp/~komata/c-kouza28.htm
http://www.ops.dti.ne.jp/~allergy/thread/thread.html


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧