Linux 8250串口控制器

1 8250串口类型的识别
Intel HW都使用DesignWare 8250:
drivers/mfd/intel-lpss-pci.c
drivers/tty/serial/8250/8250_dw.c

IIR寄存器的高2位bit7、bit6用来识别8250串口的类型:
0 - 8250,无FIFO
0 - 并且存在SCR(Scratch register)寄存器,16450,无FIFO
2 - 16550
3 - 16550A

Figure 1-1 UART register to port conversion table

其中DLAB是LCR寄存器的bit7。

2 16450
串口的5、6、7(三菱PLC是7位数据位)、8位数据长度:表示只取每个字节对应的低5、6、7、8位,剩余的高位bit丢弃

UART8250/UART16450:164 = 82 x 2,16450是8250的增强版本

USB VCP波特率可以任意设置,传输速率受限于USB速率;如果VCP的另一端是真实的物理串口,那就必须设置波特率。

16450驱动:
QNX: devc-serpci
Linux:drivers/tty/serial/8250/8250_dw.c

3 16550A
3.1 基本特征
1)16550A - 2个

<think>嗯,用户问的是8250串口控制器的注册流程。我需要先回忆一下Linux内核中串口驱动的相关知识。8250这个型号的UART控制器很常见,特别是在x86架构的老式硬件上,比如传统的PC串口。 首先,8250驱动在内核中应该是一个平台驱动程序,所以注册流程可能涉及到平台设备(platform device)和平台驱动(platform driver)的注册。平台设备通常会在设备树或者板级文件中定义,不过对于x86,可能更多是通过ACPI或者直接硬编码。 接下来,驱动程序需要注册自己,当匹配到对应的设备时,会调用探测函数。在探测函数里,应该会初始化UART端口,设置寄存器,申请中断,还有注册到串口核心层。可能需要使用uart_add_one_port这样的函数把端口添加到串口核心。 然后,串口核心层会处理tty设备的注册,这样用户空间才能通过设备节点访问。用户提到的“注册流程”可能包括这几个步骤:驱动注册、设备匹配、探测函数中的初始化,以及串口核心的注册。 还要注意8250可能有不同的变种,比如16450、16550A等,驱动需要处理这些差异,可能需要不同的配置或函数。另外,资源分配比如I/O端口和中断号是否正确获取也是关键。 可能用户是内核开发者或者在做驱动移植,需要了解如何正确地将8250控制器集成到系统中。需要确保各步骤的顺序正确,资源申请和释放无误,错误处理也要到位,避免内核崩溃或者资源泄漏。 另外,是否涉及到早期控制台的设置?比如在启动早期通过8250输出调试信息,这时候可能需要特别的初始化。不过注册流程可能还是以正常的驱动加载为主。 最后,检查是否遗漏了某些步骤,比如模块初始化和退出函数,MODULE_DEVICE_TABLE用来支持设备树或ACPI匹配,以及依赖的其他子系统是否正确初始化。</think>在Linux内核中,8250 UART控制器的注册流程可分为以下几个关键步骤: 1. **平台设备注册** $$设备信息结构体定义$$ ```c static struct plat_serial8250_port serial_ports[] = { { .iobase = 0x3F8, // 基地址 .irq = 4, // 中断号 .uartclk = 1843200,// 时钟频率 .regshift = 0, // 寄存器偏移 .iotype = UPIO_PORT, // IO类型 .flags = UPF_BOOT_AUTOCONF // 标志位 }, { /* 终止标记 */ } }; ``` 2. **平台驱动注册** ```c static struct platform_device serial_device = { .name = "serial8250", .id = PLAT8250_DEV_LEGACY, .dev = { .platform_data = serial_ports } }; platform_device_register(&serial_device); ``` 3. **串口核心层注册** - 通过`uart_register_driver()`注册8250驱动: ```c static struct uart_driver serial8250_reg = { .owner = THIS_MODULE, .driver_name = "ttyS", .dev_name = "ttyS", .major = TTY_MAJOR, .minor = 64 // 起始次设备号 }; uart_register_driver(&serial8250_reg); ``` 4. **端口添加** - 在探测函数中调用`serial8250_register_port()`: ```c struct uart_port port; memset(&port, 0, sizeof(port)); port.iobase = ...; // 填充硬件参数 uart_add_one_port(&serial8250_reg, &port); ``` 5. **中断处理** ```c request_irq(irq_num, serial8250_interrupt, IRQF_SHARED, "ttyS", port); ``` 6. **资源映射** - 对MMIO类型设备需要ioremap: ```c port.membase = ioremap(phys_addr, region_size); ``` 关键技术细节: - **自动检测机制**:通过`UPF_BOOT_AUTOCONF`标志启用自动配置波特率/校验位 - **兼容性处理**:支持16450/16550A等不同版本芯片的差异 - **控制台集成**:通过`register_console()`实现早期控制台输出 - **电源管理**:实现`pm_ops`结构体支持休眠唤醒 典型初始化流程时序: $$启动顺序 \Rightarrow 平台设备注册 \Rightarrow 驱动匹配 \Rightarrow 端口初始化 \Rightarrow 中断注册 \Rightarrow tty设备创建$$ 常见问题排查点: - 检查`dmesg`输出的"I/O port 0x3F8 not free"资源冲突警告 - 确认`setserial -g /dev/ttyS*`显示正确的配置信息 - 验证`stty -F /dev/ttyS0`的波特率设置能力 该驱动位于内核源码的drivers/tty/serial/8250目录,主要入口文件为8250_core.c和8250_port.c。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值