分享
 
 
 

Linux Serial Programming HOWTO (2)

王朝system·作者佚名  2006-11-23
窄屏简体版  字體: |||超大  

藉由修改 newtio.c_cc[VTIME] 及 newtio.c_cc[VMIN] 上述的模式就可以测试了.

[code]

#include

#include

#include

#include

#include

#define BAUDRATE B38400

#define MODEMDEVICE "/dev/ttyS1"

#define _POSIX_SOURCE 1 /* POSIX 系统相容 */

#define FALSE 0

#define TRUE 1

volatile int STOP=FALSE;

main()

{

int fd,c, res;

struct termios oldtio,newtio;

char buf[255];

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 | CRTSCTS | CS8 | CLOCAL | CREAD;

newtio.c_iflag = IGNPAR;

newtio.c_oflag = 0;

/* 设定输入模式 (非标准型, 不回应,...) */

newtio.c_lflag = 0;

newtio.c_cc[VTIME] = 0; /* 不使用分割字元组计时器 */

newtio.c_cc[VMIN] = 5; /* 在读取到 5 个字元前先停止 */

tcflush(fd, TCIFLUSH);

tcsetattr(fd,TCSANOW,&newtio);

while (STOP==FALSE) { /* 输入回圈 */

res = read(fd,buf,255); /* 在输入 5 个字元後即返回 */

buf[res]=0; /* 所以我们能用 printf... */

printf(":%s:%d\n", buf, res);

if (buf[0]=='z') STOP=TRUE;

}

tcsetattr(fd,TCSANOW,&oldtio);

}

[/code]

3.3 非同步式输入

[code]

#include

#include

#include

#include

#include

#include

#define BAUDRATE B38400

#define MODEMDEVICE "/dev/ttyS1"

#define _POSIX_SOURCE 1 /* POSIX 系统相容 */

#define FALSE 0

#define TRUE 1

volatile int STOP=FALSE;

void signal_handler_IO (int status); /* 定义讯号处理程序 */

int wait_flag=TRUE; /* 没收到讯号的话就会是 TRUE */

main()

{

int fd,c, res;

struct termios oldtio,newtio;

struct sigaction saio; /* definition of signal action */

char buf[255];

/* 开启装置为 non-blocking (读取功能会马上结束返回) */

fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);

if (fd <0) {perror(MODEMDEVICE); exit(-1); }

/* 在使装置非同步化前, 安装讯号处理程序 */

saio.sa_handler = signal_handler_IO;

saio.sa_mask = 0;

saio.sa_flags = 0;

saio.sa_restorer = NULL;

sigaction(SIGIO,&saio,NULL);

/* 允许行程去接收 SIGIO 讯号*/

fcntl(fd, F_SETOWN, getpid());

/* 使档案ake the file descriptor 非同步 (使用手册上说只有 O_APPEND 及

O_NONBLOCK, 而 F_SETFL 也可以用...) */

fcntl(fd, F_SETFL, FASYNC);

tcgetattr(fd,&oldtio); /* 储存目前的序列埠设定值 */

/* 设定新的序列埠为标准输入程序 */

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

newtio.c_iflag = IGNPAR | ICRNL;

newtio.c_oflag = 0;

newtio.c_lflag = ICANON;

newtio.c_cc[VMIN]=1;

newtio.c_cc[VTIME]=0;

tcflush(fd, TCIFLUSH);

tcsetattr(fd,TCSANOW,&newtio);

/* 等待输入讯号的回圈. 很多有用的事我们将在这做 */

while (STOP==FALSE) {

printf(".\n");usleep(100000);

/* 在收到 SIGIO 後, wait_flag = FALSE, 输入讯号存在则可以被读取 */

if (wait_flag==FALSE) {

res = read(fd,buf,255);

buf[res]=0;

printf(":%s:%d\n", buf, res);

if (res==1) STOP=TRUE; /* 如果只输入 CR 则停止回圈 */

wait_flag = TRUE; /* 等待新的输入讯号 */

}

}

/* 回存旧的序列埠设定值 */

tcsetattr(fd,TCSANOW,&oldtio);

}

/***************************************************************************

* 讯号处理程序. 设定 wait_flag 为 FALSE, 以使上述的回圈能接收字元 *

***************************************************************************/

void signal_handler_IO (int status)

{

printf("received SIGIO signal.\n");

wait_flag = FALSE;

}

[/code]

3.4 等待来自多个讯号来源的输入

这一段很短. 它只能被拿来当成写程式时的提示, 故□例程式也很简短. 但这个□例不只能用在序列埠上, 还可以用在被当成档案来使用的装置上.

select 呼叫及伴随它所引发的巨集共用 fd_set. fd_set 则是一个位元阵列, 而其中每一个位元代表一个有效的档案叙述结构. select 呼叫接受一个有效的档案叙述结构并传回 fd_set 位元阵列, 而该位元阵列中若有某一个位元为 1, 就表示相对映的档案叙述结构的档案发生了输入, 输出或有例外事件. 而这些巨集提供了所有处理 fd_set 的功能. 亦可参考手册 select(2).

以下内容为程序代码:

#include

#include

#include

main()

{

int fd1, fd2; /* 输入源 1 及 2 */

fd_set readfs; /* 档案叙述结构设定 */

int maxfd; /* 最大可用的档案叙述结构 */

int loop=1; /* 回圈在 TRUE 时成立 */

/* open_input_source 开启一个装置, 正确的设定好序列埠,

并回传回此档案叙述结构体 */

fd1 = open_input_source("/dev/ttyS1"); /* COM2 */

if (fd1<0) exit(0);

fd2 = open_input_source("/dev/ttyS2"); /* COM3 */

if (fd2<0) exit(0);

maxfd = MAX (fd1, fd2)+1; /* 测试最大位元输入 (fd) */

/* 输入回圈 */

while (loop) {

FD_SET(fd1, &readfs); /* 测试输入源 1 */

FD_SET(fd2, &readfs); /* 测试输入源 2 */

/* block until input becomes available */

select(maxfd, &readfs, NULL, NULL, NULL);

if (FD_ISSET(fd1)) /* 如果输入源 1 有讯号 */

handle_input_from_source1();

if (FD_ISSET(fd2)) /* 如果输入源 2 有讯号 */

handle_input_from_source2();

}

}

这个□例程式在等待输入讯号出现前, 不能确定它会停顿下来. 如果你需要在输入时加入逾时功能, 只需把 select 呼叫换成:

int res;

struct timeval Timeout;

/* 设定输入回圈的逾时值 */

Timeout.tv_usec = 0; /* 毫秒 */

Timeout.tv_sec = 1; /* 秒 */

res = select(maxfd, &readfs, NULL, NULL, &Timeout);

if (res==0)

/* 档案叙述结构数在 input = 0 时, 会发生输入逾时. */

这个程式会在 1 秒钟後逾时. 如果超过时间, select 会传回 0, 但是应该留意 Timeout 的时间递减是由 select 所等待输入讯号的时间为基准. 如果逾时的值是 0, select 会马上结束返回.

--------------------------------------------------------------------------------

--------------------------------------------------------------------------------

4. 其它资源

Linux Serial-HOWTO 叙述如何设定序列埠及所有相关的硬体资讯.

由 Michael Sweet 所写的 Serial Programming Guide for POSIX Compliant Operating Systems. 这个连结已经荒废了但我找不到它的新位址. 有人知道能在哪找到它吗? 它是很棒的文件!

termios(3) 的使用手册. 叙述所有有关 termios 结构体的旗标.

--------------------------------------------------------------------------------

--------------------------------------------------------------------------------

5. 贡献

就跟简介所说的一样, 我并非在这领域有所专精, 但我自己遇到问题, 并透过他人的帮助找到答案. 感谢来自 European Transonic Windtunnel 的 Strudthoff 先生, Cologne, Michael Carter (mcarter@rocke.electro.swri.edu), 及 Peter Waltenberg (p.waltenberg@karaka.chch.cri.nz)

与我同时准备这份文件的 Antonino Ianella (antonino@usa.net 所篆写的 Serial-Port-Programming Mini HOWTO. Greg Hankins 要求我把 Antonino's Mini-HOWTO 一并放入这份文件.

这份文件的结构及 SGML 的格式是源自 Greg Hankins 的 Serial-HOWTO. 感谢 Dave Pfaltzgraff (Dave_Pfaltzgraff@patapsco.com), Sean Lincolne (slincol@tpgi.com.au), Michael Wiedmann (mw@miwie.in-berlin.de), 及 Adrey Bonar (andy@tipas.lt) 各方面的协助.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有