{"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\/ro\/blog\/administrirovanie\/opencv-na-stm32f7-discovery","title":{"rendered":"OpenCV pe STM32F7-Discovery","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"OpenCV pe STM32F7-Discovery\" src=\"\/wp-content\/uploads\/2019\/09\/a2248ee685ee210ce8f7781435dd1d5a.jpg\" style=\"display:block;margin: 0 auto;\" \/> Sunt unul dintre dezvoltatorii sistemului de operare <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/embox\/embox\">Embox<\/a><\/noindex>, iar \u00een acest articol v\u0103 voi povesti despre cum am reu\u0219it s\u0103 lansez OpenCV pe placa STM32746G.<\/p>\n<p><\/p>\n<p>Dac\u0103 cau\u021bi ceva de genul \u201eOpenCV pe placa STM32\u201d \u00een motorul de c\u0103utare, po\u021bi g\u0103si destul de mul\u021bi care sunt interesa\u021bi de utilizarea acestei biblioteci pe pl\u0103ci STM32 sau alte microcontrolere.<br \/>\nExist\u0103 c\u00e2teva videoclipuri care, judec\u00e2nd dup\u0103 titlu, ar trebui s\u0103 demonstreze ceea ce este necesar, dar de obicei (\u00een toate videoclipurile pe care le-am v\u0103zut) pe placa STM32 s-a realizat doar captarea imaginii de la camer\u0103 \u0219i afi\u0219area rezultatului pe ecran, iar procesarea imaginii a fost realizat\u0103 fie pe un computer obi\u0219nuit, fie pe pl\u0103ci mai puternice (de exemplu, Raspberry Pi).<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h1 id=\"pochemu-eto-slozhno\">De ce este complicat?<\/h1>\n<p><\/p>\n<p>Popularitatea c\u0103ut\u0103rilor este explicat\u0103 prin faptul c\u0103 OpenCV este cea mai popular\u0103 bibliotec\u0103 de viziune computerizat\u0103, ceea ce \u00eenseamn\u0103 c\u0103 mai mul\u021bi dezvoltatori sunt familiariza\u021bi cu aceasta, iar posibilitatea de a rula codul preg\u0103tit pentru desktop pe un microcontroler simplific\u0103 semnificativ procesul de dezvoltare. Dar de ce nu exist\u0103 p\u00e2n\u0103 acum re\u021bete populare gata pentru a rezolva aceast\u0103 problem\u0103?<\/p>\n<p><\/p>\n<p>Problema utiliz\u0103rii OpenCV pe pl\u0103ci mici este legat\u0103 de dou\u0103 caracteristici:<\/p>\n<p><\/p>\n<ul>\n<li>Dac\u0103 se compileaz\u0103 biblioteca chiar \u0219i cu un set minim de module, \u00een memoria flash a aceea\u0219i STM32F7Discovery pur \u0219i simplu nu va \u00eenc\u0103pea (chiar f\u0103r\u0103 a lua \u00een considerare OS-ul) din cauza codului foarte mare (c\u00e2teva megabyte de instruc\u021biuni)<\/li>\n<li>\u00censu\u0219i biblioteca este scris\u0103 \u00een C++, ceea ce \u00eenseamn\u0103\n<ul>\n<li>Este necesar\u0103 suportul runtime pentru C++ (excep\u021bii \u0219i altele).<\/li>\n<li>Este pu\u021bin suport pentru LibC\/Posix, care sunt de obicei disponibile \u00een sistemele de operare pentru sisteme \u00eencorporate \u2014 este nevoie de o bibliotec\u0103 standard pentru C++ \u0219i o bibliotec\u0103 standard de \u0219abloane STL (vector etc.).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"portirovanie-na-embox\">Portarea pe Embox<\/h1>\n<p><\/p>\n<p>A\u0219a cum se \u00eent\u00e2mpl\u0103 de obicei, \u00eenainte de a porta orice program \u00een sistemul de operare, este bine s\u0103 \u00eencerca\u021bi s\u0103-l construi\u021bi \u00een forma \u00een care l-au g\u00e2ndit dezvoltatorii. \u00cen cazul nostru, nu sunt probleme cu acest lucru \u2014 sursele pot fi g\u0103site pe <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/opencv\/opencv\">GitHub<\/a><\/noindex>, biblioteca se compileaz\u0103 pe GNU\/Linux cu un cmake obi\u0219nuit.<\/p>\n<p><\/p>\n<p>Din ve\u0219tile bune \u2014 OpenCV poate fi compilat direct ca o bibliotec\u0103 static\u0103, ceea ce face portarea mai u\u0219oar\u0103. Compil\u0103m biblioteca cu configura\u021bia standard \u0219i vedem c\u00e2t spa\u021biu ocup\u0103. Fiecare modul este compilat \u00eentr-o bibliotec\u0103 separat\u0103.<\/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>Dup\u0103 cum se poate observa din ultima linie, .bss \u0219i .data nu ocup\u0103 mult spa\u021biu, dar codul este de peste 70 MiB. Este clar c\u0103, dac\u0103 se leag\u0103 static cu o aplica\u021bie specific\u0103, dimensiunea codului va sc\u0103dea.<\/p>\n<p><\/p>\n<p>S\u0103 \u00eencerc\u0103m s\u0103 elimin\u0103m c\u00e2t mai multe module, pentru a crea un exemplu minim (care, de exemplu, va afi\u0219a versiunea OpenCV), a\u0219a c\u0103 ne uit\u0103m <code>cmake .. -LA<\/code> \u0219i dezactiv\u0103m \u00een op\u021biuni tot ce poate fi dezactivat.<\/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>Pe de o parte, acesta este doar un modul al bibliotecii, pe de alt\u0103 parte, acest lucru este f\u0103r\u0103 optimizarea compilatorului pentru dimensiunea codului (<code>-Os<\/code>). ~3 MiB de cod \u2014 totu\u0219i este \u00eenc\u0103 mult, dar ofer\u0103 deja speran\u021ba succesului.<\/p>\n<p><\/p>\n<h2 id=\"zapusk-v-emulyatore\">Ruleaz\u0103 \u00een emulator<\/h2>\n<p><\/p>\n<p>Debugging-ul pe emulator este mult mai u\u0219or, a\u0219a c\u0103 \u00eent\u00e2i ne asigur\u0103m c\u0103 biblioteca func\u021bioneaz\u0103 pe qemu. Ca platform\u0103 emulat\u0103 am ales Integrator\/CP deoarece, pe de o parte, este tot ARM, iar pe de alt\u0103 parte, Embox suport\u0103 ie\u0219irea grafic\u0103 pentru aceast\u0103 platform\u0103.<\/p>\n<p><\/p>\n<p>Embox are un mecanism pentru compilarea bibliotecilor externe; folosindu-l, ad\u0103ug\u0103m OpenCV ca modul (transmi\u021b\u00e2nd acelea\u0219i op\u021biuni pentru compilarea \u201eminim\u0103\u201d sub form\u0103 de biblioteci statice), dup\u0103 care adaug un aplica\u021bie simpl\u0103 care arat\u0103 astfel:<\/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>Construim sistemul, \u00eel lans\u0103m \u2014 \u0219i ob\u021binem rezultatul a\u0219teptat.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">root@embox:\\\/ #opencv_version \nOpenCV: \nConfigurarea general\u0103 pentru OpenCV 4.0.1 =====================================\n  Controlul versiunii:               bd6927bdf-dirty\n\n  Platform\u0103:\n    Data \u0219i ora:                   2019-06-21T10:02:18Z\n    Gazd\u0103:                        Linux 5.1.7-arch1-1-ARCH x86_64\n    \u021aint\u0103:                      Generic arm-unknown-none\n    CMake:                       3.14.5\n    Generator CMake:             Unix Makefiles\n    Unelte de construire CMake:            \\\/usr\\\/bin\\\/make\n    Configurare:               Debug\n\n  Func\u021bii CPU\\\/HW:\n    Baz\u0103:\n      cerut:                 DETECT\n      dezactivat:                  VFPV3 NEON\n\n  C\\\/C++:\n    Compilat ca biblioteci dinamice?:      NU<\/code><\/pre>\n<p><\/p>\n<p>Urm\u0103torul pas este s\u0103 rul\u0103m un exemplu, cel mai bine un standard oferit de dezvoltatori <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.opencv.org\/4.1.0\/examples.html\">pe site-ul lor<\/a><\/noindex>. Am ales <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.opencv.org\/4.1.0\/d6\/d56\/samples_2cpp_2edge_8cpp-example.html\">detectorul de margini Canny<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Exemplul a trebuit s\u0103 fie rescris u\u0219or, pentru a afi\u0219a imaginea cu rezultatul direct \u00een buffer-ul de cadru. A fost necesar s\u0103 facem acest lucru, deoarece func\u021bia <code>imshow()<\/code> poate reda imagini prin interfe\u021bele QT, GTK \u0219i Windows, care, desigur, nu vor fi disponibile \u00een configura\u021bia pentru STM32. De fapt, QT poate fi rulat \u0219i pe STM32F7Discovery, dar despre asta vom vorbi \u00eentr-un articol viitor \ud83d\ude42<\/p>\n<p><\/p>\n<p>Dup\u0103 o scurt\u0103 clarificare a formatului \u00een care este stocat rezultatul detectorului de margini, ob\u021binem imaginea.<\/p>\n<p>\n<img decoding=\"async\" alt=\"OpenCV pe STM32F7-Discovery\" src=\"\/wp-content\/uploads\/2019\/09\/127f90ad8008340d73feb6ece02e52b2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Imaginea original\u0103<\/p>\n<p>\n<img decoding=\"async\" alt=\"OpenCV pe STM32F7-Discovery\" src=\"\/wp-content\/uploads\/2019\/09\/da34b3ac2561ae9f223acc5c4fe2a597.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><em>Rezultatul<\/em><\/p>\n<p><\/p>\n<h2 id=\"zapusk-na-stm32f7discovery\">Rularea pe STM32F7Discovery<\/h2>\n<p><\/p>\n<p>Pe 32F746GDISCOVERY exist\u0103 mai multe sec\u021biuni de memorie hardware, pe care le putem utiliza \u00een diverse moduri<\/p>\n<p><\/p>\n<ol>\n<li>320KiB de memorie RAM<\/li>\n<li>1MiB de memorie flash pentru imagine<\/li>\n<li>8MiB SDRAM<\/li>\n<li>16MiB de NAND flash QSPI<\/li>\n<li>Slot pentru card microSD<\/li>\n<\/ol>\n<p><\/p>\n<p>Cardul SD poate fi utilizat pentru stocarea imaginilor, dar \u00een contextul rul\u0103rii unui exemplu minim nu este foarte util.<br \/>\nEcranul are o rezolu\u021bie de 480\u00d7272, ceea ce \u00eenseamn\u0103 c\u0103 memoria pentru frame buffer va fi de 522240 bytes la o ad\u00e2ncime de 32 de bi\u021bi, adic\u0103 este mai mult dec\u00e2t dimensiunea memoriei RAM, astfel \u00eenc\u00e2t frame buffer-ul \u0219i heap-ul (care va fi necesar, inclusiv pentru OpenCV, pentru a stoca datele imaginilor \u0219i structurile auxiliare) vor fi plasate \u00een SDRAM, restul (memoria pentru stive \u0219i alte nevoi sistemice) va fi trimis \u00een RAM.<\/p>\n<p><\/p>\n<p>Dac\u0103 lu\u0103m configura\u021bia minim\u0103 pentru STM32F7Discovery (elimin\u00e2nd \u00eentreaga re\u021bea, toate comenzile, f\u0103c\u00e2nd stivele c\u00e2t mai mici \u0219i alte ajust\u0103ri) \u0219i ad\u0103ug\u0103m OpenCV cu exemple, cerin\u021bele de memorie vor fi urm\u0103toarele:<\/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>Pentru cei care nu sunt foarte familiariza\u021bi cu sec\u021biunile \u00een care se \u00eencadreaz\u0103, voi explica: \u00een <code>.text<\/code> \u0219i <code>.rodata<\/code> se afl\u0103 instruc\u021biunile \u0219i constantele (\u00een termeni simplifica\u021bi, datele readonly), \u00een <code>.data<\/code> se afl\u0103 datele care pot fi modificate, \u00een <code>.bss<\/code> exist\u0103 \u201evariabile anulate\u201d care, totu\u0219i, au nevoie de spa\u021biu (aceast\u0103 sec\u021biune va fi trimis\u0103 \u00een RAM).<\/p>\n<p><\/p>\n<p>Vestea bun\u0103 este c\u0103 <code>.data<\/code>\/<code>.bss<\/code> trebuie s\u0103 se \u00eencadreze, dar cu <code>.text<\/code> problema este c\u0103 sub imagine exist\u0103 doar 1MiB de memorie. Poate fi eliminat\u0103 imaginea din exemplu \u0219i citit\u0103, de exemplu, de pe un card SD \u00een memorie la pornire, dar fruits.png c\u00e2nt\u0103re\u0219te aproximativ 330KiB, a\u0219a c\u0103 aceast\u0103 problem\u0103 nu se rezolv\u0103: cea mai mare parte <code>.text<\/code> const\u0103 chiar \u00een codul OpenCV. <code>.text<\/code> \u00cen esen\u021b\u0103, r\u0103m\u00e2ne o singur\u0103 solu\u021bie - \u00eenc\u0103rcarea unei p\u0103r\u021bi din cod pe un chip QSPI (acesta are un mod special de operare pentru maparea memoriei pe busul de sistem, astfel \u00eenc\u00e2t procesorul s\u0103 poat\u0103 accesa aceste date direct). Totu\u0219i, apare o problem\u0103: pe de o parte, memoria chipului QSPI nu este accesibil\u0103 imediat dup\u0103 repornirea dispozitivului (trebuie s\u0103 ini\u021bializ\u0103m separat modul_memory-mapped), pe de alt\u0103 parte, nu se poate \u201eprograma\u201d aceast\u0103 memorie cu un bootloader obi\u0219nuit.<\/p>\n<p><\/p>\n<p>\u00cen esen\u021b\u0103, r\u0103m\u00e2ne un singur lucru \u2014 \u00eenc\u0103rcarea unei p\u0103r\u021bi din cod pe memoria flash QSPI (aceasta are un mod special de operare pentru maparea memoriei pe magistrala sistemului, astfel \u00eenc\u00e2t procesorul s\u0103 poat\u0103 accesa aceste date direct). Aici apare problema: pe de o parte, memoria flash QSPI nu este accesibil\u0103 imediat dup\u0103 repornirea dispozitivului (trebuie s\u0103 ini\u021bializezi separat modul de mapare a memoriei), pe de alt\u0103 parte, nu po\u021bi \u201escrie\u201d \u00een aceast\u0103 memorie folosind un bootloader obi\u0219nuit.<\/p>\n<p><\/p>\n<p>Ideea de a porta aceast\u0103 bibliotec\u0103 pe Embox a ap\u0103rut acum aproximativ un an, dar a fost am\u00e2nat\u0103 din diferite motive. Unul dintre ele este suportul pentru libstdc++ \u0219i biblioteca standard de \u0219abloane. Problema suportului C++ \u00een Embox dep\u0103\u0219e\u0219te sfera acestui articol, a\u0219a c\u0103 aici voi spune doar c\u0103 am reu\u0219it s\u0103 ob\u021binem acest suport \u00een volumul necesar pentru a face aceast\u0103 bibliotec\u0103 s\u0103 func\u021bioneze \ud83d\ude42<\/p>\n<p><\/p>\n<h1 id=\"rezultat\">Rezultatul<\/h1>\n<p><\/p>\n<p>\u00cen cele din urm\u0103, aceste probleme au fost dep\u0103\u0219ite (cel pu\u021bin, \u00eentr-o m\u0103sur\u0103 suficient\u0103 pentru a rula exemplul OpenCV), iar exemplul s-a pornit. C\u0103utarea marginilor cu filtrul Canny dureaz\u0103 40 de secunde lungi. Acest lucru, desigur, este prea mult (exist\u0103 sugestii despre cum s\u0103 optimiz\u0103m acest proces, despre care s-ar putea scrie un articol separat \u00een cazul unui succes).<\/p>\n<p><\/p>\n<p>Cu toate acestea, scopul intermediar a fost crearea unui prototip care s\u0103 demonstreze posibilitatea fundamental\u0103 a rularii OpenCV pe STM32, prin urmare, acest obiectiv a fost atins, hurrah! <\/p>\n<p>\n<img decoding=\"async\" alt=\"OpenCV pe STM32F7-Discovery\" src=\"\/wp-content\/uploads\/2019\/09\/a400c72865ec17094efc985908914463.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>tl;dr: instruc\u021biuni pas cu pas<\/p>\n<h4 id=\"tldr-poshagovaya-instrukciya\">0: Desc\u0103rc\u0103m sursele Embox, de exemplu, astfel:<\/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: S\u0103 \u00eencepem cu compilarea bootloader-ului, care \u201eva programa\u201d chipul QSPI.<\/code><\/pre>\n<p><\/p>\n<p>1: S\u0103 \u00eencepem cu compilarea bootloader-ului, care va \u201escrie\u201d \u00een memoria flash QSPI.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    face confload-arm\/stm32f7cube<\/code><\/pre>\n<p><\/p>\n<p>Acum trebuie s\u0103 configur\u0103m re\u021beaua, deoarece vom \u00eenc\u0103rca imaginea prin TFTP. Pentru a seta adresele IP ale pl\u0103cii \u0219i ale gazdei, trebuie s\u0103 modific\u0103m fi\u0219ierul conf\/rootfs\/network.<\/p>\n<p><\/p>\n<p>Exemplu de configurare:<\/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 gazdei de unde va fi \u00eenc\u0103rcat\u0103 imaginea, <code>address<\/code> \u2014 adresa pl\u0103cii.<\/p>\n<p><\/p>\n<p>Dup\u0103 aceasta, compil\u0103m \u00eenc\u0103rc\u0103torul:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    make<\/code><\/pre>\n<p><\/p>\n<p>2: \u00cenc\u0103rcare obi\u0219nuit\u0103 a \u00eenc\u0103rc\u0103torului (scuze pentru jocul de cuvinte) pe plac\u0103 \u2014 aici nu este nimic specific, trebuie s\u0103 facem asta ca pentru orice alt\u0103 aplica\u021bie pentru STM32F7Discovery. Dac\u0103 nu \u0219ti\u021bi cum se face, pute\u021bi citi despre asta <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/embox\/blog\/349034\/\">aici<\/a><\/noindex>.<br \/>\n3: Compilarea imaginii cu configura\u021bia pentru 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: Extrac\u021bia din sec\u021biunile ELF care trebuie scrise \u00een QSPI, \u00een 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>\u00cen directorul conf se afl\u0103 un script care face asta, a\u0219a c\u0103 se poate rula<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    .\\\/conf\\\/qspi_objcopy.sh # Binariul necesar -- build\/base\/bin\/qspi.bin<\/code><\/pre>\n<p><\/p>\n<p>5: Folosind tftp, \u00eenc\u0103rc\u0103m qspi.bin.bin pe memoria flash QSPI. Pe gazd\u0103, pentru asta trebuie s\u0103 copiati qspi.bin \u00een directorul r\u0103d\u0103cin\u0103 al serverului tftp (de obicei este \\\/srv\\\/tftp\\\/ sau \\\/var\\\/lib\\\/tftpboot\\\/; pachetele pentru serverul respectiv sunt disponibile \u00een majoritatea distribu\u021biilor populare, de obicei se nume\u0219te tftpd sau tftp-hpa, uneori trebuie s\u0103 rula\u021bi <code>systemctl start tftpd.service<\/code> pentru a porni).<\/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>Pe Embox (adic\u0103 \u00een \u00eenc\u0103rc\u0103tor) trebuie s\u0103 executa\u021bi urm\u0103toarea comand\u0103 ( presupun\u00e2nd c\u0103 adresa serverului este 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: Folosind comanda <code>goto<\/code> trebuie s\u0103 \u201esari\u201d \u00een memoria QSPI. Localizarea specific\u0103 va varia \u00een func\u021bie de modul \u00een care imaginea este legat\u0103, iar aceast\u0103 adres\u0103 poate fi verificat\u0103 cu comanda <code>mem 0x90000000<\/code> (adresa de start se afl\u0103 \u00een al doilea cuv\u00e2nt de 32 de bi\u021bi al imaginii); va fi necesar s\u0103 seta\u021bi stack-ul cu un flag <code>-s<\/code>, adresa stack-ului se afl\u0103 la 0x90000000, exemplu:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    embox&gt;mem 0x90000000\n    0x90000000:     0x20023200  0x9000c27f  0x9000c275  0x9000c275\n                      \u2191           \u2191\n              acesta este adresa    acesta este adresa \n                stack-ului        primei\n                           instruc\u021biuni\n\n    embox&gt;goto -i 0x9000c27f -s 0x20023200 # Flag-ul -i este necesar pentru a interzice \u00eentreruperile \u00een timpul ini\u021bializ\u0103rii sistemului\n\n    &lt; \u00cencep\u00e2nd de aici, va fi afi\u0219area imaginii cu OpenCV &gt;<\/code><\/pre>\n<p><\/p>\n<p>7: Rul\u0103m<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    embox&gt; edges 20<\/code><\/pre>\n<p><\/p>\n<p>\u0219i ne bucur\u0103m de o c\u0103utare a marginilor de 40 de secunde \ud83d\ude42<\/p>\n<p><\/p>\n<p>Dac\u0103 ceva nu decurge conform planului \u2014 scrie\u021bi o problem\u0103 \u00een <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/embox\/embox\">repository-ul nostru<\/a><\/noindex>, sau pe lista de discu\u021bii embox-devel@googlegroups.com, sau \u00een comentarii aici.<\/p>\n<p>Sursa: <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.4 - 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\/ro\/blog\/administrirovanie\/opencv-na-stm32f7-discovery\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"ro_RO\" \/>\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\/ro\/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 pe STM32F7-Discovery | ProHoster","description":"Sunt unul dintre dezvoltatorii sistemului de operare","canonical_url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/opencv-na-stm32f7-discovery","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"ro_RO","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\/ro\/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\/ro\/wp-json\/wp\/v2\/posts\/37914","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/comments?post=37914"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/37914\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media\/28450"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media?parent=37914"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/categories?post=37914"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/tags?post=37914"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}