网上有很多关于u米电签版pos机注册流程,linux串口子系统中串口设备注册与注销以及串口开发流程说明的知识,也有很多人为大家解答关于u米电签版pos机注册流程的问题,今天pos机之家(www.poszjia.com)为大家整理了关于这方面的知识,让我们一起来看下吧!
本文目录一览:
u米电签版pos机注册流程
上一章我们介绍了串口的数据结构,本章我们介绍串口相关的操作接口,并介绍串口的注册与注销接口,本章主要包括如下几个方面的内容:
串口控制器、串口的注册与注销串口子系统操作接口的介绍说明串口驱动开发流程说明串口子系统架构总结串口控制器、串口的注册与注销既然串口子系统是对tty子系统的封装,因此其注册与注销也同样包括tty_driver、tty_port两部分。在之前阅读tty子
系统时,我们可以发现真正实现读写tty端口的操作全部是由tty_driver数据结构中的操作接口实现的,而tty_port中仅仅是实现具体tty端口的使能与去使能等操作。而在串口子系统中,为了减少开发量,同时又要对接tty子系统,串口子系统内部为tty_driver注册了通用的操作接口,而把不同串口控制器操作接口的操作又移至uart_port->ops接口中,从而使串口驱动的开发只需要关注uart_potr->ops即可,无需再同时关注tty_driver->ops、tty_port->ops。
串口控制器驱动注册与注销针对串口控制器驱动,其注册接口为uart_register_driver,而针对uart_driver的注册,开发人员主要需要设置
uart_driver的driver_name、dev_name、nr、cons,其中dev_name、nr表示串口的名称前缀、串口个数,而cons则表示该串口控制器是否支持控制台功能,若支持控制台则设置该变量。
如下就是uart_driver的注册接口,其实现的功能较简单,主要功能如下:
调用alloc_tty_driver申请tty_driver类型的内存,并设置tty_driver的各成员变量,同时设置其ops成员为uart_ops;根据串口的个数,为每一个串口申请对应的uart_state类型的内存空间(也就完成了对应tty_port的创建),用于存储每一个串口的资源相关的信息以及串口对应tty_port信息,并为tty_port设置其ops成员为uart_port_ops;我们知道tty_port中包含接收数据的缓存,但却没有发送数据的缓存,而uart_state中则包含了发送数据的缓存(即环形缓存区),因此借助uart_state、tty_port则实现了串口收发数据的缓存(在我们之前实现的虚拟串口中也定义了数据发送的buff,只不过是使用kfifo实现的)。
从上面的代码我们可以看到,针对所有的uart_driver,其tty_driver成员的ops都设置为uart_ops接口,而uart_ops的定义如下,下面简要说明下其实现的功能:
open、close用于开启和关闭串口,通过调用struct uart_ops的startup、stop_rx、stop_tx,实现串口的开启与关闭操作;write接口实现将数据从串口发送出去(当然在uart_write中先将数据写入环形缓冲区中,再调用uart_port->ops->start_tx接口,实现数据的发送);uart_put_char接口主要将一个字节的数据拷贝到该串口的发送缓存中;Flush_chars接口的作用是将串口发送缓冲中的数据发送出去(调用uart_port->ops->start_tx接口,实现真正的数据发送);uart_write_room、uart_chars_in_buffer主要用于返回发送缓存中可用空间、已使用空间的字节数等;uart_flush_buffer接口主要用于flush该串口的发送缓存,并唤醒写等待队列;uart_throttle、uart_unthrottle主要是实现流控(包括硬件流控和软件流控,其中软件流控则通过定义一个特殊字符作为流控约束的标志位);uart_set_termios接口主要是termios设置,包括输入、输出参数设置、控制参数设置等,如上面说的软件流控中start、stop标志字符的设置,还包括串口波特率的设置、CRTSCTS、字节宽度的设置等等;uart_stop、uart_start、uart_hangup则主要串口停止、启动、挂起相关的接口,内部也是调用uart_port->ops->stop、start停止或启动一个发送操作;而uart_hangup则主要是挂起操作;uart_tiocmget、uart_tiocmset则主要是modem ctrl相关的操作接口。在主要的接口中,也设置了tty_port->ops成员,我们看下uart定义的tty_port操作接口函数,这几个接口也捎带说明下:
针对activate,在tty子系统中,主要在tty_port_open中调用,实现tty端口的启用,但针对uart子系统而言,在其uart_tty_driver->open接口中,并没有调用tty_port_open接口,取而代之的是uart_startup、uart_ops->start,因此只需要实现uart_ops->start接口即可,此处定义的uart_port_activate并不会被调用,没有意义。。。针对shutdown接口而言,在tty子系统中,主要是在tty_port_close接口中调用,而针对uart_tty_driver->close接口中,也没有调用uart_port_ops->shutdown接口(即uart_port_shutdown)因此此处设置的activate、shutdown,没有任何意义,没有必要设置这两个变量
串口的注册接口串口的注册接口为uart_add_one_port,该接口的定义如下,主要功能说明如下:
完成uart_state与uart_port的互相关联;调用uart_configure_port,配置该串口(如mem、io资源的申请等);调用tty_port_register_device_attr接口,完成tty_port与tty_driver的关联,并调用device_register完成tty_port对应device的注册,同时该动作也完成了tty_port对应device与tty_class的关联,同时也完成tty对应字符设备的创建(通过向应用层发送kobject add uevent,而udevd、mdev在接收到该uevent后,根据设备节点至,通过调用mknod接口完成设备文件inode的创建,也就完成了字符设备文件的创建),同时也为该tty端口对应的device创建了uart相关的属性信息(即tty_dev_attr_groups)在uart port的注册时,为其对应的device创建了属性文件(即tty_dev_attr_groups),我们看下tty_dev_attr_groups的定义。包含的属性如下所示,包括串口类型、index、端口的iobase、中断、flag、发送fifo大小、uart clk、iomem_base等,当我们需要获取一个串口详细信息时,可进入串口对应的sysfs文件下对应文件中查看(我之前实现的虚拟串口也创一个文件属性,用于模拟向虚拟串口发送,当时是调用sysfs_create_group实现的,其实tty_port_register_device_attr接口即可实现tty port注册+创建属性文件,哎,我没看这个接口啊…)。
串口子系统操作接口的介绍说明串口子系统提供的操作接口包含uart_open、uart_close、uart_write、uart_put_char uart_flush_chars、uart_write_room、uart_chars_in_buffer、uart_flush_buffer、uart_ioctl、uart_throttle、uart_unthrottle等接口,在上面也做了简要说明,此处则对应uart_open、uart_write这两个接口进行一个说明
uart_open接口一般针对tty_driver->open接口而言,基本上就是调用tty_port_open接口,增加tty_port的引用计数、完成tty_port与tty_struct的关联,并调用tty_port->ops->active接口,使能该tty端口;而在串口的open函数中,虽然没有调用tty_port_open接口,但也实现了其中的tty_port的引用计数、完成tty_port与tty_struct的关联,也调用tty_port_block_til_ready等待该串口可用。因没有调用tty_port->ops->active接口,uart_open则通过调用uart_startup使能一个串口。
下面看下该接口的实现,该接口实现如下流程图(省略了异常判断),主要功能如下:
增加tty_port的引用计数(即tty_port->count++);完成tty_struct与uart_state的关联、uart_port与uart_state的关联;完成tty_port与tty_struct的关联(在此之前tty_struct已完成tty_port),至此完成tty_port与tty_struct的相互关联调用uart_startup,用于启动一个串口,在uart_startup接口中,通过间接调用uart_port->ops->startup、uart_port->ops->set_termios完成一个端口的开启,并完成termios相关参数的设置(如波特率等)。最后调用tty_port_block_til_ready,用于等待一个tty端口准备好(若该串口正处于关闭状态,则等该串口关闭完成后,则返回失败;若该串口是通过非阻塞模式打开,则返回打开成功;若该串口为阻塞打开,则必须等待已打开该串口的进程关闭该串口后,方能返回)而tty_port_block_til_ready的作用如下:
若该端口处于hangup或者处于关闭状态中,则将该进程加入到close_wait等待队列,待hangup结束后,则返回EAGAIN;待close完成被唤醒后,则返回ERESTARTSYS;若非上述情况,且是非阻塞,则设置port的标签为ASYNC_NORMAL_ACTIVE,并返回;若非1中情况,且是第一次打开,则设置port的标签为ASYNC_NORMAL_ACTIVE,并返回;若为阻塞,且不是上述1.2.3中情况,则当前进程等待,并加入open_wait,待上一个进程关闭后,本进程被唤醒,并继续执行打开操作。 uart_write接口该接口的实现比较简单,代码如下:
将待发送的数据写入环形缓冲区;调用uart_start,启动一次发送操作,而uart_start接口则主要调用uart_port->ops->start_tx接口,由具体串口设备的start_tx接口启动一次发送(如在该接口中使能tx中断,实现tx中断触发,而在tx中断处理函数中完成一次发送)串口驱动开发流程说明在module_init标识的初始化函数中,调用uart_register_driver,完成uart_driver的注册,主要设置串口字符设备文件名称的前缀、串口个数的设置等;创建一个platform_driver,在platform_driver的probe接口中,获取待注册串口信息的资源信息,并定义struct uart_ops中各函数,并调用uart_add_one_port完成uart port的注册;为每一个待注册的串口设备,创建一个platform device,并传递该串口相关的信息(若内核支持设备树,开发人员无需事先该步,只需在设备树中增加相应串口信息即可)。基本上完成以上几步,即完成了一个串口驱动,其实最主要的就是实现struct uart_ops中各成员函数指针。下一章我们来完成一个虚拟的串口设备及其驱动。
串口子系统架构总结
串口子系统针对所有串口,完成了统一的tty_driver的变量的实现,而将每一个串口需要实现的内容全部移至uart_port、uart_pos中,而无需实现tty_driver的操作接口、tty_port的操作接口(均由串口子系统内部实现)。相对于tty子系统而言,确实方便了一些。
以上就是关于u米电签版pos机注册流程,linux串口子系统中串口设备注册与注销以及串口开发流程说明的知识,后面我们会继续为大家整理关于u米电签版pos机注册流程的知识,希望能够帮助到大家!
