Sistema eragilearen garatzaileetako bat naiz
Bilatzaile batean "OpenCV on STM32 board" bezalako zerbait idazten baduzu, liburutegi hau STM32 plaketan edo beste mikrokontrolagailuetan erabiltzeko interesa duten jende dezente aurki dezakezu.
Hainbat bideo daude, izenaren arabera, behar dena frogatu beharko luketenak, baina normalean (ikusi ditudan bideo guztietan) STM32 plakan, kameratik irudia bakarrik jasotzen zen eta emaitza pantailan bistaratzen zen, eta irudien tratamendua bera ordenagailu arrunt batean edo plaka indartsuagoetan egiten zen (adibidez, Raspberry Pi).
Zergatik da zaila?
Bilaketa-kontsulten ospea OpenCV ordenagailu bidezko ikusmenaren liburutegirik ezagunena izateak azaltzen du, hau da, garatzaile gehiagok ezagutzen dutela eta mikrokontrolagailu batean mahaigainerako prest dagoen kodea exekutatzeko gaitasunak asko errazten du garapen prozesua. Baina zergatik ez dago oraindik arazo hau konpontzeko prest dauden errezeta ezagunik?
Xal txikietan OpenCV erabiltzearen arazoa bi ezaugarrirekin lotuta dago:
- Liburutegia konpilatzen baduzu modulu multzo minimo batekin ere, besterik gabe, ez da STM32F7Discovery beraren flash memorian sartuko (nahiz eta sistema eragilea kontuan hartu gabe) kode oso handia delako (hainbat megabyte jarraibide).
- Liburutegia bera C++-n idatzita dago, hau da
- Exekuzio-denbora positiboa lortzeko laguntza behar da (salbuespenak, etab.)
- LibC/Posix-en laguntza gutxi, sistema txertatuetarako sistema eragilean aurkitu ohi dena; liburutegi estandar bat eta STL txantiloi liburutegi estandar bat behar dituzu (bektoreak, etab.)
Embox-era eramatea
Ohi bezala, edozein programa sistema eragilera eraman aurretik, komeni da garatzaileek nahi zuten moduan eraikitzen saiatzea. Gure kasuan, ez dago arazorik honekin - iturburu kodea helbidean aurki daiteke
Berri ona da OpenCV liburutegi estatiko gisa eraiki daitekeela kaxatik kanpo, eta horrek erraztu egiten du porturatzea. Konfigurazio estandarra duen liburutegi bat biltzen dugu eta zenbat leku hartzen duten ikusten dugu. Modulu bakoitza liburutegi bereizi batean biltzen da.
> 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)
Azken lerroan ikusten denez, .bss eta .data-k ez dute leku handirik hartzen, baina kodea 70 MiB baino gehiagokoa da. Argi dago hau aplikazio zehatz bati estatikoki lotuta badago, kodea txikiagoa izango dela.
Saia gaitezen ahalik eta modulu gehien botatzen, gutxieneko adibide bat muntatzeko (adibidez, OpenCV bertsioa besterik gabe aterako dena), beraz, begiratuko dugu. cmake .. -LA
eta itzali aukeretan itzaltzen dena.
-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)
Alde batetik, hau liburutegiko modulu bakarra da, bestetik, kodearen tamainarako konpiladorearen optimizaziorik gabe (-Os
). ~3 MiB kode asko dira oraindik, baina arrakastarako itxaropena ematen du dagoeneko.
Exekutatu emuladorean
Askoz errazagoa da emuladorean araztea, beraz, lehenik eta behin ziurtatu liburutegiak qemu-n funtzionatzen duela. Plataforma emulatu gisa, Integrator / CP aukeratu nuen, zeren lehenik, ARM ere bada, eta, bigarrenik, Embox-ek plataforma honetarako irteera grafikoa onartzen du.
Embox-ek kanpoko liburutegiak eraikitzeko mekanismo bat du, hura erabiliz OpenCV gehitzen dugu modulu gisa (aukera berdinak eraikitzeko "minimoa" liburutegi estatikoen moduan pasatzen), ondoren aplikazio sinple bat gehitzen dut, itxura hau duena:
version.cpp:
#include <stdio.h>
#include <opencv2/core/utility.hpp>
int main() {
printf("OpenCV: %s", cv::getBuildInformation().c_str());
return 0;
}
Sistema muntatzen dugu, exekutatu - espero den irteera lortzen dugu.
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 Π²ΠΊΠ»ΡΡΠ΅Π½Ρ Π² ΡΠ±ΠΎΡΠΊΡ ΠΈ Ρ.ΠΏ.>
Hurrengo urratsa adibideren bat exekutatzen da, hobe garatzaileek beraiek eskaintzen duten estandarren bat.
Adibidea apur bat berridatzi behar izan da emaitzarekin irudia zuzenean marko-bufferean bistaratzeko. Hau egin behar nuen, zeren. funtzioa imshow()
QT, GTK eta Windows interfazeen bidez irudiak marraz ditzake, eta hori, noski, ez da STM32-ren konfigurazioan egongo. Izan ere, QT STM32F7Discovery-n ere exekutatu daiteke, baina hori beste artikulu batean eztabaidatuko da π
Ertz-detektagailuaren emaitza zein formatutan gordetzen den argitu ondoren, irudi bat lortzen dugu.
jatorrizko irudia
Emaitza
STM32F7Discovery-n exekutatzen
32F746GDISCOVERY-n hainbat hardware-memoria atal daude era batera edo bestera erabil ditzakegun
- 320 KiB RAM
- 1 MiB flash irudirako
- 8 MiB SDRAM
- 16 MiB QSPI NAND Flash
- microSD txartelaren zirrikitua
SD txartela irudiak gordetzeko erabil daiteke, baina gutxieneko adibide bat exekutatzeko testuinguruan, hau ez da oso erabilgarria.
Pantailak 480Γ272ko bereizmena du, hau da, framebuffer memoria 522 byte izango da 240 biteko sakoneran, hau da. hau RAM-aren tamaina baino gehiago da, beraz, framebuffer-a eta heap (beharrezkoa izango dena, OpenCV-rako barne, irudien eta egitura laguntzaileen datuak gordetzeko) SDRAM-en kokatuko dira, gainerako guztia (piletarako memoria eta sistemaren behar beste ) RAMera joango da.
STM32F7Discovery-rako gutxieneko konfigurazioa hartzen badugu (sare osoa bota, komando guztiak, pilak ahalik eta txikienak egin, etab.) eta OpenCV gehitzen badugu bertan adibideekin, beharrezkoa den memoria hau izango da:
text data bss dec hex filename
2876890 459208 312736 3648834 37ad42 build/base/bin/embox
Zein atal nora doazen oso ezagutzen ez dutenentzat, azalduko dut: in .text
ΠΈ .rodata
argibideak eta konstanteak (gutxi gorabehera, irakurtzeko soilik datuak) daude .data
datuak aldagarriak dira, .bss
aldagai "nuled" daude, eta, hala ere, leku bat behar dute (atal hau RAMera "joango" da).
Berri ona hori da .data
/.bss
egokitu beharko luke, baina .text
arazoa da irudirako 1MiB memoria baino ez dagoela. Bota daiteke .text
adibideko irudia eta irakurri, adibidez, SD txarteletik memoriara abiaraztean, baina fruits.png-ek 330KiB inguru pisatzen du, beraz, honek ez du arazoa konponduko: gehienak .text
OpenCV kodeaz osatuta dago.
Oro har, gauza bakarra geratzen da: kodearen zati bat QSPI flash batean kargatzea (memoria sistema-busari mapak egiteko funtzionamendu modu berezi bat du, prozesadoreak datu hauek zuzenean atzitzeko). Kasu honetan, arazo bat sortzen da: lehenik, QSPI flash drive baten memoria ez dago erabilgarri gailua berrabiarazi eta berehala (memoria mapatutako modua bereizita hasi behar duzu), eta, bigarrenik, ezin duzu memoria hau "flash" abiarazle ezagun bat.
Ondorioz, QSPIn kode guztia lotzea erabaki zen, eta TFTP bidez eskatutako bitarra jasoko duen norberak idatzitako kargatzaile batekin flasheatzea.
Emaitza
Liburutegi hau Emboxera eramateko ideia duela urtebete inguru agertu zen, baina behin eta berriz atzeratu zen hainbat arrazoirengatik. Horietako bat libstdc++ eta txantiloi liburutegi estandarra onartzen da. Embox-en C++ euskarriaren arazoa artikulu honen esparrutik kanpo dago, beraz, hemen bakarrik esango dut euskarri hori behar bezala lortzea lortu dugula liburutegi honek funtziona dezan π
Azkenean, arazo hauek gainditu ziren (OpenCV adibidea funtzionatzeko nahikoa behintzat), eta adibidea martxan jarri zen. 40 segundo luze behar ditu taulak Canny iragazkia erabiliz mugak bilatzeko. Hau, noski, luzeegia da (gai hau optimizatzeko gogoetak daude, posible izango da honi buruz aparteko artikulu bat idaztea arrakasta izanez gero).
Hala ere, tarteko helburua STM32n OpenCV exekutatzeko oinarrizko aukera erakutsiko duen prototipo bat sortzea zen, hurrenez hurren, helburu hori lortu zen, aupa!
tl;dr: urratsez urrats argibideak
0: Deskargatu Embbox iturriak, honela:
git clone https://github.com/embox/embox && cd ./embox
1: Has gaitezen QSPI flash drive bat "flash" egingo duen abio-kargatzailea muntatzen.
make confload-arm/stm32f7cube
Orain sarea konfiguratu behar duzu, zeren. Irudia TFTP bidez igoko dugu. Taula eta ostalariaren IP helbideak ezartzeko, conf/rootfs/network editatu behar duzu.
Konfigurazio adibidea:
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
- irudia kargatuko den ostalari helbidea, address
- Kontseiluaren helbidea.
Horren ostean, abio-kargatzailea biltzen dugu:
make
2: Abio-kargatzailearen ohiko karga (barkatu hitz-jokoa) taulan - hemen ez dago ezer zehatzik, STM32F7Discovery-rako beste edozein aplikaziotarako bezala egin behar duzu. Ez badakizu nola egin, horri buruz irakur dezakezu
3: OpenCVrako konfigurazio batekin irudi bat konpilatzea.
make confload-platform/opencv/stm32f7discovery
make
4: QSPI-n idatzi beharreko ELF ataletatik qspi.bin-era idatzi behar da
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 direktorioan script bat dago hori egiten duena, exekutatu ahal izateko
./conf/qspi_objcopy.sh # ΠΡΠΆΠ½ΡΠΉ Π±ΠΈΠ½Π°ΡΠ½ΠΈΠΊ -- build/base/bin/qspi.bin
5: Tftp erabiliz, deskargatu qspi.bin.bin QSPI flash drive batera. Ostalarian, horretarako, kopiatu qspi.bin tftp zerbitzariaren erroko karpetara (normalean /srv/tftp/ edo /var/lib/tftpboot/; dagokion zerbitzarirako paketeak eskuragarri daude banaketa ezagunenetan, normalean deitzen direnak). tftpd edo tftp-hpa, batzuetan egin behar duzu systemctl start tftpd.service
hasteko).
# Π²Π°ΡΠΈΠ°Π½Ρ Π΄Π»Ρ tftpd
sudo cp build/base/bin/qspi.bin /srv/tftp
# Π²Π°ΡΠΈΠ°Π½Ρ Π΄Π»Ρ tftp-hpa
sudo cp build/base/bin/qspi.bin /var/lib/tftpboot
Emboxen (hau da, abio-kargatzailean), hurrengo komandoa exekutatu behar duzu (zerbitzariak 192.168.2.1 helbidea duela suposatzen dugu):
embox> qspi_loader qspi.bin 192.168.2.1
6: Aginduarekin goto
QSPI memoriara "jauzi" egin behar duzu. Kokapen zehatza irudia lotzen denaren arabera aldatuko da, helbide hau ikus dezakezu komandoarekin mem 0x90000000
(hasierako helbidea irudiaren bigarren 32 biteko hitzean sartzen da); pila markatu ere beharko duzu -s
, pila helbidea 0x90000000-n dago, adibidez:
embox>mem 0x90000000
0x90000000: 0x20023200 0x9000c27f 0x9000c275 0x9000c275
β β
ΡΡΠΎ Π°Π΄ΡΠ΅Ρ ΡΡΠΎ Π°Π΄ΡΠ΅Ρ
ΡΡΡΠΊΠ° ΠΏΠ΅ΡΠ²ΠΎΠΉ
ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ
embox>goto -i 0x9000c27f -s 0x20023200 # Π€Π»Π°Π³ -i Π½ΡΠΆΠ΅Π½ ΡΡΠΎΠ±Ρ Π·Π°ΠΏΡΠ΅ΡΠΈΡΡ ΠΏΡΠ΅ΡΡΠ²Π°Π½ΠΈΡ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΡΠΈΡΡΠ΅ΠΌΡ
< ΠΠ°ΡΠΈΠ½Π°Ρ ΠΎΡΡΡΠ΄Π° Π±ΡΠ΄Π΅Ρ Π²ΡΠ²ΠΎΠ΄ Π½Π΅ Π·Π°Π³ΡΡΠ·ΡΠΈΠΊΠ°, Π° ΠΎΠ±ΡΠ°Π·Π° Ρ OpenCV >
7: Abian jartzea
embox> edges 20
eta gozatu 40 segundoko muga-bilaketaz π
Zerbait gaizki ateratzen bada, idatzi arazo bat
Iturria: www.habr.com