Olen ĂŒks operatsioonisĂŒsteemi arendajatest , ja selles artiklis jutustan, kuidas mul Ă”nnestus OpenCV kĂ€ivitada STM32746G plaadil.
Kui otsida midagi sarnast nagu «OpenCV on STM32 plaadil», vÔib leida pÀris palju inimesi, kes huvituvad selle teegi kasutamisest STM32 vÔi teiste mikrokontrollerite peal.
On mitmeid videoid, mis pealkirja jÀrgi peaksid nÀitama vajalikku, kuid tavaliselt (kÔikides videotest, mida olen nÀinud) tehti STM32 plaadil ainult kaamerapildi saamine ja tulemuse kuvamine ekraanil, samas kui pilditöötlus tehti kas tavalisel arvutil vÔi vÔimsamatel plaatidel (nt Raspberry Pi).
Miks see on keeruline?
OtsingupÀringute populaarsus selgitab, et OpenCV on kÔige populaarsem arvutinÀgemise teek, seega on rohkem arendajaid sellega tuttavad, ja vÔimalus kÀivitada laua jaoks valmis kood mikrokontrolleril lihtsustab arendusprotsessi mÀrkimisvÀÀrselt. Aga miks siiani pole populaarseid valmis lahendusi selle probleemi jaoks?
Probleem OpenCV kasutamisega vÀikestel plaatidel on seotud kahe omadusega:
- Kui isegi minimaalsete moodulitega kogu teek kompileerida, ei mahu see sama STM32F7Discovery vĂ€lkmĂ€llu (isegi ilma operatsioonisĂŒsteemita) liiga suure koodi tĂ”ttu (mitu megabaidi kĂ€su).
- Teek ise on kirjutatud C++-s, seega
- on vajalik C++ kÀitusaeg (vÀlja arvatud ja muud).
- Puudub LibC/Posix tugi, mida tavaliselt leidub sisseehitatud sĂŒsteemide operatsioonisĂŒsteemides â vajalik on C++ standardteek ja STL standardteek (nĂ€iteks vektor ja nii edasi).
Portimine Emboxile
Kuna enne mĂ”ne programmi portimist operatsioonisĂŒsteemi on alati hea proovida seda koguda just sellisena, nagu arendajad ette nĂ€gid. Meie juhul ei teki selle probleemiga mingeid raskusi â allikaid saab leida , teek kogutakse GNU/Linuxi tavapĂ€rase cmake abil.
Hea uudis on see, et OpenCV-d saab vÀlja pakkuda staatilise teekina, mis muudab portimise lihtsamaks. Kogume teeki tavalise konfigureerimisega ja vaatame, kui palju ruumi see nÔuab. Iga moodul kogutakse eraldi teekina.
> 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)Nagu viimasest reast nĂ€ha, vĂ”tab .bss ja .data mitte palju ruumi, kuid kood on ĂŒle 70 MiB. On selge, et kui see linkida staatiliselt konkreetse rakendusega, vĂ€heneb koodi maht.
Proovime eemaldada nii palju mooduleid kui vĂ”imalik, et koguda minimaalne nĂ€ide (mis nĂ€iteks lihtsalt kuvab OpenCV versiooni), seega vaatame cmake .. -LA ja lĂŒlitame valikutes vĂ€lja kĂ”ik, mis vĂ€lja lĂŒlitatav on.
-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 on see ainult ĂŒks raamatukogu moodul, teiselt poolt, see on ilma koodi suuruse optimeerimiseta (-Os). ~3 MiB koodi â see on endiselt piisavalt palju, kuid juba annab lootust edule.
KĂ€ivitamine emulaatoris
Emulaatoris on palju lihtsam debugida, seega veendume esmalt, et teek töötab qemu-s. Emuleeritavaks platvormiks valisin Integrator/CP, kuna see on ka ARM ja Embox toetab selle platvormi graafikat.
Emboxis on mehhanism vĂ€liste raamatukogude kogumiseks, millega lisame OpenCV moodulina (kandes kĂ”ik samad valikud âminimaalseâ kogumise jaoks staatiliste raamatukogude kujul), seejĂ€rel lisan lihtsa rakenduse, mis nĂ€eb vĂ€lja jĂ€rgmiselt:
version.cpp:
#include
#include
int main() {
printf("OpenCV: %s", cv::getBuildInformation().c_str());
return 0;
}Kogume sĂŒsteemi, kĂ€ivitame â saame oodatud vĂ€ljundi.
root@embox:/#opencv_version
OpenCV:
OpenCV 4.0.1 ĂŒldine konfiguratsioon =====================================
Versioonikontroll: bd6927bdf-dirty
Platvorm:
Ajastamine: 2019-06-21T10:02:18Z
Alus: Linux 5.1.7-arch1-1-ARCH x86_64
Siht: Ăldine arm-unknown-none
CMake: 3.14.5
CMake generaator: Unix Makefiles
CMake ehitustööriist: /usr/bin/make
Konfiguratsioon: Debug
CPU/HW omadused:
Baas:
taotletud: DETECT
keelatud: VFPV3 NEON
C/C++:
Koostatud dĂŒnaamiliste teekidena?: EIJĂ€rgmine samm on kĂ€ivitada mĂ”ni nĂ€ide, parim on valida mĂ”ni standardne, mida pakuvad arendajad ise. . Valisin .
NĂ€idet tuli veidi ĂŒmber kirjutada, et kuvada tulemust otse raami puhveris. See tuli teha, kuna funktsioon imshow() suudab kuvada pilte lĂ€bi QT, GTK ja Windowsi liideste, mida STM32 kontekstis kindlasti ei ole. Tegelikult saab QT-d samuti kĂ€ivitada STM32F7Discovery-l, aga sellest rÀÀgitakse juba teises artiklis đ
PĂ€rast lĂŒhikest uurimist, millises formaadis piiride tuvastamise tulemused salvestatakse, saame pildi.

Originaalpilt

Tulemus
KĂ€ivitus STM32F7Discovery-l
32F746GDISCOVERY-l on mitu riistvara mÀlusegmenti, mida saame kasulikult kasutada.
- 320KiB töömÀlu
- 1MiB vÀlkmÀlu pildi jaoks
- 8MiB SDRAM
- 16MiB QSPI NAND-mÀlupulk
- MicroSD-kaardi pesa
SD-kaarti vÔib kasutada piltide salvestamiseks, kuid minimaalsete nÀidete kÀivitamise kontekstis pole see eriti kasulik.
Kuva eraldusvĂ”ime on 480Ă272, seega frame bufferi mĂ€lu suurus on 522 240 baiti 32-bitise sĂŒgavuse juures, mis tĂ€hendab, et see on suurem kui töömĂ€lu, seega paigaldame frame bufferi ja hunniku (mis on vajalik ka OpenCV jaoks piltide ja abistruktuuride andmete salvestamiseks) SDRAM-i, kĂ”ik muu (mĂ€lu rĂ”ngaste ja teiste sĂŒsteemivajaduste jaoks) saadetakse RAM-i.
Kui vÔtta minimaalne konfiguratsioon STM32F7Discovery jaoks (eemaldada kogu vÔrk, kÔik kÀsud, teha virnad vÔimalikult vÀikseks jne) ja lisada sinna OpenCV nÀidetega, siis vajalik mÀlu oleks jÀrgmine:
tekst andmed bss dec hex failinimi
2876890 459208 312736 3648834 37ad42 build/base/bin/emboxNeed for those who are not very familiar with where the sections go, I'll explain: in .text ja .rodata lie instructions and constants (roughly speaking, readonly data), in .data lie modifiable data, in .bss lie "zeroed" variables, which still need space (this section will "go" into RAM).
The good news is that .data/.bss must fit, but the trouble is .text there's only 1MiB of memory for the image. You can remove the image from the example and read it, for instance, from an SD card into memory at startup, but fruits.png weighs about 330KiB, so that won't solve the problem: most of the .text nÀiteks nÀha ja lugeda pilti SD-kaardilt kÀivitamisel, kuid fruits.png kaalub umbes 330KiB, seega see probleem ei lahenda: enamik .text consists precisely of OpenCV code.
Basically, thereâs only one option left â loading part of the code onto the QSPI flash (it has a special operating mode for memory mapping on the system bus, so the processor can directly access this data). However, thereâs a problem: first, QSPI flash memory is not available immediately after rebooting the device (you need to separately initialize memory-mapped mode), and second, you can't "flash" this memory with a conventional bootloader.
LĂ”puks otsustati sĂŒnkroonida kogu kood QSPI-sse ja kirjutada see oma laadimisseadmestikku, mis saab vajaliku binaari TFTP kaudu.
Tulemus
Idee portida see teek Emboxile tekkis umbes aasta tagasi, kuid mitmel pĂ”hjusel on see korduvalt edasi lĂŒkatud. Ăks neist pĂ”hjustest on libstdc++ ja standardne mallide teek. C++ toe toimetamine Emboxis ĂŒletab selle artikli raames kĂ€sitletava teema ulatuse, seega ĂŒtlen lihtsalt, et oleme suutnud saavutada vajaliku toetuse selle teegi tööks đ.
LĂ”puks saadi need probleemid ĂŒletatud (vĂ€hemalt piisavalt, et OpenCV nĂ€ide töötaks) ning nĂ€ide kĂ€ivitus. Plaadil kulus 40 pikemat sekundit servade tuvastamiseks Canny filtriga. See on muidugi liiga kaua (on ideid, kuidas seda optimeerida, sellest vĂ”iks kirjutada eraldi artikli, kui see Ă”nnestub).

KĂŒll aga oli vahe-eesmĂ€rk prototĂŒĂŒbi loomine, mis nĂ€itaks OpenCV kĂ€itamise pĂ”himĂ”ttelise vĂ”imaluse STM32-l, seega on see eesmĂ€rk saavutatud, hurraa!
tl;dr: samm-sammuline juhend
0: Laadige Emboxi lÀhtekood, nÀiteks nii:
git clone https://github.com/embox/embox && cd ./embox1: Alustame kÀivituslaadija koostamisest, mis "programmeerib" QSPI mÀlupulga.
make confload-arm/stm32f7cubeNĂŒĂŒd tuleb seadistada vĂ”rk, kuna laadime kujundi TFTP kaudu. Arvutite ja hosti IP-aadresside mÀÀramiseks 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:02gateway â hosti aadress, kust pilt laaditakse, address â seadme aadress.
PĂ€rast seda koondame laadija:
make2: Tavaline laadimine laadijale (palun andke andeks mĂ€ng sĂ”nadega) seadmesse â siin pole midagi spetifilist, tuleb seda teha nagu igasuguste muude rakenduste puhul STM32F7Discovery jaoks. Kui te ei tea, kuidas seda teha, vĂ”ite sellest lugeda .
3: Pildi kompileerimine OpenCV konfigureerimisega.
make confload-platform/opencv/stm32f7discovery
make4: Sektsioonide vÀljavÔtmine ELF-ist, mis tuleb QSPI-sse kirjutada, failis 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, nii et saate selle kÀivitada
./conf/qspi_objcopy.sh # Vajalik binaar -- build/base/bin/qspi.bin5: Tftp abil laadime qspi.bin.bin QSPI-mÀlupulgale. Selleks tuleb hostis kopeerida qspi.bin tftp-serveri juurkatalooge (tavaliselt on see /srv/tftp/ vÔi /var/lib/tftpboot/; vajalikud paketid on saadaval enamikus tuntud distributsioonides, neid nimetatakse tavaliselt tftpd vÔi tftp-hpa, mÔnikord tuleb teha systemctl start tftpd.service 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 laadijana) tuleb tÀita jÀrgmine kÀsk (eeldame, et serveri aadress on 192.168.2.1):
embox> qspi_loader qspi.bin 192.168.2.16: KĂ€sk goto on vajalik, et "hĂŒppata" QSPI-mĂ€llu. Konkreetne asukoht varieerub sĂ”ltuvalt sellest, kuidas pilt linkib, seda aadressi saab vaadata kĂ€suga mem 0x90000000 (algus aadress mahtus pildi teise 32-bitise sĂ”na); lisaks tuleb seadistada suurus lippudega -s, steki aadress asub aadressil 0x90000000, nĂ€iteks:
embox>mem 0x90000000
0x90000000: 0x20023200 0x9000c27f 0x9000c275 0x9000c275
â â
see aadress see aadress
stekist esimese
instruktsiooni
embox>goto -i 0x9000c27f -s 0x20023200 # Lipp -i on vajalik, et keelata katkestused sĂŒsteemi initsialiseerimise ajal7: KĂ€ivitame
embox> servad 20ja naudime 40-sekundiliste piiride otsingut đ
Kui miski lÀheb valesti, siis kirjutage issue , vÔi embox-devel@googlegroups.com listi, vÔi kommenteerige siin.
Allikas: habr.com
