{"id":37914,"date":"2019-10-31T22:20:31","date_gmt":"2019-10-31T19:20:31","guid":{"rendered":"https:\/\/prohoster.info\/blog\/opencv-na-stm32f7-discovery\/"},"modified":"2019-10-31T22:20:31","modified_gmt":"2019-10-31T19:20:31","slug":"opencv-na-stm32f7-discovery","status":"publish","type":"post","link":"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/opencv-na-stm32f7-discovery","title":{"rendered":"OpenCV na STM32F7-Discovery","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"OpenCV na STM32F7-Discovery\" src=\"\/wp-content\/uploads\/2019\/09\/a2248ee685ee210ce8f7781435dd1d5a.jpg\" style=\"display:block;margin: 0 auto;\" \/> Jsem jedn\u00edm z v\u00fdvoj\u00e1\u0159\u016f opera\u010dn\u00edho syst\u00e9mu <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/embox\/embox\">Embox<\/a><\/noindex>, a v tomto \u010dl\u00e1nku v\u00e1m pov\u00edm, jak se mi poda\u0159ilo spustit OpenCV na desce STM32746G.<\/p>\n<p><\/p>\n<p>Pokud do vyhled\u00e1va\u010de zad\u00e1te n\u011bco jako &#171;OpenCV na desce STM32&#187;, najdete pom\u011brn\u011b mnoho lid\u00ed, kte\u0159\u00ed se zaj\u00edmaj\u00ed o pou\u017eit\u00ed t\u00e9to knihovny na desk\u00e1ch STM32 nebo jin\u00fdch mikrokontrol\u00e9rech.<br \/>\nExistuje n\u011bkolik vide\u00ed, kter\u00e1 podle n\u00e1zvu maj\u00ed ukazovat to, co pot\u0159ebujete, ale obvykle (ve v\u0161ech vide\u00edch, kter\u00e1 jsem vid\u011bl) byla na desce STM32 prov\u00e1d\u011bna pouze akvizice obrazu z kamery a v\u00fdsledky byly zobrazov\u00e1ny na obrazovce, zat\u00edmco samotn\u00e9 zpracov\u00e1n\u00ed obrazu prob\u00edhalo bu\u010f na b\u011b\u017en\u00e9m po\u010d\u00edta\u010di, nebo na v\u00fdkonn\u011bj\u0161\u00edch desk\u00e1ch (nap\u0159\u00edklad Raspberry Pi).<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h1 id=\"pochemu-eto-slozhno\">Pro\u010d je to slo\u017eit\u00e9?<\/h1>\n<p><\/p>\n<p>Popularita vyhled\u00e1vac\u00edch dotaz\u016f se vysv\u011btluje t\u00edm, \u017ee OpenCV je nejpopul\u00e1rn\u011bj\u0161\u00ed knihovna po\u010d\u00edta\u010dov\u00e9ho vid\u011bn\u00ed, co\u017e znamen\u00e1, \u017ee s n\u00ed je obezn\u00e1meno v\u00edce v\u00fdvoj\u00e1\u0159\u016f, a mo\u017enost spou\u0161t\u011bt k\u00f3d p\u0159ipraven\u00fd pro desktop na mikro\u0159adi\u010di zna\u010dn\u011b usnad\u0148uje proces v\u00fdvoje. Ale pro\u010d st\u00e1le neexistuj\u00ed n\u011bjak\u00e9 popul\u00e1rn\u00ed hotov\u00e9 recepty na \u0159e\u0161en\u00ed tohoto probl\u00e9mu?<\/p>\n<p><\/p>\n<p>Probl\u00e9m s pou\u017e\u00edv\u00e1n\u00edm OpenCV na mal\u00fdch desk\u00e1ch souvis\u00ed se dv\u011bma zvl\u00e1\u0161tnostmi:<\/p>\n<p><\/p>\n<ul>\n<li>Pokud zkompilujete knihovnu i s minim\u00e1ln\u00edm po\u010dtem modul\u016f, do flash pam\u011bti stejn\u00e9 STM32F7Discovery se jednodu\u0161e nevejde (i bez ohledu na OS) kv\u016fli velmi velk\u00e9mu k\u00f3du (n\u011bkolik megabajt\u016f instrukc\u00ed)<\/li>\n<li>Sama knihovna je napsan\u00e1 v jazyce C++, a to znamen\u00e1\n<ul>\n<li>Je pot\u0159eba podpora C++ runtime (v\u00fdjimky atd.)<\/li>\n<li>N\u00edzk\u00e1 podpora LibC\/Posix, kter\u00e1 je obvykle dostupn\u00e1 v OS pro vestav\u011bn\u00e9 syst\u00e9my \u2014 pot\u0159ebn\u00e1 je standardn\u00ed knihovna C++ a standardn\u00ed knihovna \u0161ablon STL (vector atd.)<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"portirovanie-na-embox\">Portov\u00e1n\u00ed na Embox<\/h1>\n<p><\/p>\n<p>Jak u\u017e to b\u00fdv\u00e1, p\u0159ed portov\u00e1n\u00edm jak\u00fdchkoli program\u016f do opera\u010dn\u00edho syst\u00e9mu je dobr\u00e9 zkusit ji sestavit ve form\u00e1tu, v jak\u00e9m to zam\u00fd\u0161leli v\u00fdvoj\u00e1\u0159i. V na\u0161em p\u0159\u00edpad\u011b s t\u00edm nen\u00ed probl\u00e9m \u2014 zdrojov\u00e9 k\u00f3dy lze naj\u00edt na <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/opencv\/opencv\">githubu<\/a><\/noindex>, knihovna se sestavuje pod GNU\/Linux pomoc\u00ed b\u011b\u017en\u00e9ho cmake.<\/p>\n<p><\/p>\n<p>Z dobr\u00fdch zpr\u00e1v \u2014 OpenCV lze z krabice sestavit jako statickou knihovnu, co\u017e usnad\u0148uje portov\u00e1n\u00ed. Sestav\u00edme knihovnu se standardn\u00edm nastaven\u00edm a zjist\u00edme, kolik m\u00edsta zab\u00edr\u00e1. Ka\u017ed\u00fd modul se sestavuje do samostatn\u00e9 knihovny.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">&gt; size lib\/*so --totals\n   text    data     bss     dec     hex filename\n1945822   15431     960 1962213  1df0e5 lib\/libopencv_calib3d.so\n17081885     170312   25640 17277837    107a38d lib\/libopencv_core.so\n10928229     137640   20192 11086061     a928ed lib\/libopencv_dnn.so\n 842311   25680    1968  869959   d4647 lib\/libopencv_features2d.so\n 423660    8552     184  432396   6990c lib\/libopencv_flann.so\n8034733   54872    1416 8091021  7b758d lib\/libopencv_gapi.so\n  90741    3452     304   94497   17121 lib\/libopencv_highgui.so\n6338414   53152     968 6392534  618ad6 lib\/libopencv_imgcodecs.so\n21323564     155912  652056 22131532    151b34c lib\/libopencv_imgproc.so\n 724323   12176     376  736875   b3e6b lib\/libopencv_ml.so\n 429036    6864     464  436364   6a88c lib\/libopencv_objdetect.so\n6866973   50176    1064 6918213  699045 lib\/libopencv_photo.so\n 698531   13640     160  712331   ade8b lib\/libopencv_stitching.so\n 466295    6688     168  473151   7383f lib\/libopencv_video.so\n 315858    6972   11576  334406   51a46 lib\/libopencv_videoio.so\n76510375     721519  717496 77949390    4a569ce (TOTALS)<\/code><\/pre>\n<p><\/p>\n<p>Jak je vid\u011bt z posledn\u00edho \u0159\u00e1dku, .bss a .data nezab\u00edraj\u00ed p\u0159\u00edli\u0161 mnoho m\u00edsta, ale k\u00f3d m\u00e1 v\u00edce ne\u017e 70 MiB. Je jasn\u00e9, \u017ee pokud to staticky prolinkujeme s konkr\u00e9tn\u00ed aplikac\u00ed, k\u00f3d se zmen\u0161\u00ed.<\/p>\n<p><\/p>\n<p>Zkus\u00edme vyhodit co nejv\u00edce modul\u016f, abychom vytvo\u0159ili minim\u00e1ln\u00ed p\u0159\u00edklad (k kter\u00fd nap\u0159\u00edklad jen zobraz\u00ed verzi OpenCV), tak\u017ee se d\u00edv\u00e1me <code>cmake .. -LA<\/code> a vypneme v mo\u017enostech v\u0161echno, co lze vypnout.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">        -DBUILD_opencv_java_bindings_generator=OFF \n        -DBUILD_opencv_stitching=OFF \n        -DWITH_PROTOBUF=OFF \n        -DWITH_PTHREADS_PF=OFF \n        -DWITH_QUIRC=OFF \n        -DWITH_TIFF=OFF \n        -DWITH_V4L=OFF \n        -DWITH_VTK=OFF \n        -DWITH_WEBP=OFF<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"plaintext\">&gt; size lib\/libopencv_core.a --totals\n   text    data     bss     dec     hex filename\n3317069   36425   17987 3371481  3371d9 (TOTALS)<\/code><\/pre>\n<p><\/p>\n<p>Na jedn\u00e9 stran\u011b, je to pouze jeden modul knihovny, na druh\u00e9 stran\u011b, to je bez optimalizace kompil\u00e1torem na velikost k\u00f3du (<code>-Os<\/code>). ~3 MiB k\u00f3du \u2014 to je st\u00e1le dost, ale u\u017e to d\u00e1v\u00e1 nad\u011bji na \u00fasp\u011bch.<\/p>\n<p><\/p>\n<h2 id=\"zapusk-v-emulyatore\">Spu\u0161t\u011bn\u00ed v emul\u00e1toru<\/h2>\n<p><\/p>\n<p>Na emul\u00e1toru se debuguje mnohem snadn\u011bji, proto se nejprve ujist\u00edme, \u017ee knihovna funguje na qemu. Jako emulovanou platformu jsem vybral Integrator\/CP, proto\u017ee to je tak\u00e9 ARM a Embox podporuje grafick\u00fd v\u00fdstup pro tuto platformu.<\/p>\n<p><\/p>\n<p>V Emboxu je mechanismus pro sestaven\u00ed extern\u00edch knihoven, pomoc\u00ed n\u011bj p\u0159id\u00e1v\u00e1me OpenCV jako modul (p\u0159i\u010dem\u017e v\u0161echny stejn\u00e9 mo\u017enosti pro &#171;minim\u00e1ln\u00ed&#187; sestaven\u00ed ve form\u011b statick\u00fdch knihoven), pot\u00e9 p\u0159id\u00e1v\u00e1m nejjednodu\u0161\u0161\u00ed aplikaci, kter\u00e1 vypad\u00e1 takto:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">version.cpp:\n\n#include \n#include \n\nint main() {\n    printf(\"OpenCV: %s\", cv::getBuildInformation().c_str());\n\n    return 0;\n}<\/code><\/pre>\n<p><\/p>\n<p>Sestav\u00edme syst\u00e9m, spust\u00edme \u2014 z\u00edsk\u00e1me o\u010dek\u00e1van\u00fd v\u00fdstup.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">root@embox: \/#opencv_version                                                     \nOpenCV: \nObecn\u00e1 konfigurace pro OpenCV 4.0.1 =====================================\n  Kontrola verze:               bd6927bdf-dirty\n\n  Platforma:\n    \u010casov\u00e1 zna\u010dka:               2019-06-21T10:02:18Z\n    Hostitel:                    Linux 5.1.7-arch1-1-ARCH x86_64\n    C\u00edl:                        Obecn\u00e9 arm-unknown-none\n    CMake:                       3.14.5\n    Gener\u00e1tor CMake:             Unix Makefiles\n    N\u00e1stroj pro sestaven\u00ed CMake: \n    \/usr\/bin\/make\n    Konfigurace:                 Debug\n\n  CPU\/HW funkce:\n    Z\u00e1klad:\n      po\u017eadov\u00e1no:                 DETEKOVAT\n      zak\u00e1z\u00e1no:                  VFPV3 NEON\n\n  C\/C++:\n    Sestaveno jako dynamick\u00e9 knihovny?:      NE<\/code><\/pre>\n<p><\/p>\n<p>Dal\u0161\u00ed krok \u2013 spustit n\u011bjak\u00fd p\u0159\u00edklad, nejlep\u0161\u00ed je pou\u017e\u00edt n\u011bjak\u00fd standardn\u00ed, kter\u00fd nab\u00edzej\u00ed sami v\u00fdvoj\u00e1\u0159i <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.opencv.org\/4.1.0\/examples.html\">na sv\u00fdch str\u00e1nk\u00e1ch<\/a><\/noindex>. Vybral jsem si <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.opencv.org\/4.1.0\/d6\/d56\/samples_2cpp_2edge_8cpp-example.html\">detektor hranic Canny<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>P\u0159\u00edklad jsem musel trochu p\u0159epracovat, aby se obr\u00e1zek s v\u00fdsledkem zobrazil p\u0159\u00edmo ve framebufferu. Bylo to nutn\u00e9, proto\u017ee funkce <code>imshow()<\/code> um\u00ed vykreslovat obr\u00e1zky prost\u0159ednictv\u00edm rozhran\u00ed QT, GTK a Windows, kter\u00e9 v konfiguraci pro STM32 samoz\u0159ejm\u011b nebudou. Ve skute\u010dnosti lze QT tak\u00e9 spustit na STM32F7Discovery, ale o tom bude \u0159e\u010d v jin\u00e9m \u010dl\u00e1nku \ud83d\ude42<\/p>\n<p><\/p>\n<p>Po kr\u00e1tk\u00e9m vyjasn\u011bn\u00ed, v jak\u00e9m form\u00e1tu se ukl\u00e1d\u00e1 v\u00fdstup z detektoru hranic, z\u00edsk\u00e1v\u00e1me obr\u00e1zek.<\/p>\n<p>\n<img decoding=\"async\" alt=\"OpenCV na STM32F7-Discovery\" src=\"\/wp-content\/uploads\/2019\/09\/127f90ad8008340d73feb6ece02e52b2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Origin\u00e1ln\u00ed obr\u00e1zek<\/p>\n<p>\n<img decoding=\"async\" alt=\"OpenCV na STM32F7-Discovery\" src=\"\/wp-content\/uploads\/2019\/09\/da34b3ac2561ae9f223acc5c4fe2a597.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><em>V\u00fdsledek<\/em><\/p>\n<p><\/p>\n<h2 id=\"zapusk-na-stm32f7discovery\">Spu\u0161t\u011bn\u00ed na STM32F7Discovery<\/h2>\n<p><\/p>\n<p>Na 32F746GDISCOVERY je n\u011bkolik blok\u016f pam\u011bti, kter\u00e9 m\u016f\u017eeme r\u016fzn\u00fdmi zp\u016fsoby pou\u017e\u00edt<\/p>\n<p><\/p>\n<ol>\n<li>320KiB opera\u010dn\u00ed pam\u011bti<\/li>\n<li>1MiB flash pam\u011bti pro obraz<\/li>\n<li>8MiB SDRAM<\/li>\n<li>16MiB QSPI NAND-flash<\/li>\n<li>Konektor pro microSD kartu<\/li>\n<\/ol>\n<p><\/p>\n<p>SD kartu lze pou\u017e\u00edt pro ukl\u00e1d\u00e1n\u00ed obr\u00e1zk\u016f, ale v kontextu spou\u0161t\u011bn\u00ed minim\u00e1ln\u00edho p\u0159\u00edkladu to nen\u00ed p\u0159\u00edli\u0161 u\u017eite\u010dn\u00e9.<br \/>\nDisplej m\u00e1 rozli\u0161en\u00ed 480&#215;272, co\u017e znamen\u00e1, \u017ee pam\u011b\u0165 pro frame buffer bude \u010dinit 522 240 bajt\u016f p\u0159i hloubce 32 bit\u016f, tj. je to v\u00edce ne\u017e velikost RAM, tak\u017ee frame buffer a halda (kter\u00e1 bude pot\u0159eba tak\u00e9 pro OpenCV k uchov\u00e1n\u00ed dat pro obr\u00e1zky a pomocn\u00e9 struktury) budou um\u00edst\u011bny v SDRAM, v\u0161e ostatn\u00ed (pam\u011b\u0165 pro z\u00e1sobn\u00edky a dal\u0161\u00ed syst\u00e9mov\u00e9 pot\u0159eby) p\u016fjde do RAM.<\/p>\n<p><\/p>\n<p>Pokud vezmeme minim\u00e1ln\u00ed konfiguraci pro STM32F7Discovery (vyhod\u00edme celou s\u00ed\u0165, v\u0161echny p\u0159\u00edkazy, ud\u011bl\u00e1me z\u00e1sobn\u00edky co nejmen\u0161\u00ed atd.) a p\u0159id\u00e1me k tomu OpenCV s p\u0159\u00edklady, s po\u017eadovanou pam\u011bt\u00ed to bude vypadat takto:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">   text    data     bss     dec     hex filename\n2876890  459208  312736 3648834  37ad42 build\/base\/bin\/embox<\/code><\/pre>\n<p><\/p>\n<p>Pro ty, kdo nejsou p\u0159\u00edli\u0161 obezn\u00e1meni s t\u00edm, jak\u00e9 sekce kam pat\u0159\u00ed, vysv\u011btl\u00edm: v <code>.text<\/code> a <code>.rodata<\/code> jsou ulo\u017eeny instrukce a konstanty (zjednodu\u0161en\u011b \u0159e\u010deno, readonly data), v <code>.data<\/code> jsou ulo\u017eena m\u011bniteln\u00e1 data, v <code>.bss<\/code> le\u017e\u00ed &#171;nulovan\u00e9&#187; prom\u011bnn\u00e9, kter\u00e9 p\u0159esto pot\u0159ebuj\u00ed m\u00edsto (tato sekce &#171;p\u016fjde&#187; do RAM).<\/p>\n<p><\/p>\n<p>Dobrou zpr\u00e1vou je, \u017ee <code>.data<\/code>\/<code>.bss<\/code> by m\u011bly b\u00fdt um\u00edst\u011bny, ale probl\u00e9m je s <code>.text<\/code> bohu\u017eel \u2014 pro obraz je k dispozici pouze 1MiB pam\u011bti. M\u016f\u017eeme sice vyhodit obr\u00e1zek z p\u0159\u00edkladu a \u010d\u00edst ho nap\u0159\u00edklad z SD karty do pam\u011bti p\u0159i spu\u0161t\u011bn\u00ed, ale fruits.png v\u00e1\u017e\u00ed p\u0159ibli\u017en\u011b 330KiB, tak\u017ee tento probl\u00e9m to nevy\u0159e\u0161\u00ed: v\u011bt\u0161ina <code>.text<\/code> se skl\u00e1d\u00e1 pr\u00e1v\u011b z k\u00f3du OpenCV. <code>.text<\/code> Z \u010dist\u011b technick\u00e9ho hlediska z\u016fst\u00e1v\u00e1 jen jedno \u2014 na\u010d\u00edst \u010d\u00e1st k\u00f3du na QSPI-flash (m\u00e1 speci\u00e1ln\u00ed re\u017eim pro mapov\u00e1n\u00ed pam\u011bti na syst\u00e9movou sb\u011brnici, tak\u017ee procesor k t\u011bmto dat\u016fm m\u016f\u017ee p\u0159istupovat p\u0159\u00edmo). P\u0159i tom nast\u00e1v\u00e1 probl\u00e9m: zaprv\u00e9, pam\u011b\u0165 QSPI-flash nen\u00ed dostupn\u00e1 ihned po restartov\u00e1n\u00ed za\u0159\u00edzen\u00ed (je t\u0159eba zvl\u00e1\u0161\u0165 inicializovat re\u017eim memory-mapped), a zadruh\u00e9, tuto pam\u011b\u0165 nelze \u201enahr\u00e1t\u201c obvykl\u00fdm bootloaderem.<\/p>\n<p><\/p>\n<p>V z\u00e1sad\u011b zb\u00fdv\u00e1 jen jedno \u2014 nahr\u00e1n\u00ed \u010d\u00e1sti k\u00f3du do QSPI-flash pam\u011bti (m\u00e1 speci\u00e1ln\u00ed re\u017eim provozu pro mapov\u00e1n\u00ed pam\u011bti na syst\u00e9movou sb\u011brnici, tak\u017ee procesor se k t\u011bmto dat\u016fm m\u016f\u017ee p\u0159istupovat p\u0159\u00edmo). P\u0159i tom vznik\u00e1 probl\u00e9m: za prv\u00e9, pam\u011b\u0165 QSPI-flash nen\u00ed dostupn\u00e1 hned po restartu za\u0159\u00edzen\u00ed (je nutn\u00e9 samostatn\u011b inicializovat memory-mapped re\u017eim), za druh\u00e9, nen\u00ed mo\u017en\u00e9 &#171;nahr\u00e1t&#187; tuto pam\u011b\u0165 obvykl\u00fdm bootloaderem.<\/p>\n<p><\/p>\n<p>N\u00e1pad portovat tuto knihovnu na Embox se objevil p\u0159ibli\u017en\u011b p\u0159ed rokem, ale opakovan\u011b byl odkl\u00e1d\u00e1n z r\u016fzn\u00fdch d\u016fvod\u016f. Jedn\u00edm z nich je podpora libstdc++ a standardn\u00ed \u0161ablonov\u00e9 knihovny. Probl\u00e9m s podporou C++ v Embox p\u0159esahuje r\u00e1mec tohoto \u010dl\u00e1nku, proto zde jen pov\u00edm, \u017ee se n\u00e1m poda\u0159ilo dos\u00e1hnout t\u00e9to podpory v pot\u0159ebn\u00e9m rozsahu pro fungov\u00e1n\u00ed t\u00e9to knihovny \ud83d\ude42<\/p>\n<p><\/p>\n<h1 id=\"rezultat\">V\u00fdsledek<\/h1>\n<p><\/p>\n<p>Nakonec byly tyto probl\u00e9my p\u0159ekon\u00e1ny (alespo\u0148 v dostate\u010dn\u00e9 m\u00ed\u0159e pro fungov\u00e1n\u00ed p\u0159\u00edkladu OpenCV) a p\u0159\u00edklad byl spu\u0161t\u011bn. 40 dlouh\u00fdch sekund trv\u00e1 desce nalezen\u00ed hranic pomoc\u00ed Cannyho filtru. To je samoz\u0159ejm\u011b p\u0159\u00edli\u0161 dlouho (existuj\u00ed \u00favahy o tom, jak by se to dalo optimalizovat, o tom bychom mohli napsat samostatn\u00fd \u010dl\u00e1nek v p\u0159\u00edpad\u011b \u00fasp\u011bchu).<\/p>\n<p><\/p>\n<p>Nicm\u00e9n\u011b mezit\u00edm bylo c\u00edlem vytvo\u0159en\u00ed prototypu, kter\u00fd prok\u00e1\u017ee principieln\u00ed mo\u017enost spu\u0161t\u011bn\u00ed OpenCV na STM32, a tedy tento c\u00edl byl spln\u011bn, hur\u00e1! <\/p>\n<p>\n<img decoding=\"async\" alt=\"OpenCV na STM32F7-Discovery\" src=\"\/wp-content\/uploads\/2019\/09\/a400c72865ec17094efc985908914463.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>tl;dr: podrobn\u00fd n\u00e1vod<\/p>\n<h4 id=\"tldr-poshagovaya-instrukciya\">0: St\u00e1hn\u011bte si zdrojov\u00e9 k\u00f3dy Embox, nap\u0159\u00edklad takto:<\/h4>\n<p><\/p>\n<p>git clone https:\/\/github.com\/embox\/embox &amp;&amp; cd .\/embox<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    1: Za\u010dneme se sestaven\u00edm bootloaderu, kter\u00fd \"nahr\u00e1v\u00e1\" QSPI-flash.<\/code><\/pre>\n<p><\/p>\n<p>1: Za\u010dneme se sestaven\u00edm bootloaderu, kter\u00fd &#171;nahraje&#187; QSPI-flash.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    vytvo\u0159it confload-arm\/stm32f7cube<\/code><\/pre>\n<p><\/p>\n<p>Nyn\u00ed je t\u0159eba nastavit s\u00ed\u0165, proto\u017ee obraz budeme na\u010d\u00edtat p\u0159es TFTP. Abyste nastavili IP adresy pro desku a hostitele, mus\u00edte upravit soubor conf\/rootfs\/network.<\/p>\n<p><\/p>\n<p>P\u0159\u00edklad konfigurace:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">iface eth0 inet static\n    address 192.168.2.2\n    netmask 255.255.255.0\n    gateway 192.168.2.1\n    hwaddress aa:bb:cc:dd:ee:02<\/code><\/pre>\n<p><\/p>\n<p><code>gateway<\/code> \u2014 adresa hostitele, ze kter\u00e9 bude obraz na\u010d\u00edt\u00e1n, <code>address<\/code> \u2014 adresa desky.<\/p>\n<p><\/p>\n<p>Pot\u00e9 sestav\u00edme bootloader:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    make<\/code><\/pre>\n<p><\/p>\n<p>2: B\u011b\u017en\u00e9 na\u010dten\u00ed bootloaderu (omlouv\u00e1me se za h\u0159\u00ed\u010dku) na desku \u2014 zde nen\u00ed nic specifick\u00e9ho, je to t\u0159eba prov\u00e9st jako u jak\u00e9koli jin\u00e9 aplikace pro STM32F7Discovery. Pokud nev\u00edte, jak na to, m\u016f\u017eete si o tom p\u0159e\u010d\u00edst. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/embox\/blog\/349034\/\">tady<\/a><\/noindex>.<br \/>\n3: Kompilace obrazu s konfigurac\u00ed pro OpenCV.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    make confload-platform\/opencv\/stm32f7discovery\n    make<\/code><\/pre>\n<p><\/p>\n<p>4: Extrakce z ELF sekc\u00ed, kter\u00e9 je t\u0159eba zapisovat do QSPI, do souboru qspi.bin<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    arm-none-eabi-objcopy -O binary build\/base\/bin\/embox build\/base\/bin\/qspi.bin \n        --only-section=.text --only-section=.rodata \n        --only-section='.ARM.ex*' \n        --only-section=.data<\/code><\/pre>\n<p><\/p>\n<p>Ve slo\u017ece conf se nach\u00e1z\u00ed skript, kter\u00fd to provedete, tak\u017ee jej m\u016f\u017eete spustit.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    .\/conf\/qspi_objcopy.sh # Po\u017eadovan\u00fd bin\u00e1rn\u00ed soubor -- build\/base\/bin\/qspi.bin<\/code><\/pre>\n<p><\/p>\n<p>5: Pomoc\u00ed tftp na\u010dt\u011bte qspi.bin na QSPI flash pam\u011b\u0165. Na hostiteli je t\u0159eba zkop\u00edrovat qspi.bin do ko\u0159enov\u00e9ho adres\u00e1\u0159e TFTP serveru (obvykle je to \/srv\/tftp\/ nebo \/var\/lib\/tftpboot\/; bal\u00ed\u010dky pro odpov\u00eddaj\u00edc\u00ed server jsou dostupn\u00e9 v v\u011bt\u0161in\u011b popul\u00e1rn\u00edch distribuc\u00ed, obvykle se naz\u00fdv\u00e1 tftpd nebo tftp-hpa, n\u011bkdy je t\u0159eba prov\u00e9st <code>systemctl start tftpd.service<\/code> pro zah\u00e1jen\u00ed).<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    # \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0434\u043b\u044f tftpd\n    sudo cp build\/base\/bin\/qspi.bin \/srv\/tftp\n    # \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0434\u043b\u044f tftp-hpa\n    sudo cp build\/base\/bin\/qspi.bin \/var\/lib\/tftpboot<\/code><\/pre>\n<p><\/p>\n<p>Na Emboxu (tj. v bootloaderu) je t\u0159eba prov\u00e9st n\u00e1sleduj\u00edc\u00ed p\u0159\u00edkaz (p\u0159edpokl\u00e1d\u00e1me, \u017ee adresa serveru je 192.168.2.1):<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    embox&gt; qspi_loader qspi.bin 192.168.2.1<\/code><\/pre>\n<p><\/p>\n<p>6: Pomoc\u00ed p\u0159\u00edkazu <code>goto<\/code> mus\u00edme &#171;skokovat&#187; do QSPI-pam\u011bti. Konkr\u00e9tn\u00ed adresa se bude li\u0161it v z\u00e1vislosti na tom, jak je obraz zlinkov\u00e1n, tuto adresu lze zjistit p\u0159\u00edkazem <code>mem 0x90000000<\/code> (adresa startu je ulo\u017eena ve druh\u00e9m 32-bitov\u00e9m slov\u011b obrazu); tak\u00e9 bude t\u0159eba nastavit z\u00e1sobn\u00edk flagem <code>-s<\/code>, adresa z\u00e1sobn\u00edku je na adrese 0x90000000, p\u0159\u00edklad:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    embox&gt;mem 0x90000000\n    0x90000000:     0x20023200  0x9000c27f  0x9000c275  0x9000c275\n                      \u2191           \u2191\n              to je adresa    to je  adresa \n                z\u00e1sobn\u00edku    prvn\u00ed\n                           instrukce\n\n    embox&gt;goto -i 0x9000c27f -s 0x20023200 # Flag -i pot\u0159ebn\u00fd k tomu, aby se b\u011bhem inicializace syst\u00e9mu zak\u00e1zala p\u0159eru\u0161en\u00ed<\/code><\/pre>\n<p><\/p>\n<p>7: Spust\u00edme<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    embox&gt; edges 20<\/code><\/pre>\n<p><\/p>\n<p>a u\u017e\u00edv\u00e1me si 40 sekund vyhled\u00e1v\u00e1n\u00ed hran \ud83d\ude42<\/p>\n<p><\/p>\n<p>Pokud n\u011bco neprob\u011bhne spr\u00e1vn\u011b \u2014 napi\u0161te probl\u00e9m do <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/embox\/embox\">na\u0161eho repozit\u00e1\u0159e<\/a><\/noindex>, nebo na mailing list embox-devel@googlegroups.com, nebo sem do koment\u00e1\u0159\u016f.<\/p>\n<p>Zdroj: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/embox\/blog\/457724\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u042f \u043e\u0434\u0438\u043d \u0438\u0437 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b Embox, \u0438 \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043f\u0440\u043e \u0442\u043e, \u043a\u0430\u043a \u0443 \u043c\u0435\u043d\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c OpenCV \u043d\u0430 \u043f\u043b\u0430\u0442\u0435 STM32746G. \u0415\u0441\u043b\u0438 \u0432\u0431\u0438\u0442\u044c \u0432 \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u0438\u043a \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 &#171;OpenCV on STM32 board&#187;, \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u0442\u0435\u0445, \u043a\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u044d\u0442\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043d\u0430 \u043f\u043b\u0430\u0442\u0430\u0445 STM32 \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430\u0445. \u0415\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0438\u0434\u0435\u043e, \u043a\u043e\u0442\u043e\u0440\u044b\u0435, \u0441\u0443\u0434\u044f [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":28450,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-37914","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u042f \u043e\u0434\u0438\u043d \u0438\u0437 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/opencv-na-stm32f7-discovery\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"cs_CZ\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47OpenCV \u043d\u0430 STM32F7-Discovery | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u042f \u043e\u0434\u0438\u043d \u0438\u0437 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/opencv-na-stm32f7-discovery\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:20:31+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:20:31+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47OpenCV na STM32F7-Discovery | ProHoster","description":"Jsem jedn\u00edm z v\u00fdvoj\u00e1\u0159\u016f opera\u010dn\u00edho syst\u00e9mu","canonical_url":"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/opencv-na-stm32f7-discovery","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"cs_CZ","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47OpenCV \u043d\u0430 STM32F7-Discovery | ProHoster","og:description":"\u042f \u043e\u0434\u0438\u043d \u0438\u0437 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b","og:url":"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/opencv-na-stm32f7-discovery","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:20:31+00:00","article:modified_time":"2019-10-31T19:20:31+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"37914","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-23 19:45:21","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:18:22","updated":"2026-01-23 19:45:21","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts\/37914","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/comments?post=37914"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts\/37914\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/media\/28450"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/media?parent=37914"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/categories?post=37914"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/tags?post=37914"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}