مان آپريٽنگ سسٽم جي ڊولپرز مان هڪ آهيان
جيڪڏهن توهان سرچ انجڻ ۾ ”اوپن سي وي آن STM32 بورڊ“ وانگر ڪجهه ٽائيپ ڪريو ٿا، ته توهان ڪافي ٿورا ماڻهو ڳولي سگهو ٿا جيڪي هن لائبريري کي STM32 بورڊن يا ٻين مائڪرو ڪنٽرولرز تي استعمال ڪرڻ ۾ دلچسپي رکن ٿا.
اتي ڪيتريون ئي وڊيوز آھن، جن جي نالي سان فيصلو ڪندي، اھو ظاھر ڪرڻ گھرجي ته ڇا جي ضرورت آھي، پر عام طور تي (سڀني وڊيوز ۾ جيڪي مون ڏٺو) STM32 بورڊ تي، رڳو تصوير ڪئميرا مان حاصل ڪئي وئي ۽ نتيجو اسڪرين تي ڏيکاريو ويو، ۽ تصوير جي پروسيسنگ پاڻ کي باقاعده ڪمپيوٽر تي، يا وڌيڪ طاقتور بورڊن تي ڪيو ويو آهي (مثال طور، Raspberry Pi).
اهو مشڪل Whyو آهي؟
ڳولا جي سوالن جي مقبوليت ان حقيقت جي وضاحت ڪئي وئي آهي ته OpenCV تمام مشهور ڪمپيوٽر ويزن لائبريري آهي، جنهن جو مطلب آهي ته وڌيڪ ڊولپر ان کان واقف آهن، ۽ مائڪرو ڪنٽرولر تي ڊيسڪ ٽاپ تيار ڪوڊ هلائڻ جي صلاحيت ترقي جي عمل کي تمام آسان بڻائي ٿي. پر هن مسئلي کي حل ڪرڻ لاء اڃا تائين ڪو به مشهور تيار ڪيل ترڪيبون ڇو نه آهن؟
ننڍي شال تي OpenCV استعمال ڪرڻ جو مسئلو ٻن خاصيتن سان لاڳاپيل آهي:
- جيڪڏهن توهان ماڊيولز جي گهٽ ۾ گهٽ سيٽ سان به لائبريري گڏ ڪريو ٿا، ته اهو صرف هڪ ئي STM32F7Discovery جي فليش ميموري ۾ نه ٺهندو (جيتوڻيڪ او ايس کي نظر ۾ رکڻ کان سواءِ) هڪ تمام وڏي ڪوڊ جي ڪري (ڪيترائي ميگا بائيٽ هدايتون)
- لائبريري پاڻ C++ ۾ لکيل آهي، جنهن جو مطلب آهي
- مثبت رن ٽائم لاءِ سپورٽ جي ضرورت آھي (استثنائي، وغيره)
- LibC/Posix لاءِ ٿورڙي مدد، جيڪا عام طور تي ايمبيڊڊ سسٽم لاءِ OS ۾ ملي ٿي - توهان کي هڪ معياري پلس لائبريري ۽ هڪ معياري STL ٽيمپليٽ لائبريري (ویکٹر، وغيره) جي ضرورت آهي.
Embox ڏانهن پورٽنگ
هميشه وانگر، آپريٽنگ سسٽم تي ڪنهن به پروگرام کي پورٽ ڪرڻ کان اڳ، اهو هڪ سٺو خيال آهي ته ان کي فارم ۾ تعمير ڪرڻ جي ڪوشش ڪئي وڃي جنهن ۾ ڊولپرز ان جو ارادو ڪيو. اسان جي حالت ۾، هن سان ڪو به مسئلو ناهي - ماخذ ڪوڊ تي ڳولهي سگهجي ٿو
سٺي خبر اها آهي ته OpenCV کي باڪس مان هڪ جامد لائبريري جي طور تي تعمير ڪري سگهجي ٿو، جيڪا پورٽنگ کي آسان بڻائي ٿي. اسان هڪ معياري ترتيب سان گڏ هڪ لائبريري گڏ ڪريون ٿا ۽ ڏسو ته اهي ڪيترو جاء وٺن ٿا. هر ماڊل هڪ الڳ لائبريري ۾ گڏ ڪيو ويو آهي.
> size lib/*so --totals
text data bss dec hex filename
1945822 15431 960 1962213 1df0e5 lib/libopencv_calib3d.so
17081885 170312 25640 17277837 107a38d lib/libopencv_core.so
10928229 137640 20192 11086061 a928ed lib/libopencv_dnn.so
842311 25680 1968 869959 d4647 lib/libopencv_features2d.so
423660 8552 184 432396 6990c lib/libopencv_flann.so
8034733 54872 1416 8091021 7b758d lib/libopencv_gapi.so
90741 3452 304 94497 17121 lib/libopencv_highgui.so
6338414 53152 968 6392534 618ad6 lib/libopencv_imgcodecs.so
21323564 155912 652056 22131532 151b34c lib/libopencv_imgproc.so
724323 12176 376 736875 b3e6b lib/libopencv_ml.so
429036 6864 464 436364 6a88c lib/libopencv_objdetect.so
6866973 50176 1064 6918213 699045 lib/libopencv_photo.so
698531 13640 160 712331 ade8b lib/libopencv_stitching.so
466295 6688 168 473151 7383f lib/libopencv_video.so
315858 6972 11576 334406 51a46 lib/libopencv_videoio.so
76510375 721519 717496 77949390 4a569ce (TOTALS)
جئين توهان آخري لائين مان ڏسي سگهو ٿا، .bss ۽ .data گهڻو جاء نه وٺندا آهن، پر ڪوڊ 70 MiB کان وڌيڪ آهي. اهو واضح آهي ته جيڪڏهن اهو جامد طور تي هڪ مخصوص ايپليڪيشن سان ڳنڍيل آهي، ڪوڊ گهٽ ٿيندو.
اچو ته ڪوشش ڪريون ته جيترو ٿي سگهي ڪيترائي ماڊيول ڪڍيون ته جيئن هڪ گهٽ ۾ گهٽ مثال گڏ ڪيو وڃي (جيڪو، مثال طور، صرف OpenCV ورجن ڪڍي ڇڏيندو)، تنهنڪري اسان ڏسون ٿا. cmake .. -LA
۽ اختيارن ۾ بند ڪريو سڀ ڪجھ جيڪو بند ٿئي ٿو.
-DBUILD_opencv_java_bindings_generator=OFF
-DBUILD_opencv_stitching=OFF
-DWITH_PROTOBUF=OFF
-DWITH_PTHREADS_PF=OFF
-DWITH_QUIRC=OFF
-DWITH_TIFF=OFF
-DWITH_V4L=OFF
-DWITH_VTK=OFF
-DWITH_WEBP=OFF
<...>
> size lib/libopencv_core.a --totals
text data bss dec hex filename
3317069 36425 17987 3371481 3371d9 (TOTALS)
هڪ طرف، هي لائبريري جو صرف هڪ ماڊل آهي، ٻئي طرف، هي ڪوڊ سائيز لاءِ ڪمپيلر اصلاح کان سواءِ آهي (-Os
). ~ 3 MiB جو ڪوڊ اڃا تمام گهڻو آهي، پر اڳ ۾ ئي ڪاميابي جي اميد ڏئي ٿو.
ايموليٽر ۾ هلايو
ايموليٽر تي ڊيبگ ڪرڻ تمام آسان آهي، تنهن ڪري پهريان پڪ ڪريو ته لائبريري qemu تي ڪم ڪري ٿي. هڪ emulated پليٽ فارم جي طور تي، مون چونڊيو Integrator / CP، ڇاڪاڻ ته پهرين، اهو پڻ ARM آهي، ۽ ٻيو، ايمباڪس هن پليٽ فارم لاء گرافڪس آئوٽ کي سپورٽ ڪري ٿو.
ايمباڪس وٽ ٻاهرين لائبريرين جي تعمير لاءِ هڪ ميکانيزم آهي، ان کي استعمال ڪندي اسان OpenCV کي هڪ ماڊيول طور شامل ڪندا آهيون (جڏهن ته "گهٽ ۾ گهٽ" تعمير لاءِ سڀ ساڳيا آپشن جامد لائبريرين جي صورت ۾ پاس ڪرڻ)، ان کان پوءِ مان هڪ سادي ايپليڪيشن شامل ڪريان ٿو جيڪا هن طرح نظر اچي ٿي:
version.cpp:
#include <stdio.h>
#include <opencv2/core/utility.hpp>
int main() {
printf("OpenCV: %s", cv::getBuildInformation().c_str());
return 0;
}
اسان سسٽم کي گڏ ڪريون ٿا، ان کي هلائيندا آهيون - اسان کي متوقع پيداوار ملي ٿي.
root@embox:/#opencv_version
OpenCV:
General configuration for OpenCV 4.0.1 =====================================
Version control: bd6927bdf-dirty
Platform:
Timestamp: 2019-06-21T10:02:18Z
Host: Linux 5.1.7-arch1-1-ARCH x86_64
Target: Generic arm-unknown-none
CMake: 3.14.5
CMake generator: Unix Makefiles
CMake build tool: /usr/bin/make
Configuration: Debug
CPU/HW features:
Baseline:
requested: DETECT
disabled: VFPV3 NEON
C/C++:
Built as dynamic libs?: NO
< Дальше идут прочие параметры сборки -- с какими флагами компилировалось,
какие модули OpenCV включены в сборку и т.п.>
ايندڙ قدم ڪجهه مثالن کي هلائڻ لاءِ آهي، ترجيحي طور تي انهن مان هڪ معياري جيڪي پاڻ ڊولپرز پاران پيش ڪيل آهن.
تصوير کي سڌو سنئون فريم بفر ۾ نتيجو سان ڊسپلي ڪرڻ لاءِ مثال کي ٿورو ٻيهر لکڻو پوندو. مون کي اهو ڪرڻو پيو، ڇاڪاڻ ته. فنڪشن imshow()
QT، GTK ۽ ونڊوز انٽرفيس ذريعي تصويرون ٺاهي سگھي ٿو، جيڪي، يقينا، STM32 جي ترتيب ۾ نه هوندا. حقيقت ۾، QT STM32F7Discovery تي پڻ هلائي سگھجي ٿو، پر اھو ھڪڙي ٻئي مضمون ۾ بحث ڪيو ويندو 🙂
ٿوري وضاحت کان پوءِ جنهن فارميٽ ۾ ايج ڊيڪٽر جو نتيجو ذخيرو ٿيل آهي، اسان کي هڪ تصوير ملي ٿي.
اصل تصوير
نتيجي ۾
STM32F7Discovery تي هلندڙ
32F746GDISCOVERY تي ڪيترائي هارڊويئر ميموري سيڪشن آهن جيڪي اسان هڪ طريقو يا ٻيو استعمال ڪري سگهون ٿا
- 320KiB رام
- تصوير لاءِ 1MiB فليش
- 8MiB SDRAM
- 16MiB QSPI نند فليش
- microSD ڪارڊ سلاٽ
هڪ SD ڪارڊ تصويرن کي ذخيرو ڪرڻ لاء استعمال ڪري سگهجي ٿو، پر گهٽ ۾ گهٽ مثال هلائڻ جي حوالي سان، اهو تمام مفيد ناهي.
ڊسپلي ۾ 480 × 272 جي ريزوليوشن آهي، جنهن جو مطلب آهي ته فريم بفر ميموري 522 بائيٽ هوندي 240 بٽ جي کوٽائي تي، يعني. اهو RAM جي سائيز کان وڌيڪ آهي، تنهنڪري فريم بفر ۽ هيپ (جنهن جي ضرورت هوندي، بشمول OpenCV لاء، تصويرون ۽ معاون ڍانچي جي ڊيٽا کي ذخيرو ڪرڻ لاء) SDRAM ۾ واقع هوندو، باقي سڀ ڪجهه (ميموري لاء اسٽيڪ ۽ ٻين سسٽم جي ضرورتن لاء). ) RAM ڏانھن ويندا.
جيڪڏهن اسان STM32F7Discovery لاءِ گھٽ ۾ گھٽ ترتيب ڏيون (سڄو نيٽ ورڪ، سڀ ڪمانڊ، اسٽيڪ کي جيترو ٿي سگھي ننڍو ڪريو، وغيره) ۽ اتي مثالن سان OpenCV شامل ڪريو، گھربل ميموري ھيٺ ڏنل ھوندي:
text data bss dec hex filename
2876890 459208 312736 3648834 37ad42 build/base/bin/embox
انهن لاءِ جيڪي ڏاڍا واقف نه آهن ته ڪهڙا حصا ڪٿي وڃن ٿا، مان وضاحت ڪندس: ۾ .text
и .rodata
هدايتون ۽ مستقل (تقريبا ڳالهائڻ، صرف پڙهڻ واري ڊيٽا) ۾ ڪوڙ .data
ڊيٽا تبديل ٿي سگهي ٿي، .bss
اتي "نال ٿيل" متغير آھن، جن کي، ان جي باوجود، ھڪڙي جڳھ جي ضرورت آھي (ھي سيڪشن رام ڏانھن "وڃي" ويندو).
سٺي خبر اها آهي .data
/.bss
مناسب هجڻ گهرجي، پر سان گڏ .text
مصيبت اها آهي ته تصوير لاء صرف 1MiB ياداشت آهي. اڇلائي سگھجي ٿو .text
مثال مان تصوير ڪڍو ۽ ان کي پڙهو، مثال طور، SD ڪارڊ مان ميموري ۾ شروع ڪرڻ تي، پر fruits.png جو وزن 330KiB آهي، تنهنڪري اهو مسئلو حل نه ڪندو: اڪثر .text
OpenCV ڪوڊ تي مشتمل آهي.
مجموعي طور تي، اتي صرف هڪ شيء باقي آهي - ڪوڊ جو هڪ حصو QSPI فليش تي لوڊ ڪرڻ (ان ۾ سسٽم بس ۾ ميموري کي ميپ ڪرڻ لاء آپريشن جو هڪ خاص طريقو آهي، انهي ڪري ته پروسيسر هن ڊيٽا کي سڌو رسائي ڪري سگهي ٿو). انهي صورت ۾، هڪ مسئلو پيدا ٿئي ٿو: پهرين، هڪ QSPI فليش ڊرائيو جي ميموري ڊوائيس ريبوٽ ٿيڻ کان پوء فوري طور تي دستياب ناهي (توهان کي الڳ الڳ ميموري ميپڊ موڊ کي شروع ڪرڻ جي ضرورت آهي)، ۽ ٻيو، توهان هن ميموري سان "فليش" نٿا ڪري سگهو. هڪ واقف بوٽ لوڊر.
نتيجي طور، اهو فيصلو ڪيو ويو ته QSPI ۾ سڀني ڪوڊ کي ڳنڍڻ، ۽ ان کي فليش ڪريو هڪ خود لکيل لوڊر سان جيڪو گهربل بائنري TFTP ذريعي حاصل ڪندو.
نتيجي ۾
هن لائبريريءَ کي ايمباڪس ۾ پورٽ ڪرڻ جو خيال اٽڪل هڪ سال اڳ ظاهر ٿيو، پر بار بار مختلف سببن ڪري ملتوي ڪيو ويو. انهن مان هڪ آهي libstdc++ ۽ معياري ٽيمپليٽ لائبريري لاءِ سپورٽ. ايمباڪس ۾ C++ سپورٽ جو مسئلو هن آرٽيڪل جي دائري کان ٻاهر آهي، ان ڪري مان هتي صرف ايترو چوندس ته اسان هن لائبرري جي ڪم ڪرڻ لاءِ صحيح مقدار ۾ اها سپورٽ حاصل ڪرڻ ۾ ڪامياب ٿي ويا آهيون 🙂
آخر ۾، اهي مسئلا ختم ٿي ويا (گهٽ ۾ گهٽ OpenCV مثال لاءِ ڪم ڪرڻ لاءِ ڪافي)، ۽ مثال هليو ويو. ڪيني فلٽر استعمال ڪندي حدون ڳولڻ لاءِ بورڊ لاءِ 40 ڊگھا سيڪنڊ لڳن ٿا. اهو، يقينا، تمام ڊگهو آهي (هن معاملي کي ڪيئن بهتر ڪرڻ تي غور ڪيو ويو آهي، اهو ممڪن آهي ته ڪاميابي جي صورت ۾ ان بابت هڪ الڳ مضمون لکڻ لاء).
بهرحال، وچولي مقصد هڪ پروٽوٽائپ ٺاهڻ هو، جيڪو STM32 تي OpenCV هلائڻ جو بنيادي امڪان ڏيکاريندو، ترتيب سان، هي مقصد حاصل ڪيو ويو، هوري!
tl؛ dr: قدم قدم هدايتون
0: ڊائون لوڊ ڪريو ايمباڪس ذريعن، جهڙوڪ:
git clone https://github.com/embox/embox && cd ./embox
1: اچو ته هڪ بوٽ لوڊر گڏ ڪرڻ سان شروع ڪريون جيڪو QSPI فليش ڊرائيو کي ”فليش“ ڪندو.
make confload-arm/stm32f7cube
هاڻي توهان کي نيٽ ورڪ ترتيب ڏيڻ جي ضرورت آهي، ڇاڪاڻ ته. اسان تصوير کي TFTP ذريعي اپلوڊ ڪنداسين. بورڊ ۽ ميزبان IP پتي کي سيٽ ڪرڻ لاء، توهان کي تبديل ڪرڻو پوندو conf/rootfs/network.
تشڪيل مثال:
iface eth0 inet static
address 192.168.2.2
netmask 255.255.255.0
gateway 192.168.2.1
hwaddress aa:bb:cc:dd:ee:02
gateway
- ميزبان ايڊريس جتان تصوير لوڊ ڪئي ويندي، address
- بورڊ جو پتو.
ان کان پوء، اسان بوٽ لوڊر گڏ ڪريون ٿا:
make
2: بورڊ تي بوٽ لوڊر جي معمولي لوڊشيڊنگ (مقصد لاءِ معاف ڪجو) - هتي ڪجھ به خاص ناهي، توهان کي اهو ڪرڻو پوندو جيئن ڪنهن ٻئي ايپليڪيشن لاءِ STM32F7Discovery. جيڪڏهن توهان کي خبر ناهي ته اهو ڪيئن ڪجي، توهان ان بابت پڙهي سگهو ٿا
3: OpenCV لاءِ ترتيب سان تصوير گڏ ڪرڻ.
make confload-platform/opencv/stm32f7discovery
make
4: ELF سيڪشن مان ڪڍيو وڃي QSPI ڏانهن qspi.bin ڏانهن
arm-none-eabi-objcopy -O binary build/base/bin/embox build/base/bin/qspi.bin
--only-section=.text --only-section=.rodata
--only-section='.ARM.ex*'
--only-section=.data
conf ڊاريڪٽري ۾ هڪ اسڪرپٽ آهي جيڪو اهو ڪري ٿو، تنهنڪري توهان ان کي هلائي سگهو ٿا
./conf/qspi_objcopy.sh # Нужный бинарник -- build/base/bin/qspi.bin
5: tftp استعمال ڪندي، qspi.bin.bin کي QSPI فليش ڊرائيو تي ڊائون لوڊ ڪريو. ميزبان تي، اهو ڪرڻ لاء، qspi.bin کي tftp سرور جي روٽ فولڊر ۾ نقل ڪريو (عام طور تي /srv/tftp/ يا /var/lib/tftpboot/؛ لاڳاپيل سرور لاءِ پيڪيجز تمام مشهور تقسيم ۾ موجود آهن، عام طور تي سڏيو ويندو آهي. tftpd يا tftp-hpa، ڪڏهن ڪڏهن توهان کي ڪرڻو پوندو systemctl start tftpd.service
شروع ڪرڻ).
# вариант для tftpd
sudo cp build/base/bin/qspi.bin /srv/tftp
# вариант для tftp-hpa
sudo cp build/base/bin/qspi.bin /var/lib/tftpboot
ايمباڪس تي (يعني بوٽ لوڊر ۾)، توھان کي ھيٺ ڏنل حڪم تي عمل ڪرڻ جي ضرورت آھي (اسان فرض ڪريون ٿا ته سرور جو پتو آھي 192.168.2.1):
embox> qspi_loader qspi.bin 192.168.2.1
6: حڪم سان goto
توهان کي QSPI ياداشت ۾ "جمپ" ڪرڻ جي ضرورت آهي. مخصوص جڳھ مختلف ٿي ويندي ان تي منحصر آھي ته تصوير ڪيئن ڳنڍيل آھي، توھان ھي پتو ڏسي سگھو ٿا حڪم سان mem 0x90000000
(شروعاتي پتو تصوير جي ٻئي 32-bit لفظ ۾ ٺھي ٿو)؛ توهان کي پڻ اسٽيڪ کي پرچم ڪرڻ جي ضرورت پوندي -s
، اسٽيڪ ايڊريس 0x90000000 تي آهي، مثال طور:
embox>mem 0x90000000
0x90000000: 0x20023200 0x9000c27f 0x9000c275 0x9000c275
↑ ↑
это адрес это адрес
стэка первой
инструкции
embox>goto -i 0x9000c27f -s 0x20023200 # Флаг -i нужен чтобы запретить прерывания во время инициализации системы
< Начиная отсюда будет вывод не загрузчика, а образа с OpenCV >
7: لانچ
embox> edges 20
۽ لطف اندوز ٿيو 40-سيڪنڊ بارڊر سرچ 🙂
جيڪڏهن ڪجهه غلط ٿي وڃي - هڪ مسئلو لکو
جو ذريعو: www.habr.com