调试代码的最佳方法是设置另一台 Linux 机器,并通过零调制解调器电缆连接两台计算机。使用 miniterm(可从 LDP 程序员指南中获得 (ftp://sunsite.unc.edu/pub/Linux/docs/LDP/programmers-guide/lpg-0.4.tar.gz在 examples 目录中)向您的 Linux 机器传输字符。Miniterm 可以非常容易地编译,并将所有键盘输入以原始格式通过串口传输。只有 define 语句#define MODEMDEVICE "/dev/ttyS0"需要检查。将其设置为ttyS0对于 COM1,ttyS1对于 COM2,等等。对于测试至关重要的是,所有 字符都以原始格式(不经过输出处理)在线路上传输。要测试您的连接,请在两台计算机上启动 miniterm,然后随意输入。在一台计算机上输入的字符应出现在另一台计算机上,反之亦然。输入不会回显到连接的屏幕上。
要制作零调制解调器电缆,您必须交叉 TxD(发送)和 RxD(接收)线。有关电缆的描述,请参见 Serial-HOWTO 的第 7 节。
如果您有两个未使用的串口,也可以仅用一台计算机执行此测试。然后,您可以从两个虚拟控制台运行两个 miniterm。如果您通过断开鼠标连接来释放一个串口,请记住重定向/dev/mouse如果它存在。如果您使用多端口串口卡,请务必正确配置它。我的配置错误,但只要我在自己的计算机上进行测试,一切都正常。当我连接到另一台计算机时,端口开始丢失字符。在一台计算机上执行两个程序并不是完全异步的。
设备/dev/ttyS*旨在将终端连接到您的 Linux 机器,并在启动后为此目的进行配置。在编程与原始设备的通信时,必须牢记这一点。例如,端口配置为将从设备发送的字符回显给设备,这通常必须更改以进行数据传输。
所有参数都可以很容易地从程序中配置。配置存储在一个结构中struct termios,定义在<asm/termbits.h>:
#define NCCS 19 struct termios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ tcflag_t c_cflag; /* control mode flags */ tcflag_t c_lflag; /* local mode flags */ cc_t c_line; /* line discipline */ cc_t c_cc[NCCS]; /* control characters */ }; |
此文件还包括所有标志定义。中的输入模式标志c_iflag处理所有输入处理,这意味着可以先处理从设备发送的字符,然后再用以下命令读取它们read。类似地c_oflag处理输出处理。c_cflag包含端口的设置,例如波特率、每字符位数、停止位等。本地模式标志存储在c_lflag确定是否回显字符,是否向您的程序发送信号等。最后是数组c_cc定义文件结束、停止等的控制字符。控制字符的默认值在以下位置定义<asm/termios.h>。标志在手册页中描述termios(3)。结构termios包含c_line(行规程)元素,在符合 POSIX 标准的系统中未使用。
这里将介绍三种不同的输入概念。必须为预期的应用选择合适的概念。在可能的情况下,不要循环读取单个字符以获取完整的字符串。当我这样做时,我丢失了字符,而用于整个字符串的读取操作没有显示任何错误。readfor the whole string did not show any errors.
这是终端的正常处理模式,但也可能用于与其他设备通信。规范输入以行为单位进行处理,这意味着read将仅返回一整行输入。默认情况下,行由以下字符终止NL(ASCIILF),文件结束符或行尾字符。一个CR(DOS/Windows 默认行尾符)在默认设置下不会终止行。
规范输入处理还可以处理擦除、删除单词和重印字符,转换为CRtoNL,等等。
非规范输入处理将处理每次读取的固定数量的字符,并允许使用字符计时器。如果您的应用程序始终读取固定数量的字符,或者连接的设备发送突发字符,则应使用此模式。
上述两种模式可以在同步和异步模式下使用。同步是默认模式,其中read语句将阻塞,直到读取完成。在异步模式下read语句将立即返回,并在完成时向调用程序发送信号。此信号可以由信号处理程序接收。
这不是一种不同的输入模式,但如果您正在处理多个设备,则可能很有用。在我的应用程序中,我几乎同时处理通过 TCP/IP 套接字的输入和通过来自另一台计算机的串行连接的输入。下面给出的程序示例将等待来自两个不同输入源的输入。如果来自一个源的输入变为可用,它将被处理,然后程序将等待新的输入。
下面介绍的方法似乎相当复杂,但重要的是要记住 Linux 是一个多进程操作系统。select系统调用在等待输入时不会加载 CPU,而循环直到输入变为可用会减慢同时执行的其他进程的速度。