14.1.1.3. Trình mô phỏng#
Hai giá trị TARGET biên dịch firmware để chạy bên trong một trình mô phỏng trên máy chủ của bạn, không cần phần cứng nào. Chúng tồn tại để firmware có thể được chạy và kiểm thử ở bất cứ đâu.
| Lõi | NPU | Trình mô phỏng |
|---|---|---|---|
| Cortex-M7 | Không | QEMU |
| Cortex-M55 | Ethos-U55 (256 MACs) | Arm FVP -- Corstone SSE-300 |
MPS2_AN500 là target Cortex-M7 cơ sở không có NPU. Nó chạy dưới QEMU, vốn khởi động nhanh và là cách nhẹ nhàng để vận hành mã độc lập với nền tảng và bộ kiểm thử.
MPS3_AN547 là một Cortex-M55 với NPU Ethos-U55, chạy trên Fast Models của Arm -- FVP, mô phỏng hệ thống con tham chiếu Corstone SSE-300. Đây là target để vận hành NPU và đường dẫn mô hình ML trong mô phỏng.
Cả hai đều cung cấp hệ thống tệp ROM và nhiều RAM (cùng với NPU trên M55), vì vậy các script vision và ML chạy mà không cần sửa đổi.
Không có cảm biến thật, nhưng module csi vẫn hoạt động với một cảm biến ảo -- csi.CSI.snapshot() trả về một mẫu kiểm thử tổng hợp, có hoạt ảnh (một bàn cờ cuộn ở grayscale, một gradient ở RGB565), không phải cảnh trực tiếp. Để xử lý nội dung ảnh thật, hãy nạp nó từ một tệp thay thế: một image.Image từ một fixture trong hệ thống tệp ROM, hoặc một luồng image.ImageIO cho các khung hình đã ghi.
14.1.1.3.1. Biên dịch và chạy#
Mỗi trình mô phỏng là một công cụ máy chủ mà bạn tự cài đặt. Bạn biên dịch một target như bất kỳ target nào khác (xem Biên dịch firmware), sau đó run nó dưới trình mô phỏng tương ứng -- run biên dịch ảnh ROMFS, khởi động firmware, và để nó chạy với một kết nối serial mà bạn có thể gắn vào.
14.1.1.3.1.1. MPS2_AN500 (QEMU)#
QEMU có sẵn trong hầu hết các trình quản lý gói dưới dạng trình giả lập hệ thống Arm:
Linux (Debian / Ubuntu) -- cài đặt nó với
apt:sudo apt install qemu-system-armmacOS -- cài đặt nó với Homebrew:
brew install qemu
Sau đó biên dịch và chạy target:
make -j$(nproc) TARGET=MPS2_AN500
make TARGET=MPS2_AN500 run
14.1.1.3.1.2. MPS3_AN547 (Arm FVP)#
FVP là Fixed Virtual Platform của Arm cho Corstone SSE-300, được cung cấp như một phần của Arm Virtual Hardware. Nó chỉ có sẵn cho Linux -- trên máy Mac, hãy sử dụng target QEMU ở trên thay thế.
Tải bộ bundle, giải nén nó, và đặt thư mục bin/ của nó vào PATH của bạn:
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 cũng cần các thư viện Python của SDK trên LD_LIBRARY_PATH khi nó chạy. Hãy export nó một lần cho mỗi shell từ thư mục gốc của repo -- việc đọc SDK_VERSION giữ cho nó chính xác khi repo cập nhật SDK được ghim:
export LD_LIBRARY_PATH="$HOME/openmv-sdk-$(cat SDK_VERSION)/python/lib:$LD_LIBRARY_PATH"
Sau đó biên dịch và chạy target:
make -j$(nproc) TARGET=MPS3_AN547
make TARGET=MPS3_AN547 run
14.1.1.3.2. Chạy bộ kiểm thử#
Các unit test nằm trong scripts/unittest/tests/, cùng với các ảnh fixture và dữ liệu của chúng trong scripts/unittest/data/. Chúng được chạy bằng mpremote, vốn gắn kết scripts/unittest/ lên trình mô phỏng đang chạy và thực thi run.py của nó.
Liên kết trình mô phỏng chậm với mpremote gốc, vì vậy hãy sử dụng bản sao đi kèm trong repo với bản vá serial được áp dụng (áp dụng nó một lần):
patch -N -p1 -d lib/micropython < tools/mpremote-qemu-serial.patch
Đối với MPS2_AN500 dưới QEMU, hãy khởi động target -- nó in ra pseudo-terminal mà cổng serial của nó đang dùng (ví dụ /dev/pts/5):
make TARGET=MPS2_AN500 run
Sau đó, từ một shell khác, trỏ mpremote đã vá vào thiết bị đó:
python3 lib/micropython/tools/mpremote/mpremote.py connect /dev/pts/5 \
mount scripts/unittest/ run scripts/unittest/run.py
Đối với MPS3_AN547 dưới FVP, cổng serial là một socket telnet trên cổng 5555 thay thế:
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 khám phá và thực thi mọi test, in ra một dòng PASSED / FAILED cho mỗi test cùng với thời gian và một bản tóm tắt ở cuối.
14.1.1.3.3. Thêm một test#
Các test được khám phá tự động. Để thêm một test, hãy đặt một tệp vào scripts/unittest/tests/ định nghĩa một hàm unittest(data_path, temp_path) trả về True khi test vượt qua và False khi nó thất bại:
# 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)
Các đối số data_path và temp_path trỏ vào hai hệ thống tệp mà trình mô phỏng thấy trong khi bộ kiểm thử chạy:
Đường dẫn | Được hỗ trợ bởi |
|---|---|
| Thư mục |
| Hệ thống tệp ROM chỉ đọc của board, được tích hợp vào ảnh firmware từ |
Vì vậy một test mới không cần biên dịch lại, nhưng một fixture mới thì cần: ảnh ROM được khóa theo romfs_config.json thay vì các tệp dữ liệu riêng lẻ, vì vậy hãy buộc biên dịch lại bằng cách touch romfs_config.json của board (hoặc make TARGET=<TARGET> clean) và chạy lại.
Các giá trị mong đợi được khẳng định nội tuyến trong test, vì vậy không có tệp đầu ra mong đợi riêng để duy trì. Để bỏ qua một test khi chạy -- ví dụ khi nó cần phần cứng mà trình mô phỏng không mô phỏng -- hãy raise một ngoại lệ có thông báo chứa "SKIPPED".