{"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\/de\/blog\/administrirovanie\/opencv-na-stm32f7-discovery","title":{"rendered":"OpenCV auf STM32F7-Discovery","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"OpenCV auf STM32F7-Discovery\" src=\"\/wp-content\/uploads\/2019\/09\/a2248ee685ee210ce8f7781435dd1d5a.jpg\" style=\"display:block;margin: 0 auto;\" \/> Ich bin einer der Entwickler des Betriebssystems <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/embox\/embox\">Embox<\/a><\/noindex>, und in diesem Artikel werde ich dar\u00fcber berichten, wie ich OpenCV auf dem STM32746G-Board zum Laufen gebracht habe.<\/p>\n<p><\/p>\n<p>Gibt man etwas wie \u00abOpenCV auf STM32-Board\u00bb in die Suchmaschine ein, findet man ziemlich viele, die sich f\u00fcr die Verwendung dieser Bibliothek auf STM32-Platinen oder anderen Mikrocontrollern interessieren.<br \/>\nEs gibt einige Videos, die laut Titel anzeigen sollten, was erforderlich ist, aber normalerweise (in allen Videos, die ich gesehen habe) wurde auf dem STM32-Board nur das Bild von der Kamera erfasst und das Ergebnis auf dem Bildschirm ausgegeben, w\u00e4hrend die Bildverarbeitung entweder auf einem normalen Computer oder auf leistungsst\u00e4rkeren Boards (wie z. B. Raspberry Pi) durchgef\u00fchrt wurde.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h1 id=\"pochemu-eto-slozhno\">Warum ist das schwierig?<\/h1>\n<p><\/p>\n<p>Die Popularit\u00e4t der Suchanfragen erkl\u00e4rt sich dadurch, dass OpenCV die bekannteste Bibliothek f\u00fcr Computer Vision ist, was bedeutet, dass viele Entwickler damit vertraut sind. Au\u00dferdem vereinfacht die M\u00f6glichkeit, Desktop-Code auf einem Mikrocontroller auszuf\u00fchren, den Entwicklungsprozess erheblich. Aber warum gibt es bis jetzt keine popul\u00e4ren fertigen Rezepte zur L\u00f6sung dieses Problems?<\/p>\n<p><\/p>\n<p>Die Nutzung von OpenCV auf kleinen Platinen bringt zwei Herausforderungen mit sich:<\/p>\n<p><\/p>\n<ul>\n<li>Selbst wenn die Bibliothek mit dem minimalen Satz an Modulen kompiliert wird, passt sie aufgrund des sehr umfangreichen Codes (mehrere Megabyte an Anweisungen) einfach nicht in den Flash-Speicher des gleichen STM32F7Discovery (ganz zu schweigen vom Betriebssystem).<\/li>\n<li>Die Bibliothek selbst ist in C++ geschrieben, was bedeutet,\n<ul>\n<li>dass Unterst\u00fctzung f\u00fcr die C++-Laufzeitumgebung (Ausnahmen usw.) erforderlich ist.<\/li>\n<li>Es gibt nur wenig Unterst\u00fctzung f\u00fcr LibC\/Posix, die normalerweise in Betriebssystemen f\u00fcr eingebettete Systeme vorhanden ist \u2013 die Standardbibliothek f\u00fcr C++ sowie die Standard-Template-Bibliothek STL (Vector usw.) werden ben\u00f6tigt.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"portirovanie-na-embox\">Portierung auf Embox<\/h1>\n<p><\/p>\n<p>Wie gewohnt ist es vor der Portierung von Programmen in ein Betriebssystem ratsam, es in der Form zu kompilieren, in der es von den Entwicklern gedacht war. In unserem Fall treten dabei keine Probleme auf \u2013 der Quellcode ist verf\u00fcgbar unter <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/opencv\/opencv\">GitHub<\/a><\/noindex>, die Bibliothek kann mit dem \u00fcblichen cmake unter GNU\/Linux kompiliert werden.<\/p>\n<p><\/p>\n<p>Die gute Nachricht ist, dass OpenCV direkt als statische Bibliothek kompiliert werden kann, was die Portierung erleichtert. Wir kompilieren die Bibliothek mit der Standardkonfiguration und sehen, wie viel Platz sie ben\u00f6tigt. Jedes Modul wird in einer separaten Bibliothek kompiliert.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">&gt; Gr\u00f6\u00dfe lib\/*so --totals\n   Text    Daten     BSS     dez     hex Datei\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 (GESAMT)<\/code><\/pre>\n<p><\/p>\n<p>Wie aus der letzten Zeile ersichtlich, nehmen .bss und .data nicht viel Platz ein, w\u00e4hrend der Code \u00fcber 70 MiB ausmacht. Es ist klar, dass der Code bei einer statischen Verlinkung mit einer bestimmten Anwendung weniger werden w\u00fcrde.<\/p>\n<p><\/p>\n<p>Versuchen wir, so viele Module wie m\u00f6glich zu entfernen, um ein minimales Beispiel zu erstellen (das beispielsweise einfach die OpenCV-Version ausgibt), also schauen wir uns das an. <code>cmake .. -LA<\/code> und schalten in den Optionen alles ab, was abgeschaltet werden kann.<\/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; Gr\u00f6\u00dfe lib\/libopencv_core.a --totals\n   text    data     bss     dec     hex Datei\n3317069   36425   17987 3371481  3371d9 (GESAMT)<\/code><\/pre>\n<p><\/p>\n<p>Einerseits handelt es sich nur um ein Modul der Bibliothek, andererseits erfolgt dies ohne Codegr\u00f6\u00dfe-Optimierung durch den Compiler (<code>-Os<\/code>). ~3 MiB Code \u2014 das ist immer noch relativ viel, gibt aber bereits Anlass zur Hoffnung auf Erfolg.<\/p>\n<p><\/p>\n<h2 id=\"zapusk-v-emulyatore\">Ausf\u00fchrung im Emulator<\/h2>\n<p><\/p>\n<p>Es ist viel einfacher, im Emulator zu debuggen. Daher stellen wir zuerst sicher, dass die Bibliothek auf qemu funktioniert. Als emulierte Plattform habe ich Integrator\/CP gew\u00e4hlt, weil es erstens ebenfalls ARM ist und zweitens Embox die Grafikausgabe f\u00fcr diese Plattform unterst\u00fctzt.<\/p>\n<p><\/p>\n<p>Embox verf\u00fcgt \u00fcber einen Mechanismus zum Bauen externer Bibliotheken, mithilfe dessen wir OpenCV als Modul hinzuf\u00fcgen (indem wir alle gleichen Optionen f\u00fcr den \u00abminimalen\u00bb Build in Form von statischen Bibliotheken \u00fcbergeben), danach f\u00fcge ich eine einfache Anwendung hinzu, die so aussieht:<\/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>Wir kompilieren das System, starten es \u2014 und erhalten die erwartete Ausgabe.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">root@embox:\/#opencv_version                                                     \nOpenCV: \nAllgemeine Konfiguration f\u00fcr OpenCV 4.0.1 =====================================\n  Versionskontrolle:            bd6927bdf-dirty\n\n  Plattform:\n    Zeitstempel:                2019-06-21T10:02:18Z\n    Host:                       Linux 5.1.7-arch1-1-ARCH x86_64\n    Ziel:                       Generic arm-unknown-none\n    CMake:                      3.14.5\n    CMake-Generator:            Unix Makefiles\n    CMake-Bautool:              \/usr\/bin\/make\n    Konfiguration:              Debug\n\n  CPU\/HW-Funktionen:\n    Basislinie:\n      angefordert:               DETECT\n      deaktiviert:               VFPV3 NEON\n\n  C\/C++:\n    Als dynamische Bibliotheken gebaut?:  NEIN<\/code><\/pre>\n<p><\/p>\n<p>Der n\u00e4chste Schritt besteht darin, ein Beispiel zu starten, am besten eines der Standardbeispiele, die die Entwickler selbst anbieten. <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.opencv.org\/4.1.0\/examples.html\">auf ihrer Website.<\/a><\/noindex>. Ich habe mich f\u00fcr <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.opencv.org\/4.1.0\/d6\/d56\/samples_2cpp_2edge_8cpp-example.html\">den Canny-Kantendetektor<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>entschieden. Das Beispiel musste ein wenig umgeschrieben werden, um das Ergebnisbild direkt im Framebuffer anzuzeigen. Das war notwendig, da die Funktion <code>imshow()<\/code> Bilder \u00fcber die Schnittstellen QT, GTK und Windows anzeigen kann, die nat\u00fcrlich in der Konfiguration f\u00fcr STM32 nicht vorhanden sein werden. Tats\u00e4chlich kann QT auch auf STM32F7Discovery ausgef\u00fchrt werden, aber das wird in einem anderen Artikel beschrieben \ud83d\ude42<\/p>\n<p><\/p>\n<p>Nach kurzer Kl\u00e4rung, in welchem Format die Ergebnisse des Kantendetektors gespeichert werden, erhalten wir das Bild.<\/p>\n<p>\n<img decoding=\"async\" alt=\"OpenCV auf STM32F7-Discovery\" src=\"\/wp-content\/uploads\/2019\/09\/127f90ad8008340d73feb6ece02e52b2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Das Originalbild<\/p>\n<p>\n<img decoding=\"async\" alt=\"OpenCV auf STM32F7-Discovery\" src=\"\/wp-content\/uploads\/2019\/09\/da34b3ac2561ae9f223acc5c4fe2a597.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><em>Ergebnis<\/em><\/p>\n<p><\/p>\n<h2 id=\"zapusk-na-stm32f7discovery\">Start auf STM32F7Discovery<\/h2>\n<p><\/p>\n<p>Auf dem 32F746GDISCOVERY gibt es mehrere Hardware-Speicherabschnitte, die wir auf verschiedene Weise nutzen k\u00f6nnen.<\/p>\n<p><\/p>\n<ol>\n<li>320 KiB RAM<\/li>\n<li>1 MiB Flash-Speicher f\u00fcr das Image<\/li>\n<li>8 MiB SDRAM<\/li>\n<li>16 MiB QSPI NAND-Flash<\/li>\n<li>Anschluss f\u00fcr microSD-Karte<\/li>\n<\/ol>\n<p><\/p>\n<p>Die SD-Karte kann zur Speicherung von Bildern verwendet werden, ist jedoch im Kontext des Starts eines minimalen Beispiels nicht besonders n\u00fctzlich.<br \/>\nDer Bildschirm hat eine Aufl\u00f6sung von 480\u00d7272, was bedeutet, dass der Speicher f\u00fcr den Framebuffer 522.240 Bytes bei einer Tiefe von 32 Bit betragen wird, d.h. das ist mehr als die Gr\u00f6\u00dfe des Arbeitsspeichers, sodass wir den Framebuffer und den Heap (der auch f\u00fcr OpenCV ben\u00f6tigt wird, um Daten f\u00fcr Bilder und Hilfsstrukturen zu speichern) im SDRAM unterbringen werden, w\u00e4hrend alles andere (Speicher f\u00fcr Stacks und andere Systembed\u00fcrfnisse) in den RAM geht.<\/p>\n<p><\/p>\n<p>Wenn man die Minimal-Konfiguration f\u00fcr STM32F7Discovery nimmt (alle Netzwerkfunktionen entfernt, alle Befehle entfernt, die Stacks so klein wie m\u00f6glich macht, usw.) und dort OpenCV mit Beispielen hinzuf\u00fcgt, ergeben sich folgende Anforderungen an den Speicher:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">   text    data     bss     dec     hex dateiname\n2876890  459208  312736 3648834  37ad42 build\/base\/bin\/embox<\/code><\/pre>\n<p><\/p>\n<p>F\u00fcr diejenigen, die nicht ganz sicher sind, welche Sektionen wo hinein geh\u00f6ren, eine Erkl\u00e4rung: In <code>.text<\/code> und <code>.rodata<\/code> liegen die Anweisungen und Konstanten (grob gesagt, readonly-Daten), in <code>.data<\/code> liegen die ver\u00e4nderlichen Daten, in <code>.bss<\/code> liegen \u00abnullifizierte\u00bb Variablen, die dennoch Platz ben\u00f6tigen (dieser Abschnitt \u00abgeht\u00bb in den RAM).<\/p>\n<p><\/p>\n<p>Die gute Nachricht ist, dass <code>.data<\/code>\/<code>.bss<\/code> untergebracht werden m\u00fcssen, aber das <code>.text<\/code> Problem ist \u2014 es steht nur 1MiB Speicher f\u00fcr das Image zur Verf\u00fcgung. Man k\u00f6nnte das Bild aus dem Beispiel entfernen und es beispielsweise beim Start von einer SD-Karte in den Speicher laden, aber fruits.png wiegt etwa 330KiB, sodass dieses Problem nicht gel\u00f6st wird: der Gro\u00dfteil <code>.text<\/code> Das Bild aus dem Beispiel wird zum Beispiel beim Start von einer SD-Karte in den Speicher geladen, aber fruits.png hat ein Gewicht von etwa 330 KiB, sodass dieses Problem nicht gel\u00f6st wird: der Gro\u00dfteil <code>.text<\/code> besteht tats\u00e4chlich aus OpenCV-Code.<\/p>\n<p><\/p>\n<p>Im Wesentlichen bleibt nur noch eines \u00fcbrig \u2013 das Laden eines Teils des Codes auf einen QSPI-Flashspeicher (dieser hat einen speziellen Betriebsmodus, um den Speicher auf den Bussystem zu mappen, sodass der Prozessor direkt auf diese Daten zugreifen kann). Dabei gibt es ein Problem: Erstens ist der Speicher des QSPI-Flashspeichers nach einem Neustart des Ger\u00e4ts nicht sofort verf\u00fcgbar (der Memory-Mapped-Modus muss separat initialisiert werden), und zweitens kann dieser Speicher nicht mit einem herk\u00f6mmlichen Bootloader &#171;beschrieben&#187; werden.<\/p>\n<p><\/p>\n<p>Schlie\u00dflich wurde beschlossen, den gesamten Code in QSPI zu verlinken und ihn mit einem selbstgeschriebenen Bootloader zu flashen, der das ben\u00f6tigte Binary \u00fcber TFTP abruft.<\/p>\n<p><\/p>\n<h1 id=\"rezultat\">Ergebnis<\/h1>\n<p><\/p>\n<p>Die Idee, diese Bibliothek auf Embox zu portieren, kam vor etwa einem Jahr auf, wurde jedoch immer wieder aus verschiedenen Gr\u00fcnden verschoben. Einer davon ist die Unterst\u00fctzung von libstdc++ und der Standard-Template-Bibliothek. Das Problem der C++-Unterst\u00fctzung in Embox geht \u00fcber den Rahmen dieses Artikels hinaus, daher sage ich hier nur, dass es uns gelungen ist, diese Unterst\u00fctzung im notwendigen Umfang f\u00fcr den Betrieb dieser Bibliothek zu erreichen \ud83d\ude42<\/p>\n<p><\/p>\n<p>Letztendlich wurden diese Probleme \u00fcberwunden (zumindest in ausreichendem Ma\u00dfe, um das OpenCV-Beispiel zum Laufen zu bringen), und das Beispiel startete. Die Platine ben\u00f6tigt 40 lange Sekunden, um mit dem Canny-Filter die Kanten zu finden. Das ist nat\u00fcrlich zu lange (es gibt \u00dcberlegungen, wie man dies optimieren kann; dar\u00fcber kann in einem separaten Artikel im Erfolgsfall geschrieben werden). <\/p>\n<p>\n<img decoding=\"async\" alt=\"OpenCV auf STM32F7-Discovery\" src=\"\/wp-content\/uploads\/2019\/09\/a400c72865ec17094efc985908914463.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Dennoch war das Zwischenziel, einen Prototyp zu erstellen, der die grunds\u00e4tzliche M\u00f6glichkeit zeigt, OpenCV auf STM32 auszuf\u00fchren; diese Zielsetzung wurde erreicht, hurra!<\/p>\n<h4 id=\"tldr-poshagovaya-instrukciya\">tl;dr: Schritt-f\u00fcr-Schritt-Anleitung<\/h4>\n<p><\/p>\n<p>0: Laden Sie die Embox-Quellcodes herunter, zum Beispiel so:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    git clone https:\/\/github.com\/embox\/embox &amp;&amp; cd .\/embox<\/code><\/pre>\n<p><\/p>\n<p>1: Lassen Sie uns mit dem Zusammenstellen des Bootloaders beginnen, der den QSPI-Flashspeicher &#171;beschreiben&#187; wird.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    make confload-arm\/stm32f7cube<\/code><\/pre>\n<p><\/p>\n<p>Jetzt m\u00fcssen wir das Netzwerk konfigurieren, da wir das Image \u00fcber TFTP laden werden. Um die IP-Adressen f\u00fcr das Board und den Host festzulegen, muss die Datei conf\/rootfs\/network ge\u00e4ndert werden.<\/p>\n<p><\/p>\n<p>Beispielkonfiguration:<\/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 die Adresse des Hosts, von dem das Image geladen wird, <code>address<\/code> \u2014 die Adresse des Boards.<\/p>\n<p><\/p>\n<p>Nachdem dies erledigt ist, bauen wir den Bootloader:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    make<\/code><\/pre>\n<p><\/p>\n<p>2: Normales Laden des Bootloaders (Entschuldigung f\u00fcr das Wortspiel) auf das Board \u2014 hier gibt es nichts Besonderes, dies muss wie bei jeder anderen Anwendung f\u00fcr STM32F7Discovery durchgef\u00fchrt werden. Wenn Sie nicht wissen, wie das geht, k\u00f6nnen Sie dar\u00fcber lesen. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/embox\/blog\/349034\/\">hier<\/a><\/noindex>.<br \/>\n3: Kompilierung des Images mit der Konfiguration f\u00fcr 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: Extrahieren der ELF-Sektionen, die in den QSPI geschrieben werden m\u00fcssen, in 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>Im Verzeichnis conf befindet sich ein Skript, das dies erledigt, also k\u00f6nnen Sie es ausf\u00fchren.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    .\/conf\/qspi_objcopy.sh # Die ben\u00f6tigte Bin\u00e4rdatei -- build\/base\/bin\/qspi.bin<\/code><\/pre>\n<p><\/p>\n<p>5: \u00dcber tftp laden wir qspi.bin.bin auf den QSPI-Flash. Dazu muss auf dem Host die Datei qspi.bin in das Wurzelverzeichnis des tftp-Servers kopiert werden (gew\u00f6hnlich ist das \/srv\/tftp\/ oder \/var\/lib\/tftpboot\/; die Pakete f\u00fcr den entsprechenden Server sind in den meisten g\u00e4ngigen Distributionen verf\u00fcgbar, normalerweise unter dem Namen tftpd oder tftp-hpa, manchmal ist es n\u00f6tig zu starten) <code>systemctl start tftpd.service<\/code> zum Start).<\/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>Auf Embox (d.h. im Bootloader) muss der folgende Befehl ausgef\u00fchrt werden (wir gehen davon aus, dass die Adresse des Servers 192.168.2.1 ist):<\/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: Mit dem Befehl <code>goto<\/code> Es ist n\u00f6tig, in den QSPI-Speicher &#171;einzuspringen&#187;. Der spezifische Standort variiert je nachdem, wie das Abbild verlinkt wird; diesen Adressbereich kann man mit dem Befehl <code>mem 0x90000000<\/code> (die Startadresse liegt im zweiten 32-Bit-Wort des Abbildes); au\u00dferdem muss der Stack mit einem Flag festgelegt werden, <code>-s<\/code>die Stack-Adresse befindet sich bei 0x90000000, Beispiel:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    embox&gt;mem 0x90000000\n    0x90000000:     0x20023200  0x9000c27f  0x9000c275  0x9000c275\n                      \u2191           \u2191\n              dies ist die Adresse    dies ist die Adresse \n                des Stacks        der ersten\n                           Instruktion\n\n    embox&gt;goto -i 0x9000c27f -s 0x20023200 # Das Flag -i ist n\u00f6tig, um Unterbrechungen w\u00e4hrend der Systeminitialisierung zu verhindern<\/code><\/pre>\n<p><\/p>\n<p>7: Wir starten<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">    embox&gt; edges 20<\/code><\/pre>\n<p><\/p>\n<p>und genie\u00dfen eine 40-sek\u00fcndige Grenzsuche \ud83d\ude42<\/p>\n<p><\/p>\n<p>Falls etwas schiefgeht, schreiben Sie ein Issue in <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/embox\/embox\">unserem Repository<\/a><\/noindex>, oder an die Mailingliste embox-devel@googlegroups.com, oder hier in die Kommentare.<\/p>\n<p>Quelle: <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 4.9.10 - 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 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 &quot;OpenCV on STM32 board&quot;, \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\" \/>\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\/de\/blog\/administrirovanie\/opencv-na-stm32f7-discovery\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"de_DE\" \/>\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 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 &quot;OpenCV on STM32 board&quot;, \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\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/de\/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 auf STM32F7-Discovery | ProHoster","description":"Ich bin einer der Entwickler des Betriebssystems Embox und in diesem Artikel werde ich dar\u00fcber berichten, wie ich OpenCV auf dem STM32746G-Board zum Laufen gebracht habe. Wenn man in eine Suchmaschine Begriffe wie \"OpenCV auf STM32-Board\" eingibt, findet man viele, die sich f\u00fcr die Nutzung dieser Bibliothek auf STM32-Boards oder anderen Mikrocontrollern interessieren. Es gibt einige Videos, die, anhand der Bewertungen,","canonical_url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/opencv-na-stm32f7-discovery","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"de_DE","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 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 &quot;OpenCV on STM32 board&quot;, \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","og:url":"https:\/\/prohoster.info\/de\/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"},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/37914","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/comments?post=37914"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/37914\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media\/28450"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=37914"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=37914"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=37914"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}