14.1.1.2. بناء البرنامج الثابت

بوجود البيئة من إعداد بيئة التطوير في مكانها، يكون بناء صورة برنامج ثابت أمرَي make بالإضافة إلى اختيار TARGET.

14.1.1.2.1. التصريف

أولًا ابنِ mpy-cross، أداة المضيف التي تصرّف وحدات .py المُجمّدة إلى شيفرة بايت (افعل هذا مرةً واحدةً، ومجددًا كلما حدّثت MicroPython):

make -j$(nproc) -C lib/micropython/mpy-cross

ثم ابنِ البرنامج الثابت للوحة، حيث يكون <TARGET> أحد الأسماء من الجدول أدناه:

make -j$(nproc) TARGET=<TARGET>

تبني -j$(nproc) على التوازي عبر كل أنوية المعالج (على macOS استخدم -j$(sysctl -n hw.ncpu)). والـ TARGET إلزامي -- إذ يُجهَض make بلا هدف مع الرسالة "Invalid or no TARGET specified".

بناء أول كامل، من البداية إلى النهاية:

make sdk
make -j$(nproc) -C lib/micropython/mpy-cross
make -j$(nproc) TARGET=OPENMV4

14.1.1.2.1.1. اللوحات المدعومة

قيم TARGET هي أسماء المجلدات تحت boards/. والكاميرات ورقائقها:

الكاميرا

TARGET

MCU

المنفذ

النواة

OpenMV Cam M4

OPENMV2

STM32F427

stm32

Cortex-M4

OpenMV Cam M7

OPENMV3

STM32F765

stm32

Cortex-M7

OpenMV Cam H7

OPENMV4

STM32H743

stm32

Cortex-M7

OpenMV Cam H7 Plus

OPENMV4P

STM32H743 + SDRAM

stm32

Cortex-M7

OpenMV Pure Thermal

OPENMVPT

STM32H743 + SDRAM

stm32

Cortex-M7

OpenMV Cam N6

OPENMV_N6

STM32N657

stm32

Cortex-M55

OpenMV Cam RT1062

OPENMV_RT1060

MIMXRT1062

mimxrt

Cortex-M7

OpenMV AE3

OPENMV_AE3

Alif Ensemble (dual M55)

alif

Cortex-M55

Arduino Portenta H7

ARDUINO_PORTENTA_H7

STM32H747

stm32

Cortex-M7

Arduino Giga

ARDUINO_GIGA

STM32H747

stm32

Cortex-M7

Arduino Nicla Vision

ARDUINO_NICLA_VISION

STM32H747

stm32

Cortex-M7

Arduino Nano 33 BLE Sense

ARDUINO_NANO_33_BLE_SENSE

nRF52840

nrf

Cortex-M4

Arduino Nano RP2040 Connect

ARDUINO_NANO_RP2040_CONNECT

RP2040

rp2

Cortex-M0+

ابنِ TARGET المضبوط لعتادك بالضبط -- مثلًا OPENMV4 لـ OpenMV Cam H7، و OPENMV4P لـ H7 Plus، و OPENMV_N6 لـ N6.

14.1.1.2.1.2. خرج البناء

كل ما يخص لوحةً يستقر في build/<TARGET>/bin/. وبالنسبة لـ TARGET=OPENMV4 يكون ذلك build/OPENMV4/bin/، ويحتوي على:

الملف

ما هو

firmware.bin

ثنائي البرنامج الثابت -- يُومَض بواسطة OpenMV IDE عبر Tools -> Load Custom Firmware وبواسطة dfu-util

firmware.elf

البرنامج الثابت مع رموز التنقيح -- الملف الذي توجّه المنقّح إليه

bootloader.bin / .elf

محمّل الإقلاع (فقط على اللوحات التي يكون فيها محمّل الإقلاع مُفعّلًا)

openmv.bin

صورة مدمجة لمحمّل الإقلاع + البرنامج الثابت

romfs<n>.img

صورة نظام ملفات ROM للقراءة فقط تُومَض إلى جانب البرنامج الثابت

إن Alif AE3 ثنائي النواة، لذا فهو يُنتج firmware_M55_HP.elf / firmware_M55_HP.bin (النواة عالية الأداء) و firmware_M55_HE.elf / firmware_M55_HE.bin منفصلة (النواة عالية الكفاءة) بالإضافة إلى صورة جدول محتويات (TOC) تُخبر ROM الإقلاع بمكان صورة كل نواة.

14.1.1.2.1.3. التنظيف وإعادة البناء

البناءات معزولة لكل لوحة تحت build/<TARGET>/. ولمحو بناء لوحة واحدة:

make TARGET=<TARGET> clean

لا يوجد distclean؛ إذ يحتاج clean دائمًا إلى TARGET. والـ mpy-cross مُشترك عبر اللوحات -- فإذا حدّثت MicroPython، أعِد بناءه أيضًا:

make -C lib/micropython/mpy-cross clean
make -j$(nproc) -C lib/micropython/mpy-cross

للإبلاغ عن استخدام البناء للذاكرة فلاش/RAM:

make TARGET=<TARGET> size

14.1.1.2.1.4. البناء في Docker (دون سلسلة أدوات على المضيف)

إن كنت تفضّل عدم تثبيت أي شيء على المضيف (أو كنت على منصة دون بناء أصلي)، استخدم مسار Docker:

git clone --recursive https://github.com/openmv/openmv.git
cd openmv/docker
make TARGET=<TARGET>

تظهر القطع الناتجة في openmv/docker/build/<TARGET>. وللبناءات المتكررة يوجد مسار تطوير تزايدي يضمّ المستودع عند المسار المطلق نفسه داخل الحاوية كما على المضيف، بحيث تتحلل مسارات مصدر المنقّح دون إعادة تخطيط:

make install-sdk
make build-firmware-dev TARGET=<TARGET>

شغّل make clean-dev عند تبديل TARGET.

14.1.1.2.2. خيارات البناء

يُتحكَّم في سلوك البناء عبر متغيرات تُمرَّر على سطر أمر make، على سبيل المثال:

make -j$(nproc) TARGET=OPENMV4 DEBUG=1 V=1

المتغيرات التي سيستخدمها مطور البرنامج الثابت:

المتغير

الافتراضي

الأثر

TARGET

(مطلوب)

اللوحة المراد بناؤها. يختار boards/<TARGET>/board_config.mk، الذي يضبط الـ MCU، والنواة، وخريطة الذاكرة، ومعرّفات USB، والوحدات المُفعّلة.

DEBUG

0

يصرّف DEBUG=1 بالخيارات -Og -ggdb3 (مُحسَّن للتنقيح، مع معلومات تنقيح GDB كاملة) ويعطّل ضغط نص ROM في MicroPython -- هذا هو البناء الذي تنقّحه. أما DEBUG=0 فيصرّف بـ -O2 -DNDEBUG (أصغر، وأسرع، والتأكيدات مُعطّلة) وهو بناء الإصدار.

V

0

تطبع V=1 كل أمر مصرّف/رابط بدلًا من الملخص القصير CC file.c. استخدمها لرؤية الخيارات بالضبط أو لتشخيص مشكلات البناء.

DEBUG_PRINTF

0

تُعرّف DEBUG_PRINTF=1 الماكرو OMV_DEBUG_PRINTF، مُفعّلةً خرج تنقيح printf منخفض المستوى في البرنامج الثابت (اقرنها بـ SWO/RTT، انظر تصحيح أخطاء البرنامج الثابت).

PROFILE_ENABLE

0

تبني PROFILE_ENABLE=1 مع أدوات قياس استدعاء الدوال (-finstrument-functions، و -DOMV_PROFILER_ENABLE=1) بحيث يمكنك تحليل أين يُقضى الوقت. وتضبط PROFILE_HASH=<N> حجم جدول التجزئة للمُحلِّل (قوة للعدد اثنين؛ الافتراضي 256)، كما تُحلّل PROFILE_IRQ=1 أيضًا الشيفرة التي تعمل في سياق المقاطعة.

STACK_PROTECTOR

0

تضيف STACK_PROTECTOR=1 الخيار -fstack-protector-all -- وهي طيور الكنار للمكدس التي تصطاد تجاوزات مخزن المكدس المؤقت. مفيدة عند ملاحقة تلف الذاكرة.

DEBUGGER

JLINK

أيُّ منقّح تستخدمه أهداف make debug / make deploy. والـ JLINK هو الافتراضي؛ بينما يعطّل NONE هدف debug.

ملاحظة

توجد متغيرات كثيرة أخرى (مشغّلات الكاميرا/المستشعر، والمكدسات اللاسلكية، وخلفيات ML، ومكدس USB، والإقلاع الآمن، إلخ)، لكن تلك تُضبط لكل لوحة في boards/<TARGET>/board_config.mk ولا تُتجاوز عادةً على سطر الأمر. وتغييرها هو تخصيص للوحة، لا بناء مطوّر عادي -- انظر docs/boards.md في مستودع البرنامج الثابت.

للعمل اليومي، الخيارات الوحيدة التي تحتاجها هي TARGET (دائمًا)، و DEBUG=1 (كلما عزمت على التنقيح، انظر تصحيح أخطاء البرنامج الثابت)، و V=1 أحيانًا.