当前位置: 首页 > news >正文

怎样监测熊掌号绑定成功网站做机器人的网站

怎样监测熊掌号绑定成功网站,做机器人的网站,html网页设计工具,徐州高端网站建设tty 驱动程序框架 tty 驱动程序从下往上分别是设备驱动层、行规程、终端虚拟化、TTY I/O层#xff0c;它们的功能如下#xff1a; 设备驱动层#xff1a;用于驱动设备#xff0c;如串口、显示器、键盘等。行规程#xff1a;用于处理控制字符、回显输入数据、缓存输入数据…tty 驱动程序框架 tty 驱动程序从下往上分别是设备驱动层、行规程、终端虚拟化、TTY I/O层它们的功能如下 设备驱动层用于驱动设备如串口、显示器、键盘等。行规程用于处理控制字符、回显输入数据、缓存输入数据、显示数据输出等如果应用层不需要这些处理机制可以将行规程设置为原始模式设置方法参考11.1Linux串口应用程序开发。终端虚拟化用于对显示器、键盘、鼠标组成的终端进行虚拟化。TTY I/O层与应用层进行交互。 struct uart_driver 对象 uart_driver 对象表示一个 uart 驱动一个串口驱动可以由多个串口端口其核心成员如下 //所属模块struct module *owner;//驱动名称const char *driver_name;//设备名称串口设备文件名以此为基础生成const char *dev_name;//主设备号为0表示系统自动分配int major;//起始次设备号即第一个串口的次设备号int minor;//此驱动支持的串口个数int nr;//若驱动支持 console 则指向对应的 serial console 否则为 NULLstruct console *cons;//串口的状态信息每个串口端口都有自己的状态信息其中主要包括 tty_port 和 uart_portstruct uart_state *state;//串口驱动对应的 tty 驱动struct tty_driver *tty_driver;struct console 对象 console 对象用于描述一个控制台驱动其核心成员如下 //该 console 的名称配合index字段使用如果name为“ttySTM”index字段为小于0则可以和“consolettySTMn“n0,1,2…来确定index字段的值char name[16];//写函数void (*write)(struct console *, const char *, unsigned);//读函数int (*read)(struct console *, char *, unsigned);//获取 console 对应的 tty 驱动struct tty_driver *(*device)(struct console *, int *);//初始化 consoleint (*setup)(struct console *, char *);//console 标志short flags;//console 索引若小于 0 则由命令行参数确定short index;struct uart_state 对象 uart_state 对象表示一个串口端口的状态信息其核心成员如下 //串口端口所属的 tty 端口主要包含 tty 端口的 buf 、端口操作函数等信息struct tty_port port;//串口端口对应一个串口设备主要包含串口的硬件操作函数等信息struct uart_port *uart_port;struct uart_port 对象 uart_port 对象表示一个串口端口其核心成员如下 //配置 RS485int (*rs485_config)(struct uart_port *, struct serial_rs485 *rs485);//中断号unsigned int irq;//串口基准时钟unsigned int uartclk;//发送 FIFO 大小unsigned int fifosize;//流控字符unsigned char x_char;//IO 类型unsigned char iotype;//串口标志upf_t flags;//操作函数集合const struct uart_ops *ops;//端口索引unsigned int line;//寄存器逻辑基地址resource_size_t mapbase;//寄存器映射大小resource_size_t mapsize;//所属父设备struct device *dev;//RS485 配置信息struct serial_rs485 rs485;struct tty_driver 对象 tty_driver 对象用于表示一个 tty 驱动其核心成员如下 //幻数用于检查结构体是否是一个 tty_driverint magic;//cdev 指针数组用于关联 tty_port 的字符设备驱动struct cdev **cdevs;//所属模块struct module *owner;//驱动名称const char *driver_name;//设备名称对于非 TTY_DRIVER_TYPE_PTY 类型的 tty_port 其设备文件名以此为基础生成const char *name;//主设备号为0表示系统自动分配int major;//起始次设备号即第一个 tty_port 的次设备号int minor_start;//此驱动支持的 tty_port 个数unsigned int num;//tty 类型short type;//tty 子类型short subtype;//初始配置参数struct ktermios init_termios;//tty 驱动标志unsigned long flags;//tty_struct 指针数组struct tty_struct **ttys;//tty_port 指针数组struct tty_port **ports;//ktermios 指针数组struct ktermios **termios;//tty 驱动操作函数接口const struct tty_operations *ops;串口驱动注册过程 串口驱动注册包括两个主要步骤分别是注册串口驱动和在串口驱动下添加串口端口。 5. 串口驱动注册过程 构建并初始化 struct uart_driver调用 uart_register_driver 函数注册 struct uart_driver根据 struct uart_driver 中的端口数量为其分配 struct uart_state struct uart_state 中包含一个 struct tty_port 和一个 struct uart_port调用 alloc_tty_driver 函数分配一个 struct tty_driver通过宏定义调用 __tty_alloc_driver 函数分配 struct tty_driver并初始化为前面分配的 struct tty_driver 分配 struct tty_struct 、 struct tty_port 、 struct ktermios 、 struct cdev 指针数组这里只分配了指针将分配的 struct tty_driver 与 struct uart_driver 关联利用 struct uart_driver 初始化前面分配的 struct tty_driver调用 tty_set_operationsstruct uart_driver 函数设置 struct tty_driver 的操作函数集合循环调用 tty_port_init 函数初始化 struct uart_state *state 中的 struct tty_port port 调用 tty_register_driver 函数将 struct uart_driver 中的 struct tty_driver *tty_driver 注册到系统中注册 uart_driver 的本质就是注册 tty_driver 只是这个 tty_driver 属于uart_driver 且对应的的操作函数集合具体操作对象为 uart_driver uart_driver 继承于 tty_driver 。 6. 在串口驱动下添加串口端口的过程 先注册 struct uart_driver 然后构建并初始化 struct uart_port调用 uart_add_one_port 函数在 struct uart_driver 中添加一个 struct uart_port根据 struct uart_port 中的 unsigned int line 成员从 struct uart_driver 中找到对应的 struct uart_state 及 struct uart_state 中的struct tty_port初始化对应的 struct uart_state 并将其与 struct uart_port 进行关联通过传入的 struct uart_driver 初始化 struct uart_port其中包括次设备号、端口名称、端口的 console调用 tty_port_link_device 函数将 struct uart_state 中的 struct tty_port 与 struct uart_driver 中的 struct tty_driver 进行关联调用 uart_configure_port 函数对 struct uart_port *uport 进行一些配置如果 struct uart_port 的 iobase 、 mapbase 、 membase 均为 0 则直接退出如果 struct uart_port 的 flags 设置了 UPF_BOOT_AUTOCONF 则调用 config_port 函数配置串口硬件如果 struct uart_port 的 struct console *cons 不为空且还未使能则调用 register_console 注册 console利用启动命令行参数中的 console_cmdline 参数进行匹配匹配成功则设置 console 的 index 然后调用 console 的 setup 函数进行硬件初始化将 console 添加到 console_drivers 链表中设置 struct tty_port 中的 console 属性需要 struct uart_port 的 line 与 struct console 的 index 一致才设置而 struct console 的 index 值可以由 bootargs 参数确定调用 tty_port_register_device_attr_serdev 函数注册 struct tty_port调用 tty_register_device_attr 函数注册 tty 设备调用 tty_line_name 生成设备文件名分配一个 device 对象并对其初始化这里配置了设备号和设备名注册后会创建设备文件调用 device_register 注册分配的 device调用 tty_cdev_add 注册字符设备驱动分配 cdev 对象并进行初始化主要配置操作函数集合调用 cdev_add 将分配 cdev 对象注册到内核在 uart_driver 下添加 uart_port 的本质就是在其对应的 tty_driver 下添加 tty_port 只不过事先通过 uart_state 将 uart_port 和 tty_port 进行了关联 串口打开过程 添加端口的时注册一个 cdev 并设置其操作函数集合为 tty_fops 其中提供了 tty_open 函数在应用层执行 open 时会通过虚拟文件系统调用到此函数其执行过程如下 在应用层执行 open 时会通过虚拟文件系统调用 tty_open执行 tty_open_current_tty 函数尝试打开进程所属的 tty 其设备文件名是/dev/tty设备ID应该是MKDEV(5, 0)对于打开串口此函数会执行失败tty_open_current_tty 函数执行失败后会执行 tty_open_by_driver 函数来打开 tty执行 tty_lookup_driver 函数找到对应的 tty_driver执行 tty_driver_lookup_tty 函数从 tty_driver 找到对应的 tty_struct 对于打开过的 tty 会执行成功然后对 tty 进行检查和设置并返回对应的 ttytty_driver_lookup_tty 函数未找到 tty 则调用 tty_init_dev 函数分配 tty_struct 并进行相应的配置调用 alloc_tty_struct 分配 tty_strct调用 kzalloc 分配 tty_strct调用 tty_ldisc_init 绑定行规程调用 tty_driver_install_tty 将 tty_strct 安装到 tty_driver 中调用 tty_ldisc_setup 对配置行规程通过 tty-ops-open 指针调用 serial_core.c 中 的 uart_open 函数调用 tty_port_open 打开对应端口通过 port-ops-activate 调用 serial_core.c 中的 uart_port_activate 函数调用 uart_startup 函数启动串口调用 uart_port_startup 函数启动串口通过 uport-ops-startup 调用串口驱动提供的 startup 函数串口读过程 读串口数据可分为两部分 7. 应用程序从行规程中读取数据 与执行 open 过程类似在应用层执行 read 时会通过虚拟文件系统调用 tty_read 函数其执行过程如下在应用层执行 read 时会通过虚拟文件系统调用 tty_read通过 tty_ldisc_ref_wait 函数得到 tty 的行规程通过 ld-ops-read 调用行规程的 read 函数这里通常是 N_TTY中的 n_tty_read 函数在 n_tty_read 函数中无数据则休眠等待数据有数据则将数据拷贝到应用层串口向行规程上报数据 串口收到数据进入中断程序中断程序从硬件读取数据调用 tty_insert_flip_string 函数将数据存入 tty_port 的 tty_buffer 中调用 tty_flip_buffer_push 函数通知行规程处理数据调用 tty_schedule_flip 函数启动数据处理调用 queue_work 函数启动一个工作队列处理数据这里的工作队列处理函数为 flush_to_ldisc 函数串口写过程 在应用层执行 write 时会通过虚拟文件系统调用 tty_write 函数然后 tty_write 函数通过绑定的行规程调用到行规程的 n_tty_write 函数接下来由行规程对数据处理后调用 serial_core.c 中的 uart_flush_chars 函数启动发送如果行规程设置原始模式则不进行处理直接调用 serial_core.c 的 uart_write 函数启动发送发送过程由串口的中断或 DMA 完成其流程如下 在应用层执行 write 时会通过虚拟文件系统调用 tty_write 函数通过 tty_ldisc_ref_wait 函数获得与tty绑定的行规程调用 do_tty_write 函数执行数据发送操作在执行 do_tty_write 函数传入的是行规程 write 函数作为实际的写函数通过 copy_from_user 函数将数据拷贝到 write_buf 中通过 write 指针调用行规程的 write 函数这里对应的是 n_tty_write 函数如果设置了 OPOST 标志则对数据进行处理后调用 tty 操作函数集合中的 flush_chars 函数发送数据这里实际对应的是 uart_flush_chars 函数调用 uart_start 启动串口发送调用 __uart_start 函数调用 uart_port 中的 start_tx 函数即硬件驱动提供的发送启动函数如果没有设置 OPOST 标志则调用 tty 操作函数集合中的 write 函数发送数据这里实际对应的是 uart_write 函数将数据写入到 uart_state 的 buf 中后在调用 __uart_start 启动串口发送调用 uart_port 中的 start_tx 函数即硬件驱动提供的发送启动函数通过 tty_ldisc_deref 释放对行规程的占用console 注册过程 在前面的串口驱动注册过程已经介绍了 console 的注册这里在简单梳理一下 console 的注册步骤 构建并初始化 struct console 对象 将 struct console 对象的地址给 struct uart_driver 的 cons 成员 调用 uart_register_driver 函数注册 struct uart_driver 调用 uart_add_one_port 函数添加一个串口端口此时会顺便完成对 console 的注册将 struct uart_driver 的 cons 赋给 struct uart_port 的 cons调用 uart_configure_port 函数若 struct uart_port 的 cons 成员有效且未使能则调用 register_console 函数注册 console利用启动命令行中的 console_cmdline 参数进行匹配匹配成功则设置 console 的 index 然后调用 setup 函数进行配置将新注册的 console 添加到 console_drivers 链表中当 struct uart_port 的 line 与其 console 的 index 一致则设置 struct tty_port 的 console 标志因此在多个 uart_port 中只有一个 uart_port 真正的拥有 struct uart_driver 中的 consoleprintk 执行流程 printk 的执行流程大致如下 通过 va_start 取出不定参数列表然后调用 vprintk_func然后调用 vprintk_default 函数再调用 vprintk_emit 函数调用 vprintk_store 函数使用 vscnprintf 进行格式化处理调用 log_output 输出数据并未通过硬件输出实际上是将数据存储在 log_buf 中调用 console_unlock 函数可能是直接调用也可能是通过 wake_up_klogd 函数唤醒工作队列然后由工作队列处理函数去调用通过 log_from_idx 从 log_buf 取出一个 msg如果 msg 优先级不够则跳过通过 call_console_drivers 将数据从 console 输出系统中可能会有多个 consoleprintk 使用 /** fmt 格式字符串其前面还包含描述优先级的字符它们的定义如下* ASCII的标题开始字符SOH表示后面是优先级字符* #define KERN_SOH \001* 不同优先级定义数字越小优先级越高* #define KERN_EMERG KERN_SOH 0* #define KERN_ALERT KERN_SOH 1* #define KERN_CRIT KERN_SOH 2* #define KERN_ERR KERN_SOH 3* #define KERN_WARNING KERN_SOH 4* #define KERN_NOTICE KERN_SOH 5* #define KERN_INFO KERN_SOH 6* #define KERN_DEBUG KERN_SOH 7* ... 不定参数列表与格式字符串有关**/int printk(const char *fmt, ...)设置系统的输出优先级 系统输出等级存储在 /proc/sys/kernel/printk 文件中它有4个参数依次是控制台消息级别、默认信息级别、最小控制台级别、默认控制台级别 early_printk 当在 uboot 的命令行参数中传入 earlyprintk 且在内核配置选项中使能 Early printk 选项后系统会调用 setup_early_printk 函数创建一个 console 此 console 的 write 函数最终会调用 printascii 输出数据 STM 官方内核已经通过汇编实现 printascii 函数用于在串口初始化完成以前输出调试信息具体使用步骤如下 配置内核 Kernel hacking --- [*] Kernel low-level debugging functions (read help!)(0x40010000) Physical base address of debug UART (NEW)(0xfe010000) Virtual base address of debug UART (NEW)[*] Early printk在 bootargs 中加入 earlyprintk earlyprintk 注册过程 当 bootargs 中包含 earlyprintk 且内核配置选项中使能 Early printk 时在系统初始化阶段会调用 setup_early_printk调用 register_console 注册一个 console 用于系统早期输出通过 console 通过的 write 函数输出在STM32中此 write 函数最终会调用 printascii 输出数据
http://www.zqtcl.cn/news/746851/

相关文章:

  • 怎么做网站的seo排名知乎茂名网站制作公司
  • 建安证查询网站官方网站建设对比
  • 关于医院要求建设网站的请示市场推广12种推广渠道
  • php做不了大型网站深圳公司注册网址官方
  • 网站副标题怎么写杭州抖音代运营
  • 网站建设基本资料网站数据库连接出错
  • 娄底网站开发温州seo排名公司
  • 成都有哪些网站开发公司最新网推项目
  • 分享公众号的网站小型企业类网站开发公司
  • 青岛网站建设方案案例wordpress主题模板 国人
  • 哪家高端网站建设好贷款织梦网站模板
  • 北京网站建设公司价格最近中文字幕2018免费版2019
  • 帮人做设计的网站自己怎么做新闻开头视频网站
  • 网站开发搜索功能中国建设银行ie下载网站
  • 中山网站建设 骏域网站的形式有哪些
  • 深圳企业网站重庆建站塔山双喜
  • 征婚网站 女 做茶叶生意企业网站推广服务协议
  • 安徽省住房城乡建设厅网站官网英语机构网站建设方案
  • 电商建站价格深圳龙岗建站公司
  • 可以下载源程序的网站.htaccess wordpress
  • 国内优秀设计网站小程序推广方案
  • 网站构建是什么意思怎么做网站盗号
  • 学校网站建设行业现状wordpress怎么保存图片
  • 网站 框架网页建设title:(网站建设)
  • 素材网站推广方案安卓端开发
  • 网站制作可以询价么168推广
  • 河南城乡和住房建设厅网站网络营销的主要特点有哪些
  • 哪些网站可以做自媒体wordpress 左侧
  • joomla! 1.5 网站建设基础教程丹阳网站推广
  • 中国建设银行山东省分行网站怎么做网站制作