URN Logo
UNIX Resources » Linux » China Linux Forum » C/C++编程版 » 28 » [Linux Serial Programming]Non-Canonicalmode如何SIGIO
announcement 声明: 本页内容为中国Linux论坛的内容镜像,文章的版权以及其他所有的相关权利属于中国Linux论坛和相应文章的作者,如果转载,请注明文章来源及相关版权信息。
Resources
China Linux Forum(finished)
Linux Forum(finished)
FreeBSD China(finished)
linuxforum.net
  业界新闻与评论
  自由软件杂谈
  IT 人生
  Linux软件快递
  翻译作坊
  Linux图书与评论
  GNU Emacs/XEmacs
  Linux 中文环境和中文化
  Linux桌面与办公软件
  Linux 多媒体与娱乐版
  自由之窗Mozilla
  笔记本电脑上的Linux
  Gentoo
  Debian 一族
  网络管理技术
  Linux 安装与入门
  WEB服务器和FTP服务器
  域名服务器和邮件服务器
  Linux防火墙和代理服务器应用
  文件及打印服务器
  技术培训与认证
  Linux内核技术
  Linux 嵌入技术
  Linux设备驱动程序
  Linux 集群技术
  LINUX平台数据库
  系统和网络安全
  CPU 与 编译器
  系统计算研究所专栏
  Linux下的GUI软件开发
  C/C++编程版
  PHP 技 术
  Java&jsp技术
  Shell编程技术
  Perl 编 程
  Python 编 程
  XML/Web Service 技术
  永远的Unix
  FreeBSD世界
   
[Linux Serial Programming]Non-Canonicalmode如何SIGIO
 
 
Subject: [Linux Serial Programming]Non-Canonicalmode如何SIGIO
Author: geshu    Posted: 2005-07-26 22:49    Length: 5,857 byte(s)
[Original] [Print] [Top]
主  题: [Linux Serial Programming 问题] Non-Canonical mode 如何 加上 SIGIO 信号处理

小弟第一次 在这里提问。

麻烦经历如下.

现在要给公司开发短信程序,基于 linux 平台。最终的问题 归结于 linux 串口编程。
在 google 上 search 发现这篇 资料, linux serial how-to.

http://www.ibiblio.org/pub/Linux/docs/HOWTO/Serial-Programming-HOWTO

我想要的东西是, 用一个 semaphore 来控制 程序是否去读 serial port, 而不是用一个 while loop 来循环读 serial port。要不然 cpu 时间 都耗在这个上面了。

于是 经过思考, 得出以下思路。

[1] 直接修改 Asynchronous Input 的 programme (因为它已经有了 signal handling)
[2] 修改 Non-Canonical Input Processing 的 programme, 然后加上 signal handling


第一个方案 好像必须在输入的字符上,做手脚 才可以,因必须得读满一行(cononical mode, 至少得有一个 line feed)。只好放弃

第二个方案 现在可以做到 死循环 读取 serial port, 但是 想 加进 SIGIO 就是不行。

[问题 1] 望各位NB的 大大 帮帮小弟, 第二个方案 如何 加进 SIGIO handling? 现在的问题是, 既石有IO, signal_handler_IO  也不会被调用。(郁闷中)
[问题 2] 现在 第二个方案,发现所有 输入的 input 都会在下次输入的时候,重新读回来 (好像是 所说的 echo), 如何控制参数 关闭这个 echo?

代码(修改 后 Non-Canonical Input Processing 的 programme)如下:

// global variables
static bool bWaitFlag = true; // TRUE while no signal received
static char SerialBuffer[512];
static int nByteRead;
static int nStrLength;
static char * BufferPtr;

static int DevPtr;
static termios OldTermios, NewTermios;


// external variables
extern sem_t ReadBufferCounter;


void * ReadThread(void *) {

struct sigaction SigAction; // definition of signal action

/* open the device to be non-blocking (read will return immediatly) */
DevPtr = open(MODEMDEVICE, O_RDWR | O_NOCTTY);
if (DevPtr < 0) {
std::cout << "Failed to open Modem!" << std::endl;
exit(-1);
}

/* install the signal handler before making the device asynchronous */
SigAction.sa_handler = signal_handler_IO;
sigemptyset(&SigAction.sa_mask);

SigAction.sa_flags = 0;
SigAction.sa_restorer = NULL;
sigaction(SIGIO, &SigAction, NULL);

/* allow the process to receive SIGIO */
fcntl(DevPtr, F_SETOWN, getpid());
/* Make the file descriptor asynchronous (the manual page says only O_APPEND and O_NONBLOCK, will work with F_SETFL...) */
//fcntl(DevPtr, F_SETFL, FASYNC);

tcgetattr(DevPtr,&OldTermios); // save current port settings

/* set new port settings for non-canonical input processing */
bzero(&NewTermios, sizeof(NewTermios));
NewTermios.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
NewTermios.c_iflag = IGNPAR;// | ICRNL;
NewTermios.c_oflag = 0;
NewTermios.c_lflag = 0; //ICANON;
NewTermios.c_cc[VMIN] = 0;
NewTermios.c_cc[VTIME] = 1; // maximum time of 100 ms
tcflush(DevPtr, TCIFLUSH);
tcsetattr(DevPtr, TCSANOW, &NewTermios);

// initialize the Modem
strcpy(SerialBuffer, "AT+CMGF=1x0D");
nStrLength = strlen(SerialBuffer);
write(DevPtr, SerialBuffer, nStrLength);

/* loop while waiting for input. normally we would do something useful here */

while (true) {

//sleep(2);
BufferPtr = SerialBuffer;
sleep(1);

//sem_wait(& ReadBufferCounter); // wating for SIGIO

while (true) {
//std::cout << "Reading +" << std::endl;
nByteRead = read(DevPtr, BufferPtr, 255);
//std::cout << "Reading -" << std::endl;
if (nByteRead == -1 || nByteRead == 0) {
break;
}

BufferPtr[nByteRead] = 0;
//std::cout << nByteRead << " Bytes:" << BufferPtr << std::endl;

BufferPtr += nByteRead;
}

if (BufferPtr != SerialBuffer) {
std::cout << "Reading over:" << SerialBuffer << std::endl;
MessageHandler(); // handle buffer message
SerialBuffer[0] = 0;
}
}

/* restore old port settings */
tcsetattr(DevPtr, TCSANOW, & OldTermios);
}

/***************************************************************************
* signal handler. sets bWaitFlag to FALSE, to indicate above loop that *
* characters have been received. *
***************************************************************************/
void signal_handler_IO (int status) {

std::cout << "received SIGIO signal." << std::endl;
//sem_post(& ReadBufferCounter); // unlocking
}
[Original] [Print] [Top]
Subject: Re: [Linux Serial Programming]Non-Canonicalmode如何S
Author: z_york    Posted: 2005-07-27 09:40    Length: 199 byte(s)
[Original] [Print] [Top]
如果用一个独立的线程或进程去读串口,即使是在一个while loop里面读,也是不会耗尽CPU的,而且实现起来很简单──使用pipe去缓冲就行了。

附件里的miniterm.c,一个不错的串口例子。
----
I love David Beckham and Man.Utd. for ever.
--
[Original] [Print] [Top]
« Previous thread
请教:关于命名管道的问题
C/C++编程版
28
Next thread »
【请教】在netfilter的hook函数中如何使用socket编程?
     

Copyright © 2007 UNIX Resources Network, All Rights Reserved.      About URN | Privacy & Legal | Help | Contact us
备案序号: 京ICP备05006143    webmaster: webmaster@unixresources.net
This page created on 2008-07-17 03:52:44, cost 0.039058923721313 ms.