{"id":314081,"date":"2020-12-01T09:00:58","date_gmt":"2020-12-01T09:00:58","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=314081"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=314081","title":{"rendered":"\u0414\u0435\u043b\u0430\u0435\u043c \u0438\u0437 ENC28J60 \u0432\u043d\u0435\u0448\u043d\u044e\u044e USB \u0441\u0435\u0442\u0435\u0432\u0443\u044e \u043a\u0430\u0440\u0442\u0443"},"content":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b73\/7dc\/7ae\/b737dc7ae2c2c805602dc33c7a9fd0cf.jpg\" width=\"1200\" height=\"800\"><figcaption><\/figcaption><\/figure>\n<p>ENC28J60 &#8212; \u043f\u0440\u043e\u0441\u0442\u043e\u0439 Ethernet \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442  \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u0432 \u0440\u043e\u043b\u0438 \u0432\u043d\u0435\u0448\u043d\u0435\u0439 \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u043a\u0430\u0440\u0442\u044b \u0443 \u043e\u0434\u043d\u043e\u043f\u043b\u0430\u0442\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u043e\u0432 \u0441 GPIO (\u0434\u043b\u044f raspberry \u0435\u0441\u0442\u044c \u0434\u0430\u0436\u0435 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0434\u0440\u0430\u0439\u0432\u0435\u0440) \u0438 \u043f\u0440\u043e\u0447\u0438\u0445 \u0430\u0440\u0434\u0443\u0438\u043d. \u0423 \u043c\u043e\u0435\u0433\u043e \u043b\u044d\u043f\u0442\u043e\u043f\u0430 GPIO \u043d\u0435 \u0432\u044b\u0432\u0435\u0434\u0435\u043d\u044b, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c <s>\u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u043a \u0438<\/s> \u043f\u0440\u0438\u043a\u0440\u0443\u0442\u0438\u0442\u044c \u043a \u043d\u0435\u043c\u0443 ENC28J60 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c STM32F103 \u0438 \u0448\u043d\u0443\u0440\u043a\u0430 USB.<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c. <\/p>\n<p>\u041d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f: <\/p>\n<ul>\n<li>\n<p>ENC28J60<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u0430\u044f \u043f\u043b\u0430\u0442\u0430 \u0441 STM32 \u0441 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 USB device (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u043e\u0442 \u0442\u0430\u043a\u0430\u044f):<\/p>\n<\/li>\n<\/ul>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0c9\/5b2\/845\/0c95b2845a5a2ec55a0887dda4f8f30b.jpg\" width=\"250\" height=\"233\"><figcaption><\/figcaption><\/figure>\n<ul>\n<li>\n<p>\u041a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440 \u0441 Linux (\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e Ubuntu 16)<\/p>\n<\/li>\n<li>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440 \u0441 Ethernet \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f (\u0443 \u043c\u0435\u043d\u044f raspberry pi), \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0439 \u043f\u043e wi-fi (\u0438 \u0432 \u043e\u0434\u043d\u043e\u0439 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0435\u0442\u0438 \u0441 \u043f\u0435\u0440\u0432\u044b\u043c)<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 STM32F103 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0443, \u043c\u0430\u043d\u0443\u0430\u043b\u043e\u0432 \u0432 \u0441\u0435\u0442\u0438 \u0445\u0432\u0430\u0442\u0430\u0435\u0442. \u041a\u0430\u043a \u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0430\u043c\u043e\u0433\u043e ENC28J60 (\u0432 \u0441\u0432\u043e\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0432\u043e\u0442 \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 c \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f\u043c\u0438). \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 ENC28J60 \u043a STM32F103 \u043f\u043e SPI1 \u043e\u043f\u0438\u0441\u0430\u043d\u043e <a href=\"https:\/\/narodstream.ru\/stm-urok-68-lan-enc28j60-chast-1\/\" rel=\"noopener noreferrer nofollow\">\u0442\u0430\u043c \u0436\u0435<\/a>.<\/p>\n<h3>\u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435<\/h3>\n<p>\u041a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440 (usb) -&gt; stm32(SPI) -&gt; ENC28J60(Ethernet \u043a\u0430\u0431\u0435\u043b\u044c) -&gt; raspberry <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ea5\/960\/e49\/ea5960e49ea116d742a2f88091fb4bec.jpg\" width=\"2250\" height=\"2020\"><figcaption><\/figcaption><\/figure>\n<h3>\u041a\u0430\u043a \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442<\/h3>\n<p>\u041e\u0431\u043e\u0439\u0434\u0435\u043c\u0441\u044f \u0431\u0435\u0437 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u043e\u0432 \u044f\u0434\u0440\u0430, \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432 user space. \u041d\u0430 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0435\u0442\u0435\u0432\u043e\u0439 tap \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 (\u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f, \u0441 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430\u043c\u0438 Ethernet \u0444\u0440\u0435\u0439\u043c\u043e\u0432, \u0435\u0441\u0442\u044c \u0435\u0449\u0435 tun \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0441 ip \u043f\u0430\u043a\u0435\u0442\u0430\u043c\u0438), \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043f\u043e\u0434\u0441\u043e\u0435\u0434\u0438\u043d\u0438\u043c \u043d\u0430\u0448\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 (\u043d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0435 tap_handler.c<em>). <\/em>\u0427\u0442\u043e\u0431\u044b \u0444\u0440\u0435\u0439\u043c \u043f\u043e\u043f\u0430\u043b \u0432 \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u0441\u0442\u0435\u043a Linux\u0430, tap_handler&#8217;\u0443 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0433\u043e \u0432 tap \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441. \u041d\u0443 \u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442, \u043f\u0430\u043a\u0435\u0442\u044b, \u0430\u0434\u0440\u0435\u0441\u043e\u0432\u0430\u043d\u043d\u044b\u0435 tap \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443, \u0431\u0443\u0434\u0443\u0442 \u0447\u0438\u0442\u0430\u0442\u044c\u0441\u044f tap_handler&#8217;\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0441 \u043d\u0438\u043c\u0438 \u0447\u0442\u043e-\u0442\u043e \u0434\u0430\u043b\u044c\u0448\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c. \u0412 \u0438\u0442\u043e\u0433\u0435, tap_handler \u0431\u0435\u0433\u0430\u0435\u0442 \u0432 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435 \u0438 \u0436\u0434\u0435\u0442 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u043b\u0438\u0431\u043e \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b tap \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430, \u043b\u0438\u0431\u043e \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b \/dev\/ttyACM0 (\u044d\u0442\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430\u0448\u0435\u0433\u043e USB \u0434\u0435\u0432\u0430\u0439\u0441\u0430 \u0432 Linux\u0435). \u0412 \u043f\u0435\u0440\u0432\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0438\u0448\u0435\u043c \u0432 \/dev\/ttyACM0, \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u043c \u0432 tap \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441.<\/p>\n<p>\u0411\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043f\u0440\u043e \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430\u043c\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e <a href=\"https:\/\/backreference.org\/2010\/03\/26\/tuntap-interface-tutorial\/\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a> (\u0434\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0440\u0430\u0431\u043e\u0442\u044b vpn). \u041e\u0442\u0441\u044e\u0434\u0430 \u0436\u0435 \u044f \u0432\u0437\u044f\u043b \u043a\u043e\u0434, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0438\u0439 \u0437\u0430 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430\u043c\u0438.<\/p>\n<p>\u041d\u0430 STM32 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 CubeMX \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 USB CDC (virtual com port). \u041f\u043e\u0441\u043b\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f SMT32 \u043a \u043a\u043e\u043c\u043f\u0443 Linux \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u0444\u0430\u0439\u043b \/dev\/ttyACM0 (\u043d\u0443 \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u043d\u043e\u043c\u0435\u0440). \u0418\u0437 \u044d\u0442\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b STM32, \u0430 \u0435\u0441\u043b\u0438 \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0443\u0434\u0430 \u0434\u0430\u043d\u043d\u044b\u0435, \u0438\u0445 \u0441\u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c STM32.<\/p>\n<p>\u041f\u0440\u043e\u0448\u0438\u0432\u043a\u0430 STM32 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e. \u0412 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435 \u0447\u0438\u0442\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u043a\u043e\u043c\u043f\u0430 (\u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>CDC_Receive_FS<\/code> \u0432 \u0444\u0430\u0439\u043b\u0435 usbd_cdc_if.c) \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0438\u0445 \u0432 ENC28J60, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0436\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442 \u0438\u0445 \u0434\u0430\u043b\u044c\u0448\u0435 \u0432 \u0441\u0435\u0442\u044c, \u0430 \u0442\u0430\u043a\u0436\u0435  \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0444\u0440\u0435\u0439\u043c\u044b \u0438\u0437 ENC28J60 \u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0445 \u0432 \u043a\u043e\u043c\u043f \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 <code>CDC_Transmit_FS<\/code>.<\/p>\n<p>\u041d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044f \u043f\u043e\u043d\u0438\u043c\u0430\u044e, CDC \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0435\u0437 \u043e\u0448\u0438\u0431\u043e\u043a. \u041e\u0434\u043d\u0430\u043a\u043e \u044f \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0441\u044f \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e \u043e\u0448\u0438\u0431\u043a\u0438 \u0432\u0441\u0435 \u0436\u0435 \u0435\u0441\u0442\u044c. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 \u043e\u0431\u044b\u0447\u043d\u043e \u0432\u0441\u0435\u0433\u0434\u0430 \u0434\u0443\u0431\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f (\u043f\u0440\u0438\u0447\u0438\u043d\u0443 \u044f \u043d\u0435 \u043d\u0430\u0448\u0435\u043b, \u0434\u0443\u0431\u043b\u044f\u0436 \u0432\u0438\u0434\u0435\u043d \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0432 wireshark \u043f\u0440\u0438 \u043f\u0440\u043e\u0441\u043b\u0443\u0448\u0438\u0432\u0430\u043d\u0438\u0438 \u0448\u0438\u043d\u044b usb). \u0413\u0443\u0433\u043b\u0435\u0436 \u043f\u043e\u043a\u0430\u0437\u0430\u043b, \u0447\u0442\u043e \u0443 \u043a\u043e\u0433\u043e-\u0442\u043e \u044d\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u043b\u043e \u0438\u0437-\u0437\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0435\u043f\u043e\u0434\u0430\u0431\u0430\u044e\u0449\u0435\u0433\u043e \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0447\u0430\u0441\u0442\u043e\u0442\u044b \u043d\u0430 STM32, \u0447\u0442\u043e \u0432\u0440\u044f\u0434 \u043b\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438\u0447\u0438\u043d\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0432 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0442.\u043a.  \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u043a\u0432\u0430\u0440\u0446. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0433\u043e\u0440\u043e\u0434\u0438\u0442\u044c \u043e\u0433\u043e\u0440\u043e\u0434 \u0441 \u043c\u0435\u0442\u043a\u0430\u043c\u0438.<\/p>\n<h3>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043a\u043e\u043c\u043f\u0430<\/h3>\n<p>\u0421\u0435\u0442\u0435\u0432\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439:<\/p>\n<pre><code class=\"bash\">sudo openvpn --mktun --dev tap0 <\/code><\/pre>\n<p>\u041f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c ip \u0430\u0434\u0440\u0435\u0441:<\/p>\n<pre><code class=\"bash\">sudo ifconfig tap0 10.0.0.1\/24 up <\/code><\/pre>\n<h4>tap_handler.\u0441<\/h4>\n<p>\u0414\u043b\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \/dev\/ttyACM0 \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 raw \u0432\u0438\u0434\u0435 \u0438 \u043d\u0435 \u0434\u0430\u0432\u0430\u0442\u044c \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0443 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0430 \u0432\u043d\u043e\u0441\u0438\u0442\u044c \u0432 \u043d\u0438\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043d\u0435\u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u043c\u0438 \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u043c\u0438 \u0438 \u043f\u0440.). \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0430:<\/p>\n<pre><code class=\"cpp\">char cdc_name[20]=\"\/dev\/ttyACM0\"; int tty_fd = open(cdc_name, O_RDWR | O_NOCTTY);  struct termios portSettings; tcgetattr(tty_fd, &amp;portSettings); cfmakeraw(&amp;portSettings); tcsetattr(tty_fd, TCSANOW, &amp;portSettings); tcflush(tty_fd, TCOFLUSH); <\/code><\/pre>\n<p>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c tap_handler \u043a tap0:<\/p>\n<pre><code class=\"cpp\">\/* \u0432 dev \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0438\u043c\u044f \u0443\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 tap0*\/ int tun_alloc(char *dev, int flags) {     struct ifreq ifr;     int fd, err;     char *clonedev = \"\/dev\/net\/tun\";     \/* \u043e\u0442\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u043c\u0441\u044f \u043e\u0442 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430  \/dev\/net\/tun *\/     if( (fd = open(clonedev , O_RDWR)) &lt; 0 ) {         perror(\"Opening \/dev\/net\/tun\");         return fd;     }         memset(&amp;ifr, 0, sizeof(ifr));      ifr.ifr_flags = flags;          \/* \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0443\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 tap0 *\/     if (*dev) {         strncpy(ifr.ifr_name, dev, IFNAMSIZ);     }     \/* \u043f\u043e\u0434\u0441\u043e\u0435\u0434\u0438\u043d\u044f\u0435\u043c\u0441\u044f \u043a \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443 *\/     if( (err = ioctl(fd, TUNSETIFF, (void *)&amp;ifr)) &lt; 0 ) {         perror(\"ioctl(TUNSETIFF)\");                 close(fd);         return err;     }          strcpy(dev, ifr.ifr_name);      return fd; }<\/code><\/pre>\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u044d\u0442\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0432 main.c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"cpp\">strcpy(tun_name, \"tap0\"); int tap_fd = tun_alloc(tun_name, IFF_TAP | IFF_NO_PI); <\/code><\/pre>\n<p>\u0424\u043b\u0430\u0433 IFF_TAP \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u0442\u0438\u043f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 (tap). \u0424\u043b\u0430\u0433 IFF_NO_PI \u043d\u0443\u0436\u0435\u043d, \u0447\u0442\u043e\u0431\u044b \u044f\u0434\u0440\u043e \u043d\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u043b\u043e \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u043d\u044b\u0435 \u0431\u0430\u0439\u0442\u044b \u043f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u043f\u0430\u043a\u0435\u0442\u0430.<\/p>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 tap0 \u0438 \u0432 \/dev\/ttyACM0. \u041f\u043e\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0435\u0442, tap_handler \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0435\u043c select:<\/p>\n<pre><code class=\"cpp\">while(1) {     int ret;     fd_set rd_set;      FD_ZERO(&amp;rd_set);     \/* tap_fd - tap inteface descriptor *\/     FD_SET(tap_fd, &amp;rd_set);     \/* tty_fd - \/dev\/ttyACM0 descriptor *\/     FD_SET(tty_fd, &amp;rd_set);      ret = select(maxfd + 1, &amp;rd_set, NULL, NULL, NULL);<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a. \u041f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u0444\u0440\u0435\u0439\u043c\u0430 \u043e\u0442 tap0 tap_handler \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u043f\u0430\u043a\u0435\u0442 \u0434\u043b\u044f STM32 (\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0430\u043a\u0435\u0442\u0430: \u043f\u0430\u043a\u0435\u0442 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 \u043c\u0435\u0442\u043a\u0438 &#8212; \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 4 \u0431\u0430\u0439\u0442, \u0447\u0442\u043e\u0431\u044b \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0447\u0430\u043b\u043e \u0444\u0440\u0435\u0439\u043c\u0430, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 2 \u0431\u0430\u0439\u0442\u0430 &#8212; \u0434\u043b\u0438\u043d\u0430 \u0444\u0440\u0435\u0439\u043c\u0430, \u0437\u0430\u0442\u0435\u043c \u0443\u0436\u0435 \u0441\u0430\u043c \u0444\u0440\u0435\u0439\u043c) \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0435\u0433\u043e \u0432 \/dev\/ttyACM0. \u0417\u0430\u0442\u0435\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430, \u0447\u0442\u043e\u0431\u044b \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0448\u043b\u0438 \u0443\u0441\u043f\u0435\u0448\u043d\u043e:<\/p>\n<pre><code class=\"cpp\">if(FD_ISSET(tap_fd, &amp;rd_set)) {         uint16_t nread = cread(tap_fd, buffer, BUFSIZE);        uint8_t buf[6];     *(uint32_t *)buf = PACKET_START_SIGN;     *(uint16_t *)(buf + 4) = nread;         cwrite(tty_fd,(char *)buf,6);         cwrite(tty_fd, buffer, nread);     delay_micro(delay_m);     }<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \/dev\/ttyACM0, \u0443\u0431\u0435\u0436\u0434\u0430\u0435\u043c\u0441\u044f \u0447\u0442\u043e \u043e\u043d\u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442\u0441\u044f \u0441 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u043c\u0435\u0442\u043a\u0438 (\u0442\u0435 \u0436\u0435 4 \u0431\u0430\u0439\u0442\u0430), \u0437\u0430\u0442\u0435\u043c \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0434\u043b\u0438\u043d\u0443 \u0444\u0440\u0435\u0439\u043c\u0430, \u0438 \u043f\u043e\u0442\u043e\u043c \u0441\u0430\u043c \u0444\u0440\u0435\u0439\u043c. \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0444\u0440\u0435\u0439\u043c \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432 tap \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441:<\/p>\n<pre><code class=\"cpp\">if(FD_ISSET(tty_fd, &amp;rd_set)) {     uint32_t sign;     \/* \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u043c\u0435\u0442\u043a\u0443 *\/     int nread = read_n(tty_fd, (char *)&amp;sign, sizeof(sign));     \/* \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440 \u0437\u0430\u043a\u0440\u044b\u0442, \u0432\u044b\u0445\u043e\u0434\u0438\u043c \u0438\u0437 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b *\/     if(nread == 0) {               break;     }     \/* \u0435\u0441\u043b\u0438 \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442, \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043d\u0430\u0439\u0442\u0438 \u043f\u043e\u0434\u043f\u0438\u0441\u044c \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 4 \u0431\u0430\u0439\u0442\u0430\u0445 *\/     if(sign != PACKET_START_SIGN){              continue;     }     \/* \u0447\u0438\u0442\u0430\u0435\u043c \u0434\u043b\u0438\u043d\u0443 \u0444\u0440\u0435\u0439\u043c\u0430 *\/     nread = read_n(tty_fd, (char *)&amp;plength, 2);     if(nread == 0) {               break;     }      if (nread != 2){               continue;     }   \/* \u0437\u0434\u0435\u0441\u044c \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 \u0434\u0443\u0431\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f *\/     if(flag){       flag = 0;       nread = cread(tty_fd, buffer, sizeof(buffer));       if(nread != 6){                 continue;       }     }   \/* \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0434\u043b\u0438\u043d\u0430 \u043f\u0430\u043a\u0435\u0442\u0430, \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 *\/     if(plength &gt; BUFSIZE){             break;     }      \/* \u0447\u0438\u0442\u0430\u0435\u043c \u0444\u0440\u0435\u0439\u043c (plength \u0431\u0430\u0439\u0442)  \u0438 \u043f\u0438\u0448\u0435\u043c \u0435\u0433\u043e \u0432 tap interface*\/     nread = read_n(tty_fd, buffer, plength);                 if (nread != 0){                     cwrite(tap_fd, buffer, nread);                     delay_micro(delay_m);     }   }<\/code><\/pre>\n<h3>\u0421\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b STM32<\/h3>\n<p>\u041a\u0440\u043e\u043c\u0435 USB CDC \u0432 CubeMX \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043c \u0442\u0430\u043a\u0436\u0435 HAL \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 SPI1 \u0438 \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u043e\u043c.<\/p>\n<p>\u041f\u0440\u0438\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432 callback&#8217;\u0435 <code>CDC_Receive_FS<\/code> (\u0444\u0430\u0439\u043b usbd_cdc_if.c), \u0437\u0430\u043f\u0443\u0441\u043a \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f\u043c\u0438 \u0432 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 USB. \u0412 \u044d\u0442\u043e\u043c \u043c\u0435\u0441\u0442\u0435 \u043d\u0435\u043b\u044c\u0437\u044f \u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u043b\u0433\u043e\u0438\u0433\u0440\u0430\u044e\u0449\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0448\u0435\u0434\u0448\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0432 \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u0439 \u0431\u0443\u0444\u0435\u0440, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0437\u0430\u0431\u0438\u0440\u0430\u0435\u043c \u0438\u0445 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u0430\u0440\u0443\u0436\u0443 \u0447\u0435\u0440\u0435\u0437 ENC28J60. \u041f\u0440\u0438 \u0440\u0438\u0441\u043a\u0435 \u043f\u0435\u0440\u0435\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0431\u0443\u0444\u0435\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0442\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f:<\/p>\n<pre><code class=\"cpp\">\/* USB_POINTERS_ARRAY_SIZE - \u0440\u0430\u0437\u043c\u0435\u0440 array_pos *\/ \/* MAX_FRAMELEN - \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0434\u043b\u0438\u043d\u0430 \u0444\u0440\u0435\u0439\u043c\u0430 *\/ \/* USB_BUFSIZE - \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u0433\u043e \u0431\u0443\u0444\u0435\u0440\u0430 *\/  extern uint8_t usb_buf[]; \/* \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u0439 \u0431\u0443\u0444\u0435\u0440 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u043e\u0442 \u043a\u043e\u043c\u043f\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 *\/ extern uint32_t pos_int; \/* \u0438\u043d\u0434\u0435\u043a\u0441 \u0434\u043b\u044f \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u043f\u0430\u043a\u0435\u0442\u0430 \u0432 \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u043c \u0431\u0443\u0444\u0435\u0440\u0435 *\/ extern uint32_t array_pos[]; \/* \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b \u0432 \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u043c \u0431\u0443\u0444\u0435\u0440\u0435 *\/ extern uint32_t p_a; \/* \u0438\u043d\u0434\u0435\u043a\u0441 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 array_pos \u0434\u043b\u044f CDC_Receive_FS*\/ extern uint32_t pl_a;\/* \u0438\u043d\u0434\u0435\u043a\u0441 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 array_pos \u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430 *\/  \/* USB_POINTERS_ARRAY_SIZE - \u0440\u0430\u0437\u043c\u0435\u0440 array_pos *\/ \/* MAX_FRAMELEN - \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0434\u043b\u0438\u043d\u0430 \u0444\u0440\u0435\u0439\u043c\u0430 *\/ \/* USB_BUFSIZE - \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u0433\u043e \u0431\u0443\u0444\u0435\u0440\u0430 *\/  static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) {   int8_t memok = 1;   \/* \u043e\u0442\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u043f\u0440\u0438\u0448\u0435\u0434\u0448\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \u043c\u0435\u0441\u0442\u0430 \u0432 \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u043c \u0431\u0443\u0444\u0435\u0440\u0435 *\/   if( pl_a !=0 &amp;&amp; p_a !=0){     int32_t mem_lag = array_pos[(p_a - 1) % USB_POINTERS_ARRAY_SIZE] - array_pos[(pl_a - 1) % USB_POINTERS_ARRAY_SIZE];     if(mem_lag &gt; USB_BUFSIZE - MAX_FRAMELEN)       memok = 0;   }   \/* \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u043f\u043e\u0441\u0442\u0443\u043f\u0438\u0432\u0448\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u0439 \u0431\u0443\u0444\u0435\u0440,     \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432 \u043f\u0440\u0438\u0448\u0435\u0434\u0448\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 (array_pos) *\/   if(*Len &lt; USB_BUFSIZE &amp;&amp; *Len != 0 &amp;&amp; memok){     uint16_t offset = pos_int % USB_BUFSIZE;     uint16_t new_pos = offset + *Len;     uint8_t split = 0;     if (new_pos &gt; USB_BUFSIZE){       split = 1;     }     if(split){       int len1 = USB_BUFSIZE - offset;       int len2 = *Len - len1;       memcpy(usb_buf + offset, Buf, len1);       memcpy(usb_buf, Buf + len1, len2);     }     else       memcpy(usb_buf + offset, Buf, *Len);     pos_int += *Len;      array_pos[p_a % USB_POINTERS_ARRAY_SIZE] = pos_int;     p_a++;   }   USBD_CDC_SetRxBuffer(&amp;hUsbDeviceFS, &amp;Buf[0]);   USBD_CDC_ReceivePacket(&amp;hUsbDeviceFS);   return (USBD_OK); }<\/code><\/pre>\n<p>\u0412 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 (main.c) \u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0431\u0443\u0444\u0435\u0440\u0435 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0445 \u0447\u0435\u0440\u0435\u0437 ENC28J60:<\/p>\n<pre><code class=\"cpp\">if(pl_a &lt; p_a){       uint32_t prev = 0;   if(pl_a &gt; 0)     prev = array_pos[(pl_a - 1) % USB_POINTERS_ARRAY_SIZE];   \/* \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u0430\u043a\u0435\u0442\u0430 (\u043a\u0443\u0441\u043e\u0447\u0435\u043a \u0444\u0440\u0435\u0439\u043c\u0430), \u043f\u0440\u0438\u043d\u044f\u0442\u043e\u0433\u043e \u0432 CDC_Receive_FS *\/   int32_t n = array_pos[pl_a % USB_POINTERS_ARRAY_SIZE] - prev;\/\/usb frame size   \/* \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u043f\u0430\u043a\u0435\u0442 \u0432 \u0431\u0443\u0444\u0435\u0440\u0435 *\/   uint8_t *from = usb_buf + prev % USB_BUFSIZE;   \/* \u043f\u0440\u0438\u0437\u043d\u0430\u043a \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u0438 \u043f\u0430\u043a\u0435\u0442\u0430 *\/   uint8_t right_n = 1;   if (n &lt; 0 || n &gt; MAX_FRAMELEN){     right_n = 0;   }    \/* \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u043d\u043e\u0432\u044b\u0439 \u0444\u0440\u0435\u0439\u043c. \u0412 \u043f\u0430\u043a\u0435\u0442\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043c\u0438\u043d\u0438\u043c\u0443\u043c 6 \u0431\u0430\u0439\u0442\u043e\u0432 (\u043f\u043e\u0434\u043f\u0438\u0441\u044c 4 \u0431\u0430\u0439\u0442\u0430 \u0438 2 \u0431\u0430\u0439\u0442\u0430 \u0434\u043b\u0438\u043d\u0430) *\/   if((packet_len == 0) &amp;&amp; packet_start &amp;&amp; (n &gt; 5) &amp;&amp; right_n){     \/* \u0441\u043f\u0435\u0446. \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0438\u0437 \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u0433\u043e \u0431\u0443\u0444\u0435\u0440\u0430 *\/     uint32_t sign = read32(from,usb_buf);      \/* \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0435 \u0447\u0435\u0440\u0435\u0437 4 \u0431\u0430\u0439\u0442\u0430 *\/     uint8_t *next = next_usb_ptr(from,usb_buf,4);     \/* \u0447\u0438\u0442\u0430\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0440 \u0444\u0440\u0435\u0439\u043c\u0430 *\/     packet_size = read16(next,usb_buf);\/\/ 2 bytes after sign is packet length     \/* \u043e\u0442\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 *\/     if (packet_size &gt; MAX_FRAMELEN || sign != PACKET_START_SIGN){             packet_size = 0;     }     else{       \/* \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u043f\u0440\u0438\u043d\u044f\u0442\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0431\u0443\u0444\u0435\u0440 \u0444\u0440\u0435\u0439\u043c\u0430 *\/       next = next_usb_ptr(from,usb_buf,6);       copy_buf(packet_buf, next, usb_buf, n - 6);             packet_len = n - 6;       packet_next_ptr = packet_buf + packet_len;       packet_start = 0;     }    }   \/* \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u044b \u0432 \u0444\u0440\u0435\u0439\u043c\u0435 *\/   else if(packet_len &lt; packet_size &amp;&amp; right_n){   \/* \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u043f\u0440\u0438\u043d\u044f\u0442\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0431\u0443\u0444\u0435\u0440 \u0444\u0440\u0435\u0439\u043c\u0430 *\/         copy_buf(packet_next_ptr, from, usb_buf, n);         packet_len += n;     packet_next_ptr = packet_buf + packet_len;   }   \/* \u043e\u0442\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u044b\u0439 \u0444\u0440\u0435\u0439\u043c *\/   else if (packet_len &gt; packet_size){         packet_len = 0;     packet_start = 1;   }   \/* \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0444\u0440\u0435\u0439\u043c \u0447\u0435\u0440\u0435\u0437 enc28j60 *\/   if(packet_len == packet_size &amp;&amp; packet_size &gt; 0){         enc28j60_packetSend(packet_buf, packet_size);     packet_len = 0;     packet_start = 1;   }    pl_a++; }<\/code><\/pre>\n<p>\u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 ENC28J60 \u0438 \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0445 \u0432 USB \u0438 \u043c\u0438\u0433\u0430\u0435\u043c \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u043e\u043c:<\/p>\n<pre><code class=\"cpp\">len = enc28j60_packetReceive(net_buf,sizeof(net_buf)); if (len &gt; 0) {   *((uint16_t*)(sign_buf + 4)) = len;   while(CDC_Transmit_FS(sign_buf, sizeof(sign_buf)) == USBD_BUSY_CDC_TRANSMIT);   while(CDC_Transmit_FS(net_buf, len) == USBD_BUSY_CDC_TRANSMIT);   HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13); }<\/code><\/pre>\n<p>\u0412 <code>CDC_Transmit_FS<\/code><em> <\/em>\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u043b \u043a\u043e\u0434, \u0447\u0442\u043e\u0431\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432 while. \u0412 \u044d\u0442\u043e\u043c \u043c\u0435\u0441\u0442\u0435 <code>CDC_Transmit_FS<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u0441\u0442\u0430\u0442\u0443\u0441 <code>USBD_BUSY_CDC_TRANSMIT<\/code> \u0432\u043c\u0435\u0441\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e <code>USBD_BUSY<\/code>. \u0411\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0443\u0437\u043d\u0430\u0442\u044c \u043f\u0440\u0438\u043d\u044f\u0442\u044b \u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043a \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0435 \u043c\u043d\u0435 \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c:<\/p>\n<pre><code class=\"cpp\">if (hcdc-&gt;TxState != 0){     return USBD_BUSY_CDC_TRANSMIT; } <\/code><\/pre>\n<p>\u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 ENC28J60 <code>enc28j60_ini<\/code> \u043d\u0443\u0436\u043d\u043e \u0440\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u043b\u044e\u0431\u044b\u0435 \u0444\u0440\u0435\u0439\u043c\u044b, \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0430\u0434\u0440\u0435\u0441\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0435\u043c\u0443 (promiscuous mode):<\/p>\n<pre><code class=\"cpp\">enc28j60_writeRegByte(ERXFCON,0); <\/code><\/pre>\n<h3>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430<\/h3>\n<h4>Raspberry<\/h4>\n<p>\u041f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u043c eth0 \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c ip \u0430\u0434\u0440\u0435\u0441. \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c ping<\/p>\n<pre><code class=\"bash\">sudo ifconfig eth0 up 10.0.0.2\/24 ping 10.0.0.2 <\/code><\/pre>\n<p>\u0412 \u0434\u0440\u0443\u0433\u043e\u043c \u043e\u043a\u043d\u0435 \u043c\u043e\u0436\u043d\u043e \u0438 tcpdump:<\/p>\n<pre><code class=\"bash\">sudo tcpdump -i eth0 <\/code><\/pre>\n<h4>\u041a\u043e\u043c\u043f<\/h4>\n<p>\u041f\u043e\u0434\u0441\u043e\u0435\u0434\u0438\u043d\u044f\u0435\u043c \u043f\u0440\u043e\u0448\u0438\u0442\u044b\u0439 STM32 \u043a \u043a\u043e\u043c\u043f\u0443, \u0441\u043e\u0435\u0434\u0438\u043d\u044f\u0435\u043c ENC28J60 \u0441\u0435\u0442\u0435\u0432\u044b\u043c \u043a\u0430\u0431\u0435\u043b\u0435\u043c \u0441 raspberry. \u041d\u0430 STM32 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u043c\u0438\u0433\u0430\u0442\u044c \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434, \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044f \u043f\u0440\u0438\u0445\u043e\u0434 arp \/ icmp \u043f\u0430\u043a\u0435\u0442\u043e\u0432 (\u043e\u0442 ping). \u0423\u0431\u0435\u0436\u0434\u0430\u0435\u043c\u0441\u044f, \u0447\u0442\u043e \u043f\u043e\u044f\u0432\u0438\u043b\u0441\u044f \/dev\/ttyACM0:<\/p>\n<pre><code class=\"bash\">ls \/dev\/ttyACM* <\/code><\/pre>\n<p>\u041a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c tap_handler:<\/p>\n<pre><code class=\"bash\">gcc tap_handler.c -o tap_handler .\/tap_handler <\/code><\/pre>\n<p>tap_handler \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0432\u0441\u044e \u0446\u0435\u043f\u043e\u0447\u043a\u0443 &#8212; \u043f\u043e\u0434\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u044b \u043e\u0442 raspberry, \u0430\u0434\u0440\u0435\u0441\u0443\u0435\u0442 \u0438\u0445 tap0, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043e\u0442 \u043d\u0435\u0433\u043e \u0444\u0440\u0435\u0439\u043c \u0432 \u043e\u0442\u0432\u0435\u0442, \u0448\u043b\u0435\u0442 \u0435\u0433\u043e STM32, \u043a\u043e\u0433\u0434\u0430 \u0444\u0440\u0435\u0439\u043c \u0434\u043e\u0445\u043e\u0434\u0438\u0442 \u0434\u043e raspberry \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043f\u0438\u043d\u0433\u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442\u044c.<\/p>\n<h3>\u0414\u0435\u043b\u0430\u0435\u043c \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442 \u043d\u0430 \u043a\u043e\u043c\u043f\u0435<\/h3>\n<p>\u0415\u0441\u043b\u0438 \u043f\u0438\u043d\u0433\u0438 \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0443 \u043d\u0430\u0448\u0435\u0439 \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u043a\u0430\u0440\u0442\u044b.<\/p>\n<h4>\u041a\u043e\u043c\u043f<\/h4>\n<p>\u042f \u043f\u043e\u0434\u0441\u043e\u0435\u0434\u0438\u043d\u0438\u043b\u0441\u044f \u043a raspberry \u043f\u043e ssh \u0447\u0435\u0440\u0435\u0437 wi-fi \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u044e \u0438\u043c \u0441 \u043a\u043e\u043c\u043f\u0430, \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u043d\u0430\u043c \u0442\u0435\u0440\u044f\u0442\u044c \u043d\u0435 \u0441\u0442\u043e\u0438\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u043e\u0441\u0442\u043e \u043c\u0435\u043d\u044f\u0435\u043c default gateway. \u0411\u0440\u0430\u0443\u0437\u0435\u0440 \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u043d\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 raspberry \u043d\u0435 \u0442\u0435\u0440\u044f\u0435\u0442\u0441\u044f:<\/p>\n<pre><code class=\"bash\">sudo route del default gateway 192.168.1.1 sudo route add default gateway 10.0.0.2 <\/code><\/pre>\n<p>\u041c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u043a\u0430 DNS \u0441\u0435\u0440\u0432\u0435\u0440\u0430 (\u0432 \/etc\/resolv.conf \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 nameserver, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, 8.8.8.8).<\/p>\n<h4>Raspberry<\/h4>\n<p>\u0420\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0438\u0437 eth0 \u0432 wlan0 \u0438 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c NAT:<\/p>\n<pre><code class=\"bash\">echo 1 | sudo tee -a \/proc\/sys\/net\/ipv4\/ip_forward sudo iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE <\/code><\/pre>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043a\u043e\u043c\u043f. \u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u044f\u0432\u0438\u0442\u044c\u0441\u044f, \u043f\u0440\u0430\u0432\u0434\u0430 \u043d\u0435\u0431\u044b\u0441\u0442\u0440\u044b\u0439 (\u0443 \u043c\u0435\u043d\u044f 0.5 \u041c\u0431\u0438\u0442\/\u0441).<\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u043d\u0435 \u0437\u0430\u043c\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441 raspberry, \u0430 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u043f\u043e\u0434\u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u043f\u0440\u043e\u0432\u043e\u0434 \u043e\u0442 \u0440\u0443\u0442\u0435\u0440\u0430 \u0432 ENC28J60 (\u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u044c wi-fi \u043d\u0430 \u043a\u043e\u043c\u043f\u0435 \u0438 \u0437\u0430\u0434\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u0430\u0434\u0440\u0435\u0441 tap0). \u041d\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0449\u0435 \u0441 raspberry, \u0432 tcpdump \u0432\u0438\u0434\u043d\u043e \u0432\u0441\u0435 \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442.<\/p>\n<h3>\u0417\u0430\u0447\u0435\u043c \u0432\u0441\u0435 \u044d\u0442\u043e<\/h3>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u0441\u0432\u044f\u0437\u043a\u0443 \u0432 \u0436\u0438\u0437\u043d\u0438 \u043d\u0430\u0432\u0435\u0440\u043d\u043e \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u043e (\u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u043d\u0435\u0434\u043e\u0440\u043e\u0433\u0438\u0445 usb ethernet \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u043e\u0432 \u0432 \u043f\u0440\u043e\u0434\u0430\u0436\u0435), \u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0435 \u0431\u044b\u043b\u043e \u043e\u0447\u0435\u043d\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e. \u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435. <a href=\"https:\/\/github.com\/dsoastro\/stm32_usb_eth_card\" rel=\"noopener noreferrer nofollow\">\u0421\u0441\u044b\u043b\u043a\u0430<\/a> \u043d\u0430 \u043a\u043e\u0434 (\u043f\u0440\u043e\u0435\u043a\u0442 \u0432 Atollic TrueStudio).<\/p>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/530730\/\"> https:\/\/habr.com\/ru\/post\/530730\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>ENC28J60 &#8212; \u043f\u0440\u043e\u0441\u0442\u043e\u0439 Ethernet \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442  \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u0432 \u0440\u043e\u043b\u0438 \u0432\u043d\u0435\u0448\u043d\u0435\u0439 \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u043a\u0430\u0440\u0442\u044b \u0443 \u043e\u0434\u043d\u043e\u043f\u043b\u0430\u0442\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u043e\u0432 \u0441 GPIO (\u0434\u043b\u044f raspberry \u0435\u0441\u0442\u044c \u0434\u0430\u0436\u0435 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0434\u0440\u0430\u0439\u0432\u0435\u0440) \u0438 \u043f\u0440\u043e\u0447\u0438\u0445 \u0430\u0440\u0434\u0443\u0438\u043d. \u0423 \u043c\u043e\u0435\u0433\u043e \u043b\u044d\u043f\u0442\u043e\u043f\u0430 GPIO \u043d\u0435 \u0432\u044b\u0432\u0435\u0434\u0435\u043d\u044b, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c <s>\u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u043a \u0438<\/s> \u043f\u0440\u0438\u043a\u0440\u0443\u0442\u0438\u0442\u044c \u043a \u043d\u0435\u043c\u0443 ENC28J60 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c STM32F103 \u0438 \u0448\u043d\u0443\u0440\u043a\u0430 USB.<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c. <\/p>\n<p>\u041d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f: <\/p>\n<ul>\n<li>\n<p>ENC28J60<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u0430\u044f \u043f\u043b\u0430\u0442\u0430 \u0441 STM32 \u0441 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 USB device (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u043e\u0442 \u0442\u0430\u043a\u0430\u044f):<\/p>\n<\/li>\n<\/ul>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<ul>\n<li>\n<p>\u041a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440 \u0441 Linux (\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e Ubuntu 16)<\/p>\n<\/li>\n<li>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440 \u0441 Ethernet \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f (\u0443 \u043c\u0435\u043d\u044f raspberry pi), \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0439 \u043f\u043e wi-fi (\u0438 \u0432 \u043e\u0434\u043d\u043e\u0439 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0435\u0442\u0438 \u0441 \u043f\u0435\u0440\u0432\u044b\u043c)<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 STM32F103 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0443, \u043c\u0430\u043d\u0443\u0430\u043b\u043e\u0432 \u0432 \u0441\u0435\u0442\u0438 \u0445\u0432\u0430\u0442\u0430\u0435\u0442. \u041a\u0430\u043a \u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0430\u043c\u043e\u0433\u043e ENC28J60 (\u0432 \u0441\u0432\u043e\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0432\u043e\u0442 \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 c \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f\u043c\u0438). \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 ENC28J60 \u043a STM32F103 \u043f\u043e SPI1 \u043e\u043f\u0438\u0441\u0430\u043d\u043e <a href=\"https:\/\/narodstream.ru\/stm-urok-68-lan-enc28j60-chast-1\/\" rel=\"noopener noreferrer nofollow\">\u0442\u0430\u043c \u0436\u0435<\/a>.<\/p>\n<h3>\u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435<\/h3>\n<p>\u041a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440 (usb) -&gt; stm32(SPI) -&gt; ENC28J60(Ethernet \u043a\u0430\u0431\u0435\u043b\u044c) -&gt; raspberry <\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<h3>\u041a\u0430\u043a \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442<\/h3>\n<p>\u041e\u0431\u043e\u0439\u0434\u0435\u043c\u0441\u044f \u0431\u0435\u0437 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u043e\u0432 \u044f\u0434\u0440\u0430, \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432 user space. \u041d\u0430 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0435\u0442\u0435\u0432\u043e\u0439 tap \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 (\u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f, \u0441 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430\u043c\u0438 Ethernet \u0444\u0440\u0435\u0439\u043c\u043e\u0432, \u0435\u0441\u0442\u044c \u0435\u0449\u0435 tun \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0441 ip \u043f\u0430\u043a\u0435\u0442\u0430\u043c\u0438), \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043f\u043e\u0434\u0441\u043e\u0435\u0434\u0438\u043d\u0438\u043c \u043d\u0430\u0448\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 (\u043d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0435 tap_handler.c<em>). <\/em>\u0427\u0442\u043e\u0431\u044b \u0444\u0440\u0435\u0439\u043c \u043f\u043e\u043f\u0430\u043b \u0432 \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u0441\u0442\u0435\u043a Linux\u0430, tap_handler&#8217;\u0443 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0433\u043e \u0432 tap \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441. \u041d\u0443 \u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442, \u043f\u0430\u043a\u0435\u0442\u044b, \u0430\u0434\u0440\u0435\u0441\u043e\u0432\u0430\u043d\u043d\u044b\u0435 tap \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443, \u0431\u0443\u0434\u0443\u0442 \u0447\u0438\u0442\u0430\u0442\u044c\u0441\u044f tap_handler&#8217;\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0441 \u043d\u0438\u043c\u0438 \u0447\u0442\u043e-\u0442\u043e \u0434\u0430\u043b\u044c\u0448\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c. \u0412 \u0438\u0442\u043e\u0433\u0435, tap_handler \u0431\u0435\u0433\u0430\u0435\u0442 \u0432 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435 \u0438 \u0436\u0434\u0435\u0442 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u043b\u0438\u0431\u043e \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b tap \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430, \u043b\u0438\u0431\u043e \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b \/dev\/ttyACM0 (\u044d\u0442\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430\u0448\u0435\u0433\u043e USB \u0434\u0435\u0432\u0430\u0439\u0441\u0430 \u0432 Linux\u0435). \u0412 \u043f\u0435\u0440\u0432\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0438\u0448\u0435\u043c \u0432 \/dev\/ttyACM0, \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u043c \u0432 tap \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441.<\/p>\n<p>\u0411\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043f\u0440\u043e \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430\u043c\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e <a href=\"https:\/\/backreference.org\/2010\/03\/26\/tuntap-interface-tutorial\/\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a> (\u0434\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0440\u0430\u0431\u043e\u0442\u044b vpn). \u041e\u0442\u0441\u044e\u0434\u0430 \u0436\u0435 \u044f \u0432\u0437\u044f\u043b \u043a\u043e\u0434, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0438\u0439 \u0437\u0430 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430\u043c\u0438.<\/p>\n<p>\u041d\u0430 STM32 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 CubeMX \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 USB CDC (virtual com port). \u041f\u043e\u0441\u043b\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f SMT32 \u043a \u043a\u043e\u043c\u043f\u0443 Linux \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u0444\u0430\u0439\u043b \/dev\/ttyACM0 (\u043d\u0443 \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u043d\u043e\u043c\u0435\u0440). \u0418\u0437 \u044d\u0442\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b STM32, \u0430 \u0435\u0441\u043b\u0438 \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0443\u0434\u0430 \u0434\u0430\u043d\u043d\u044b\u0435, \u0438\u0445 \u0441\u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c STM32.<\/p>\n<p>\u041f\u0440\u043e\u0448\u0438\u0432\u043a\u0430 STM32 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e. \u0412 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435 \u0447\u0438\u0442\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u043a\u043e\u043c\u043f\u0430 (\u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>CDC_Receive_FS<\/code> \u0432 \u0444\u0430\u0439\u043b\u0435 usbd_cdc_if.c) \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0438\u0445 \u0432 ENC28J60, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0436\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442 \u0438\u0445 \u0434\u0430\u043b\u044c\u0448\u0435 \u0432 \u0441\u0435\u0442\u044c, \u0430 \u0442\u0430\u043a\u0436\u0435  \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0444\u0440\u0435\u0439\u043c\u044b \u0438\u0437 ENC28J60 \u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0445 \u0432 \u043a\u043e\u043c\u043f \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 <code>CDC_Transmit_FS<\/code>.<\/p>\n<p>\u041d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044f \u043f\u043e\u043d\u0438\u043c\u0430\u044e, CDC \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0435\u0437 \u043e\u0448\u0438\u0431\u043e\u043a. \u041e\u0434\u043d\u0430\u043a\u043e \u044f \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0441\u044f \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e \u043e\u0448\u0438\u0431\u043a\u0438 \u0432\u0441\u0435 \u0436\u0435 \u0435\u0441\u0442\u044c. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 \u043e\u0431\u044b\u0447\u043d\u043e \u0432\u0441\u0435\u0433\u0434\u0430 \u0434\u0443\u0431\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f (\u043f\u0440\u0438\u0447\u0438\u043d\u0443 \u044f \u043d\u0435 \u043d\u0430\u0448\u0435\u043b, \u0434\u0443\u0431\u043b\u044f\u0436 \u0432\u0438\u0434\u0435\u043d \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0432 wireshark \u043f\u0440\u0438 \u043f\u0440\u043e\u0441\u043b\u0443\u0448\u0438\u0432\u0430\u043d\u0438\u0438 \u0448\u0438\u043d\u044b usb). \u0413\u0443\u0433\u043b\u0435\u0436 \u043f\u043e\u043a\u0430\u0437\u0430\u043b, \u0447\u0442\u043e \u0443 \u043a\u043e\u0433\u043e-\u0442\u043e \u044d\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u043b\u043e \u0438\u0437-\u0437\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0435\u043f\u043e\u0434\u0430\u0431\u0430\u044e\u0449\u0435\u0433\u043e \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0447\u0430\u0441\u0442\u043e\u0442\u044b \u043d\u0430 STM32, \u0447\u0442\u043e \u0432\u0440\u044f\u0434 \u043b\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438\u0447\u0438\u043d\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0432 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0442.\u043a.  \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u043a\u0432\u0430\u0440\u0446. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0433\u043e\u0440\u043e\u0434\u0438\u0442\u044c \u043e\u0433\u043e\u0440\u043e\u0434 \u0441 \u043c\u0435\u0442\u043a\u0430\u043c\u0438.<\/p>\n<h3>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043a\u043e\u043c\u043f\u0430<\/h3>\n<p>\u0421\u0435\u0442\u0435\u0432\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439:<\/p>\n<pre><code class=\"bash\">sudo openvpn --mktun --dev tap0 <\/code><\/pre>\n<p>\u041f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c ip \u0430\u0434\u0440\u0435\u0441:<\/p>\n<pre><code class=\"bash\">sudo ifconfig tap0 10.0.0.1\/24 up <\/code><\/pre>\n<h4>tap_handler.\u0441<\/h4>\n<p>\u0414\u043b\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \/dev\/ttyACM0 \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 raw \u0432\u0438\u0434\u0435 \u0438 \u043d\u0435 \u0434\u0430\u0432\u0430\u0442\u044c \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0443 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0430 \u0432\u043d\u043e\u0441\u0438\u0442\u044c \u0432 \u043d\u0438\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043d\u0435\u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u043c\u0438 \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u043c\u0438 \u0438 \u043f\u0440.). \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0430:<\/p>\n<pre><code class=\"cpp\">char cdc_name[20]=\"\/dev\/ttyACM0\"; int tty_fd = open(cdc_name, O_RDWR | O_NOCTTY);  struct termios portSettings; tcgetattr(tty_fd, &amp;portSettings); cfmakeraw(&amp;portSettings); tcsetattr(tty_fd, TCSANOW, &amp;portSettings); tcflush(tty_fd, TCOFLUSH); <\/code><\/pre>\n<p>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c tap_handler \u043a tap0:<\/p>\n<pre><code class=\"cpp\">\/* \u0432 dev \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0438\u043c\u044f \u0443\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 tap0*\/ int tun_alloc(char *dev, int flags) {     struct ifreq ifr;     int fd, err;     char *clonedev = \"\/dev\/net\/tun\";     \/* \u043e\u0442\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u043c\u0441\u044f \u043e\u0442 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430  \/dev\/net\/tun *\/     if( (fd = open(clonedev , O_RDWR)) &lt; 0 ) {         perror(\"Opening \/dev\/net\/tun\");         return fd;     }         memset(&amp;ifr, 0, sizeof(ifr));      ifr.ifr_flags = flags;          \/* \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0443\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 tap0 *\/     if (*dev) {         strncpy(ifr.ifr_name, dev, IFNAMSIZ);     }     \/* \u043f\u043e\u0434\u0441\u043e\u0435\u0434\u0438\u043d\u044f\u0435\u043c\u0441\u044f \u043a \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443 *\/     if( (err = ioctl(fd, TUNSETIFF, (void *)&amp;ifr)) &lt; 0 ) {         perror(\"ioctl(TUNSETIFF)\");                 close(fd);         return err;     }          strcpy(dev, ifr.ifr_name);      return fd; }<\/code><\/pre>\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u044d\u0442\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0432 main.c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"cpp\">strcpy(tun_name, \"tap0\"); int tap_fd = tun_alloc(tun_name, IFF_TAP | IFF_NO_PI); <\/code><\/pre>\n<p>\u0424\u043b\u0430\u0433 IFF_TAP \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u0442\u0438\u043f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 (tap). \u0424\u043b\u0430\u0433 IFF_NO_PI \u043d\u0443\u0436\u0435\u043d, \u0447\u0442\u043e\u0431\u044b \u044f\u0434\u0440\u043e \u043d\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u043b\u043e \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u043d\u044b\u0435 \u0431\u0430\u0439\u0442\u044b \u043f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u043f\u0430\u043a\u0435\u0442\u0430.<\/p>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 tap0 \u0438 \u0432 \/dev\/ttyACM0. \u041f\u043e\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0435\u0442, tap_handler \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0435\u043c select:<\/p>\n<pre><code class=\"cpp\">while(1) {     int ret;     fd_set rd_set;      FD_ZERO(&amp;rd_set);     \/* tap_fd - tap inteface descriptor *\/     FD_SET(tap_fd, &amp;rd_set);     \/* tty_fd - \/dev\/ttyACM0 descriptor *\/     FD_SET(tty_fd, &amp;rd_set);      ret = select(maxfd + 1, &amp;rd_set, NULL, NULL, NULL);<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a. \u041f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u0444\u0440\u0435\u0439\u043c\u0430 \u043e\u0442 tap0 tap_handler \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u043f\u0430\u043a\u0435\u0442 \u0434\u043b\u044f STM32 (\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0430\u043a\u0435\u0442\u0430: \u043f\u0430\u043a\u0435\u0442 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 \u043c\u0435\u0442\u043a\u0438 &#8212; \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 4 \u0431\u0430\u0439\u0442, \u0447\u0442\u043e\u0431\u044b \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0447\u0430\u043b\u043e \u0444\u0440\u0435\u0439\u043c\u0430, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 2 \u0431\u0430\u0439\u0442\u0430 &#8212; \u0434\u043b\u0438\u043d\u0430 \u0444\u0440\u0435\u0439\u043c\u0430, \u0437\u0430\u0442\u0435\u043c \u0443\u0436\u0435 \u0441\u0430\u043c \u0444\u0440\u0435\u0439\u043c) \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0435\u0433\u043e \u0432 \/dev\/ttyACM0. \u0417\u0430\u0442\u0435\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430, \u0447\u0442\u043e\u0431\u044b \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0448\u043b\u0438 \u0443\u0441\u043f\u0435\u0448\u043d\u043e:<\/p>\n<pre><code class=\"cpp\">if(FD_ISSET(tap_fd, &amp;rd_set)) {         uint16_t nread = cread(tap_fd, buffer, BUFSIZE);        uint8_t buf[6];     *(uint32_t *)buf = PACKET_START_SIGN;     *(uint16_t *)(buf + 4) = nread;         cwrite(tty_fd,(char *)buf,6);         cwrite(tty_fd, buffer, nread);     delay_micro(delay_m);     }<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \/dev\/ttyACM0, \u0443\u0431\u0435\u0436\u0434\u0430\u0435\u043c\u0441\u044f \u0447\u0442\u043e \u043e\u043d\u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442\u0441\u044f \u0441 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u043c\u0435\u0442\u043a\u0438 (\u0442\u0435 \u0436\u0435 4 \u0431\u0430\u0439\u0442\u0430), \u0437\u0430\u0442\u0435\u043c \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0434\u043b\u0438\u043d\u0443 \u0444\u0440\u0435\u0439\u043c\u0430, \u0438 \u043f\u043e\u0442\u043e\u043c \u0441\u0430\u043c \u0444\u0440\u0435\u0439\u043c. \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0444\u0440\u0435\u0439\u043c \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432 tap \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441:<\/p>\n<pre><code class=\"cpp\">if(FD_ISSET(tty_fd, &amp;rd_set)) {     uint32_t sign;     \/* \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u043c\u0435\u0442\u043a\u0443 *\/     int nread = read_n(tty_fd, (char *)&amp;sign, sizeof(sign));     \/* \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440 \u0437\u0430\u043a\u0440\u044b\u0442, \u0432\u044b\u0445\u043e\u0434\u0438\u043c \u0438\u0437 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b *\/     if(nread == 0) {               break;     }     \/* \u0435\u0441\u043b\u0438 \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442, \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043d\u0430\u0439\u0442\u0438 \u043f\u043e\u0434\u043f\u0438\u0441\u044c \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 4 \u0431\u0430\u0439\u0442\u0430\u0445 *\/     if(sign != PACKET_START_SIGN){              continue;     }     \/* \u0447\u0438\u0442\u0430\u0435\u043c \u0434\u043b\u0438\u043d\u0443 \u0444\u0440\u0435\u0439\u043c\u0430 *\/     nread = read_n(tty_fd, (char *)&amp;plength, 2);     if(nread == 0) {               break;     }      if (nread != 2){               continue;     }   \/* \u0437\u0434\u0435\u0441\u044c \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 \u0434\u0443\u0431\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f *\/     if(flag){       flag = 0;       nread = cread(tty_fd, buffer, sizeof(buffer));       if(nread != 6){                 continue;       }     }   \/* \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0434\u043b\u0438\u043d\u0430 \u043f\u0430\u043a\u0435\u0442\u0430, \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 *\/     if(plength &gt; BUFSIZE){             break;     }      \/* \u0447\u0438\u0442\u0430\u0435\u043c \u0444\u0440\u0435\u0439\u043c (plength \u0431\u0430\u0439\u0442)  \u0438 \u043f\u0438\u0448\u0435\u043c \u0435\u0433\u043e \u0432 tap interface*\/     nread = read_n(tty_fd, buffer, plength);                 if (nread != 0){                     cwrite(tap_fd, buffer, nread);                     delay_micro(delay_m);     }   }<\/code><\/pre>\n<h3>\u0421\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b STM32<\/h3>\n<p>\u041a\u0440\u043e\u043c\u0435 USB CDC \u0432 CubeMX \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043c \u0442\u0430\u043a\u0436\u0435 HAL \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 SPI1 \u0438 \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u043e\u043c.<\/p>\n<p>\u041f\u0440\u0438\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432 callback&#8217;\u0435 <code>CDC_Receive_FS<\/code> (\u0444\u0430\u0439\u043b usbd_cdc_if.c), \u0437\u0430\u043f\u0443\u0441\u043a \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f\u043c\u0438 \u0432 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 USB. \u0412 \u044d\u0442\u043e\u043c \u043c\u0435\u0441\u0442\u0435 \u043d\u0435\u043b\u044c\u0437\u044f \u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u043b\u0433\u043e\u0438\u0433\u0440\u0430\u044e\u0449\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0448\u0435\u0434\u0448\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0432 \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u0439 \u0431\u0443\u0444\u0435\u0440, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0437\u0430\u0431\u0438\u0440\u0430\u0435\u043c \u0438\u0445 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u0430\u0440\u0443\u0436\u0443 \u0447\u0435\u0440\u0435\u0437 ENC28J60. \u041f\u0440\u0438 \u0440\u0438\u0441\u043a\u0435 \u043f\u0435\u0440\u0435\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0431\u0443\u0444\u0435\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0442\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f:<\/p>\n<pre><code class=\"cpp\">\/* USB_POINTERS_ARRAY_SIZE - \u0440\u0430\u0437\u043c\u0435\u0440 array_pos *\/ \/* MAX_FRAMELEN - \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0434\u043b\u0438\u043d\u0430 \u0444\u0440\u0435\u0439\u043c\u0430 *\/ \/* USB_BUFSIZE - \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u0433\u043e \u0431\u0443\u0444\u0435\u0440\u0430 *\/  extern uint8_t usb_buf[]; \/* \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u0439 \u0431\u0443\u0444\u0435\u0440 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u043e\u0442 \u043a\u043e\u043c\u043f\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 *\/ extern uint32_t pos_int; \/* \u0438\u043d\u0434\u0435\u043a\u0441 \u0434\u043b\u044f \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u043f\u0430\u043a\u0435\u0442\u0430 \u0432 \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u043c \u0431\u0443\u0444\u0435\u0440\u0435 *\/ extern uint32_t array_pos[]; \/* \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b \u0432 \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u043c \u0431\u0443\u0444\u0435\u0440\u0435 *\/ extern uint32_t p_a; \/* \u0438\u043d\u0434\u0435\u043a\u0441 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 array_pos \u0434\u043b\u044f CDC_Receive_FS*\/ extern uint32_t pl_a;\/* \u0438\u043d\u0434\u0435\u043a\u0441 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 array_pos \u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430 *\/  \/* USB_POINTERS_ARRAY_SIZE - \u0440\u0430\u0437\u043c\u0435\u0440 array_pos *\/ \/* MAX_FRAMELEN - \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0434\u043b\u0438\u043d\u0430 \u0444\u0440\u0435\u0439\u043c\u0430 *\/ \/* USB_BUFSIZE - \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u0433\u043e \u0431\u0443\u0444\u0435\u0440\u0430 *\/  static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) {   int8_t memok = 1;   \/* \u043e\u0442\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u043f\u0440\u0438\u0448\u0435\u0434\u0448\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \u043c\u0435\u0441\u0442\u0430 \u0432 \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u043c \u0431\u0443\u0444\u0435\u0440\u0435 *\/   if( pl_a !=0 &amp;&amp; p_a !=0){     int32_t mem_lag = array_pos[(p_a - 1) % USB_POINTERS_ARRAY_SIZE] - array_pos[(pl_a - 1) % USB_POINTERS_ARRAY_SIZE];     if(mem_lag &gt; USB_BUFSIZE - MAX_FRAMELEN)       memok = 0;   }   \/* \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u043f\u043e\u0441\u0442\u0443\u043f\u0438\u0432\u0448\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u0439 \u0431\u0443\u0444\u0435\u0440,     \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432 \u043f\u0440\u0438\u0448\u0435\u0434\u0448\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 (array_pos) *\/   if(*Len &lt; USB_BUFSIZE &amp;&amp; *Len != 0 &amp;&amp; memok){     uint16_t offset = pos_int % USB_BUFSIZE;     uint16_t new_pos = offset + *Len;     uint8_t split = 0;     if (new_pos &gt; USB_BUFSIZE){       split = 1;     }     if(split){       int len1 = USB_BUFSIZE - offset;       int len2 = *Len - len1;       memcpy(usb_buf + offset, Buf, len1);       memcpy(usb_buf, Buf + len1, len2);     }     else       memcpy(usb_buf + offset, Buf, *Len);     pos_int += *Len;      array_pos[p_a % USB_POINTERS_ARRAY_SIZE] = pos_int;     p_a++;   }   USBD_CDC_SetRxBuffer(&amp;hUsbDeviceFS, &amp;Buf[0]);   USBD_CDC_ReceivePacket(&amp;hUsbDeviceFS);   return (USBD_OK); }<\/code><\/pre>\n<p>\u0412 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 (main.c) \u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0431\u0443\u0444\u0435\u0440\u0435 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0445 \u0447\u0435\u0440\u0435\u0437 ENC28J60:<\/p>\n<pre><code class=\"cpp\">if(pl_a &lt; p_a){       uint32_t prev = 0;   if(pl_a &gt; 0)     prev = array_pos[(pl_a - 1) % USB_POINTERS_ARRAY_SIZE];   \/* \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u0430\u043a\u0435\u0442\u0430 (\u043a\u0443\u0441\u043e\u0447\u0435\u043a \u0444\u0440\u0435\u0439\u043c\u0430), \u043f\u0440\u0438\u043d\u044f\u0442\u043e\u0433\u043e \u0432 CDC_Receive_FS *\/   int32_t n = array_pos[pl_a % USB_POINTERS_ARRAY_SIZE] - prev;\/\/usb frame size   \/* \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u043f\u0430\u043a\u0435\u0442 \u0432 \u0431\u0443\u0444\u0435\u0440\u0435 *\/   uint8_t *from = usb_buf + prev % USB_BUFSIZE;   \/* \u043f\u0440\u0438\u0437\u043d\u0430\u043a \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u0438 \u043f\u0430\u043a\u0435\u0442\u0430 *\/   uint8_t right_n = 1;   if (n &lt; 0 || n &gt; MAX_FRAMELEN){     right_n = 0;   }    \/* \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u043d\u043e\u0432\u044b\u0439 \u0444\u0440\u0435\u0439\u043c. \u0412 \u043f\u0430\u043a\u0435\u0442\u0435 <\/code><\/pre>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-314081","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/314081","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=314081"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/314081\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=314081"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=314081"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=314081"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}