linux的最新uart驱动,Linux下的UART驱动框架详解

Linux  下的 UART  驱动框架

53.1.1 uart_driver  结构体

在 Linux 中 uart 和 I2C、SPI 一样,提供了串口驱动框架,只需要按照提供的串口框架函数编译驱动即可。一般来说串口驱动都已经实现好了,我们需要做的就是在设备树文件中,添加相应的设备节点。当设备和驱动匹配成功后,串口就能够正常工作。

在 Linux 中,用 uart_driver 结构体来描述串口,uart_driver 定义在 include/linux/serial_core.h 文件中,内容如下:

295 struct uart_driver {

296 struct module *owner; /* 模块所属者 */

297 const char *driver_name; /* 驱动名字 */

298 const char *dev_name; /* 设备名字 */

299 int major; /* 主设备号 */

300 int minor; /* 次设备号 */

301 int nr; /* 设备数 */

302 struct console *cons; /* 控制台 */

303

304 /*

305 * these are private; the low level driver should not

306 * touch these; they should be initialised to NULL

307 */

308 struct uart_state *state;

309 struct tty_driver *tty_driver;

310 };

一般在开发板上有几个串口,每个串口驱动都需要定义一个 uart_driver 结构体来表示。

同其他设备一样,当 uart_driver 结构体创建好后,然后注册到内核中去。使用 uart_register_driver 函数来完成注册行为,函数原型如下:

int uart_register_driver(struct uart_driver *drv)

参数 drv 就是创建好要注册的 uart_driver 结构体,返回 0,表示成功,失败返回负值。

既然有注册函数,同样的也有注销函数 uart_unregister_driver,函数原型如下:

void uart_unregister_driver(struct uart_driver *drv)

参数 drv 是要注销的 uart_driver 结构体,没有返回值。

53.1.2 uart_port  结构体

uart_port 用于描述一个 UART 端口(直接对应于一个串口)的 I/O 端口或 I/O 内存地址、FIFO 大小、端口类型等信息。

uart_port 定义在 include/linux/serial_core.h 文件,部分内容如下:

117 struct uart_port {

118 spinlock_t lock; /* port lock */

119 unsigned long iobase; /* in/out[bwl] */

120 unsigned char __iomem *membase; /* read/write[bwl] */

......

235 const struct uart_ops *ops;

236 unsigned int custom_divisor;

237 unsigned int line; /* port index */

238 unsigned int minor;

239 resource_size_t mapbase; /* for ioremap */

240 resource_size_t mapsize;

241 struct device *dev; /* parent device */

......

250 };

在 uart_port 结构体中主要关注 ops 成员,ops 成员包含了串口的具体驱动函数,后面具体了解。

每个 UART 都有一个 uart_port 结构体,那么 uart_port 和 uart_driver 是如何结合起来的,要用到

uart_add_one_port 函数,函数原型如下:

int uart_add_one_port(struct uart_driver *drv,

struct uart_port *uport)

drv:与 uart_port 对应的 uart_driver 结构体,

uport:要添加到 uart_driver 结构体中的 uart_port 结构体。

返回值:0,表示成功,负值,表示失败。

卸载 UART 驱动时,也需要将 uart_port 从相应的 uart_driver 中移除,使用 uart_remove_one_port 函数来实现,函数原型如下:

int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)

drv:要卸载的 uart_port 对应的 uart_driver。

uport:要卸载的 uart_port。

返回值:0,表示成功,负值,表示失败。

53.1.3 uart_ops  结构体

uart_ops 结构体中包含了 UART 框架中具体的驱动函数,Linux 系统收发数据最终调用的都是 ops 中的函数。ops 是 uart_ops 类型的结构体指针变量,uart_ops 定义在 include/linux/serial_core.h 文件中,内容如下:

49 struct uart_ops {

50 unsigned int (*tx_empty)(struct uart_port *);

51 void (*set_mctrl)(struct uart_port *, unsigned int mctrl);

52 unsigned int (*get_mctrl)(struct uart_port *);

53 void (*stop_tx)(struct uart_port *);

54 void (*start_tx)(struct uart_port *);

55 void (*throttle)(struct uart_port *);

56 void (*unthrottle)(struct uart_port *);

57 void (*send_xchar)(struct uart_port *, char ch);

58 void (*stop_rx)(struct uart_port *);

59 void (*enable_ms)(struct uart_port *);

60 void (*break_ctl)(struct uart_port *, int ctl);

61 int (*startup)(struct uart_port *);

62 void (*shutdown)(struct uart_port *);

63 void (*flush_buffer)(struct uart_port *);

64 void (*set_termios)(struct uart_port *, struct ktermios *new,

65 struct ktermios *old);

66 void (*set_ldisc)(struct uart_port *, struct ktermios *);

67 void (*pm)(struct uart_port *, unsigned int state,

68 unsigned int oldstate);

69

70 /*

71 * Return a string describing the type of the port

72 */

73 const char *(*type)(struct uart_port *);

74

75 /*

76 * Release IO and memory resources used by the port.

77 * This includes iounmap if necessary.

78 */

79 void (*release_port)(struct uart_port *);

80

81 /*

82 * Request IO and memory resources used by the port.

83 * This includes iomapping the port if necessary.

84 */

85 int (*request_port)(struct uart_port *);

86 void (*config_port)(struct uart_port *, int);

87 int (*verify_port)(struct uart_port *, struct serial_struct *);

88 int (*ioctl)(struct uart_port *, unsigned int, unsigned long);

89 #ifdef CONFIG_CONSOLE_POLL

90 int (*poll_init)(struct uart_port *);

91 void (*poll_put_char)(struct uart_port *, unsigned char);

92 int (*poll_get_char)(struct uart_port *);

93 #endif

94 };

UART 驱动编写人员需要实现 uart_ops,因为 uart_ops 是最底层的 UART 驱动接口,是实实在在的和UART 寄存器打交道的。关于 uart_ops 结构体中的这些函数的具体含义请参考 Documentation/serial/driver这个文档。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值