mpm: print error if loading FPGA bitstream failed

This commit is contained in:
Jörg Hofrichter 2026-07-13 09:37:28 +02:00 committed by mkoop-ni
parent 752b878a08
commit aa2665d6f4
4 changed files with 35 additions and 0 deletions

View File

@ -20,6 +20,7 @@ from usrp_mpm.mpmutils import get_dboard_class_from_pid
from usrp_mpm.rpc_utils import no_claim, no_rpc from usrp_mpm.rpc_utils import no_claim, no_rpc
from usrp_mpm.sys_utils import dtoverlay, net from usrp_mpm.sys_utils import dtoverlay, net
from usrp_mpm.sys_utils.filesystem_status import get_fs_version, get_mender_artifact from usrp_mpm.sys_utils.filesystem_status import get_fs_version, get_mender_artifact
from usrp_mpm.sys_utils.sysfs_fpga_manager import FpgaManager
from usrp_mpm.sys_utils.udev import ( from usrp_mpm.sys_utils.udev import (
get_eeprom_paths, get_eeprom_paths,
get_eeprom_paths_by_symbol, get_eeprom_paths_by_symbol,
@ -242,6 +243,7 @@ class PeriphManagerBase:
# this is to compare the FPGA compat number with a given compat number # this is to compare the FPGA compat number with a given compat number
# that added a feature. # that added a feature.
self.fpga_features = set() self.fpga_features = set()
self.fpga_manager = FpgaManager()
self._default_args = "" self._default_args = ""
# CHDR transport managers. These need to be instantiated by the child # CHDR transport managers. These need to be instantiated by the child
# classes. # classes.
@ -591,6 +593,11 @@ class PeriphManagerBase:
# Need to wait here a second to make sure the ethernet interfaces are up # Need to wait here a second to make sure the ethernet interfaces are up
# TODO: Fine-tune this number, or wait for some smarter signal. # TODO: Fine-tune this number, or wait for some smarter signal.
sleep(1) sleep(1)
fpga_state = self.fpga_manager.get_state()
if fpga_state != "operating":
msg = f'Failed to apply overlays {requested_overlays}, FPGA is in state "{fpga_state}"'
self.log.error(msg)
raise RuntimeError(msg)
def _init_dboards(self, dboard_infos, override_dboard_pids, default_args): def _init_dboards(self, dboard_infos, override_dboard_pids, default_args):
""" """

View File

@ -285,6 +285,11 @@ class x4xx(ZynqComponents, PeriphManagerBase):
# Need to wait here a second to make sure the ethernet interfaces are up # Need to wait here a second to make sure the ethernet interfaces are up
# TODO: Fine-tune this number, or wait for some smarter signal. # TODO: Fine-tune this number, or wait for some smarter signal.
sleep(1) sleep(1)
fpga_state = self.fpga_manager.get_state()
if fpga_state != "operating":
msg = f'Failed to apply overlays {requested_overlays}, FPGA is in state "{fpga_state}"'
self.log.error(msg)
raise RuntimeError(msg)
########################################################################### ###########################################################################
# Ctor and device initialization tasks # Ctor and device initialization tasks

View File

@ -10,6 +10,7 @@ set(USRP_MPM_SYSUTILS_FILES
${CMAKE_CURRENT_SOURCE_DIR}/dtoverlay.py ${CMAKE_CURRENT_SOURCE_DIR}/dtoverlay.py
${CMAKE_CURRENT_SOURCE_DIR}/i2c_dev.py ${CMAKE_CURRENT_SOURCE_DIR}/i2c_dev.py
${CMAKE_CURRENT_SOURCE_DIR}/net.py ${CMAKE_CURRENT_SOURCE_DIR}/net.py
${CMAKE_CURRENT_SOURCE_DIR}/sysfs_fpga_manager.py
${CMAKE_CURRENT_SOURCE_DIR}/sysfs_gpio.py ${CMAKE_CURRENT_SOURCE_DIR}/sysfs_gpio.py
${CMAKE_CURRENT_SOURCE_DIR}/sysfs_thermal.py ${CMAKE_CURRENT_SOURCE_DIR}/sysfs_thermal.py
${CMAKE_CURRENT_SOURCE_DIR}/udev.py ${CMAKE_CURRENT_SOURCE_DIR}/udev.py

View File

@ -0,0 +1,22 @@
#
# Copyright 2017-2026 Ettus Research, A National Instruments Brand
#
# SPDX-License-Identifier: GPL-3.0-or-later
"""Utilty functions for the sysfs fpga_manager API."""
import pyudev
class FpgaManager:
"""Class representing the fpga_manager class in sysfs."""
def __init__(self):
"""Initalize the udev context and find the fpga_manager device."""
context = pyudev.Context()
self.fpga_manager = [x for x in context.list_devices(subsystem="fpga_manager")][0]
def get_state(self):
"""Get the state of the FPGA manager."""
with open(self.fpga_manager.sys_path + "/state", "r") as f:
state = f.read()
# return state without linebreak
return state[:-1]