Skip to content

Commit 3f5ed7b

Browse files
committed
Add QEMU support for NuttX
1 parent 8b81166 commit 3f5ed7b

File tree

3 files changed

+103
-24
lines changed

3 files changed

+103
-24
lines changed

pytest-embedded-nuttx/pytest_embedded_nuttx/__init__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,23 @@
44

55
from pytest_embedded.utils import lazy_load
66

7-
from .dut import NuttxDut, NuttxEspDut
7+
from .app import NuttxApp
8+
from .dut import NuttxDut, NuttxEspDut, NuttxQemuDut, NuttxSerialDut
89

910
__getattr__ = lazy_load(
1011
importlib.import_module(__name__),
1112
{
1213
'NuttxDut': NuttxDut,
14+
'NuttxSerialDut': NuttxSerialDut,
1315
'NuttxEspDut': NuttxEspDut, # requires 'esp' service
16+
'NuttxQemuDut': NuttxQemuDut, # requires 'qemu' service
1417
},
1518
{
1619
'NuttxApp': '.app', # requires 'esp' service
1720
'NuttxSerial': '.serial', # requires 'esp' service
1821
},
1922
)
2023

21-
__all__ = ['NuttxApp', 'NuttxSerial', 'NuttxEspDut', 'NuttxDut']
24+
__all__ = ['NuttxApp', 'NuttxSerial', 'NuttxSerialDut', 'NuttxQemuDut', 'NuttxEspDut', 'NuttxDut']
2225

2326
__version__ = '1.12.0'

pytest-embedded-nuttx/pytest_embedded_nuttx/dut.py

Lines changed: 83 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,23 @@
44
from typing import TYPE_CHECKING, AnyStr
55

66
import pexpect
7+
from pytest_embedded.dut import Dut
8+
from pytest_embedded_qemu.dut import QemuDut
9+
from pytest_embedded_qemu.qemu import Qemu
710
from pytest_embedded_serial.dut import SerialDut
811

912
if TYPE_CHECKING:
1013
from .app import NuttxApp
1114

1215

13-
class NuttxDut(SerialDut):
16+
class NuttxDut(Dut):
1417
"""
1518
Generic DUT class for use with NuttX RTOS.
1619
"""
1720

1821
PROMPT_NSH = 'nsh>'
1922
PROMPT_TIMEOUT_S = 30
2023

21-
def __init__(
22-
self,
23-
**kwargs,
24-
) -> None:
25-
super().__init__(**kwargs)
26-
2724
def write(self, data: str) -> None:
2825
"""
2926
Write to NuttShell and sleep for a few hundred milliseconds to
@@ -45,11 +42,14 @@ def return_code(self, timeout: int = PROMPT_TIMEOUT_S) -> int:
4542
Matches the 'echo $?' response and extracts the integer value
4643
corresponding to the last program return code.
4744
45+
The first regex option on expect is for serial interface,
46+
while the second will match QEMU.
47+
4848
Returns:
4949
int: return code.
5050
"""
5151
self.write('echo $?')
52-
echo_match = self.expect(r'echo \$\?\r\n(\d+)', timeout=timeout)
52+
echo_match = self.expect([r'echo \$\?\r\n(\d+)', r'echo \$\?\n*(\d+)\n'], timeout=timeout)
5353
ret_code = re.findall(r'\d+', echo_match.group().decode())
5454

5555
if not ret_code:
@@ -75,8 +75,78 @@ def write_and_return(self, data: str, timeout: int = 2) -> AnyStr:
7575
ans = self.expect(pexpect.TIMEOUT, timeout=timeout)
7676
return ans.rstrip().decode()
7777

78+
def reset_to_nsh(self, ready_prompt: str = PROMPT_NSH) -> None:
79+
"""
80+
Resets the board and waits until the Nuttshell prompt appears.
81+
Defaults to 'nsh>'.
82+
83+
Args:
84+
ready_prompt (str): string on prompt that signals completion.
85+
86+
Returns:
87+
None
88+
"""
89+
if self.reset:
90+
logging.info('Resetting board')
91+
self.reset()
92+
else:
93+
logging.error('Resetting method not available')
94+
self.expect(ready_prompt, timeout=self.PROMPT_TIMEOUT_S)
95+
96+
97+
class NuttxSerialDut(SerialDut, NuttxDut):
98+
"""
99+
DUT class for serial ports connected to generic boards running NuttX
100+
with NuttX RTOS.
101+
"""
102+
103+
def __init__(
104+
self,
105+
**kwargs,
106+
) -> None:
107+
super().__init__(**kwargs)
108+
109+
def reset(self) -> None:
110+
"""Reset the DUT by toggling the DTR line.
111+
112+
Args:
113+
None.
114+
115+
Returns:
116+
None.
117+
"""
118+
self.serial.proc.dtr = False
119+
sleep(0.2)
120+
self.serial.proc.dtr = True
121+
122+
123+
class NuttxQemuDut(QemuDut, NuttxDut):
124+
"""
125+
DUT class for QEMU usage of the NuttX RTOS.
126+
"""
127+
128+
def __init__(
129+
self,
130+
qemu: Qemu,
131+
**kwargs,
132+
) -> None:
133+
self.qemu = qemu
134+
135+
super().__init__(qemu=qemu, **kwargs)
78136

79-
class NuttxEspDut(NuttxDut):
137+
def reset(self) -> None:
138+
"""Hard reset the DUT.
139+
140+
Args:
141+
None.
142+
143+
Returns:
144+
None.
145+
"""
146+
self.hard_reset()
147+
148+
149+
class NuttxEspDut(NuttxSerialDut):
80150
"""
81151
DUT class for serial ports connected to Espressif boards which are
82152
flashed with NuttX RTOS.
@@ -91,16 +161,14 @@ def __init__(
91161

92162
super().__init__(app=app, **kwargs)
93163

94-
def reset_to_nsh(self, ready_prompt: str = NuttxDut.PROMPT_NSH) -> None:
164+
def reset(self) -> None:
95165
"""
96-
Resets the board and waits until the Nuttshell prompt appears.
97-
Defaults to 'nsh>'.
166+
Resets the board.
98167
99168
Args:
100-
ready_prompt (str): string on prompt that signals completion.
169+
None.
101170
102171
Returns:
103-
None
172+
None.
104173
"""
105174
self.serial.hard_reset()
106-
self.expect(ready_prompt, timeout=NuttxDut.PROMPT_TIMEOUT_S)

pytest-embedded/pytest_embedded/dut_factory.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -362,12 +362,20 @@ def _fixture_classes_and_options_fn(
362362
else:
363363
raise SystemExit('wokwi service should be used together with idf or arduino service')
364364
elif 'qemu' in _services:
365-
from pytest_embedded_qemu import QemuDut
365+
if 'nuttx' in _services:
366+
from pytest_embedded_nuttx import NuttxQemuDut
366367

367-
classes[fixture] = QemuDut
368-
kwargs[fixture].update({
369-
'qemu': None,
370-
})
368+
classes[fixture] = NuttxQemuDut
369+
kwargs[fixture].update({
370+
'qemu': None,
371+
})
372+
else:
373+
from pytest_embedded_qemu import QemuDut
374+
375+
classes[fixture] = QemuDut
376+
kwargs[fixture].update({
377+
'qemu': None,
378+
})
371379
elif 'jtag' in _services:
372380
if 'idf' in _services:
373381
from pytest_embedded_idf import IdfDut
@@ -400,9 +408,9 @@ def _fixture_classes_and_options_fn(
400408
'serial': None,
401409
})
402410
elif 'nuttx' in _services:
403-
from pytest_embedded_nuttx import NuttxDut
411+
from pytest_embedded_nuttx import NuttxSerialDut
404412

405-
classes[fixture] = NuttxDut
413+
classes[fixture] = NuttxSerialDut
406414
kwargs[fixture].update({
407415
'serial': None,
408416
})

0 commit comments

Comments
 (0)