Abdi salah sahiji pamekar sistem operasi
Upami anjeun ngetik sapertos "OpenCV on STM32 board" kana mesin pencari, anjeun tiasa mendakan sababaraha jalma anu resep ngagunakeun perpustakaan ieu dina papan STM32 atanapi mikrokontroler anu sanés.
Aya sababaraha pidéo anu, ditilik ku nami, kedah nunjukkeun naon anu diperyogikeun, tapi biasana (dina sadaya pidéo anu kuring tingali) dina papan STM32, ngan ukur gambar anu ditampi tina kaméra sareng hasilna ditampilkeun dina layar. jeung ngolah gambar sorangan dipigawé boh dina komputer biasa, atawa dina papan leuwih kuat (Contona, buah prambus Pi).
Naha sesah?
Popularitas queries pilarian dijelaskeun ku kanyataan yén OpenCV nyaéta perpustakaan visi komputer pang populerna, nu hartina leuwih pamekar wawuh jeung eta, sarta kamampuhan pikeun ngajalankeun kode desktop-siap dina mikrokontroler greatly simplifies prosés ngembangkeun. Tapi naha aya kénéh euweuh populér resep siap-dijieun pikeun ngarengsekeun masalah ieu?
Masalah ngagunakeun OpenCV dina shawl leutik aya hubunganana sareng dua fitur:
- Lamun compile perpustakaan sanajan kalawan set minimal tina modul, eta ngan saukur moal cocog kana mémori flash sarua STM32F7Discovery (malah tanpa nyokot kana akun OS) alatan kode anu kacida gedéna (sababaraha megabytes parentah).
- Perpustakaan sorangan ditulis dina C ++, nu hartina
- Peryogi dukungan pikeun waktos jalan anu positif (pangecualian, jsb.)
- Saeutik dukungan pikeun LibC/Posix, anu biasana aya dina OS pikeun sistem anu dipasang - anjeun peryogi perpustakaan tambah standar sareng perpustakaan template STL standar (vektor, jsb.)
Porting ka Embox
Sakumaha biasa, sateuacan porting program naon waé kana sistem operasi, éta hadé pikeun nyobian ngawangun éta dina bentuk anu dituju ku pamekar. Dina kasus urang, teu aya masalah sareng ieu - kode sumber tiasa dipendakan dina
Warta anu saé nyaéta OpenCV tiasa diwangun salaku perpustakaan statik tina kotak, anu ngagampangkeun porting. Urang ngumpulkeun perpustakaan kalawan config baku tur tingal sabaraha spasi maranéhna butuh nepi. Unggal modul dikumpulkeun dina perpustakaan misah.
> 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)
Salaku bisa ningali tina garis panungtungan, .bss na .data teu butuh nepi teuing spasi, tapi kode nu leuwih ti 70 MiB. Ieu jelas yén lamun ieu statis numbu ka aplikasi husus, kode bakal jadi kirang.
Hayu urang cobian buang saloba modul anu mungkin supados conto minimal dirakit (anu, contona, ngan saukur bakal ngahasilkeun versi OpenCV), ku kituna urang tingali. cmake .. -LA
sareng mareuman dina pilihan sadayana anu pareum.
-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)
Di hiji sisi, ieu ngan hiji modul perpustakaan, di sisi séjén, ieu tanpa optimasi compiler pikeun ukuran kode (-Os
). ~3 kode MiB masih cukup loba, tapi geus méré harepan sukses.
Ngajalankeun dina émulator
Éta langkung gampang pikeun debug dina émulator, janten pastikeun yén perpustakaan dianggo dina qemu. Salaku platform emulated, kuring milih Integrator / CP, sabab firstly, eta oge ARM, jeung Bréh, Embox ngarojong kaluaran grafik pikeun platform ieu.
Embox gaduh mékanisme pikeun ngawangun perpustakaan éksternal, ngagunakeun éta kami nambihan OpenCV salaku modul (ngaliwatan sadaya pilihan anu sami pikeun ngawangun "minimal" dina bentuk perpustakaan statik), saatos éta kuring nambihan aplikasi saderhana sapertos kieu:
version.cpp:
#include <stdio.h>
#include <opencv2/core/utility.hpp>
int main() {
printf("OpenCV: %s", cv::getBuildInformation().c_str());
return 0;
}
Urang ngumpul sistem, ngajalankeun eta - urang meunang kaluaran ekspektasi.
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 включены в сборку и т.п.>
Lengkah saterusna nyaéta ngajalankeun sababaraha conto, preferably salah sahiji standar ditawarkeun ku pamekar sorangan.
Contona kudu rada ditulis ulang pikeun mintonkeun gambar jeung hasilna langsung dina pigura panyangga. Kuring kungsi ngalakukeun ieu, sabab. fungsi imshow()
bisa ngagambar gambar ngaliwatan interfaces QT, GTK jeung Windows, nu, tangtosna, pasti moal di config pikeun STM32. Kanyataanna, QT ogé tiasa dijalankeun dina STM32F7Discovery, tapi ieu bakal dibahas dina tulisan anu sanés 🙂
Saatos klarifikasi pondok nu format disimpen hasil detektor ujung, urang meunang hiji gambar.
gambar aslina
hasil
Dijalankeun dina STM32F7Discovery
Dina 32F746GDISCOVERY aya sababaraha bagian mémori hardware anu urang tiasa nganggo hiji cara atanapi anu sanés.
- 320KiB RAM
- 1MiB flash pikeun gambar
- 8MiB SDRAM
- 16MiB QSPI NAND Flash
- slot kartu microSD
Hiji kartu SD bisa dipaké pikeun nyimpen gambar, tapi dina konteks ngajalankeun hiji conto minimal, ieu teu pisan mangpaat.
tampilan ngabogaan resolusi 480 × 272, nu hartina mémori framebuffer bakal 522 bait dina jero 240 bit, i.e. ieu leuwih ti ukuran RAM, jadi framebuffer jeung numpuk (anu bakal diperlukeun, kaasup pikeun OpenCV, pikeun nyimpen data pikeun gambar jeung struktur bantu) bakal lokasina di SDRAM, sagalana sejenna (memori pikeun tumpukan jeung kabutuhan sistem séjén). ) bakal balik ka RAM.
Lamun urang nyokot config minimum pikeun STM32F7Discovery (ngalungkeun kaluar sakabéh jaringan, sagala paréntah, nyieun tumpukan sakumaha leutik-gancang, jsb) jeung nambahkeun OpenCV kalawan conto aya, memori diperlukeun bakal kieu:
text data bss dec hex filename
2876890 459208 312736 3648834 37ad42 build/base/bin/embox
Pikeun maranéhanana anu teu pisan wawuh jeung nu bagian mana, Kuring bakal ngajelaskeun: di .text
и .rodata
parentah jeung konstanta (kasarna diomongkeun, data readonly) perenahna di .data
datana bisa dirobah, .bss
Aya variabel "nulled", nu, Tapi, perlu tempat (bagian ieu bakal "buka" ka RAM).
Warta alus éta .data
/.bss
kudu pas, tapi kalawan .text
masalahna nyaeta ngan aya 1MiB memori pikeun gambar. Bisa dibuang .text
gambar tina conto jeung maca eta, contona, tina kartu SD kana memori dina ngamimitian, tapi fruits.png weighs ngeunaan 330KiB, jadi ieu moal ngajawab masalah: paling .text
diwangun ku kode OpenCV.
Sacara umum, ngan ukur aya hiji hal anu tinggaleun - ngamuat bagian kodeu kana lampu kilat QSPI (mibanda modeu operasi khusus pikeun mémori peta kana beus sistem, supados prosésor tiasa ngaksés data ieu langsung). Dina hal ieu, timbul masalah: kahiji, mémori QSPI flash drive teu sadia langsung saatos alat rebooted (anjeun kudu misah initialize mode memori-dipetakeun), sarta kadua, Anjeun teu bisa "flash" memori ieu kalawan. a bootloader akrab.
Hasilna, eta ieu mutuskeun pikeun numbu sakabeh kode dina QSPI, sarta flash eta kalawan loader timer ditulis anu bakal nampa binér diperlukeun via TFTP.
hasil
Gagasan pikeun port perpustakaan ieu ka Embox mucunghul ngeunaan sataun katukang, tapi leuwih sarta leuwih deui ditunda alatan sagala rupa alesan. Salah sahijina nyaéta dukungan pikeun libstdc ++ sareng perpustakaan template standar. Masalah pangrojong C ++ di Embox saluareun ruang lingkup artikel ieu, jadi di dieu kuring ngan bakal disebutkeun yen urang junun ngahontal rojongan ieu dina jumlah katuhu pikeun perpustakaan ieu jalan 🙂
Tungtungna, masalah ieu diatasi (sahenteuna cukup pikeun conto OpenCV tiasa dianggo), sareng conto éta jalan. Butuh 40 detik panjang pikeun dewan pikeun milarian wates nganggo saringan Canny. Ieu, tangtosna, panjang teuing (aya pertimbangan ngeunaan cara ngaoptimalkeun masalah ieu, bakal mungkin nulis artikel misah ngeunaan ieu bisi sukses).
Nanging, tujuan panengah nyaéta nyiptakeun prototipe anu bakal nunjukkeun kamungkinan dasar pikeun ngajalankeun OpenCV dina STM32, masing-masing, tujuan ieu kahontal, hore!
tl;dr: step by step parentah
0: Unduh sumber Embox, sapertos kieu:
git clone https://github.com/embox/embox && cd ./embox
1: Hayu urang mimitian ku assembling bootloader nu bakal "flash" a QSPI flash drive.
make confload-arm/stm32f7cube
Ayeuna anjeun kudu ngonpigurasikeun jaringan, sabab. Urang bakal unggah gambar via TFTP. Pikeun nyetel papan sareng alamat IP host, anjeun kedah ngédit conf/rootfs/network.
Conto konfigurasi:
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
- alamat host ti mana gambar bakal dimuat, address
- alamat dewan.
Sanggeus éta, urang ngumpulkeun bootloader:
make
2: The loading dawam tina bootloader (punten pikeun Pun) dina dewan - aya nanaon husus di dieu, anjeun kudu ngalakukeun hal eta kawas pikeun sagala aplikasi sejenna pikeun STM32F7Discovery. Upami anjeun henteu terang kumaha ngalakukeunana, anjeun tiasa maca ngeunaan éta
3: Nyusun gambar sareng konfigurasi pikeun OpenCV.
make confload-platform/opencv/stm32f7discovery
make
4: Ékstrak tina bagian ELF pikeun ditulis ka QSPI ka 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
Aya skrip dina diréktori conf anu ngalakukeun ieu, ku kituna anjeun tiasa ngajalankeunana
./conf/qspi_objcopy.sh # Нужный бинарник -- build/base/bin/qspi.bin
5: Ngagunakeun tftp, ngundeur qspi.bin.bin ka QSPI flash drive. Dina host, pikeun ngalakukeun ieu, nyalin qspi.bin kana polder akar tina server tftp (biasana / srv / tftp / atanapi / var / lib / tftpboot /; bungkusan pikeun server anu cocog sayogi dina distribusi anu paling populér, biasana disebut. tftpd atanapi tftp-hpa, sakapeung anjeun kedah ngalakukeun systemctl start tftpd.service
pikeun ngamimitian).
# вариант для tftpd
sudo cp build/base/bin/qspi.bin /srv/tftp
# вариант для tftp-hpa
sudo cp build/base/bin/qspi.bin /var/lib/tftpboot
Dina Embox (nyaéta dina bootloader), anjeun kedah ngajalankeun paréntah di handap ieu (urang nganggap yén server ngagaduhan alamat 192.168.2.1):
embox> qspi_loader qspi.bin 192.168.2.1
6: Kalayan paréntah goto
anjeun kedah "luncat" kana mémori QSPI. Lokasi husus bakal rupa-rupa gumantung kana kumaha gambar numbu, anjeun tiasa ningali alamat ieu kalawan paréntah mem 0x90000000
(alamat mimiti pas kana kecap 32-bit kadua gambar); anjeun ogé bakal kedah bandéra tumpukan -s
, alamat tumpukan aya dina 0x90000000, contona:
embox>mem 0x90000000
0x90000000: 0x20023200 0x9000c27f 0x9000c275 0x9000c275
↑ ↑
это адрес это адрес
стэка первой
инструкции
embox>goto -i 0x9000c27f -s 0x20023200 # Флаг -i нужен чтобы запретить прерывания во время инициализации системы
< Начиная отсюда будет вывод не загрузчика, а образа с OpenCV >
7: ngajalankeun
embox> edges 20
sarta ngarasakeun pilarian wates 40 detik 🙂
Upami aya anu salah - tuliskeun masalah dina
sumber: www.habr.com