[완료] ARM 키트 2대를 이용해 시리얼을 통해 이미지 파일을 전송할려는데.. 조언좀 부탁드립니다...ㅠㅠ
글쓴이: kidsstar1 / 작성시간: 화, 2009/08/25 - 3:02오후
원래는 fopen을 안쓰고 open으로만 해봤는데, 안되서 fopen으로 써봤는데도 잘 되질 않습니다.
수신부분에서 read에서 제대로 받질 못합니다.
도대체 어떻게 해야될지 모르겠습니다..ㅠㅠ
벌써 2주째 하고있는데, 점점 절망하고있습니다..ㅠㅠ;
고수님들의 조언좀 부탁드리겠습니다.
void Init_port(const int PORT, struct termios *before) { struct termios new_t; // termios 구조체 변수 new_t 선언 long buad = B38400; // 보레이트 값 설정 memset(&new_t, 0, sizeof(new_t)); tcgetattr(PORT, &new_t); // 현재포트 속성 값을 new_t 로 가져온다. // input flag(입력과 관련된 제어를 함) new_t.c_iflag = 0; //new_t.c_iflag = ICRNL; new_t.c_iflag = IGNPAR | IGNBRK | ICRNL |IXANY; // 패리티 에러 문자 무시, break 무시, CR문자를 NL문자로 변환처리 //new_t.c_iflag &= ~(IXON|IXOFF); // S/W flow disable //now_t.c_iflag &= ~(INPCK|ISTRIP); // 패리티 사용안함(패리티체크안함,8bit입력) // output_flag(출력과 관련된 제어를 함) new_t.c_oflag = 0; // Control_flag(하드웨어와 관련된 제어를 함) new_t.c_cflag = 0; new_t.c_cflag = buad|CS8|CREAD|CLOCAL; // 보레이트설정, Data bit 8, 리시버 활성화 //now_t.c_cflag &= ~HUPCL; // 프로세스가 종료되면 disconnect 발생안함 //new_t.c_cflag &= ~CSTOPB; // stop bit 1개로 설정 //new_t.c_cflag &= ~CRTSCTS; // h/w flow control disable //now_t.c_cflag &= ~PARENB; // 패리티발생과 검사기능 사용안함 // Local_flag(사용자 터미널에 관련된 제어를 함) new_t.c_lflag = 0; //new_t.c_lflag &= (~ISIG); new_t.c_lflag = ICANON; // 정규모드 입력(~을 취하면 바로전달) tcflush(PORT, TCIFLUSH); // PORT에 아직 읽지 않은 입력데이터를 제거 tcsetattr(PORT, TCSANOW, &new_t); // 설정된값을 즉시 포트 속성을 변경 } /////////////////////////////////////////////////////////////////////////////////////////////// // 시리얼(STandard UART) 디바이스 Open if((PORT=open("/dev/ttySAC2",O_RDWR | O_NOCTTY)) <= 0) { perror("Serial open fail\n\n"); return -1; } /////////////////////////////////////////////////////////////////////////////////////////////// // 파일 전송함수 void file_send(int chk){ char send_file[BUF_LEN]={0,}, file[BUF_LEN]={0,}, f_size[BUF_LEN]={0,}; char buffer[BUF_LEN]={0,}, new_buffer[BUF_LEN]={0,}; FILE *fp; int fd; long i=0; int filesize=0, size=0, tmp=0; //pthread_mutex_lock(&mutex_lock); //pthread_cond_wait(&thread_cond1, &mutex_lock); printf("전송할 파일명 입력: \n"); // 전송할 파일명을 키보드로부터 읽어드림 if( (size=read(0, file, sizeof(file))) > 0){ // file size를 읽기위해 전송할파일 open strncpy(send_file, file, strlen(file)-1); if( (fp = fopen(send_file, "rb")) == NULL ) perror("send_file open error: "); else{ // 전송할 파일명을 전송 write(PORT, file, strlen(file)); fseek(fp, 0L, SEEK_END); filesize = ftell(fp); fclose(fp); sprintf(f_size, "%d\n", filesize); // 파일 사이즈 전송 printf("f_size=%s\n", f_size); write(PORT, f_size, strlen(f_size)); if( (fp= fopen(send_file, "rb")) == NULL ) perror("send_file open error: "); else{ do{ size=fread(buffer, sizeof(char), BUF_LEN, fp); //printf("%s\n", buffer); write(PORT, buffer, size); printf("filesize=%d, size=%d\n", filesize, size); filesize -= size; memset(&buffer, 0, sizeof(buffer)); }while(filesize >0); printf("\n파일 전송이 완료 되었습니다.\n"); fclose(fp); } } } // pthread_mutex_unlock(&mutex_lock); } // 파일 수신 함수 void file_receive(int chk){ char recv_file[BUF_LEN]={0,}, file[BUF_LEN]={0,}, f_size[BUF_LEN]={0,}; char buffer[BUF_LEN]={0,}, new_buffer[BUF_LEN]={0,}; FILE *fp; int fd=0; long i=0; int filesize=0, size=0; // pthread_mutex_lock(&mutex_lock); // pthread_cond_wait(&thread_cond2, &mutex_lock); // 전송할 파일명을 키보드로부터 읽어드림 // 파일명을 수신 read(PORT, file, sizeof(file)); strncpy(recv_file, file, strlen(file)-1); // 파일사이즈를 수신 read(PORT, f_size, sizeof(f_size)); filesize=atoi(f_size); printf("f_size=%s, filesize=%d\n",f_size, filesize); // 파일 내용 수신 if( (fp= fopen(recv_file, "w+b")) == NULL ) perror("send_file open error: "); else{ do{ size=read(PORT, buffer, sizeof(buffer)); //printf("%s\n", buffer); fwrite(buffer, sizeof(char), size, fp); printf("filesize=%d, size=%d\n", filesize, size); filesize -= size; memset(&buffer, 0, sizeof(buffer)); }while(filesize >0); printf("\n파일 수신이 완료 되었습니다.\n"); fclose(fp); } // pthread_mutex_unlock(&mutex_lock); }
Forums:
main문은 별다른게 없어서 빼버렸습니다.
맨위가 termios 초기화 시키는 과정이고,
그담은 시리얼 포트 open이고
그담은 파일 송수신 함수입니다.
조언좀 부탁드립니다.ㅠㅠ
소스 코드는
< code > < /code > 요 사이에 넣어주세요. 괄호와 알파벳은 붙여서... ----------------------- Go to the U-City
----------------------------------------------------------------------------------------
Don't Feed the Trolls!
----------------------------------------------------------------------------------------
네~!
넣었어요~!ㅎㅎ
이미 있는 것에 적용하지 마시고
들여쓰기 깔끔하게 보기 위해서 넣어달라고 말씀드린 것이니까요...
< code > < /code > 사이에 들여쓰기까지 복사해 넣어주세요 ^^; ---------------------------- Go to the U-City
----------------------------------------------------------------------------------------
Don't Feed the Trolls!
----------------------------------------------------------------------------------------
시리얼 통신하실때..
보낸 데이터하고 받은 데이터가 제대로 전송되었는지 일단 비교해보시고, 동일한지 확인하세요.
경험상 그냥 바이너리로 보내면 깨져서 제대로된 데이터를 복구하기 힘들었던 기억이 있습니다.
모두 아스키코드로 변환해서 보내고 받을때도 아스키 코드를 다시 바이너리로 바꿔서 저장하세요.
Team BlackIz
휴.....;;
프리스타일님// 겨우 프리스타일님말씀대로 바꿨네요..ㅠㅠ;
제로나인님// char형소스파일같은건 잘 전송되는데..음.. 아스키코드로 변환하란 말씀은 소스코드에 변환코드를 넣으란 말씀이시죠..??
그럼 바이나리로 읽은뒤 아스키코드변환 한것을 전송한뒤 아스키코드로 받은것을 다시 바이너리로 쓰란 말씀이시져..?
예... 맞아요.
예를 들어서 0x16 (binary) 날릴때 아스키코드로 1 , 6이라고 바꿔서 날리세요. 뭐 간단하게 100바이트(뭐 그 이상하셔도 되고요)씩 checksum 넣어서 확인하시고요.
uart 통신의 경우 많은 데이터가 날라 갈경우 아스키코드라도 깨지는 경우가 있습니다. 아스키코드가 아무렇게나 만들어진 것이 아니고,
통신을 위해 만들어진 코드거든요. 한번 아스키코드를 이진수로 바꿔서 보세요. 어떻게 만들어졌는지. 아마 금방 아실수 있을 겁니다.
그리고 혹시나 모르니까. 100바이트씩 쪼개서 날릴때 앞쪽에 0xaa (10101010) 두바이트 날려주시고 마지막에 0x55 (01010101) 날려주세요. UART가 어떻게 통신하시는지 아시면 제말을 이해하실 수 있을 겁니다.
그럼 수고하세요.
--
YoungBu Park
http://zeronine.org/today
Team BlackIz
댓글 달기