我不确定我在哪个级别遇到了问题。
系统是LeopardBoard DM368,运行TI自己的SDK/LSP/BusyBox内核,核心Linux内核是2.6.x,所以使用serial_core.c驱动模型。
默认情况下,系统有一个启用的 UART,即 UART0,挂载后/dev/ttyS0
也可通过 bootargs 使用/调用console=ttyS0,115200n8 earlyprintk
。
我们希望将 UART1 启用为/dev/ttyS1
,因此已经完成了设置 pinmux、时钟等的低级板初始化代码。
启动时,低级 init 报告(通过我添加的 printk)它已启用 UART1,并且驱动程序代码也报告幸福:
[ 0.547812] serial8250.0: ttyS0 at MMIO 0x1c20000 (irq = 40) is a 16550A
[ 0.569849] serial8250.0: ttyS1 at MMIO 0x1d06000 (irq = 41) is a 16550A
但是,该端口没有出现在/dev/
(as /dev/ttyS1
)中,并且其状态(流量控制位)存在差异,我怀疑这可能导致它挂起/从不传输:
cat /proc/tty/driver/serial
serinfo:1.0 driver revision:
0: uart:16550A mmio:0x01C20000 irq:40 tx:97998 rx:0 CTS|DSR
1: uart:16550A mmio:0x01D06000 irq:41 tx:0 rx:0 DSR
如果我尝试从命令行配置或修改它,我会收到错误:
>: stty -F /dev/ttyS1
stty: can't open '/dev/ttyS1': No such file or directory
奇怪的是,如果我将 bootargs 更改为console=ttyS1,115200n8 earlyprintk
端口,则效果很好,并且 ttyS0 仍然正确初始化并且也可以工作:
cat /proc/tty/driver/serial
serinfo:1.0 driver revision:
0: uart:16550A mmio:0x01C20000 irq:40 tx:0 rx:0 CTS|DSR
1: uart:16550A mmio:0x01D06000 irq:41 tx:11563 rx:0 RTS|DTR|DSR
现在,这很好,但我们的引导加载程序必须使用 UART0,因此最好将所有控制台内容保留在 ttyS0 上,并使用 ttyS1 作为辅助通信。
我在serial_core.c中插入了几个printk,并且似乎从未为ttyS1调用uart_open(),我假设它是Linux init/startup序列中需要修改的东西?
已编辑:因为我欺骗了自己,做了一个echo >/dev/ttyS1
创造了一个文件称为/dev/ttyS1
,这在一定程度上使问题变得模糊。我现在 99% 确定/dev/ttyS1
是绝不创建的。
答案1
mknod /dev/ttyS1 c 4 65
(如果/dev
是只读的,则使用不带选项安装的任何可写目录nodev
)
如果创建的节点没有错误,您可以检查您的补丁是否正在读取/写入该节点或使用任何终端模拟器。
问题是节点没有创建?
如果您正在使用一些自动魔法动态开发文件系统devfs
,或者udev
可能有一些登记中间的问题(但我认为不是,因为大多数代码与调出 ttyS0 是相同的,我猜添加串行端口就像在某些平台文件的数组中添加配置行)。
如果您没有像这样使用 dev fs,那么您MAKEDEV
的构建树中可能有一个文件,可以在其中手动添加一行以静态创建新设备。我还看到过一个系统,其中开发节点是由 init 脚本创建的。