欢迎分享,转载请注明来源:内存溢出
通用控制台和串口控制台 控制台的思想 过去,计算机是一个庞然大物,附带着十几个终端设备。其中一个终端具有“系统控制台”的特殊作用。它是唯一用于系统恢复的单用户模式终端,也是唯一接受系统错误消息的终端。当今的计算机都配有键盘和显示设备,不再带有多个文本终端。于是“系统控制台”就由本地键盘和监视器担任。而当计算机主机没有连接显示硬件设备时,一般就由串口设备担任“系统控制台”。把串口设备的电缆插入就可以得到诊断信息和登陆提示字。把控制台当作控制终端是合适的。通过它作为输入输出通道从而可以启动一个根shell并发送内核消息则是完全不同的机制。我们关注的是消息是如何传送给系统控制台设备的。系统预设的控制台 当在计算机中安装了文本模式的gnu/linux系统时,系统预设的控制台就是当前的虚拟终端。 传送消息到控制台的机制是由printk函数实现的。该函数使用vsprintf(lib/vsprintf.c)产生消息串,把它放入内核消息的环形缓冲区中,然后将消息传给所有活动的console设备,只要该消息的优先级数字小于console_loglevel。 变量console_loglevel用于选择何种消息可以输出到系统控制台上。预设值是DEFAUL_CONSOLE_LOGLEVEL。系统管理员可以通过写/proc/sys/kernel/printk 该变其值。 这些优先级数值用宏KERN_ERROR,KERN_DEBUG等定义为0-7级。 if (msg_level <console_loglevel &&console_drivers) { struct console *c = console_driverswhile(c) { if ((c->flags &CON_ENABLED) &&c->write) c->write(c, msg, p - msg + line_feed)c = c->next} } 大多数linux配置中只有一个控制台注册,它对应于虚拟终端,代码在consol.c中。实际的消息打印是由vt_console_print执行的。看一下它的源码就会发现它并不总是把消息打印到前台虚拟终端,但可以配置为打印消息到一个虚拟终端上。如果变量kmsg_redirect非0,其值就是那个选来接受内核消息的虚拟终端的号。该变量可以通过调用ioctl(TIOCLINUX)(一个linux定义的tty的ioctl命令)作用到一个虚拟终端的文件描述符上。 如果正在运行的是带有串口的标准pc,可以通过传递一个命令行选项console=给内核以选择一个串口作为控制台。文件Documentation/serial-console.txt清楚地描述了所需要的整个设备和 *** 作细节。 声明和选择一个控制台 为了声明一个新的控制台设备,内核代码应首先包含,这个头文件定义了struct console结构和几个flags.随后就可以调用register_console把控制台插入到活动控制台的数据结构表格中例如以下是串口声明和注册过程: static struct console sercons = { name: "ttyS", write: serial_console_write, device: serial_console_device, wait_key: serial_console_wait_key, setup: serial_console_setup, flags: CON_PRINTBUFFER, index: -1, }void __init serial_console_init(void) { register_console(&sercons)} 写一个控制台驱动程序 console的初始化console结构中有几个成员只是为了使console的初始化和配置过程简单.name和setup成员用于命令行解析系统启动时,为每个"console="内核命令行参数调用console_setup (在kernel/printk.c中).该函数保存所有命令行的命令到一个数组中.当以后调用register_console注册一个console时,如果发现命令数组中的名字和console的名字域匹配,则以命令行中相应的option为参数调用console的setup初始化函数.使得console符合命令行的要求. console标志CON_ENABLE 指明该控制台设备是否是默认启动的,只有启动的控制台才接受内核消息,如果内核命令行选中了 这个console,并且console的setup函数调用成功,系统自动为该console设置此标志. 进一步,此标志为首次注册的console设立.这就是串口或并口控制台在自己的console结构中默认都没有 设置这一标志的原因.默认情况下串,并口不是作为控制台使用的.除非用户在命令行指定串,并口作为 控制台或者没有虚拟终端设备作为默认控制台.CON_PRINTBUFFER 此标志请求将缓冲的内核消息输出到这个控制台上.例如串,并口设置此标志就可显示所有内核启动消息: 当注册串,并口为console时设置了此标志,内核随即把缓存的消息输出到它们上面.CON_CONSDEV 控制台请求成为优先的设备,优先的设备总是被放入console表的第一项. ----------------------------控制台数据结构表struct console { char name[8]//设备名用于解析命令行选项console= void (*write)(struct console *,const char *,unsigned)int (*read)(struct console*,const char*,unsigned)struct tty_driver *(*device)(struct console, void (*unblank)(void)int*)//当前作为console的tty设备 int (*setup)(struct console*,char*)初始化串口函数 short falgsshort index//设备数组中为console设备的索引号 int cflagstruct console *next} console_drivers是表头指针(不是console_driver)目前串口和终端都可以同时收到到数据,同时在终端中如果输入CTRL+C程序可以推出,哈哈,很好玩! void CloseConsole(void){int fp,errunsigned char buff unsigned char send_buff struct termios optionsprintf("change1\n"fp = open("/dev/console",O_RDONLY)// 改变consoleioctl(fp,TIOCCONS)close(fp)fp = open("/dev/ttyS0",O_RDWR|O_NOCTTY|O_NDELAY|O_NONBLOCK)//打开串口0读写if(fp == -1) exit(0)tcgetattr(fp,&options)cfsetispeed(&options,B115200)cfsetospeed(&options,B115200)options.c_cflag |= (CLOCAL|CREAD)tcsetattr(fp,TCSANOW,&options)write(fp,"hello world!\n12",15)while(1){sleep(11)while(err=ReadComPort(fp,buff,20)/*read(fp,buff,1)*/>0) { WriteComPort(fp, send_buff, }}close(fp)//关闭串口0fp = open("/dev/console",O_RDONLY)//恢复console 到串口0ioctl(fp,TIOCCONS)close(fp)printf("change2\n"}
赞
(0)
打赏
微信扫一扫
支付宝扫一扫
win7如何删除屏保
上一篇
2023-05-21
matlab2014b输入的安装密钥无效怎么办
下一篇
2023-05-21
评论列表(0条)