Вопрос или проблема
Я работаю с встроенной системой Linux (ядро-5.10.188) и использую /dev/ttyS2
в качестве последовательной консоли, а ash
в busybox
— как оболочку для входа в систему.
После входа в систему я запустил top -d 1
в последовательной консоли (я использую mobaxterm в Windows 11 для доступа к последовательной консоли), и она работала хорошо. Затем я закрыл крышку компьютера (Windows перешел в режим ожидания).
Несколько минут спустя я возобновил работу компьютера и обнаружил, что последовательное соединение в mobaxterm не работает. Я набрал ‘R’ для повторного подключения к последовательной консоли, но НЕТ вывода из последовательной консоли.
Я залогинился в систему через adb shell
, и получил следующее.
top -d 1
— это процесс с PID, его статус показал
Имя: top
Umask: 0022
Состояние: S (спит)
Tgid: 345
Ngid: 0
Pid: 345
PPid: 210
.....
voluntary_ctxt_switches: 51
nonvoluntary_ctxt_switches: 22
Последние две строки показали то же значение при нескольких запросах cat /proc/345/status
. Таким образом, процесс не выполняется.
Запустив cat /proc/345/stack
, я получил следующее.
# cat /proc/345/stack
[<0>] wait_woken+0x74/0x94
[<0>] n_tty_write+0x480/0x4f0
[<0>] file_tty_write.isra.36+0x1c8/0x358
[<0>] vfs_write+0x3e8/0x4d8
[<0>] ksys_write+0xe0/0x124
[<0>] syscall_common+0x34/0x58
Процесс ожидает в vfs_write
и n_tty_write
(я думаю, это из-за чего-то вроде printf
или puts
из утилиты top
).
Я могу завершить процесс top
с помощью kill -9 345
.
Но в консоли все равно НЕТ отклика, поэтому я проверил процесс оболочки shell
для входа в систему.
- Проверьте процесс с ID 210 (оболочка для входа и родительский процесс
top
).
# cat /proc/210/status
Имя: sh
Umask: 0022
Состояние: S (спит)
Tgid: 210
Ngid: 0
Pid: 210
PPid: 1
......
voluntary_ctxt_switches: 236
nonvoluntary_ctxt_switches: 45
# cat /proc/210/stack
[<0>] wait_woken+0x74/0x94
[<0>] n_tty_write+0x480/0x4f0
[<0>] file_tty_write.isra.36+0x1c8/0x358
[<0>] vfs_write+0x3e8/0x4d8
[<0>] ksys_write+0xe0/0x124
[<0>] syscall_common+0x34/0x58
Оболочка shell
для входа также находится в vfs_write
и не выполняется.
Мне пришлось kill -9 210
для восстановления оболочки shell
для входа в систему.
Я определенно могу воспроизвести эту проблему при переходе Windows в режим ожидания и возвращении из него. Я изучил длинный список коммитов ядра на tty, но не нашел такой же проблемы или исправления для нее.
Так в чем причина этого зависания в последовательной консоли и как его исправить?
Или куда мне можно обратиться с этой проблемой или багом за помощью?
После тестирования, поиска и отладки я нашел основную причину зависания
и исправления для этой проблемы (благодаря https://zhuanlan.zhihu.com/p/706612622).
Во-первых, это НЕ ОШИБКА в ядре. Это связано с использованием связи через tty консоль.
Зависание процесса top
вызвано программным управлением потоком в системе tty. Когда ПК переходит в режим ожидания
, Mobaxterm должен отправить XOFF
на Linux, что останавливает процесс передачи данных. (Мой Mobaxterm настроен с XON/XOFF как управление потоком).
Top
можно вернуть в рабочее состояние, нажав Ctrl-Q
(XON) в Mobaxterm.
Таким образом, решение одно из следующих.
- Использовать ‘None’ в качестве управления потоком в MobaXterm.
- Использовать
stty -F /dev/ttyS2 -ixoff
для отключения XOFF в порту последовательной консоли. - Использовать
Ctrl-Q
(XON) для начала передачи в порту последовательной консоли.
Ответ или решение
Когда вы работаете с встраиваемой системой Linux, особенно с использованием сериального консольного подключения, могут возникнуть определенные проблемы с взаимодействием, связанные с управлением потоком данных. Рассмотрим ситуацию, возникшую в вашей системе на ядре Linux версии 5.10.188, где наблюдается зависание сериальной консоли.
Теория
Проблема, возникшая в вашей системе, связана с управлением потоком в сериальной консоли, которое реализуется с помощью протоколов XON/XOFF. Когда ваш компьютер переходит в режим ожидания (suspend), программное обеспечение MobaXterm, используемое для подключения к системному терминалу через Windows, посылает сигнал XOFF системе Linux. Этот сигнал предназначен для остановки передачи данных, чтобы предотвратить потерю данных при отсутствии активного взаимодействия. В результате процессов, таких как top
, ожидающих возможности записать данные в консоль, происходит их "заморозка" в контексте системных вызовов на запись, таких как vfs_write
и n_tty_write
.
Пример
В вашем случае, при возобновлении работы ПК после состояния ожидания, вы обнаружили, что подключения в MobaXterm нет, и консоль не дает ответа на ввод. Проверив состояние процесса top
и оболочки ash
, вы увидели, что обе программы находятся в состоянии ожидания, связанного с попыткой записи в tty интерфейс (внутри функций vfs_write
и n_tty_write
). То есть, процессы ожидают возможности продолжить передачу данных, которая была приостановлена сигналом XOFF.
Применение
Решение проблемы может быть реализовано несколькими способами:
-
Изменение параметров управления потоком в MobaXterm: Если ваш сценарий использования позволяет, можно настроить MobaXterm так, чтобы не использовать управление потоком XON/XOFF, переключив его в состояние "None". Это предотвратит отправку сигналов XOFF, устраняя проблему зависания при переходах системы Windows в режим ожидания.
-
Изменение настроек терминала в Linux: Альтернативно, можно изменить параметры терминала на стороне Linux, выполнив команду
stty -F /dev/ttyS2 -ixoff
, чтобы отключить восприятие сигналов XOFF. Это также предотвратит блокировку передачи данных в случае отправки таких сигналов. -
Использование ручного восстановления передачи данных: Если вы не хотите или не можете изменить настройки по умолчанию, всегда можно вручную восстановить передачу данных после выхода из режима ожидания, нажав
Ctrl-Q
в MobaXterm. Эта комбинация клавиш отправляет сигнал XON, который сообщает Linux, что передача данных может быть продолжена.
Эти подходы иллюстрируют способы, которыми можно избежать проблем с консольным управлением в системах, где задействованы сложные сценарии взаимодействия между устройством и хост-системой управления.
Заключение
Проблемы, связанные с управлением потоком данных, такие как описанная, являются частыми для встраиваемых систем, использующих сериальные интерфейсы. Понимание принципов работы таких систем и соответствующая настройка средств взаимодействия могут значительно улучшить стабильность и надежность системы. Решение вашей проблемы демонстрирует необходимость тщательной конфигурации параметров взаимодействия, особенно в условиях, где различные системы должны работать в едином комплексе.