QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1098|回复: 3

急!!求助!!linux下串口编程问题!

[复制链接]
发表于 2005-2-27 04:28:09 | 显示全部楼层 |阅读模式
刚刚接触linux和串口编程的菜鸟,看到一个源程序实例,却不知道如何执行,请教各位大侠。
以下是在网上找到的例子。
请问一下,那4个文件中的 SEND和 RECV是干什么用的?用gcc编译了recv.c和 send.c,之后就不知道该如何进行下去了。只知道linux下要用minicom去进行串口程序的信息交换,可是实在不知道实际怎么操作,查了很久也没查到,也许我的问题实在太白痴,大家不要笑我阿。
我的任务,是要做一个串口程序,在linux系统下的2个串口之间进行信息传递,星期一就要交作业了,大侠们帮帮忙啊。。。


共四个文件:RECV recv.c SEND send.c
用串口线连接两台PC,第二根与第三根交叉
该程序我一直用于两台计算机交换文件,从未出错

----------------------SEND-------------------------
cat $1 |send /dev/tty2a 9600
----------------------send.c-------------------------

/* this program read from stdin and write to serial(specify in command parg) */
/* usage: send device baud, for example cat <file>|send /dev/ttyi01 9600 */

#include<unistd.h>
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<termio.h>
#include<time.h>
#include<signal.h>

#define C_SND 1
#define C_RCV 2
#define C_ACK 7
#define C_END 9
#define C_BEG 11
#define C_ERR 63

struct PACKHEAD
{
short cmd;
int len;
}pkhead;

main(int argc, char *argv[])
{
int fd;
int baud;
int len, cou;
char buf[2050];

if(argc != 3)
{
fprintf(stderr,"usage: send device baud\n");
return(1);
}
baud=atoi(argv[2]);
if(baud<0||baud>38400)
{
fprintf(stderr,"baud error\n");
return(1);
}
fd=open(argv[1],O_RDWR,0);
if(fd<0)
{
fprintf(stderr,"open <%s> error %s\n",argv[1],strerror(errno));
return(1);
}
if(setTerm(fd))
{
fprintf(stderr,"setterm error %s\n",strerror(errno));
return(1);
}

cou=0;

/* i am begin to send */
pkhead.cmd=C_BEG;
pkhead.len=0;
write_n(fd,&pkhead,sizeof(pkhead));

/* is server ready */
read_n(fd,&pkhead,sizeof(pkhead));
if(pkhead.cmd!=C_RCV)
{
fprintf(stderr,"recvive not ready");
return(1);
}

fprintf(stderr,"begin to send\n");

while( (len=read(0,buf,204) >0 )
{
/* send a pack */
pkhead.cmd=C_SND;
pkhead.len=len;
write_n(fd,&pkhead,sizeof(pkhead));
write_n(fd,buf,len);

/* has peer receive the pack */
read_n(fd,&pkhead,sizeof(pkhead));
if(pkhead.cmd!=C_ACK)
{
fprintf(stderr,"recvive not recv this pack");
return(1);
}

cou+=len;
fprintf(stderr,"send %d byte\n",len);
}
pkhead.cmd=C_END;
pkhead.len=0;
write_n(fd,&pkhead,sizeof(pkhead));
fprintf(stderr,"all send %d byte\n",cou);
}

/* 时间中断处理函数 */
void sig_alarm(int sig)
{
}

/* 设超时时间 */
static void (*old_sig)();
static int sig_flag=0;

int set_time_out(int sec)
{
if(sec<1)
return(1);
sig_flag=1;
old_sig=signal(SIGALRM,sig_alarm);
alarm(sec);
return(0);
}

/* 设超时时间 */
int reset_time()
{
if(sig_flag==1)
{
signal(SIGALRM,old_sig);
alarm(0);
}
return(0);
}

static struct termio oterm_attr;
int setTerm(int fd)
{
struct termio term_attr;
if(ioctl(fd,TCGETA,&oterm_attr)<0) return -1;
if(ioctl(fd,TCGETA,&term_attr)<0) return -1;

term_attr.c_iflag &=~(IXON|IXOFF|IXANY|INLCR|IGNCR|ICRNL|ISTRIP);
term_attr.c_lflag &=~(ISIG|ECHO|ICANON|NOFLSH|XCLUDE);
term_attr.c_cflag &=~CBAUD;
term_attr.c_cflag |=B19200;
term_attr.c_oflag &=~(OPOST|ONLCR|OCRNL);

term_attr.c_cc[VMIN]=1;
term_attr.c_cc[VTIME]=0;

if(ioctl(fd,TCSETAW,&term_attr)<0) return(-1);
if(ioctl(fd,TCFLSH,2)<0) return(-1);

return 0;
}

int resetTerm(int fd)
{

if(ioctl(fd,TCSETAW,&oterm_attr)<0) return -1;
return 0;
}

read_n(int fd, void *buf, int len)
{
int cou, ret;
ret=0;cou=0;
while(len>0)
{
ret=read(fd,(char*)buf+cou,len);
if(ret<1)
{
fprintf(stderr,"read device err %s\n",strerror(errno));
break;
}
cou+=ret;
len=len-ret;
}
}
write_n(int fd, void *buf, int len)
{
int cou, ret;
ret=0;cou=0;
while(len>0)
{
ret=write(fd,(char*)buf+cou,len);
if(ret<1)
{
fprintf(stderr,"write device err %s\n",strerror(errno));
break;
}
cou+=ret;
len=len-ret;
}
}



----------------------RECV-------------------------
recv /dev/tty2a 9600 >$1
----------------------recv.c-------------------------


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

#define C_SND 1
#define C_RCV 2
#define C_ACK 7
#define C_END 9
#define C_BEG 11
#define C_ERR 63

struct PACKHEAD
{
short cmd;
int len;
}pkhead;

main(int argc, char *argv[])
{
int fd;
int baud;
int len, cou;
char buf[2050];

if(argc != 3)
{
fprintf(stderr,"usage: send device baud\n");
return(1);
}
baud=atoi(argv[2]);
if(baud<0||baud>38400)
{
fprintf(stderr,"baud error\n");
return(1);
}
fd=open(argv[1],O_RDWR,0);
if(fd<0)
{
fprintf(stderr,"open <%s> error %s\n",argv[1],strerror(errno));
return(1);
}
if(setTerm(fd))
{
fprintf(stderr,"setterm error %s\n",strerror(errno));
return(1);
}

cou=0;

/* are you ready */
read_n(fd,&pkhead,sizeof(pkhead));
if(pkhead.cmd!=C_BEG)
{
fprintf(stderr,"send not ready\n");
return(1);
}

/* i am ready to recv */
pkhead.cmd=C_RCV;
pkhead.len=0;
write_n(fd,&pkhead,sizeof(pkhead));

fprintf(stderr,"begin to receive\n");

while( 1 )
{
/* read a pack */
read_n(fd,&pkhead,sizeof(pkhead));
if(pkhead.cmd!=C_SND) break;
len=pkhead.len;
read_n(fd,buf,len);
write(1,buf,len);

/* i receive a pack */
pkhead.cmd=C_ACK;
pkhead.len=0;
write_n(fd,&pkhead,sizeof(pkhead));

cou+=len;
fprintf(stderr,"recv %d byte\n",len);
}
fprintf(stderr,"all recv %d byte\n",cou);
}

/* 时间中断处理函数 */
void sig_alarm(int sig)
{
}

/* 设超时时间 */
static void (*old_sig)();
static int sig_flag=0;

int set_time_out(int sec)
{
if(sec<1)
return(1);
sig_flag=1;
old_sig=signal(SIGALRM,sig_alarm);
alarm(sec);
return(0);
}

/* 设超时时间 */
int reset_time()
{
if(sig_flag==1)
{
signal(SIGALRM,old_sig);
alarm(0);
}
return(0);
}

static struct termio oterm_attr;
int setTerm(int fd)
{
struct termio term_attr;
if(ioctl(fd,TCGETA,&oterm_attr)<0) return -1;
if(ioctl(fd,TCGETA,&term_attr)<0) return -1;

term_attr.c_iflag &=~(IXON|IXOFF|IXANY|INLCR|IGNCR|ICRNL|ISTRIP);
term_attr.c_lflag &=~(ISIG|ECHO|ICANON|NOFLSH|XCLUDE);
term_attr.c_cflag &=~CBAUD;
term_attr.c_cflag |=B19200;
term_attr.c_oflag &=~(OPOST|ONLCR|OCRNL);

term_attr.c_cc[VMIN]=1;
term_attr.c_cc[VTIME]=0;

if(ioctl(fd,TCSETAW,&term_attr)<0) return(-1);
if(ioctl(fd,TCFLSH,2)<0) return(-1);

return 0;
}

int resetTerm(int fd)
{

if(ioctl(fd,TCSETAW,&oterm_attr)<0) return -1;
return 0;
}

read_n(int fd, void *buf, int len)
{
int cou, ret;
ret=0;cou=0;
while(len>0)
{
ret=read(fd,(char*)buf+cou,len);
if(ret<1)
{
fprintf(stderr,"read device err %s\n",strerror(errno));
break;
}
cou+=ret;
len=len-ret;
}
}
write_n(int fd, void *buf, int len)
{
int cou, ret;
ret=0;cou=0;
while(len>0)
{
ret=write(fd,(char*)buf+cou,len);
if(ret<1)
{
fprintf(stderr,"write device err %s\n",strerror(errno));
break;
}
cou+=ret;
len=len-ret;
}
}
发表于 2005-2-27 05:07:55 | 显示全部楼层
RECV recv.c SEND send.c
先把“recv.c”和“send.c”编译出来,编译好的执行档应该就叫“recv”和“send”(注意是小写,不要和另外那两个大写搞浑)。

运行:
$ export PATH=目录:$PATH
把“目录”替换成“recv”和“send”所在的目录。
付予“RECV”和“SEND”(这回是大写的那两个)可运行权:
$ chmod +x RECV
$ chmod +x SEND

这个程序看起来不需要minicom...
先在“接收”的电脑上运行:
$ cd RECV所在的目录
$ ./RECV recevedFile
然后在“发送”的电脑上运行:
$ cd SEND所在的目录
$ ./SEND fileToSend.txt

以上应该就可以了
回复

使用道具 举报

 楼主| 发表于 2005-2-28 18:46:31 | 显示全部楼层
非常感谢楼上的耐心!
我按照你的方法运行,在./RECV recevedFile的时候,出现错误:setterm error Invalid argument
请问这是怎么回事啊?
我是在同一台机器上的两个串口之间进行文件传递,能实现吗?还是说必须要有2台机器?
回复

使用道具 举报

 楼主| 发表于 2005-2-28 21:41:10 | 显示全部楼层
终于弄好了。
那个recv.c程序里面有一个include <termios.h>改成 <termio.h>,就编译通过,可以传输了,虽然我不明白为什么,不过总算有的交差了。

再一次多谢玛宁。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-6 14:43 , Processed in 0.047620 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表