如何在Ubuntu下将串口设置为PIO模式(非DMA)并验证状态
Let’s work through this step by step—your need for high-deterministic parity error detection means locking your serial port into PIO mode is critical, so let’s clear up the confusion and get you sorted.
First: Fix the Driver Parameter Misconception
The fsl_lpuart.nodma parameter you came across is designed for Freescale/NXP LPUART controllers, not the Intel 16550A integrated serial port in your Lenovo V520S. Your port uses the standard 8250/serial kernel driver (the go-to for legacy UARTs like 16550A), so that parameter won’t have any effect here.
Checking Current DMA/PIO State
Since setserial and stty don’t expose DMA status, use these reliable methods to check your port’s current mode:
- Kernel Log Check: Run
dmesg | grep -i ttyS0and scan for lines mentioning DMA or PIO. For example, you might see[ 0.123456] 00:06: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A—if DMA was enabled, it would explicitly stateusing DMA. - Proc Filesystem Check: Run
cat /proc/tty/driver/serialto get detailed serial port stats. Look for the line forttyS0; theflagsfield will show if DMA is active (a flag like0x2000means DMA is enabled, its absence confirms PIO mode). Example snippet:serinfo:1.0 driver revision: 0: uart:16550A port:000003F8 irq:4 tx:0 rx:0 flags:0x100000 - Sysfs Check: Some kernel versions expose DMA status via sysfs:
cat /sys/class/tty/ttyS0/device/dma_enabled—a value of0means PIO mode,1means DMA is active.
Forcing PIO Mode (Disabling DMA)
Use one of these methods to lock your port into PIO mode:
1. Kernel Boot Parameter (Temporary or Permanent)
Your Intel system uses GRUB (not U-Boot, where setenv defargs is used), so here’s how to set the correct kernel parameter:
- Temporary Test: Reboot, press
Escto bring up the GRUB menu, select your Ubuntu entry, presseto edit the boot command. Find the line starting withlinux, add8250.nodma=1to the end, then pressF10to boot. This disables DMA for all 8250-based serial ports. If you only want to targetttyS0, use8250.nodma=0x1(bit 0 maps to the first serial port). - Permanent Setting: Edit
/etc/default/grubwith your preferred text editor, find eitherGRUB_CMDLINE_LINUX_DEFAULTorGRUB_CMDLINE_LINUX, add8250.nodma=1inside the quoted string. For example:
Save the file, runGRUB_CMDLINE_LINUX_DEFAULT="quiet splash 8250.nodma=1"sudo update-grub, then reboot. The setting will persist across reboots.
2. Module Parameter (If 8250 is Loaded as a Module)
If the 8250 driver is loaded as a kernel module (check with lsmod | grep 8250), you can set the parameter at load time:
- One-Time Load: Run
sudo modprobe -r 8250 && sudo modprobe 8250 nodma=1 - Permanent Module Setting: Create a file
/etc/modprobe.d/8250.confwith this line:
Reboot, and the module will load with DMA disabled by default.options 8250 nodma=1
3. Runtime Sysfs Toggle (If Supported)
Some newer kernels let you toggle DMA at runtime:
sudo echo 0 > /sys/class/tty/ttyS0/device/dma_enabled
Note: This setting won’t survive a reboot unless you add it to a startup script (like /etc/rc.local or a systemd service).
Verifying PIO Mode is Active
After applying any of the above, re-run the checks from the "Checking Current DMA/PIO State" section to confirm DMA is disabled. For your parity error detection use case, PIO mode will give you the deterministic byte-by-byte processing you need—avoiding the batch-transfer delays and potential detection gaps that can come with DMA.
内容的提问来源于stack exchange,提问作者Luis Alvarado Day

