目前,由于国产的中标麒麟操作系统有着高安全性,以及其功能、稳定性、效率方面都达到国外同类产品水平,部分指标还要优于国外同类产品,极大地降低了采购成本及维护成本等特点,中标麒麟操作系统逐步地应用到了部队、国家大型的建设项目、企事业单位中,如国家电网D5000项目等[1]。串口作为一种广泛应用的计算机接口,计算机对设备进行通信控制几乎都是通过串口进行的。在中标麒麟操作系统下进行串口调试与Windows不同,本文将介绍两种中标麒麟操作系统下的串口调试方法。
1 串口编程
在任何操作系统下,串口调试程序的编写都是按照打开串口设备、初始化串口和串口读写操作的步骤进行[2]。
1.1 打开串口
中标麒麟操作系统与Linux系统类似都是基于文件的,把硬件设备都看作文件,对硬件设备进行操作,就是对设备文件的操作[3]。串口设备的设备文件是用“/dev/ttyS0”、“/dev/ttyS1”来命名的,Windows下的“COM1”对应于中标麒麟下的“/dev/ttyS0”。打开串口只需要调用open()函数打开设备文件即可。
1.2 初始化串口
串口的初始化设置包括波特率、数据位、奇偶校验位、停止位和流控制设置。对它们各自进行设置时都有多种选择,因此编程时一般采用switch()函数实现。
1.3 串口读写操作
串口工作模式有阻塞方式和非阻塞方式两种。阻塞方式比较简单,当对串口进行操作时,如果条件不满足,操作会被阻塞,只有条件满足时操作才会进行;非阻塞方式是采用轮询对串口进行操作,编程时可以定义一个定时函数,通过定时实现对串口缓冲区的访问[2]。
2 minicom串口调试软件
2.1 minicom简介
minicom的功能与Windows系统下的超级终端类似,计算机可以利用此软件通过串口控制外部硬件设备。
2.2 minicom安装
中标麒麟操作系统最新发行版(NeoKylin3.2.1)的系统盘中集成有minicom的rpm安装包,因此只需要将系统盘插入电脑,打开终端,运行#yum list | grep minicom 命令查看minicom的版本, 然后采用#yum install命令安装。
2.3 minicom配置及使用
第一次运行minicom,为了保证minicom能正确地对CPU进行读写操作,需要对minicom的端口和波特率等进行配置[4]。
进入root输入#minicom-s命令,确定后会弹出minicom的配置界面如图1所示。
选择Serial port setup 进入串口设置, 如图2。根据实际要求设置好串口名、波特率、数据位、停止位、奇偶校验位和流控制等, 然后按回车退出到配置界面。选择Save setup as dfl 保存配置信息, 再选择Exit 退出配置界面回到minicom 使用界面, 然后就可以按照提示进行串行数据收发。
2.4 minicom控制VGA8×4矩阵切换器
VGA8×4是8输入4输出的矩阵切换器,它具有标准的RS-232串行通信接口,用户可以通过RS-232接口,进行计算机远端控制。其通信控制协议:波特率为9 600 b/s,数据位为8 bit,停止位1 bit,没有奇偶校验位和流控制位。控制命令格式为:设备号+输出端口号+控制符+输入端口号+!。其中“设备号”和“控制符”都是1个字符位,“输出端口号”和“输入端口号”都是2 bit数字,“!”是命令结束符。例如:设备号为A,以视频控制方式(控制符为“[”),第3路输入信号切换到第1路输出,其控制命令为“A01[03!”。如果控制成功,矩阵切换器前面板中由4个数码管组成的状态显示区会显示“0103”4个数字,它表示矩阵切换器当前的状态为第1路输出信号是由第3路输入的[5]。
利用minicom控制矩阵切换器以视频控制方式,第3路输入后由第2路输出的控制实验如图3所示。图3中上侧图显示minicom发送的控制名令为A02[03!,下侧图可以看出矩阵切换器前面板4个数码管显示0203,这说明控制实验成功。
3 Qt4编写串口调试程序
3.1 Qt简介
Qt是挪威的Trolltech公司开发的面向对象的C++图形用户界面程序开发框架。Qt以其作为一个跨平台框架而著称,它使用“一次编写,随处编译”的方式为开发包括Windows、Linux和Mac等多平台的应用软件提供方便,在中标麒麟操作系统下也可以用Qt编程。Qt拥有直观、强大的API,用户只要具备一定的C/C++基础,就能够快速地用Qt编写应用程序[6]。
NeoKylin3.2.1系统安装盘中集成有Qt4.6版本的rpm安装包,要想安装Qt只需将系统盘插入电脑,采用install命令就能把Qt4.6安装到自己的电脑中。
3.2 Qt串口编程
到目前为止,Qt的发行版本中还没有专门针对串口定义控制类,要用Qt编写串口调试程序,最简单的方法是使用第三方编写的Qextserialport类[7-8]。Qextserialport继承自Qt定义的对输入/输出设备操作的基类QIODevice。Qextserialport类中完整定义了包括打开串口、串口初始化设置和读写串口的一系列操作。使用Qextserialport类编写串口调试程序时,只需将串口操作相关的参数传递给它,就能完成相应的功能。因此,使用Qextserialport类编写串口调试程序时,只需要编写很少的代码就能实现串口调试的功能。
3.3 Qt4编写VGA8×4矩阵切换器控制程序
控制要求:矩阵切换器的第3路输出连接一个40英寸的大屏幕显示器,第1路至第4路输入分别连接4台计算机,要求编写控制程序,通过4个控制按钮实现大屏幕显示器可以选择显示4台计算机。
console可以是串口,也可以是vga,console确实是只能输出,write,内核打印。在UNIX系统中,计算机显示器通常被称为控制台终端(Console)。它仿真了类型为Linux的一种终端(TERM=Linux),并且有一些设备特殊文件与之相关联:tty0、tty1、tty2等。当你在控制台上登录时,使用的是tty1。使用Alt+[F1—F6]组合键时,我们就可以切换到tty2、tty3等上面去。tty1 –tty6等称为虚拟终端,而tty0则是当前所使用虚拟终端的一个别名,系统所产生的信息会发送到该终端上。因此不管当前正在使用哪个虚拟终端,系统信息都会发送到控制台终端上。你可以登录到不同的虚拟终端上去,因而可以让系统同时有几个不同的会话期存在。只有系统或超级用户root可以向/dev/tty0进行写操作,
serial_em86xx.c实现的是串口uart驱动,也注册了console,在console_init中调用console初始化,但是如果serial不做console的话,应该就不用注册console,但是串口uart驱动是必须的,就是uart_register_driver,其中涉及最关键的tty_driver,
tty是一类char设备的通称,它们有相同的特性,比如对^C的处理,驱动使用tty_register_driver注册一个tty。
/dev/console是一个虚拟的tty,它映射到真正的tty上,如何映射等会再说。
console有多种含义,这里特指printk输出的设备,驱动使用register_console注册一个console。 console和tty有很大区别:console是个只输出的设备,功能很简单,只能在内核中访问;tty是char设备,可以被用户程序访问。
实际的驱动比如串口对一个物理设备会注册两次,一个是tty,一个是console,并通过在console的结构中记录tty的主次设备号建立了联系。
在内核中,tty和console都可以注册多个。当内核命令行上指定console=ttyS0之类的参数时,首先确定了printk实际使用那个console作为输出,其次由于console和tty之间的对应关系,打开/dev/console时,就会映射到相应的tty上。用一句话说:/dev/console将映射到默认console对应的tty上。
顺便说一句,console=ttyS0和/dev/ttyS0包含相同的设备名字完全是巧合,不同也没事。
所以如果是一个单纯的串口通信,可以不用实现console,只要实现uart驱动,包括tty_driver,就可以在应用层调用串口设备实现的接口,比如open(/dev/ttyS0),然后selest,用于等待串口上的数据,而在内和层,驱动中,就是用wait_queue等来实现select的。/dev/tty,/dev/console,/dev/tty是正在使用的虚拟终端,因此在这里tty_open就是ttyS0,因为前台进程的控制终端现在就是ttyS0,/dev/tty可以在用户空间访问,就是用户打印可以在该空间。
serial.c不是必须的,而serial_em86xx.c中提供了与其相似的功能,比如shutdown,startup等方法,以及console_write等,而console是在内核打印,而在erial_em86xx.c中,已经有串口uart驱动,而且与tty_driver关联起来,所以tty_open打开的就是ttyS0了。如果当前进程有控制终端(Controlling Terminal)的话,那么/dev/tty就是当前进程的控制终端的设备特殊文件,用户打印。tty_io.c中除了有tty_init,tty_open之外还有tty_poll,用于实现poll,另外还有用于异步通知的tty_fasync,主要是通过SIGIO信号来通知用户进程,因为串口速度不快,用异步通知也可以。而如果速度要求快的话,就需要在中断中唤醒进程,用户程序用poll,select来等待了。
ldd3中有tty_driver的介绍了。
tty_ldisc是和console有关系的,n_tty,多串口支持,SIGIO。
tty_ldisc下面才是tty_driver。
串口如果是普通功能,就可以不跟tty关联起来,而实现char设备即可。
console是内核打印,在tty_io.c中console_init中有初始化em86xx_uart_console_init,在serial_em86xx.c中,有register_console,而register_console的实现是在printk.c,从而也说明了console内核打印和用户打印tty底层实现不一样。而用户程序打印以及输入是tty,代码在行规n_tty.c中,而tty_ldisc的注册也是在console_init开始部分的,
(void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY)
只不过这里的console_init部分是与定义的CONFIG_SERIAL_EM86XX_CONSOLE没有关系的,而是与tty有关的,n_tty->tty_io->serial_em86xx,serial_core.也就是说即使没有CONFIG_SERIAL_EM86XX_CONSOLE,假设console内核打印是在framebuffer,键盘的tty0,但用户程序的打印输入是在/dev/tty,最终是可以是在/dev/ttyS0,从而用户程序就可以通过/dev/ttyS0普通串口通信与串口通信设备通信了,而此时串口驱动可以不实现serial_console功能.
console.c
#ifdef CONFIG_VT
con_init()
#endif
tty_init
#ifdef CONFIG_VT
dev_console_driver = dev_tty_driver
dev_console_driver.driver_name = "/dev/vc/0"
dev_console_driver.name = dev_console_driver.driver_name + 5
dev_console_driver.major = TTY_MAJOR
dev_console_driver.type = TTY_DRIVER_TYPE_SYSTEM
dev_console_driver.subtype = SYSTEM_TYPE_CONSOLE
if (tty_register_driver(&dev_console_driver))
panic("Couldn't register /dev/tty0 driver\n")
kbd_init()
#endif
console.c以及CONFIG_VT是内核控制台,内核打印方面的。
config VT
bool "Virtual terminal" if EMBEDDED
select INPUT
default y if !VIOCONS
---help---
If you say Y here, you will get support for terminal devices with
display and keyboard devices. These are called "virtual" because you
can run several virtual terminals (also called virtual consoles) on
one physical terminal. This is rather useful, for example one
virtual terminal can collect system messages and warnings, another
one can be used for a text-mode user session, and a third could run
an X session, all in parallel. Switching between virtual terminals
is done with certain key combinations, usually Alt-<function key>.
The setterm command ("man setterm") can be used to change the
properties (such as colors or beeping) of a virtual terminal. The
man page console_codes(4) ("man console_codes") contains the special
character sequences that can be used to change those properties
directly. The fonts used on virtual terminals can be changed with
the setfont ("man setfont") command and the key bindings are defined
with the loadkeys ("man loadkeys") command.
You need at least one virtual terminal device in order to make use
of your keyboard and monitor. Therefore, only people configuring an
embedded system would want to say N here in order to save some
memorythe only way to log into such a system is then via a serial
or network connection.
If unsure, say Y, or else you won't be able to do much with your new
shiny Linux system :-)
config VT_CONSOLE
bool "Support for console on virtual terminal" if EMBEDDED
depends on VT
default y
---help---
The system console is the device which receives all kernel messages
and warnings and which allows logins in single user mode. If you
answer Y here, a virtual terminal (the device used to interact with
a physical terminal) can be used as system console. This is the most
common mode of operations, so you should say Y here unless you want
the kernel messages be output only to a serial port (in which case
you should say Y to "Console on serial port", below).
If you do say Y here, by default the currently visible virtual
terminal (/dev/tty0) will be used as system console. You can change
that with a kernel command line option such as "console=tty3" which
would use the third virtual terminal as system console. (Try "man
bootparam" or see the documentation of your boot loader (lilo or
loadlin) about how to pass options to the kernel at boot time.)
If unsure, say Y.
config SERIAL_8250_CONSOLE
bool "Console on 8250/16550 and compatible serial port"
depends on SERIAL_8250=y
select SERIAL_CORE_CONSOLE
---help---
可以。中标麒麟通用服务器操作系统提供中文化的操作系统环境和常用图形管理工具。支持多种安装方式,提供完善的系统服务和网络服务;集成多种易用的编译器并支持众多开发语言,全面兼容国内外的软硬件厂商;在安全上进行了加强,确保关键应用能安全、可控、稳定的对外提供服务。欢迎分享,转载请注明来源:夏雨云
评论列表(0条)