14.1.1.3. Simulatorer#
Två TARGET-värden bygger den fasta programvaran för att köras inuti en simulator på din värddator, utan någon hårdvara ansluten. De finns till för att den fasta programvaran ska kunna köras och testas var som helst.
| Kärna | NPU | Simulator |
|---|---|---|---|
| Cortex-M7 | Ingen | QEMU |
| Cortex-M55 | Ethos-U55 (256 MACs) | Arm FVP – Corstone SSE-300 |
MPS2_AN500 är basmålet med Cortex-M7 utan NPU. Det körs under QEMU, som startar snabbt och är det lättviktiga sättet att köra den plattformsoberoende koden och testsviten.
MPS3_AN547 är en Cortex-M55 med Ethos-U55-NPU:n, körd på Arms Fast Models – FVP:n, som modellerar referensdelsystemet Corstone SSE-300. Detta är målet för att köra NPU:n och ML-modellsökvägen i simulering.
Båda tillhandahåller ROM-filsystemet och gott om RAM (och NPU:n på M55), så vision- och ML-skript körs oförändrade.
Det finns ingen riktig sensor, men csi-modulen fungerar fortfarande mot en virtuell sådan – csi.CSI.snapshot() returnerar ett syntetiskt, animerat testmönster (ett rullande schackbräde i gråskala, en gradient i RGB565), inte en livescen. För att bearbeta verkligt bildinnehåll, ladda det från en fil i stället: en image.Image från en fixtur i ROM-filsystemet, eller en image.ImageIO-ström för inspelade bildrutor.
14.1.1.3.1. Bygga och köra#
Varje simulator är ett värdverktyg som du installerar själv. Du bygger ett mål som vilket annat som helst (se Bygga den fasta programvaran), och run-kör det sedan under den matchande simulatorn – run bygger ROMFS-avbildningen, startar den fasta programvaran och lämnar den körande med en seriell anslutning som du kan ansluta till.
14.1.1.3.1.1. MPS2_AN500 (QEMU)#
QEMU finns i de flesta pakethanterare som Arm-systememulatorn:
Linux (Debian / Ubuntu) – installera det med
apt:sudo apt install qemu-system-armmacOS – installera det med Homebrew:
brew install qemu
Bygg och kör sedan målet:
make -j$(nproc) TARGET=MPS2_AN500
make TARGET=MPS2_AN500 run
14.1.1.3.1.2. MPS3_AN547 (Arm FVP)#
FVP:n är Arms Fixed Virtual Platform för Corstone SSE-300, levererad som en del av Arm Virtual Hardware. Den är endast tillgänglig för Linux – på en Mac, använd QEMU-målet ovan i stället.
Ladda ner paketet, packa upp det och lägg dess bin/-katalog på din PATH:
wget https://artifacts.tools.arm.com/avh/11.31.28/avh-linux-x86_11.31_28_Linux64.tar.gz
mkdir -p ~/fvp
tar --strip-components=1 -xzf avh-linux-x86_11.31_28_Linux64.tar.gz -C ~/fvp
export PATH="$HOME/fvp/bin:$PATH"
FVP:n behöver också SDK:ns Python-bibliotek på LD_LIBRARY_PATH när den körs. Exportera det en gång per skal från repots rot – att läsa SDK_VERSION håller det korrekt allteftersom repot uppdaterar den fastlåsta SDK:n:
export LD_LIBRARY_PATH="$HOME/openmv-sdk-$(cat SDK_VERSION)/python/lib:$LD_LIBRARY_PATH"
Bygg och kör sedan målet:
make -j$(nproc) TARGET=MPS3_AN547
make TARGET=MPS3_AN547 run
14.1.1.3.2. Köra testsviten#
Enhetstesterna ligger i scripts/unittest/tests/, med sina fixturbilder och data i scripts/unittest/data/. De körs med mpremote, som monterar scripts/unittest/ på den körande simulatorn och kör dess run.py.
Simulatorlänken är långsam med standard-mpremote, så använd kopian som medföljer i repot med serieprogramfixen tillämpad (tillämpa den en gång):
patch -N -p1 -d lib/micropython < tools/mpremote-qemu-serial.patch
För MPS2_AN500 under QEMU, starta målet – det skriver ut den pseudoterminal som dess serieport ligger på (till exempel /dev/pts/5):
make TARGET=MPS2_AN500 run
Rikta sedan, från ett annat skal, den patchade mpremote mot den enheten:
python3 lib/micropython/tools/mpremote/mpremote.py connect /dev/pts/5 \
mount scripts/unittest/ run scripts/unittest/run.py
För MPS3_AN547 under FVP:n är serieporten i stället ett telnet-uttag på port 5555:
make TARGET=MPS3_AN547 run
python3 lib/micropython/tools/mpremote/mpremote.py connect socket://localhost:5555 \
mount scripts/unittest/ run scripts/unittest/run.py
run.py upptäcker och kör varje test och skriver ut en PASSED / FAILED-rad per test med tidtagning och en sammanfattning i slutet.
14.1.1.3.3. Lägga till ett test#
Tester upptäcks automatiskt. För att lägga till ett, släpp en fil i scripts/unittest/tests/ som definierar en unittest(data_path, temp_path)-funktion som returnerar True när testet lyckas och False när det misslyckas:
# scripts/unittest/tests/circles.py
def unittest(data_path, temp_path):
import image
img = image.Image(data_path + "/shapes.ppm", copy_to_fb=True)
circles = img.find_circles(threshold=5000, x_margin=30, y_margin=30, r_margin=30)
return len(circles) == 1 and circles[0][0:] == (118, 56, 22, 5856)
Argumenten data_path och temp_path pekar in i de två filsystem som simulatorn ser medan sviten körs:
Sökväg | Backas upp av |
|---|---|
| Värdens |
| Kortets skrivskyddade ROM-filsystem, inbyggt i den fasta programvarans avbildning från |
Så ett nytt test behöver ingen ombyggnad, men en ny fixtur gör det: ROM-avbildningen baseras på romfs_config.json snarare än de enskilda datafilerna, så framtvinga ombyggnaden genom att röra (touch) kortets romfs_config.json (eller make TARGET=<TARGET> clean) och köra igen.
Förväntade värden hävdas inline i testet, så det finns ingen separat fil med förväntad utdata att underhålla. För att hoppa över ett test vid körning – till exempel när det behöver hårdvara som simulatorn inte modellerar – höj ett undantag vars meddelande innehåller "SKIPPED".