Olen ĂŒks operatsioonisĂŒsteemi arendajatest , ja selles artiklis rÀÀkisin sellest, kuidas suutsin OpenCV-d STM32746G plaadil kĂ€ivitada.
Kui otsingumootorisse sisestada midagi sellist nagu «OpenCV on STM32 board», siis leiab ĂŒsna palju inimesi, kes on huvitatud selle biblioteka kasutamisest STM32 plaatidel vĂ”i teistel mikroprotsessoritel.
On mitmeid videoid, mis pealkirja pÔhjal peaksid demonstreerima seda, mida on vaja, kuid tavaliselt (kÔigis videot, mida olen nÀinud) on STM32 plaadil tehtud ainult pildi saamine kaamerast ja tulemuse kuvamine ekraanil, samas kui pildi töötlemine toimus kas tavalises arvutis vÔi vÔimsamatel plaatidel (nÀiteks Raspberry Pi).
Miks see on keeruline?
OtsingupÀringute populaarsus on tingitud sellest, et OpenCV on kÔige populaarsem arvutinÀgemise teek, seega on paljud arendajad selle eest tuttavad, ja vÔimalus kÀivitada lauaarvutiks mÔeldud kood mikroprotsessoril lihtsustab arendamisprotsessi. Kuid miks ei ole siiani populaarseid lahenduste retsepte selle probleemi lahendamiseks?
OpenCV kasutamise probleem vÀiksematel plaatidel on seotud kahe omadusega:
- Kui teegi isegi minimaalse moodulite kogumiga kokku panna, siis STM32F7Discovery vĂ€lkmĂ€lusse lihtsalt ei mahu (isegi ilma operatsioonisĂŒsteemita) vĂ€ga suure koodi tĂ”ttu (mitu megabaidi instruktsioone)
- Ise teek on kirjutatud C++-s, seega
- On vajalik C++ jooksuta teatamine (erandid jne)
- VĂ€he LibC/Posix toe, mis tavaliselt on integreeritud sĂŒsteemide opsĂŒsteemidesse â on vajalik C++ standardraamatukogu ja STL malliraamatukogu (vector jne)
Portimine Emboxi
Nagu tavaliselt, enne kui porteerite mĂ”nda programmide opsĂŒsteemi, on hea proovida see koguda sellisel kujul, nagu arendajad selle ette nĂ€gid. Meie juhul ei ole sellega probleeme â algkoodid on saadaval , teeki saab GNU/Linux'is tavalise cmake abil kokku panna.
Headest uudistest â OpenCV-d saab otse vĂ€ljaĂ”ppe kaudu kokku panna staatilise teegina, mis muudab portimise lihtsamaks. Kogume teegi standardse config-iga ja vaatame, palju ruumi nad kasutavad. Iga moodul kogutakse eraldi teegina.
> 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)Viimane rida nÀitab, et .bss ja .data ei vÔta palju ruumi, kuid koodi on enam kui 70 MiB. On selge, et kui see staatiliselt kindla rakendusega siduda, siis koodi maht vÀheneb.
Proovime eemaldada vÔimalikult palju mooduleid, et koostada minimaalne nÀide (mis nÀiteks lihtsalt kuvab OpenCV versiooni), nii et vaatame. cmake .. -LA ja blokeerime kÔik valikutes, mida on vÔimalik blokeerida.
-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)Ăhelt poolt, see on ainult ĂŒks teegi moodul, teiselt poolt, see pole koodi suuruse optimeerimise tĂ”ttu (-Os). ~3 MiB koodi â see on ikka veel piisavalt palju, kuid annab juba lootust edule.
KĂ€ivitamine emulaatoris
Emulaatoris on lihtsam siluda, seega veendume kÔigepealt, et teek töötab qemu-s. Emuleeritud platvormiks valisin Integrator/CP, kuna esiteks on see samuti ARM ja teiseks toetab Embox selle platvormi jaoks graafika vÀljundit.
Emboxil on mehhanism vÀliste teekide kompileerimiseks, millega lisame OpenCV moodulina (edastades kÔik samad valikud «minimaalse» töötlemise jaoks staatiliste teekidena), pÀrast seda lisan kÔige lihtsama rakenduse, mis nÀeb vÀlja jÀrgmiselt:
version.cpp:
#include
#include
int main() {
printf("OpenCV: %s", cv::getBuildInformation().c_str());
return 0;
}Kompileerime sĂŒsteemi, kĂ€ivitame â saame oodatud vĂ€ljundi.
root@embox: /#opencv_version
OpenCV:
Ăldine konfiguratsioon OpenCV 4.0.1 =====================================
Versioonikontroll: bd6927bdf-dirty
Platvorm:
Aeg: 2019-06-21T10:02:18Z
Host: Linux 5.1.7-arch1-1-ARCH x86_64
Sihitarget: Ăldine arm-unknown-none
CMake: 3.14.5
CMake generaator: Unix Makefiles
CMake ehitusvahend: /usr/bin/make
Konfiguratsioon: Debug
CPU/HW omadused:
Alus:
nÔutud: DETECT
keelatud: VFPV3 NEON
C/C++:
Ehitatud dĂŒnaamilisteks teekideks?: EI
Edasi on teised kogumise parameetrid - milliste lippudega see kompileeritud on,
millised OpenCV moodulid on kogumisse kaasatud jne.JÀrgmine samm on kÀivitada mÔni nÀidis, parem oleks mÔni standardne, mida arendajad ise pakuvad. . Ma valisin .
NĂ€idis tuli natuke ĂŒmber kirjutada, et tulemus otse frame bufferisse kuvada. Seda tuli teha, kuna funktsioon imshow() oskab pilte kuvada QT, GTK ja Windowsi liideste kaudu, mida STM32 seadistuses kindlasti ei ole. Tegelikult saab QT-d ka STM32F7Discovery-l kĂ€ivitada, aga sellest rÀÀgitakse juba teises artiklis đ
PĂ€rast lĂŒhikest arutelu, millises formaadis servade detektori töö tulemus hoitakse, saame pildi.

Originaalpilt

Tulemus
KĂ€ivitus STM32F7Discovery-l
32F746GDISCOVERY-l on mitu mÀlusegmenti, mida saame erinevalt kasutada
- 320KiB jÀrgnevat mÀlu
- 1MiB vÀlkmÀlu pildifaili jaoks
- 8MiB SDRAM
- 16MiB QSPI NAND vÀlkmÀlukaart
- microSD mÀlukaardi pesad
SD-kaarti saab kasutada piltide salvestamiseks, kuid minimaalse nÀidise kÀitamise kontekstis ei ole see eriti kasulik.
Ekraanil on eraldusvĂ”ime 480Ă272, seega frame bufferi mĂ€lu suurus on 522 240 baiti 32-bitise sĂŒgavusega, st see on suurem kui operatiivmĂ€lu suurus, seega frame buffer ja hunnik (mis on vajalik ka OpenCV jaoks, et hoida andmeid piltide ja abistruktuuride jaoks) asub SDRAM-is, kĂ”ik muu (mĂ€lu stekkide ja muude sĂŒsteemivajaduste jaoks) saadetakse RAM-i.
Kui vÔtta STM32F7Discovery minimaalne konfiguratsioon (kÔik vÔrgud vÀlja visata, kÔik kÀsud, stekke vÔimalikult vÀikesteks teha jne) ja lisada sinna OpenCV koos nÀidistega, on nÔutav mÀlu jÀrgmine:
text data bss dec hex filename
2876890 459208 312736 3648834 37ad42 build/base/bin/emboxNende jaoks, kes ei ole eriti tuttavad sellega, kuhu sektsioonid paigutatakse, selgitan: .text ja .rodata sisaldavad juhiseid ja konstande (lihtsalt öeldes, readonly-andmeid), .data sisaldavad muudetavaid andmeid, .bss sisaldab nullitud muutujaid, millele tuleb siiski koht anda (see sektsioon "lÀheb" RAM-i).
Hea uudis on see, et .data/.bss peavad mahutama, aga probleem on selles, et .text ruumi on ainult 1MiB. NĂ€iteks saab nĂ€idisekraanist pildi eemaldada ja lugeda seda SD-kaardilt mĂ€llu kĂ€ivitamisel, aga fruits.png kaalub umbes 330KiB, nii et see probleem ei lahenda: suurem osa .text koostis on tĂ”epoolest OpenCV kood. .text PĂ”himĂ”tteliselt jÀÀb ĂŒle vaid ĂŒks â laadida koodi osa QSPI-mĂ€lupulgale (sel on spetsiaalne tööreĆŸiim, mis vĂ”imaldab mĂ€lu sĂŒsteembussile kaardistada, mistĂ”ttu protsessor saab neile andmetele otse juurde pÀÀseda). Kuid on ĂŒks probleem: esiteks, QSPI-mĂ€lupulga mĂ€lu ei ole kohe pĂ€rast seadme taaskĂ€ivitamist saadaval (moodul tuleb eraldi initsialiseerida), teiseks ei saa seda mĂ€lupulka tavalise laadijaga "vĂ€lja kirjutada".
LÔpuks otsustati siduda kogu kood QSPI-sse ja kirjutada selle peale kohandatud laadija, mis saab vajaliku binaari TFTP kaudu.
Idee portida see teek Emboxile tekkis umbes aasta tagasi, kuid see lĂŒkati korduvalt edasi erinevatel pĂ”hjustel. Ăks neist on libstdc++ ja standardne malliraamatukogu toetus. C++ toetuse probleem Emboxis jÀÀb sellest artiklist vĂ€ljapoole, seega ĂŒtlen vaid, et meil Ă”nnestus saavutada vajaliku mahuga toetus selle teegi jaoks đ
Tulemus
LĂ”ppkokkuvĂ”ttes need probleemid ĂŒletati (vĂ€hemalt piisavas ulatuses OpenCV nĂ€idise tööks) ja nĂ€idis kĂ€ivitus. 40 pikka sekundit vĂ”tab arvel servade leidmine Canny filtriga. See on muidugi liiga pikk (on mĂ”tteid, kuidas seda optimeerida, sellest vĂ”iks kirjutada eraldi artikli juhul, kui see Ă”nnestub).
Siiski oli vahe-eesmĂ€rk luua prototĂŒĂŒp, mis nĂ€itab pĂ”himĂ”ttelist vĂ”imalust kĂ€ivitada OpenCV STM32-l, seega see eesmĂ€rk saavutati, hurraa!

tl;dr: samm-sammuline juhend
0: Laadige Emboxi allikakoodid alla, nÀiteks nii:
git clone https://github.com/embox/embox && cd ./embox
1: Alustame laadija kogumisega, mis "vÀlja kirjutab" QSPI mÀlupulga.make confload-arm/stm32f7cube
tee confload-arm/stm32f7cubeNĂŒĂŒd tuleb seadistada vĂ”rk, kuna me laadime kujutise TFTP kaudu. IP-aadresside seadmiseks plaadil ja hostil tuleb muuta faili conf/rootfs/network.
Konfiguratsiooni nÀidis:
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:02vĂ€rav â hosti aadress, kust kuvandi laadimine toimub, aadress â seadme aadress.
PÀrast seda kogume kÀivitaja:
tee2: Tavaline kĂ€ivitaja laadimine seadmele (palun vabandage mĂ€ngu sĂ”na) â siin pole midagi spetsiifilist, seda tuleb teha nagu iga teise rakenduse puhul STM32F7Discovery jaoks. Kui te ei tea, kuidas seda teha, saate lugeda sellest .
3: Kujutise kompileerimine OpenCV konfiguratsiooniga.
make confload-platform/opencv/stm32f7discovery
make4: ELF sektsioonide eraldamine, mis tuleb kirjutada QSPI-sse, faili 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=.dataKaustas conf on skript, mis seda teeb, seega on vÔimalik see kÀivitada
./conf/qspi_objcopy.sh # Vajalik binarne fail -- build/base/bin/qspi.bin5: TFTP abil laadime qspi.bin.bin QSPI-mÀlupulgale. Hostis tuleb qspi.bin kopeerida tftp-serveri juurkaustasse (tavaliselt on see /srv/tftp/ vÔi /var/lib/tftpboot/; vastava serveri paketid on enamiku populaarsete distributsioonide jaoks olemas, tavaliselt nimetatakse tftpd vÔi tftp-hpa, mÔnikord tuleb teha systemctl start tftpd.service selle kÀivitamiseks).
# ĐČаŃĐžĐ°ĐœŃ ĐŽĐ»Ń tftpd
sudo cp build/base/bin/qspi.bin /srv/tftp
# ĐČаŃĐžĐ°ĐœŃ ĐŽĐ»Ń tftp-hpa
sudo cp build/base/bin/qspi.bin /var/lib/tftpbootEmboxis (st. kÀivitajas) tuleb sisestada selline kÀsk (eeldades, et serveri aadress on 192.168.2.1):
embox> qspi_loader qspi.bin 192.168.2.16: KĂ€sk goto on vajalik, et "hĂŒpata" QSPI-mĂ€lu. Konkreetne asukoht vĂ”ib varieeruda sĂ”ltuvalt sellest, kuidas kujutis linkitakse, seda aadressi saab vaadata kĂ€suga mem 0x90000000 (algusaadress on teise 32-bitise sĂ”na kujutisest); samuti on vajalik seada virna mĂ€rk sĂŒmboliga -s, virna aadress asub aadressil 0x90000000, nĂ€ide:
embox>mem 0x90000000
0x90000000: 0x20023200 0x9000c27f 0x9000c275 0x9000c275
â â
see aadress see aadress
virnast esimese
kÀsu
embox>goto -i 0x9000c27f -s 0x20023200 # Lipp -i on vajalik, et keelata katkestused sĂŒsteemi initsialiseerimise ajal7: KĂ€ivitame
embox> edges 20ja naudime 40-sekundilist servade otsingu đ
Kui midagi lÀheb valesti, kirjutage probleem meie , vÔi embox-devel@googlegroups.com, vÔi kommentaarides siit.
Allikas: habr.com
