Невозможно прервать uboot «Нажмите любую клавишу, чтобы остановить автозагрузку:» с помощью pySerial

У меня есть скрипт Python, который должен запускать обновление Linux на устройстве iMX6. Я могу перезагрузить Linux через последовательное соединение. Я вижу перезагрузку устройства (вывод консоли переносится). Однако, когда я встречаю строку «Нажмите любую клавишу, чтобы остановить автозагрузку:» в последовательном выводе, команда записи, похоже, игнорируется.

import time
import serial


def reboot_and_update(port, baudrate=115200):
    # Open the serial connection
    ser = serial.Serial(port, baudrate, timeout=1,
                        bytesize=serial.EIGHTBITS, xonxoff=True,
                        parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE)
    print(f"Connected to {port} at {baudrate} baud. Output:")
    ser.write(b"reboot\r")  # Send the command
    try:
        while True:
            # Read a line from the serial port
            line = ser.readline().decode('utf-8').strip()
            if line:
                # Print the received line to the console
                print(f"{line}")

                # Check for the specific line to trigger actions
                if "Hit any key to stop autoboot:" in line:
                    print("Interrupt autoboot...")
                    time.sleep(0.1)
                    ser.write(b"345ju\r")
                    time.sleep(1)
                    ser.write(b"run install_linux_fw_sd\r")  # Send the command

                # Check for the login prompt and wait 3 seconds
                elif "ccimx6ulsbc login:" in line:
                    print("Login prompt detected. Waiting for 3 seconds.")
                    time.sleep(3)

                    # If nothing else happens, close the connection
                    additional_line = ser.readline().decode('utf-8').strip()
                    if not additional_line:
                        break
                    else:
                        # Print any additional lines received during the wait period
                        print(f"Received after login prompt: {additional_line}")
            else:
                time.sleep(0.1)  # Small delay to prevent busy waiting

    finally:
        ser.close()
        print("Finished")

Результат, который я получаю:

  (py312) C:\...>python serialconn.py
Connected to COM5 at 115200 baud. Output:
reboot
Broadcast message from root@ccimx6ulsbc (ttymxc4) (Fri Mar  9 14:41:36 2018):
The system is going down for reboot NOW!
INIT: Switching to runlevel: 6
INIT: Sending processes configured via /etc/inittab the TERM signal
root@ccimx6ulsbc:~# Stopping syslogd/klogd: stopped syslogd (pid 639)
stopped klogd (pid 642)
done
Stopping Dropbear SSH server: stopped /usr/sbin/dropbear (pid 661)
dropbear.
Stopping bluetooth: bluetoothd.
Stopping Busybox ACPI daemon: done
stopping Busybox HTTP Daemon: httpd... no httpd found; none killed
Stopping Busybox NTP client/server: done
Stopping system message bus: dbus.
ModemManager[739]: <warn>  could not acquire the 'org.freedesktop.ModemManager1' service name
ModemManager[739]: <info>  ModemManager is shut down
Stopping HOSTAP Daemon: hostapd.
Stopping tcf-agent: OK
ALSA: Storing mixer settings...
Unmounting remote filesystems...
Deconfiguring network interfaces... done.
Stopping NetworkManager: done
Stopping vsftpd server: done
Sending all processes the TERM signal...
Sending all processes the KILL signal...
Deactivating swap...
Unmounting local filesystems...
Rebooting...
U-Boot dub-2020.04-r7.1+gaf77921f51 (Jan 30 2024 - 12:53:20 +0000)
CPU:   i.MX6UL rev1.2 528 MHz (running at 396 MHz)
CPU:   Industrial temperature grade (-40C to 105C) at 68C
Reset cause: POR
DRAM:  1 GiB
MCA:   HW_VER=1  FW_VER=1.14
PMIC:  PFUZE3000 DEV_ID=0x30 REV_ID=0x11
NAND:  1024 MiB
MMC:   FSL_SDHC: 0
In:    serial
Out:   serial
Err:   serial
Model: Digi International ConnectCore 6UL SBC.
ConnectCore 6UL SOM variant 0x04: Industrial Ultralite 528MHz, 1GB NAND, 1GB DDR3, -40/+85C, Wireless, Bluetooth
Board version undefined, ID undefined
Boot device:  NAND
Net:   FEC0 [PRIME]
Fastboot: Normal
Normal Boot
Hit any key to stop autoboot:  0
Interrupt autoboot...
ubi0: attaching mtd4
ubi0: scanning is finished
ubi0: attached mtd4 (name "linux", size 24 MiB)
ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
ubi0: VID header offset: 2048 (aligned 2048), data offset: 4096
ubi0: good PEBs: 192, bad PEBs: 0, corrupted PEBs: 0
ubi0: user volume: 1, internal volumes: 1, max. volumes count: 128
ubi0: max/mean erase counter: 15/11, WL threshold: 4096, image sequence number: 0
ubi0: available PEBs: 0, total reserved PEBs: 192, PEBs reserved for bad PEB handling: 8
Loading file 'boot.scr' to addr 0x80800000...
Done
## Executing script at 80800000
## Loading kernel: zImage-ccimx6ulsbc.bin

...

Итак, похоже, что любой ввод во время загрузки каким-то образом игнорируется.

Я попробовал сделать то же самое с PuTTY, здесь получилось. Я скопировал все настройки подключения в свой скрипт Python (но даже с отключенным xonxoff это не сработало).

Может ли кто-нибудь помочь мне здесь?

Если верить логу, который вы здесь приводите, то вы просто упустили момент нажать любую клавишу... таймаут (0) уже истек.

Risto 21.06.2024 12:56

@Risto окно тайм-аута составляет 2 секунды (считая 1, 0, прошло).

Markus Klingsiek 21.06.2024 14:04

Да, и согласно вашему логу это выглядит так: Hit any key to stop autoboot: 0 а потом Interrupt autoboot... а потом через 100 мс вы пытаетесь отправить какой-то текст...

Risto 21.06.2024 14:08
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
3
123
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ваш код Python, очевидно, обрабатывает

                    # Check for the specific line to trigger actions
                    if "Hit any key to stop autoboot:" in line:

после завершения обратного отсчета.

Причина этого в том, что загрузчик выполняет некоторую магию терминала, чтобы отобразить обратный отсчет 2,1,0, и вы используете readLine(), которому нужно что-то вроде символа конца строки (например, «\n»), чтобы понять это. линия закончена.

Вместо этого вам, вероятно, придется использовать read() с некоторой дополнительной логикой, чтобы получить текст до того, как будет отправлен символ конца строки и закончится обратный отсчет.

Ответ принят как подходящий
  • U-Boot не поддерживает протокол Xon/Xoff. Пожалуйста, используйте xonxoff=False.
  • Как упомянул пользователь Ристо, вам не следует использовать readline(), а читать отдельные байты.
  • Вам следует использовать командную строку U-Boot, чтобы знать, когда писать команду U-Boot.
    line = b''
    uboot = 0
    prompt = b'=>'
    try:
        while True:
            # Read a line from the serial port
            char = ser.read()
            if char == b'':
                continue
            if char[0] == 13:
                # Print the received line to the console
                print(f"{line.decode('utf-8').strip()}")
                line = b''
            line += char
            # Check for the specific line to trigger actions
            if uboot == 0 and b'Hit any key to stop autoboot:' in line:
                print("Interrupt autoboot...")
                ser.write(b'\r')
                uboot = 1
            elif uboot == 1 and prompt in line:
                ser.write(b"run install_linux_fw_sd\r")  # Send the command
                uboot = 2
            # Check for the login prompt and wait 3 seconds
            elif uboot == 2 and b'ccimx6ulsbc login:' in line:
                print("Login prompt detected. Waiting for 3 seconds.")

Другие вопросы по теме