[완료]RS232C를 이용한 시리얼통신으로 파일전송을 하려고 합니다

토끼아빠의 이미지

시리얼통신으로 파일을 전송하려고 하는데
음 ~ 두 PC를 COM포트로 연결하고 파일을 전송하려 하는데~~
정말 캄캄~~~
제가 왕~~왕초보라서 정말 미안하네요~~
점 도와주세요~~~
뭐 오픈소스같은거 없을가요???

엠브리오의 이미지

"나 좀 도와주세요. 급해요." 라고 물어보면
답변은 당연히 "뭘 도와드릴까요?" 일수 밖에 없습니다.

내용을 알아야 뭔가 답변이 나올텐데 정보가 너무 없군요.

1. com 포트를 가지고 C 프로그래밍을 하겠다는 것인지?
2. 아니면 기존의 있는 프로그램들 가지고 파일전송만 하면 된다는 것인지?
3. 리눅스인지? Windows 인지?

토끼아빠의 이미지

정말 미안하네요~
바쁜 김에 마구 때려넣다나니 아주 엉망이 되어버렸네...
시스템은 리눅스이구요, 목적은 COM 포트를 이용하여 두 PC사이에 파일을 전송하려고 해요~~
헌데 정말 왕초보라서 암것도 모르겠네요~
점 도와주세요~~

좋은 하루 되세요!!

익명 사용자의 이미지

그냥 파일만 전송할꺼면, 윈도라면 버그쟁이 하이퍼터미널 양쪽에 띄워놓고 zmodem이나 기타 프로토콜로 파일 주고받으면 됩니다.
리눅스라면 minicom 패키지랑 zmodem 프로토콜인 lrzsz인가 하는 패키지 깔고 minicom 에서 파일 보낼 수 있습니다.

엠브리오의 이미지

리눅스 끼리의 파일전송 방법은 많습니다.

굳이 com port 를 써야만 한다면 위에 적힌 방법대로 minicom + lrzsz(Z-MODEM) 조합도 가능하고
minicom 에서의 타이핑이 번거로우면 tcp/ip 방식의 ppp 접속 스크립트를 써도 됩니다.

토끼아빠의 이미지

물론 리눅스끼리의 파일전송방법은 많겠죠~~
헌데 전 꼭 com포트를 이용하여 파일을 전송해야 하거든요~~
지금 한창 코딩하고있는데 송신측에서는 그런대로 전송되고있는것 같애요
실지 com 포트에서 나오는 전압을 측정해보았으니깐요~~~ㅎㅎ
그런데 수신측에서는 네발벋치구 안받네요~~
어쩜 좋을가요 '엠브리오'님~~
항상 좋은 답변 주셔서 정말 감사합니다...
마지막까지 좀 도와주세요!!
제가 실현한 소스코드를 한번 좀 봐주세요~~
어데가 잘못되였는지...
송신측
#include
#include
#include
#include
#include

#define BAUDRATE B115200
#define MODEMDEVICE "/dev/ttyS0"
#define _POSIX_SOURCE 1

#define FALSE 0
#define TRUE 1
#define CRTSCTS 020000000000
#define MAX 255
#define DATA_MAX 20
#define GET_DONE 0

FILE *fp1;
FILE *fp2;

long buffsize = 0;

long lFilesize = 0;

char serial_buf[MAX];
int fd;
int res;
struct termios oldtio,newtio;

void serial_open()
{

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

tcgetattr(fd,&oldtio);
bzero(&newtio, sizeof(newtio));

newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;

newtio.c_iflag = ICRNL;

newtio.c_lflag = ICANON;

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

}

void serial_close()
{
tcsetattr(fd,TCSANOW,&oldtio);
close(fd);
}

void send_data( )
{

fp1 = fopen("a","rb");
if( fp1 == NULL )
{
exit(0);
}

fseek(fp1, 0, 2);
lFilesize = ftell(fp1);
fseek(fp1, 0, 0);
res = 0;

while(lFilesize > 0)
{
if(lFilesize > DATA_MAX)
buffsize = DATA_MAX;
else
buffsize = lFilesize;

fread(serial_buf, buffsize,1,fp1);
printf ( "%s",serial_buf);
if(write(fd,serial_buf,buffsize) < 0)
{
printf("Writing Error\n");
exit(0);
}

lFilesize -= buffsize;

bzero(serial_buf,MAX);
}

bzero(serial_buf,MAX);
fclose(fp1);
}

int main()
{
serial_open();
send_data();
printf("Writing SUCCESS!\n");
serial_close();
return 0;
}

수신측
#include
#include
#include
#include
#include

#define BAUDRATE B115200
#define MODEMDEVICE "/dev/ttyS0"
#define _POSIX_SOURCE 1

#define FALSE 0
#define TRUE 1
#define CRTSCTS 020000000000
#define MAX 255
#define DATA_MAX 20
#define GET_DONE 0

FILE *fp1;
FILE *fp2;

long buffsize = 0;

long rFilesize = 0;

char serial_buf[MAX];
int fd;
int res;
struct termios oldtio,newtio;

void serial_open()
{

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

tcgetattr(fd,&oldtio);
bzero(&newtio, sizeof(newtio));

newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;

newtio.c_iflag = ICRNL;

newtio.c_lflag = ICANON;

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

}

void serial_close()
{
tcsetattr(fd,TCSANOW,&oldtio);
close(fd);
}

int main()
{
serial_open();
fp2 = fopen("c","wb");
res =0;

while(read(fd,serial_buf,MAX)) {
printf("%s\n",serial_buf);
fwrite(serial_buf,sizeof(serial_buf),1,fp2);
bzero(serial_buf,MAX);
}
return 0;
}

파일송수신은 후차라도 우선은 한바이트라도 송수신했음 좋겠네요~~
잘 부탁드립니다~~

좋은 하루 되세요!!

그노카스의 이미지

일단, 케이블이.. 크로스로 만들어 져 있는지..
(즉, A컴 송신부가, B컴 수신부.... B컴 송신이 A컴 수신,,,,, 그리고 그라운드까지..)
확인해 보셔야 할 듯 하구요..

소스를 올리셨으면.... 그 소스가 다른 분들이 읽을 수 있게.. 제대로 나오는지 확인을 하심이 좋을듯 합니다.

 이렇게... [code]라는 테그를 사용해서 감싸야 합니다.
그노카스의 이미지

시리얼 연결이 잘 되어 있는지 확인해 보려구 한다면..

A컴(혹은 A장비)에서,

 # cat /dev/ttyS0

B컴 (혹은 B장비 이겠죠?)에서..

 # echo "test" > /dev/ttyS0

이렇게 해서.... A장비에 정상적으로 출력되는지 확인해 보세요.

덧붙여... 질문은 질문 게시판에... 또한 도배는 자제를..

토끼아빠의 이미지

어드바이스 고맙습니다.
A측에서 # cat /dev/ttyS0
B측에서 # echo "test" > /dev/ttyS0
라고 명령 줬는데 A측은 cat명령에서 리턴되지 못하네요~~
즉 두 컴퓨터사이 표준 com통신도 안되는거네~~
이건 어떻게 해야 하죠????
다시 한번 어드바이스 부탁합니다!

좋은 하루 되세요!!

그노카스의 이미지

A의 ttyS0에 데이터가 들어가지 못한겁니다.
이유는 여러가지가 있을껍니다.

케이블 불량부터... 씨피유불량? 까지..

즉 가장 기본적으로 해보셔야 할것이..

cpu에 ttyS0 칩(uArt칩?)에서.. 인터럽트가 뜨는지 부터 보셔야 할껍니다.

즉,

위에서와 마찬가지로.... B컴에서..

cat /bin/busybox(즉, 큰 파일) > /dev/ttyS0

(많은 데이터를 A 컴으로 보내기 위한 방법입니다.)

이렇게 실행해 두고..

A 컴에서..... rx쪽으로 파형이 뜨는지 보고,
rx에 파형이 뜨면, uArt칩에서 인터럽트를 치는지 보고,
uArt칩에서 인터럽트가 뜬다면.... /proc/interupt에... 변화가 있는지.. 커널이 처리하는지
확인해야 할껍니다.

물론, B컴은.. 신뢰성이 있는(즉, 일반 컴퓨터?)를 사용하는 것이
범위를 빠르게 좁혀가는 방법일 껍니다.

토끼아빠의 이미지

"그 노카스"님 항상 고맙네요~
테스터를 가지고 com포트에서 나오는 전압 재여보았는데 RD, TD둘다 항상 12V인데요
송신할 때나 송신 중지되였을 때나 항상 12V네요
대체 뭘 보고 정확히 송신되는지 알아봐야 하나요?
이번에 정말 신세많이 집니다...

좋은 하루 되세요!!

그노카스의 이미지

테스터기로.. 볼 수 없습니다..
물론.. "기인"이라면 가능하겠지만..

Oscillo Scope가 있어야 합니다...

토끼아빠의 이미지

고마워요
제가 워낙 왕초보라서 ...
지금 쓰고있는 COM 라인이 크로스가 아니네요~~
이제 당장 크로서로 바꿔버릴게요
헌데 H/W쪽에서 문제 없다면 코딩을 어떻게 하면 될가요?
시리얼통신하는 간단한 샘플 있으면 좀....

좋은 하루 되세요!!

cookielounge의 이미지

샘플은 찾아보시면 매우 많습니다

cookielounge의 이미지

1. 포트를 엽니다.
2. 포트 상태를 설정합니다.
3. 데이터를 송수신 합니다.
4. 포트를 닫습니다.

예를 들어 포트에 pBuff의 내용을 nToWrite만큼 쓴다면...

DWORD CCommThread::WriteComm(BYTE *pBuff, DWORD nToWrite)
{
	DWORD	dwWritten, dwError, dwErrorFlags;
	COMSTAT	comstat;
 
	//--> 포트가 연결되지 않은 상태이면
	if( !m_bConnected )		
	{
		return 0;
	}
 
 
	//--> 인자로 들어온 버퍼의 내용을 nToWrite 만큼 쓰고. 쓴 갯수를.,dwWrite 에 넘김.
	if( !WriteFile( m_hComm, pBuff, nToWrite, &dwWritten, &m_osWrite))
	{
		//--> 아직 전송할 문자가 남았을 경우.
		if (GetLastError() == ERROR_IO_PENDING)
		{
			// 읽을 문자가 남아 있거나 전송할 문자가 남아 있을 경우 Overapped IO의
			// 특성에 따라 ERROR_IO_PENDING 에러 메시지가 전달된다.
			//timeouts에 정해준 시간만큼 기다려준다.
			while (! GetOverlappedResult( m_hComm, &m_osWrite, &dwWritten, TRUE))
			{
				dwError = GetLastError();
				if (dwError != ERROR_IO_INCOMPLETE)
				{
					ClearCommError( m_hComm, &dwErrorFlags, &comstat);
					break;
				}
			}
		}
		else
		{
			dwWritten = 0;
			ClearCommError( m_hComm, &dwErrorFlags, &comstat);
		}
	}
 
 
	//--> 실제 포트로 쓰여진 갯수를 리턴.
	return dwWritten;
}
토끼아빠의 이미지

여러가지로 고수님들 신세 많습니다~~
windows에서는 문제없이 진행되고있습니다...
그런데 리눅스에서는 통신이 안되고있네///
여하튼 정말 고맙습니다...
저는 리눅스에서 통신 마저 완성해야하겠네요~~
다시 한번 감사드립니다...

좋은 하루 되세요!!

토끼아빠의 이미지

현재 상황을 말씀드린다면 ...
리눅스에서 데이터를 송신하면 윈도우에서는 깨끗하게 수신하고있어요...
단 리눅스에서 수신이 걸렸는데....
어떻게???

좋은 하루 되세요!!

ses4love의 이미지

파일 바이너리로 읽고 쓰시는거같은데요..

리눅스에서 터미널 캐노니컬모드로 하시믄 0x00만나면 자동 수신종료됩니다.

논 캐노니컬 모드로 바꾸시고 하셔보세요..

newtio.c_lflag = ICANON;
이부분 0으로 고치시고 해보시길..

정상적으로 송신이된다면..

제생각에는 캐노니컬 모드때문에 자동수신종료되는게 100퍼같은데;;ㅡ,.ㅡ;;

뭐 고수님들이 못보셨을리없겠지만요;;ㅡ.ㅡ

그리고 특수문자를 제외하고 100프로 문자열 스트링이라는 가정이 없다면..

어진간하믄 캐노니컬 비추입니다.

오실로로 값이 다 들어온다는거 확인해도..

커널단에서 자동으로수신끊어버리고 리드에서 블락걸리는경우가

많아요..