概述
1 、重要结构
/* 描述端口信息 */
struct uart_port {
....
unsigned long iobase;
const struct uart_ops *ops;
struct uart_icount *icount;
...
};
//回调函数
struct uart_ops {
...
void (*set_mctrl)(struct uart_port *, unsigned int); // 流控配置
void (*stop_tx)(struct uart_port *); //停止发送
void (*stop_rx)(struct uart_port *); //停止接收
void (*set_termios)(struct uart_port *, struct ktermios *, struct ktermios *); //配置端口
void (*config_port)(struct uart_port *, int);
const char *(*type)(struct uart_port *);
...
};
/* 描述状态*/
struct uart_state
{
...
struct tty_port port;
struct circ_buf xmit;
...
};
/* 描述接收和发送信息*/
struct uart_icount {
...
__u32 tx;
__u32 rx;
...
};
/* 描述驱动信息 */
struct uart_driver {
...
struct module *owner;
const char *driver_name;
const char *dev_name;
struct console *cons;
int nr;
...
};
/* 用于作为终端时使用*/
struct console {
...
void (*write)(struct console *, const char *, unsigned);
int (*setup)(struct console *, char *);
...
};
2、重要信息
在实现UART驱动时,需要填充多个重要数据。
1、struct uart_port
iotype:使用于描述端口类型,常用的类型有UPIO_MEM, UPIO_MEM32,区别在于8位和32位数据。
flag:建议配置UPF_BOOT_AUTOCONF
line:用于标记第几个端口。
membase:寄存器地址
mapbase:map基地址
2、struct uart_ops
这个结构体的函数基本全部需要实现。
填充完以上基本信息后,便可调用uart_register_driver注册uart驱动。
最调用uart_add_one_port。为uart驱动添加端口。
在调用uart_add_one_port后,set_mctrl,config_port会被调用。
在config_port回调中,需要设置port的type和uartclk, uartclk为串口波特率的16倍大小。
3、数据收发
1、发送数据 start_tx
在这个回调函数中,通过port->state->xmit中保存了待发送数据。
需要自己实现将数据放到uart的发送寄存器中。
2、接收数据
接收数据比较特殊。在串口设备被打开并进行配置,不再主动调用任何函数拉取数据。
在调用设备被打开后会调用set_mctrl。
在set_mctrl的第二个参数中传递了串口的配置(如RTS,CTS等)
在这个过程中可以打开中断,或开启定时器使用轮训串口寄存器,从寄存器中读取到数据后,
可通过uart_insert_char函数将单个字符添加到串口发送子系统。
当需要一次发送一个字符串时,可以使用tty_insert_flip_string.
将待发送数据添加到发送队列中后,需要调用tty_flip_buffer_push和tty_kref_put将队列中的数据
推送到用户态的应用中。
最后
以上就是细腻黑猫为你收集整理的linux uart驱动1 、重要结构2、重要信息3、数据收发的全部内容,希望文章能够帮你解决linux uart驱动1 、重要结构2、重要信息3、数据收发所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复