从 Linux 用户空间设置 16550A UART 硬件 FIFO 中断级别
Posted
技术标签:
【中文标题】从 Linux 用户空间设置 16550A UART 硬件 FIFO 中断级别【英文标题】:Set 16550A UART Hardware FIFO interrupt level from Linux Userspace 【发布时间】:2016-12-07 07:38:27 【问题描述】:我目前正在使用兼容 16550 的 UART,并且我希望能够更改 FIFO 中断触发级别(我在高 UART 负载下丢弃字节并且我想降低阈值 - 这是一个功率不足的嵌入式系统)。当然,如果我愿意,我可以在 8250_port.c 驱动程序中更改它:
[PORT_NS16550A] =
.name = "NS16550A",
.fifo_size = 16,
.tx_loadsz = 16,
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
.flags = UART_CAP_FIFO | UART_NATSEMI,
,
但是从用户空间更改它会方便得多,而无需重新编译内核。
我希望following documentation 已过时:
截至 2000 年底,Linux 用户无法设置这些 直接(setserial 做不到)。虽然许多 PC 只有 16550 使用 16 字节缓冲区,更好的 UART 具有更大的缓冲区。
如果有办法这样做(例如一些新的 ioctl),那么 seterial (8) 和 stty (1) 还没有公开接口。
【问题讨论】:
哦,还有 isaset -y -f 0x3fA 0x07(直接戳/dev/ttyS0的FCR寄存器)不算! 如果isaset
不算数,为什么其他解决方案也算数?
因为无论何时重新打开端口,更改都会丢失。此外,它必须由特权用户来完成 - 从用户空间中插入随机 IO 端口通常不是一个安全的选择!
有一个 sysfs 方法必须严格以 root 身份运行:echo 4 > /sys/class/tty/ttyS6/rx_trig_bytes。 isaset 更安全,但不是可以委派特权的东西。 2014 年是added to the kernel。
【参考方案1】:
我认为这个问题的一般解决方案是使用 setserial 来使 uart 改变模式。例如,使用 pericom PI7C9X7958,您有多种操作模式,例如“550”和 950 模式。这些对应于 16550 或 16950 标准 uart 类型。每种模式都有与其相关的特定 fifo 大小和一些其他功能。
所以,如果你的设备支持,你可以试试
setserial -v /dev/ttyS1 uart 16950
然后去验证
setserial -g /dev/ttyS1 /dev/ttyS1,UART:16950/954,端口:0xc800,IRQ:16
【讨论】:
我不想改变 UART 类型;我正在尝试更改 FIFO 阈值级别,即原始帖子中的“UART_FCR_R_TRIG_10”标志。以上是关于从 Linux 用户空间设置 16550A UART 硬件 FIFO 中断级别的主要内容,如果未能解决你的问题,请参考以下文章