linux uart 驱动总结

1.串口是很常用的一个外设,在 Linux 下通常通过串口和其他设备或传感器进行通信。电平的不同,串口分为 TTL 和 RS232。
RS232、RS485 以及 GPS 模块接口通通连接到了 I.MX6U 的 UART3 接口上。

2.linux uart 驱动框架
同 I2C、SPI 一样,Linux 也提供了串口驱动框架。
我们只需要按照相应的串口框架编写驱动程序即可。
串口驱动没有什么主机端和设备端之分,就只有一个串口驱动,而且这个驱动也已经由 NXP 官方已经编写好了。

我们真正要做的就是在设备树中添加所要使用的串口节点信息。
当系统启动以后串口驱动和设备匹配成功,相应的串口就会被驱动起来,生成/dev/ttymxcX(X=0….n)文件。

虽然串口驱动不需要我们去写,但是串口驱动框架我们还是需要了解的,uart_driver 结构体表示 UART 驱动。
uart_driver 定义在 include/linux/serial_core.h 文件中。

uart_driver 结构体
struct uart_driver {
struct module *owner; /* 模块所属者 */
const char *driver_name; /* 驱动名字 */
const char *dev_name; /* 设备名字 */
int major; /* 主设备号 */
int minor; /* 次设备号 */
int nr; /* 设备数 */
struct console *cons; /* 控制台 */

/*
 *these are private; the low level driver should not
 * touch these; they should be initialised to NULL
*/
struct uart_state *state; 
struct tty_driver *tty_driver;
};

每个串口驱动都需要定义一个 uart_driver,加载驱动的时候通过 uart_register_driver 函数向
系统注册这个 uart_driver,此函数原型如下:
int uart_register_driver(struct uart_driver *drv)
函数参数和返回值含义如下:
drv:要注册的 uart_driver。
返回值:0,成功;负值,失败。
注销驱动的时候也需要注销掉前面注册的 uart_driver,需要用到 uart_unregister_driver 函数,

函数原型如下:
void uart_unregister_driver(struct uart_driver *drv)
函数参数和返回值含义如下:
drv:要注销的 uart_driver。
返回值:无。

uart_port 定义在 include/linux/serial_core.h

int uart_add_one_port(struct uart_driver *drv, 
 struct uart_port *uport)
函数参数和返回值含义如下:
drv:此 port 对应的 uart_driver。
uport:要添加到 uart_driver 中的 port。
返回值:0,成功;负值,失败。

卸载 UART 驱动的时候也需要将 uart_port 从相应的 uart_driver 中移除,需要用到
uart_remove_one_port 函数,函数原型如下:
int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)

Linux 系统收发数据最终调用的都是 ops 中的函数

struct uart_ops {
unsigned int (*tx_empty)(struct uart_port *);
void (*set_mctrl)(struct uart_port *, unsigned int mctrl);
unsigned int (*get_mctrl)(struct uart_port *);
void (*stop_tx)(struct uart_port *);
void (*start_tx)(struct uart_port *);
void (*throttle)(struct uart_port *);
 
I.MX6U 嵌入式 Linux 驱动开发指南
void (*unthrottle)(struct uart_port *);
void (*send_xchar)(struct uart_port *, char ch);
void (*stop_rx)(struct uart_port *);
(*enable_ms)(struct uart_port *);
void (*break_ctl)(struct uart_port *, int ctl);
int (*startup)(struct uart_port *);
void (*shutdown)(struct uart_port *);
void (*flush_buffer)(struct uart_port *);
void (*set_termios)(struct uart_port *, struct ktermios *new,
struct ktermios *old);
void (*set_ldisc)(struct uart_port *, struct ktermios *);
void (*pm)(struct uart_port *, unsigned int state,
unsigned int oldstate);

/*
* Return a string describing the type of the port
*/
const char *(*type)(struct uart_port *);

/*
* Release IO and memory resources used by the port.
* This includes iounmap if necessary.
*/
void (*release_port)(struct uart_port *);

/*
* Request IO and memory resources used by the port.
* This includes iomapping the port if necessary.
*/
int (*request_port)(struct uart_port *);
void (*config_port)(struct uart_port *, int);
int (*verify_port)(struct uart_port *, struct serial_struct *);
int (*ioctl)(struct uart_port *, unsigned int, unsigned long);
#ifdef CONFIG_CONSOLE_POLL
int (*poll_init)(struct uart_port *);
void (*poll_put_char)(struct uart_port *, unsigned char);
int (*poll_get_char)(struct uart_port *);
 #endif
};

第 1987~1988 行,从设备树中获取 I.MX 系列 SOC UART 外设寄存器首地址,对于
I.MX6ULL 的 UART3 来说就是 0X021EC000。得到寄存器首地址以后对其进行内存映射,得到
对应的虚拟地址。

我们要做的就是在设备树中添加 UART3 对应的设备节点即可。打开 imx6ull-alientek-emmc.dts
文件,在此文件中只有 UART1 对应的 uart1 节点,并没有 UART3 对应的节点,因此我们可以
参考 uart1 节点创建 uart3 节点
iomuxc
pinctrl_uart3: uart3grp { 
fsl,pins = < 
    MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX 0X1b0b1
    MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX 0X1b0b1
    >;
};

&uart3 { 
    pinctrl-names = "default"; 
    pinctrl-0 = <&pinctrl_uart3>;
    status = "okay"; 
};
 

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Linux中的UART是一种串口通信接口,用于在计算机和外部设备之间进行数据传输。在Linux中,可以通过打开串口设备文件(如/dev/ttyS0)来进行串口通信。可以使用open函数打开串口设备文件,并使用相应的参数(如O_RDWR、O_NOCTTY、O_NDELAY)来配置串口的工作方式。其中,O_NOCTTY表示程序不会成为串口的控制终端,O_NDELAY表示程序不关心DCD信号线的状态。接下来,可以使用相应的寄存器(如ULCONn、UCONx、UBRDIVn)来设置串口的传输格式、时钟源和波特率等参数。ULCONn寄存器用于设置传输格式,UCONx寄存器用于选择UART时钟源和设置中断方式,UBRDIVn寄存器用于设置比特率。通过配置这些寄存器,可以实现对串口的控制和数据传输。 #### 引用[.reference_title] - *1* *3* [linux之UART](https://blog.csdn.net/pengliang528/article/details/79847817)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Linux串口UART编程--C语言](https://blog.csdn.net/leumber/article/details/80105295)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦幽风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值