Skip to content

Commit bb1066e

Browse files
committed
add support for rpiboot to enable rpi as msd
Allow for using the rpiboot tool to start up a raspberry pi cm 4 or 5 as a MassStorageDevice so that a USBStorageDriver can be used to bootstrap a raspberry pi cm 4 or 5. https://github.com/raspberrypi/usbboot
1 parent e9e43aa commit bb1066e

File tree

6 files changed

+97
-0
lines changed

6 files changed

+97
-0
lines changed

labgrid/driver/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,4 @@
4848
from .deditecrelaisdriver import DeditecRelaisDriver
4949
from .dediprogflashdriver import DediprogFlashDriver
5050
from .httpdigitaloutput import HttpDigitalOutputDriver
51+
from .rpibootdriver import RpibootDriver

labgrid/driver/rpibootdriver.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import attr
2+
3+
from ..factory import target_factory
4+
from ..step import step
5+
from .common import Driver
6+
from ..util.helper import processwrapper
7+
8+
@target_factory.reg_driver
9+
@attr.s(eq=False)
10+
class RpibootDriver(Driver):
11+
bindings = {
12+
"rpi": {"RpibootDevice", "NetworkRpibootDevice"},
13+
}
14+
15+
image = attr.ib(default=None)
16+
17+
def __attrs_post_init__(self):
18+
super().__attrs_post_init__()
19+
if self.target.env:
20+
self.tool = self.target.env.config.get_tool('rpiboot')
21+
else:
22+
self.tool = 'rpiboot'
23+
24+
def on_activate(self):
25+
pass
26+
27+
def on_deactivate(self):
28+
pass
29+
30+
@Driver.check_active
31+
@step(args=['filename'])
32+
def enable(self, filename=None,):
33+
# Switch raspberry pi into MassStorageDevice mode using the rpiboot tool
34+
args = []
35+
processwrapper.check_output(
36+
self.rpi.command_prefix + [self.tool] + args,
37+
print_on_silent_log=True
38+
)

labgrid/remote/exporter.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,26 @@ def __attrs_post_init__(self):
546546
self.data["cls"] = f"Remote{self.cls}".replace("Network", "")
547547

548548

549+
@attr.s(eq=False)
550+
class RpibootExport(USBGenericExport):
551+
"""ResourceExport for raspberry pi in boot mode"""
552+
553+
def __attrs_post_init__(self):
554+
super().__attrs_post_init__()
555+
556+
def _get_params(self):
557+
"""Helper function to return parameters"""
558+
return {
559+
"host": self.host,
560+
"busnum": self.local.busnum,
561+
"devnum": self.local.devnum,
562+
"path": self.local.path,
563+
"vendor_id": self.local.vendor_id,
564+
"model_id": self.local.model_id,
565+
"serial_id": self.local.serial_id,
566+
}
567+
568+
549569
exports["AndroidFastboot"] = USBGenericExport
550570
exports["AndroidUSBFastboot"] = USBGenericRemoteExport
551571
exports["DFUDevice"] = USBGenericExport
@@ -569,6 +589,7 @@ def __attrs_post_init__(self):
569589
exports["HIDRelay"] = USBHIDRelayExport
570590
exports["USBFlashableDevice"] = USBFlashableExport
571591
exports["LXAUSBMux"] = USBGenericExport
592+
exports["RpibootDevice"] = RpibootExport
572593

573594

574595
@attr.s(eq=False)

labgrid/resource/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
USBSerialPort,
3333
USBTMC,
3434
USBVideo,
35+
RpibootDevice,
3536
)
3637
from .common import Resource, ResourceManager, ManagedResource
3738
from .ykushpowerport import YKUSHPowerPort, NetworkYKUSHPowerPort

labgrid/resource/remote.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,3 +414,14 @@ class RemoteNFSProvider(NetworkResource):
414414
@attr.s(eq=False)
415415
class RemoteHTTPProvider(RemoteBaseProvider):
416416
pass
417+
418+
@target_factory.reg_resource
419+
@attr.s(eq=False)
420+
class NetworkRpibootDevice(RemoteUSBResource):
421+
"""The NetworkRpibootDevice describes a remotely accessible raspberry pi ready for rpiboot"""
422+
423+
serial_id = attr.ib(validator=attr.validators.optional(attr.validators.instance_of(str)))
424+
425+
def __attrs_post_init__(self):
426+
self.timeout = 10.0
427+
super().__attrs_post_init__()

labgrid/resource/udev.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,3 +803,28 @@ def update(self):
803803
self.index = int(self.read_attr('base')) + self.pin
804804
else:
805805
self.index = None
806+
807+
@target_factory.reg_resource
808+
@attr.s(eq=False)
809+
class RpibootDevice(USBResource):
810+
"""The RpibootDevice describes an attached raspberry pi device in boot mode,
811+
it is identified via USB using udev.
812+
"""
813+
814+
def filter_match(self, device):
815+
match = (device.properties.get('ID_VENDOR_ID'), device.properties.get('ID_MODEL_ID'))
816+
817+
if match not in [("0a5c", "2711"), # rpi4
818+
("0a5c", "2712"), # rpi5
819+
]:
820+
return False
821+
822+
return super().filter_match(device)
823+
824+
@property
825+
def serial_id(self):
826+
device = self._get_usb_device()
827+
if device:
828+
return str(device.properties.get('ID_SERIAL_SHORT'))
829+
830+
return None

0 commit comments

Comments
 (0)