Skip to content

Commit 373fa8f

Browse files
committed
Improvements on NuttX app. Add tests for multiple use cases.
1 parent a00dffe commit 373fa8f

File tree

7 files changed

+136
-65
lines changed

7 files changed

+136
-65
lines changed

pytest-embedded-nuttx/pytest_embedded_nuttx/app.py

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import logging
22
from pathlib import Path
33

4-
from esptool.cmds import FLASH_MODES, LoadFirmwareImage
54
from pytest_embedded.app import App
65

76

@@ -22,13 +21,9 @@ def __init__(
2221
):
2322
super().__init__(**kwargs)
2423

25-
self.flash_size = None
26-
self.flash_freq = None
27-
self.flash_mode = None
2824
self.file_extension = file_extension
2925
files = self._get_bin_files()
3026
self.app_file, self.bootloader_file, self.merge_file = files
31-
self._get_binary_target_info()
3227

3328
def _get_bin_files(self) -> list:
3429
"""
@@ -66,38 +61,3 @@ def _get_bin_files(self) -> list:
6661
print(bin_files)
6762

6863
return app_file, bootloader_file, merge_file
69-
70-
def _get_binary_target_info(self):
71-
"""Binary target should be in the format nuttx.merged.bin, where
72-
the 'merged.bin' extension can be modified by the file_extension
73-
argument.
74-
75-
Important note regarding MCUBoot:
76-
If enabled, the magic number will be on the MCUBoot binary. In this
77-
case, image_info should run on the mcuboot binary, not the NuttX one.
78-
"""
79-
80-
def get_key_from_value(dictionary, val):
81-
"""Get key from value in dictionary"""
82-
for key, value in dictionary.items():
83-
if value == val:
84-
return key
85-
return None
86-
87-
binary_path = self.app_file
88-
if self.bootloader_file:
89-
binary_path = self.bootloader_file
90-
91-
# Load app image and retrieve flash information
92-
image = LoadFirmwareImage(self.target, binary_path.as_posix())
93-
94-
# Flash Size
95-
flash_s_bits = image.flash_size_freq & 0xF0
96-
self.flash_size = get_key_from_value(image.ROM_LOADER.FLASH_SIZES, flash_s_bits)
97-
98-
# Flash Frequency
99-
flash_fr_bits = image.flash_size_freq & 0x0F # low four bits
100-
self.flash_freq = get_key_from_value(image.ROM_LOADER.FLASH_FREQUENCY, flash_fr_bits)
101-
102-
# Flash Mode
103-
self.flash_mode = get_key_from_value(FLASH_MODES, image.flash_mode)

pytest-embedded-nuttx/pytest_embedded_nuttx/dut.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,6 @@ def __init__(
143143
app: 'NuttxApp',
144144
**kwargs,
145145
) -> None:
146-
self.target = app.target
147-
148146
super().__init__(app=app, **kwargs)
149147

150148
def reset(self) -> None:

pytest-embedded-nuttx/pytest_embedded_nuttx/serial.py

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
from typing import ClassVar, Dict, Optional
1+
from typing import ClassVar, Dict
22

33
import esptool
4+
from esptool.cmds import FLASH_MODES, LoadFirmwareImage
45
from pytest_embedded_serial_esp.serial import EspSerial
56

67
from .app import NuttxApp
@@ -30,14 +31,49 @@ class NuttxSerial(EspSerial):
3031
def __init__(
3132
self,
3233
app: NuttxApp,
33-
target: Optional[str] = None,
3434
**kwargs,
3535
) -> None:
3636
self.app = app
37-
super().__init__(
38-
target=target or self.app.target,
39-
**kwargs,
40-
)
37+
super().__init__(**kwargs)
38+
self.flash_size = None
39+
self.flash_freq = None
40+
self.flash_mode = None
41+
self._get_binary_target_info()
42+
43+
def _get_binary_target_info(self):
44+
"""Binary target should be in the format nuttx.merged.bin, where
45+
the 'merged.bin' extension can be modified by the file_extension
46+
argument.
47+
48+
Important note regarding MCUBoot:
49+
If enabled, the magic number will be on the MCUBoot binary. In this
50+
case, image_info should run on the mcuboot binary, not the NuttX one.
51+
"""
52+
53+
def get_key_from_value(dictionary, val):
54+
"""Get key from value in dictionary"""
55+
for key, value in dictionary.items():
56+
if value == val:
57+
return key
58+
return None
59+
60+
binary_path = self.app.app_file
61+
if self.app.bootloader_file:
62+
binary_path = self.app.bootloader_file
63+
64+
# Load app image and retrieve flash information
65+
image = LoadFirmwareImage(self.target, binary_path.as_posix())
66+
67+
# Flash Size
68+
flash_s_bits = image.flash_size_freq & 0xF0
69+
self.flash_size = get_key_from_value(image.ROM_LOADER.FLASH_SIZES, flash_s_bits)
70+
71+
# Flash Frequency
72+
flash_fr_bits = image.flash_size_freq & 0x0F # low four bits
73+
self.flash_freq = get_key_from_value(image.ROM_LOADER.FLASH_FREQUENCY, flash_fr_bits)
74+
75+
# Flash Mode
76+
self.flash_mode = get_key_from_value(FLASH_MODES, image.flash_mode)
4177

4278
@EspSerial.use_esptool()
4379
def flash(self) -> None:
@@ -52,17 +88,17 @@ def flash(self) -> None:
5288

5389
flash_settings = [
5490
'--flash_mode',
55-
self.app.flash_mode,
91+
self.flash_mode,
5692
'--flash_size',
57-
self.app.flash_size,
93+
self.flash_size,
5894
'--flash_freq',
59-
self.app.flash_freq,
95+
self.flash_freq,
6096
]
6197

6298
esptool.main(
6399
[
64100
'--chip',
65-
self.app.target,
101+
self.target,
66102
'--port',
67103
self.port,
68104
'--baud',

pytest-embedded-nuttx/tests/test_nuttx.py

Lines changed: 90 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ def test_nuttx_app_info(testdir):
55
testdir.makepyfile("""
66
import pytest
77
8-
def test_nuttx_app(app):
9-
assert 'esp32s3' == app.target
10-
assert '40m' == app.flash_freq
11-
assert '4MB' == app.flash_size
12-
assert 'dio' == app.flash_mode
8+
def test_nuttx_app(dut, app, target):
9+
assert 'esp32s3' == target
10+
assert '40m' == dut.serial.flash_freq
11+
assert '4MB' == dut.serial.flash_size
12+
assert 'dio' == dut.serial.flash_mode
1313
""")
1414

1515
result = testdir.runpytest(
@@ -26,11 +26,11 @@ def test_nuttx_app_mcuboot(testdir):
2626
testdir.makepyfile("""
2727
import pytest
2828
29-
def test_nuttx_app_mcuboot(app):
30-
assert 'esp32s3' == app.target
31-
assert '40m' == app.flash_freq
32-
assert '4MB' == app.flash_size
33-
assert 'dio' == app.flash_mode
29+
def test_nuttx_app_mcuboot(dut, app, target):
30+
assert 'esp32s3' == target
31+
assert '40m' == dut.serial.flash_freq
32+
assert '4MB' == dut.serial.flash_size
33+
assert 'dio' == dut.serial.flash_mode
3434
assert None != app.bootloader_file
3535
""")
3636

@@ -42,3 +42,83 @@ def test_nuttx_app_mcuboot(app):
4242
)
4343

4444
result.assert_outcomes(passed=1)
45+
46+
47+
def test_nuttx_serial_generic_with_target(testdir):
48+
"""
49+
The target option is not used, since the esp service is not active.
50+
It can be used internally normally as the user requires.
51+
"""
52+
testdir.makepyfile("""
53+
import pytest
54+
55+
def test_nuttx_serial_only(dut, app, target):
56+
assert '/dev/ttyUSB0' == dut.serial.port
57+
assert 'esp32s3' == target
58+
""")
59+
60+
result = testdir.runpytest(
61+
'-s',
62+
'--embedded-services', 'nuttx,serial',
63+
'--target', 'esp32s3',
64+
'--port', '/dev/ttyUSB0',
65+
'--app-path', os.path.join(testdir.tmpdir, "hello_world_nuttx")
66+
)
67+
68+
result.assert_outcomes(passed=1)
69+
70+
71+
def test_nuttx_serial_generic_no_target_no_app(testdir):
72+
"""
73+
Very crude usage, simply connects to serial port and
74+
does not search for binaries.
75+
"""
76+
testdir.makepyfile("""
77+
import pytest
78+
79+
def test_nuttx_serial_only(dut, target):
80+
assert '/dev/ttyUSB0' == dut.serial.port
81+
assert None == target
82+
83+
def test_hello(dut, target):
84+
dut.write("ls /dev")
85+
dut.expect("console")
86+
""")
87+
88+
result = testdir.runpytest(
89+
'-s',
90+
'--embedded-services', 'nuttx,serial',
91+
'--port', '/dev/ttyUSB0'
92+
)
93+
94+
result.assert_outcomes(passed=2)
95+
96+
97+
def test_nuttx_app_qemu(testdir):
98+
testdir.makepyfile("""
99+
import pytest
100+
from time import sleep
101+
102+
def test_nuttx_app_qemu(dut):
103+
# Wait boot sequence
104+
sleep(1)
105+
dut.write("ls /dev")
106+
dut.expect("console")
107+
""")
108+
109+
efuse_path = os.path.join(testdir.tmpdir, "hello_world_nuttx_qemu", "qemu_efuse.bin")
110+
qemu_extra = f'-drive file={efuse_path},if=none,format=raw,id=efuse '
111+
qemu_extra += '-global driver=nvram.esp32.efuse,property=drive,value=efuse'
112+
113+
print(qemu_extra)
114+
result = testdir.runpytest(
115+
'-s',
116+
'--embedded-services', 'nuttx,qemu',
117+
'--target', 'esp32',
118+
'--app-path', os.path.join(testdir.tmpdir, "hello_world_nuttx_qemu"),
119+
'--qemu-image-path', os.path.join(testdir.tmpdir, "hello_world_nuttx_qemu", "nuttx.merged.bin"),
120+
'--qemu-extra-args', qemu_extra,
121+
'--qemu-prog-path', 'qemu-system-xtensa',
122+
)
123+
124+
result.assert_outcomes(passed=1)

pytest-embedded/pytest_embedded/dut_factory.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,6 @@ def _fixture_classes_and_options_fn(
199199
from pytest_embedded_nuttx import NuttxApp
200200

201201
classes[fixture] = NuttxApp
202-
kwargs[fixture].update({
203-
'target': target,
204-
})
205202
else:
206203
from .app import App
207204

4 MB
Binary file not shown.
124 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)