{"id":289851,"date":"2018-09-25T08:25:02","date_gmt":"2018-09-25T04:25:02","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=289851"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=289851","title":{"rendered":"DevCore: \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442\u0430 DevBoy"},"content":{"rendered":"\n<div class=\"post__text post__text-html js-mediator-article\"><b>\u041f\u0440\u0438\u0432\u0435\u0442, \u0434\u0440\u0443\u0437\u044c\u044f!<\/b><\/p>\n<p>  \u0421 \u0432\u0430\u043c\u0438 \u0441\u043d\u043e\u0432\u0430 \u041d\u0438\u043a\u043e\u043b\u0430\u0439, \u0432 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 &#171;<i><a href=\"https:\/\/habr.com\/post\/423499\/\">DevBoy \u2014 \u043a\u0430\u043a \u044f \u0441\u043e\u0437\u0434\u0430\u043b \u043f\u0440\u043e\u0435\u043a\u0442 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430 Kickstarter<\/a><\/i>&#187; \u0443\u043f\u043e\u0440 \u0434\u0435\u043b\u0430\u043b\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0430 \u0432\u043d\u0435\u0448\u043d\u0435\u043c \u0432\u0438\u0434\u0435 \u0438 \u0436\u0435\u043b\u0435\u0437\u0435, \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e &#171;<i>\u0432\u043d\u0443\u0442\u0440\u0438<\/i>&#187; \u0438 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u0443\u044e \u0447\u0430\u0441\u0442\u044c. <br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/6r\/n4\/u8\/6rn4u8jvzpd-c9_oykzqia4l8fk.jpeg\"><br \/>  \u041a\u043e\u043c\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u2014 \u043f\u0440\u043e\u0448\u0443 \u043f\u043e\u0434 \u043a\u0430\u0442.<a name=\"habracut\"><\/a><\/p>\n<p>  \u041a\u0430\u043a \u0431\u044b\u043b\u043e \u0441\u043a\u0430\u0437\u0430\u043d\u043e \u0440\u0430\u043d\u0435\u0435, \u043f\u0440\u043e\u0435\u043a\u0442 \u0431\u0430\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u0430 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0435 <b>STM32F416RG<\/b> \u043e\u0442 STMicroelectronics \u043d\u0430 \u044f\u0434\u0440\u0435 ARM Cortex-M4. \u0414\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u043e\u0434 \u0434\u0430\u043d\u043d\u044b\u0435 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u044b \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 IDE, \u043e\u0434\u043d\u0430\u043a\u043e \u0434\u043b\u044f \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0443\u0436\u043d\u0430 \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u0430\u044f IDE, \u0430 \u043b\u0443\u0447\u0448\u0435 \u0435\u0449\u0435 \u0438 Open Source. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, IDE \u0434\u043e\u043b\u0436\u043d\u0430 \u0435\u0449\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0432 <b>STM32CubeMX<\/b>. \u041d\u0430 \u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442, \u043a\u043e\u0433\u0434\u0430 \u044f \u043d\u0430\u0447\u0430\u043b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0430\u0434 \u044d\u0442\u0438\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c \u0431\u044b\u043b\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0430 IDE \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0449\u0430\u044f \u0432\u0441\u0435\u043c \u044d\u0442\u0438\u043c \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f\u043c \u2014 <b><a href=\"http:\/\/www.openstm32.org\/System%2BWorkbench%2Bfor%2BSTM32\">System Workbench for STM32<\/a><\/b>.<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/v7\/pz\/vi\/v7pzviufspf40flvruysuro_ex0.png\">\u041d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0435\u0449\u0435 Atollic TrueStudio \u0441\u0442\u0430\u0432\u0448\u0430\u044f \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a STMicroelectronics \u0438\u0445 \u043a\u0443\u043f\u0438\u043b\u0430.<\/p>\n<p>  \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0430\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u2014 \u044d\u0442\u043e <b><a href=\"https:\/\/www.st.com\/en\/development-tools\/stm32cubemx.html\">STM32CubeMX<\/a><\/b>. \u0414\u0430\u043d\u043d\u0430\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u0443 \u0434\u043b\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0435\u0440\u0438\u0444\u0435\u0440\u0438\u0438 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430.<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/i4\/ym\/3u\/i4ym3unkrgskza2fmumqmmfzs1o.png\"><br \/>  \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u0434 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f <b>H<\/b>ardware <b>A<\/b>bstraction <b>L<\/b>ayer(HAL). \u041c\u043d\u043e\u0433\u0438\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u044b \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043b\u044e\u0431\u044f\u0442 \u044d\u0442\u043e &#171;<i>\u0442\u0432\u043e\u0440\u0435\u043d\u0438\u0435<\/i>&#171;, \u043e\u043d\u043e \u043d\u0435 \u043b\u0438\u0448\u0435\u043d\u043e \u0431\u0430\u0433\u043e\u0432, \u043d\u043e, \u0442\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u043e\u043d\u043e \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0438 \u0443\u043b\u0443\u0447\u0448\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u043c\u0435\u0436\u0434\u0443 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430\u043c\u0438 \u043e\u0442 STMicroelectronics.<br \/>  \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043f\u0440\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0435\u0433\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u0433\u043e \u041f\u041e \u0442\u0430\u043a\u043e\u0433\u043e \u043a\u0430\u043a <b><a href=\"https:\/\/www.freertos.org\/\">FreeRTOS<\/a><\/b>, <b><a href=\"http:\/\/elm-chan.org\/fsw\/ff\/00index_e.html\">FatFS<\/a><\/b> \u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0434\u0440\u0443\u0433\u0438\u0445.<\/p>\n<p>  \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0433\u043e \u041f\u041e \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0438, \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0441\u0430\u043c\u043e\u043c\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u043c\u0443 \u2014 \u043a <b>DevCore<\/b>. \u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043e\u0442 &#171;<i>\u042f\u0434\u0440\u043e \u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438<\/i>&#187; \u043f\u043e\u0439\u0434\u0435\u043c \u043f\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0443.<\/p>\n<p>  \u0412 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u044d\u0442\u043e <b>\u0421++ RTOS Wrapper<\/b>(<i>FreeRTOS \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435<\/i>). \u0412\u0440\u0430\u043f\u043f\u0435\u0440 \u043d\u0443\u0436\u0435\u043d \u043f\u043e \u0434\u0432\u0443\u043c \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c:<\/p>\n<ul>\n<li>\u0413\u043e\u0440\u0430\u0437\u0434\u043e \u043f\u0440\u0438\u044f\u0442\u043d\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442, \u0430 \u043f\u043e\u0442\u043e\u043c \u0437\u0432\u0430\u0442\u044c \u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443 mutex.Take(), \u0447\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0445\u044d\u043d\u0434\u043b, \u0437\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f, \u0430 \u043f\u043e\u0442\u043e\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0445\u044d\u043d\u0434\u043b \u0432\u043e \u0432\u0441\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043c\u044c\u044e\u0442\u0435\u043a\u0441\u0430\u043c\u0438<\/li>\n<li>\u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0437\u0430\u043c\u0435\u043d\u044b RTOS \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u0440\u0430\u043f\u043f\u0435\u0440, \u0430 \u043d\u0435 \u0432\u0441\u0435 \u0432\u044b\u0437\u043e\u0432\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0439 RTOS \u0438\u0437 \u043a\u043e\u0434\u0430<\/li>\n<\/ul>\n<p>  \u041f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u044c \u043a\u043e\u0434 \u0432\u0440\u0430\u043f\u043f\u0435\u0440\u0430 \u0442\u0443\u0442 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430, \u043a\u043e\u043c\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u2014 <a href=\"https:\/\/github.com\/nickshl\/devboy\">\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 GitHub<\/a>, \u0430 \u043c\u044b \u0438\u0434\u0435\u043c \u0434\u0430\u043b\u044c\u0448\u0435.<\/p>\n<p>  \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u2014 <b>Application Framework<\/b>. \u042d\u0442\u043e \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0437\u0430\u0434\u0430\u0447. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044d\u0442\u043e \u0432\u0441\u0435\u0433\u043e \u0434\u0432\u0430 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0435 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u0444\u0430\u0439\u043b\u0430 \u0435\u0441\u0442\u044c \u0441\u043c\u044b\u0441\u043b \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u0438\u0445 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Header<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">\/\/****************************************************************************** \/\/  @file AppTask.h \/\/  @author Nicolai Shlapunov \/\/ \/\/  @details DevCore: Application Task Base Class, header \/\/ \/\/  @section LICENSE \/\/ \/\/   Software License Agreement (Modified BSD License) \/\/ \/\/   Copyright (c) 2016, Devtronic &amp; Nicolai Shlapunov \/\/   All rights reserved. \/\/ \/\/   Redistribution and use in source and binary forms, with or without \/\/   modification, are permitted provided that the following conditions are met: \/\/ \/\/   1. Redistributions of source code must retain the above copyright \/\/      notice, this list of conditions and the following disclaimer. \/\/   2. Redistributions in binary form must reproduce the above copyright \/\/      notice, this list of conditions and the following disclaimer in the \/\/      documentation and\/or other materials provided with the distribution. \/\/   3. Neither the name of the Devtronic nor the names of its contributors \/\/      may be used to endorse or promote products derived from this software \/\/      without specific prior written permission. \/\/   4. Redistribution and use of this software other than as permitted under \/\/      this license is void and will automatically terminate your rights under \/\/      this license. \/\/ \/\/   THIS SOFTWARE IS PROVIDED BY DEVTRONIC ''AS IS'' AND ANY EXPRESS OR IMPLIED \/\/   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \/\/   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \/\/   IN NO EVENT SHALL DEVTRONIC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \/\/   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED \/\/   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR \/\/   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY \/\/   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING \/\/   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS \/\/   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \/\/ \/\/  @section SUPPORT \/\/ \/\/   Devtronic invests time and resources providing this open source code, \/\/   please support Devtronic and open-source hardware\/software by \/\/   donations and\/or purchasing products from Devtronic. \/\/ \/\/******************************************************************************  #ifndef AppTask_h #define AppTask_h  \/\/ ***************************************************************************** \/\/ ***   Includes   ************************************************************ \/\/ ***************************************************************************** #include \"DevCfg.h\"  \/\/ ***************************************************************************** \/\/ * AppTask class. This class is wrapper for call C++ function from class. **** \/\/ ***************************************************************************** class AppTask {   public:     \/\/ *************************************************************************     \/\/ ***   Init Task   *******************************************************     \/\/ *************************************************************************     virtual void InitTask(void) {CreateTask();}    protected:     \/\/ *************************************************************************     \/\/ ***   Constructor   *****************************************************     \/\/ *************************************************************************     AppTask(uint16_t stk_size, uint8_t task_prio, const char name[],             uint16_t queue_len = 0U, uint16_t queue_msg_size = 0U,             void* task_msg_p = nullptr, uint32_t task_interval_ms = 0U) :       ctrl_queue((queue_len + 2U), sizeof(CtrlQueueMsg)),       task_queue(queue_len, queue_msg_size), task_msg_ptr(task_msg_p),       timer(task_interval_ms, RtosTimer::REPEATING, TimerCallback, (void*)this),       stack_size(stk_size), task_priority(task_prio), task_name(name) {};      \/\/ *************************************************************************     \/\/ ***   Virtual destructor - prevent warning   ****************************     \/\/ *************************************************************************     virtual ~AppTask() {};      \/\/ *************************************************************************     \/\/ ***   Create task function   ********************************************     \/\/ *************************************************************************     \/\/ * This function creates new task in FreeRTOS, provide pointer to function     \/\/ * and pointer to class as parameter. When TaskFunctionCallback() called     \/\/ * from FreeRTOS, it use pointer to class from parameter to call virtual     \/\/ * functions.     void CreateTask();      \/\/ *************************************************************************     \/\/ ***   Setup function   **************************************************     \/\/ *************************************************************************     \/\/ * * virtual function - some tasks may not have Setup() actions     virtual Result Setup() {return Result::RESULT_OK;}      \/\/ *************************************************************************     \/\/ ***   IntervalTimerExpired function   ***********************************     \/\/ *************************************************************************     \/\/ * Empty virtual function - some tasks may not have TimerExpired() actions     virtual Result TimerExpired() {return Result::RESULT_OK;}      \/\/ *************************************************************************     \/\/ ***   ProcessMessage function   *****************************************     \/\/ *************************************************************************     \/\/ * Empty virtual function - some tasks may not have ProcessMessage() actions     virtual Result ProcessMessage() {return Result::RESULT_OK;}      \/\/ *************************************************************************     \/\/ ***   Loop function   ***************************************************     \/\/ *************************************************************************     \/\/ * Empty virtual function - some tasks may not have Loop() actions     virtual Result Loop() {return Result::RESULT_OK;}      \/\/ *************************************************************************     \/\/ ***   SendTaskMessage function   ****************************************     \/\/ *************************************************************************     Result SendTaskMessage(const void* task_msg, bool is_priority = false);    private:     \/\/ Task control queue message types     enum CtrlQueueMsgType     {        CTRL_TIMER_MSG,        CTRL_TASK_QUEUE_MSG     };     \/\/ Task control queue message struct     struct CtrlQueueMsg     {       CtrlQueueMsgType type;     };     \/\/ Task control queue     RtosQueue ctrl_queue;      \/\/ Task queue     RtosQueue task_queue;     \/\/ Pointer to receive message buffer     void* task_msg_ptr;      \/\/ Timer object     RtosTimer timer;      \/\/ Task stack size     uint16_t stack_size;     \/\/ Task priority     uint8_t task_priority;     \/\/ Pointer to the task name     const char* task_name;      \/\/ *************************************************************************     \/\/ ***   IntLoop function   ************************************************     \/\/ *************************************************************************     Result IntLoop();      \/\/ *************************************************************************     \/\/ ***   TaskFunctionCallback   ********************************************     \/\/ *************************************************************************     static void TaskFunctionCallback(void* ptr);      \/\/ *************************************************************************     \/\/ ***   IntervalTimerCallback function   **********************************     \/\/ *************************************************************************     static void TimerCallback(void* ptr);      \/\/ *************************************************************************     \/\/ ***   SendControlMessage function   *************************************     \/\/ *************************************************************************     Result SendControlMessage(const CtrlQueueMsg&amp; ctrl_msg, bool is_priority = false);      \/\/ *************************************************************************     \/\/ ***   Change counter   **************************************************     \/\/ *************************************************************************     static void ChangeCnt(bool is_up);      \/\/ *************************************************************************     \/\/ ***   Private constructor and assign operator - prevent copying   *******     \/\/ *************************************************************************     AppTask();     AppTask(const AppTask&amp;);     AppTask&amp; operator=(const AppTask&amp;); };  #endif<\/code><\/pre>\n<\/div>\n<\/div>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Code<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">\/\/****************************************************************************** \/\/  @file AppTask.cpp \/\/  @author Nicolai Shlapunov \/\/ \/\/  @details DevCore: Application Task Base Class, implementation \/\/ \/\/  @copyright Copyright (c) 2016, Devtronic &amp; Nicolai Shlapunov \/\/             All rights reserved. \/\/ \/\/  @section SUPPORT \/\/ \/\/   Devtronic invests time and resources providing this open source code, \/\/   please support Devtronic and open-source hardware\/software by \/\/   donations and\/or purchasing products from Devtronic. \/\/ \/\/******************************************************************************  \/\/ ***************************************************************************** \/\/ ***   Includes   ************************************************************ \/\/ ***************************************************************************** #include \"AppTask.h\" #include \"RtosMutex.h\"  \/\/ ***************************************************************************** \/\/ ***   Static variables   **************************************************** \/\/ ***************************************************************************** static RtosMutex startup_mutex; static uint32_t startup_cnt = 0U;  \/\/ ***************************************************************************** \/\/ ***   Create task function   ************************************************ \/\/ ***************************************************************************** void AppTask::CreateTask() {   Result result = Result::RESULT_OK;    \/\/ If interval timer period isn't zero or task queue present   if((timer.GetTimerPeriod() != 0U) || (task_queue.GetQueueLen() != 0U))   {     \/\/ Set Control Queue name     ctrl_queue.SetName(task_name, \"Ctrl\");     \/\/ Create control queue     result = ctrl_queue.Create();   }   \/\/ If task queue present   if(task_queue.GetQueueLen() != 0U)   {     \/\/ Set Task Queue name     task_queue.SetName(task_name, \"Task\");     \/\/ Create task queue     result |= task_queue.Create();   }   \/\/ If interval timer period isn't zero   if(timer.GetTimerPeriod() != 0U)   {     \/\/ Create timer     result |= timer.Create();   }   \/\/ Create task: function - TaskFunctionCallback(), parameter - pointer to \"this\"   result |= Rtos::TaskCreate(TaskFunctionCallback, task_name, stack_size, this, task_priority);    \/\/ Check result   if(result.IsBad())   {     \/\/ TODO: implement error handling     Break();   } }  \/\/ ***************************************************************************** \/\/ ***   SendTaskMessage function   ******************************************** \/\/ ***************************************************************************** Result AppTask::SendTaskMessage(const void* task_msg, bool is_priority) {   Result result = Result::RESULT_OK;    \/\/ Send task message to front or back of task queue   if(is_priority == true)   {     result = task_queue.SendToFront(task_msg);   }   else   {     result = task_queue.SendToBack(task_msg);   }    \/\/ If successful - send message to the control queue   if(result.IsGood())   {     CtrlQueueMsg ctrl_msg;     ctrl_msg.type = CTRL_TASK_QUEUE_MSG;     result = SendControlMessage(ctrl_msg, is_priority);   }    return result; }  \/\/ ***************************************************************************** \/\/ ***   IntLoop function   **************************************************** \/\/ ***************************************************************************** Result AppTask::IntLoop() {   Result result = Result::RESULT_OK;    while(result.IsGood())   {     \/\/ Buffer for control message     CtrlQueueMsg ctrl_msg;     \/\/ Read on the control queue     result = ctrl_queue.Receive(&amp;ctrl_msg, timer.GetTimerPeriod() * 2U);     \/\/ If successful     if(result.IsGood())     {       \/\/ Check message type       switch(ctrl_msg.type)       {         case CTRL_TIMER_MSG:           result = TimerExpired();           break;           case CTRL_TASK_QUEUE_MSG:          {            \/\/ Non blocking read from the task queue            result = task_queue.Receive(task_msg_ptr, 0U);            \/\/ If successful            if(result.IsGood())            {              \/\/ Process it!              result = ProcessMessage();            }            break;          }           default:            result = Result::ERR_INVALID_ITEM;            break;       }     }   }    return result; }  \/\/ ***************************************************************************** \/\/ ***   TaskFunctionCallback   ************************************************ \/\/ ***************************************************************************** void AppTask::TaskFunctionCallback(void* ptr) {   Result result = Result::ERR_NULL_PTR;    if(ptr != nullptr)   {     \/\/ Set good result     result = Result::RESULT_OK;     \/\/ Get reference to the task object     AppTask&amp; app_task = *(static_cast&lt;AppTask*&gt;(ptr));      \/\/ Increment counter before call Setup()     ChangeCnt(true);     \/\/ Call virtual Setup() function from AppTask class     app_task.Setup();     \/\/ Decrement counter after call Setup()     ChangeCnt(false);     \/\/ Pause for give other tasks run Setup()     RtosTick::DelayTicks(1U);     \/\/ Pause while other tasks run Setup() before executing any Loop()     while(startup_cnt) RtosTick::DelayTicks(1U);      \/\/ If no timer or queue - just call Loop() function     if((app_task.timer.GetTimerPeriod() == 0U) &amp;&amp; (app_task.task_queue.GetQueueLen() == 0U))     {       \/\/ Call virtual Loop() function from AppTask class       while(app_task.Loop() == Result::RESULT_OK);     }     else     {       \/\/ Start task timer if needed       if(app_task.timer.GetTimerPeriod() != 0U)       {         result = app_task.timer.Start();       }       \/\/ Check result       if(result.IsGood())       {         \/\/ Call internal AppTask function         result = app_task.IntLoop();       }       \/\/ Stop task timer if needed       if(app_task.timer.GetTimerPeriod() != 0U)       {         result |= app_task.timer.Stop();       }     }   }    \/\/ Check result   if(result.IsBad())   {     \/\/ TODO: implement error handling     Break();   }    \/\/ Delete task after exit   Rtos::TaskDelete(); }  \/\/ ***************************************************************************** \/\/ ***   TimerCallback function   ********************************************** \/\/ ***************************************************************************** void AppTask::TimerCallback(void* ptr) {   Result result = Result::ERR_NULL_PTR;    if(ptr != nullptr)   {     \/\/ Get reference to the task object     AppTask&amp; task = *((AppTask*)ptr);      \/\/ Create control timer message     CtrlQueueMsg timer_msg;     timer_msg.type = CTRL_TIMER_MSG;      \/\/ Send message to the control queue     result = task.SendControlMessage(timer_msg);   }    \/\/ Check result   if(result.IsBad())   {     \/\/ TODO: implement error handling     Break();   } }  \/\/ ***************************************************************************** \/\/ ***   SendControlMessage function   ***************************************** \/\/ ***************************************************************************** Result AppTask::SendControlMessage(const CtrlQueueMsg&amp; ctrl_msg, bool is_priority) {   Result result;    if(is_priority == true)   {     result = ctrl_queue.SendToFront(&amp;ctrl_msg);   }   else   {     result = ctrl_queue.SendToBack(&amp;ctrl_msg);   }    return result; }  \/\/ ***************************************************************************** \/\/ ***   Change counter   ****************************************************** \/\/ ***************************************************************************** void AppTask::ChangeCnt(bool is_up) {   \/\/ Take semaphore before change counter   startup_mutex.Lock();   \/\/ Check direction   if(is_up == true)   {     \/\/ Increment counter     startup_cnt++;   }   else   {     \/\/ Decrement counter     startup_cnt--;   }   \/\/ Give semaphore after changes   startup_mutex.Release(); } <\/code><\/pre>\n<\/div>\n<\/div>\n<p>\u041d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u043c\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u043c\u043e\u0433\u0443\u0442 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c 4 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<ul>\n<li><b>Setup()<\/b> \u2014 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u0430\u044f \u043f\u0435\u0440\u0435\u0434 \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u043c \u0437\u0430\u0434\u0430\u0447\u0438. \u0413\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u043a\u043e\u0434\u0430 \u0432\u043e \u0432\u0441\u0435\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u0445 \u0432\u0441\u0435\u0445 \u0437\u0430\u0434\u0430\u0447 \u043f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0446\u0438\u043a\u043b\u043e\u0432.<\/li>\n<li><b>Loop()<\/b> \u2014 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0446\u0438\u043a\u043b \u0437\u0430\u0434\u0430\u0447\u0438, \u0433\u0434\u0435 \u0437\u0430\u0434\u0430\u0447\u0430 \u0441\u0430\u043c\u0430 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0443\u0435\u0442 \u0447\u0442\u043e \u043e\u043d\u0430 \u0445\u043e\u0447\u0435\u0442. \u041d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e \u0441 \u0434\u0432\u0443\u043c\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438.<\/li>\n<li><b>TimerExpired()<\/b> \u2014 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u0430\u044f \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u043e\u043c. \u0423\u0434\u043e\u0431\u043d\u043e \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u043f\u0440\u043e\u0441\u0430 \u0434\u0430\u0442\u0447\u0438\u043a\u0430 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440.<\/li>\n<li><b>ProcessMessage()<\/b> \u2014 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u0437\u0430\u0434\u0430\u0447.<\/li>\n<\/ul>\n<p>  \u0414\u0432\u0435 \u043f\u0435\u0440\u0432\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442 &#171;<i>Arduino-Style<\/i>&#187; \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447. <br \/>  \u0414\u0432\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442 &#171;<i>\u0441\u043e\u0431\u044b\u0442\u0438\u0439\u043d\u0443\u044e<\/i>&#187; \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0443\u043f\u0440\u043e\u0449\u0430\u044e\u0449\u0443\u044e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0437\u0430\u0434\u0430\u0447. \u041f\u0440\u0438 \u0442\u0430\u043a\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435 \u0437\u0430\u0434\u0430\u0447\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0432 \u0432\u0438\u0434\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0435 \u0447\u0435\u0440\u0435\u0437 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u043f\u043e\u0447\u0442\u043e\u0432\u044b\u0439 \u044f\u0449\u0438\u043a. \u041f\u0440\u0438 \u0442\u0430\u043a\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0435\u043c\u0443 \u0434\u0430\u043d\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u0435\u0441\u043f\u043e\u043a\u043e\u0438\u0442\u0441\u044f \u0432 \u043a\u0430\u043a\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f. \u041f\u0440\u0430\u0432\u0434\u0430 \u044d\u0442\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0441\u0435\u0442\u0442\u0435\u0440\u043e\u0432 \u0438\u043b\u0438 \u043a\u043e\u043c\u0430\u043d\u0434. \u0414\u043b\u044f \u0433\u0435\u0442\u0442\u0435\u0440\u043e\u0432 \u043b\u0443\u0447\u0448\u0435 \u0432\u0441\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u044c\u044e\u0442\u0435\u043a\u0441\u044b \u0438 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0437\u0430\u0445\u0432\u0430\u0442\u0430 \u043c\u044c\u044e\u0442\u0435\u043a\u0441\u0430 \u043d\u0430\u0434\u043e\u043b\u0433\u043e.<br \/>  \u0414\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0431\u044b\u043b \u043f\u043e\u0434\u0441\u043c\u043e\u0442\u0440\u0435\u043d \u043a\u043e\u0433\u0434\u0430 \u044f \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b \u041f\u041e \u0434\u043b\u044f \u043c\u0435\u0434\u0438\u0446\u0438\u043d\u0441\u043a\u043e\u0433\u043e \u043e\u0431\u043e\u0440\u0443\u0434\u043e\u0432\u0430\u043d\u0438\u044f. \u041c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0438\u043c\u0435\u0435\u0442 \u043e\u0434\u043d\u0443 \u00ab\u0441\u0442\u043e\u0440\u043e\u0436\u0435\u0432\u0443\u044e \u0441\u043e\u0431\u0430\u043a\u0443\u00bb(<i>watchdog<\/i>) \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u0437\u0430\u0434\u0430\u0447 \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0438\u0445 \u0432\u0441\u0435\u0445. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0431\u044b\u043b\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043b\u0430 watchdog \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u043b\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 \u0432\u044b\u0441\u044b\u043b\u0430\u0435\u043c\u044b\u0445 \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 TimerExpired(). \u0415\u0441\u043b\u0438 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0438 \u043f\u0435\u0440\u0438\u043e\u0434\u0430 \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0437\u0430\u0434\u0430\u0447\u0438 * n \u043d\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u2014 \u0437\u0430\u0434\u0430\u0447\u0430 \u0443\u043c\u0435\u0440\u043b\u0430, <s>\u0442\u0443\u0448\u0438\u043c \u0441\u0432\u0435\u0442<\/s> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u043c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043f\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044e \u0432\u0441\u0435\u0445 \u0436\u0435\u043b\u0435\u0437\u043e\u043a \u0432\u043e\u0437\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043d\u0430 \u043f\u0430\u0446\u0438\u0435\u043d\u0442\u0430.<br \/>  \u0412\u0441\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0441\u043e\u0431\u043e\u0439 \u0441\u0438\u043d\u0433\u043b\u0442\u043e\u043d\u044b, \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0438\u0445 \u043d\u0435\u043b\u044c\u0437\u044f, \u043d\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0443. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043a\u0430\u0436\u0434\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 <b>GetInstance()<\/b>:  <\/p>\n<pre><code class=\"cpp\">\/\/ ***************************************************************************** \/\/ ***   Get Instance   ******************************************************** \/\/ ***************************************************************************** Application&amp; Application::GetInstance(void) {    static Application application;    return application; }<\/code><\/pre>\n<p>  \u0422\u0430\u043a \u0436\u0435 \u0432 \u0441\u043e\u0441\u0442\u0430\u0432 \u0432\u0445\u043e\u0434\u044f\u0442 \u0437\u0430\u0434\u0430\u0447\u0438 \u0434\u043b\u044f <b>\u0432\u044b\u0432\u043e\u0434\u0430 \u0437\u0432\u0443\u043a\u0430<\/b>, \u0434\u043b\u044f <b>\u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0432\u0432\u043e\u0434\u0430<\/b> \u0438 \u0434\u043b\u044f <b>\u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u044d\u043a\u0440\u0430\u043d\u0430.<\/b><\/p>\n<p>  \u0417\u0430\u0434\u0430\u0447\u0430 <b>\u0432\u044b\u0432\u043e\u0434\u0430 \u0437\u0432\u0443\u043a\u0430<\/b> \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0430 \u2014 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0447\u0430\u0441\u0442\u043e\u0442 \u0438 \u0434\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0435\u0439 \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u043c\u0435\u043d\u044f\u0435\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u044b\u0445 \u0438\u043c\u043f\u0443\u043b\u044c\u0441\u043e\u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u043e\u0442\u044b.  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Header<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">\/\/****************************************************************************** \/\/  @file SoundDrv.h \/\/  @author Nicolai Shlapunov \/\/ \/\/  @details DevCore: Sound Driver Class, header \/\/ \/\/  @section LICENSE \/\/ \/\/   Software License Agreement (Modified BSD License) \/\/ \/\/   Copyright (c) 2016, Devtronic &amp; Nicolai Shlapunov \/\/   All rights reserved. \/\/ \/\/   Redistribution and use in source and binary forms, with or without \/\/   modification, are permitted provided that the following conditions are met: \/\/ \/\/   1. Redistributions of source code must retain the above copyright \/\/      notice, this list of conditions and the following disclaimer. \/\/   2. Redistributions in binary form must reproduce the above copyright \/\/      notice, this list of conditions and the following disclaimer in the \/\/      documentation and\/or other materials provided with the distribution. \/\/   3. Neither the name of the Devtronic nor the names of its contributors \/\/      may be used to endorse or promote products derived from this software \/\/      without specific prior written permission. \/\/   4. Redistribution and use of this software other than as permitted under \/\/      this license is void and will automatically terminate your rights under \/\/      this license. \/\/ \/\/   THIS SOFTWARE IS PROVIDED BY DEVTRONIC ''AS IS'' AND ANY EXPRESS OR IMPLIED \/\/   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \/\/   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \/\/   IN NO EVENT SHALL DEVTRONIC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \/\/   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED \/\/   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR \/\/   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY \/\/   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING \/\/   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS \/\/   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \/\/ \/\/  @section SUPPORT \/\/ \/\/   Devtronic invests time and resources providing this open source code, \/\/   please support Devtronic and open-source hardware\/software by \/\/   donations and\/or purchasing products from Devtronic. \/\/ \/\/******************************************************************************  #ifndef SoundDrv_h #define SoundDrv_h  \/\/ ***************************************************************************** \/\/ ***   Includes   ************************************************************ \/\/ ***************************************************************************** #include \"DevCfg.h\" #include \"AppTask.h\" #include \"RtosMutex.h\" #include \"RtosSemaphore.h\"  \/\/ ***************************************************************************** \/\/ ***   Sound Driver Class. This class implement work with sound.   *********** \/\/ ***************************************************************************** class SoundDrv : public AppTask {   public:     \/\/ *************************************************************************     \/\/ ***   Get Instance   ****************************************************     \/\/ *************************************************************************     \/\/ * This class is singleton. For use this class you must call GetInstance()     \/\/ * to receive reference to Sound Driver class     static SoundDrv&amp; GetInstance(void);      \/\/ *************************************************************************     \/\/ ***   Init Sound Driver Task   ******************************************     \/\/ *************************************************************************     virtual void InitTask(TIM_HandleTypeDef *htm);      \/\/ *************************************************************************     \/\/ ***   Sound Driver Setup   **********************************************     \/\/ *************************************************************************     virtual Result Setup();      \/\/ *************************************************************************     \/\/ ***   Sound Driver Loop   ***********************************************     \/\/ *************************************************************************     virtual Result Loop();      \/\/ *************************************************************************     \/\/ ***   Beep function   ***************************************************     \/\/ *************************************************************************     void Beep(uint16_t freq, uint16_t del, bool pause_after_play = false);      \/\/ *************************************************************************     \/\/ ***   Play sound function   *********************************************     \/\/ *************************************************************************     void PlaySound(const uint16_t* melody, uint16_t size, uint16_t temp_ms = 100U, bool rep = false);      \/\/ *************************************************************************     \/\/ ***   Stop sound function   *********************************************     \/\/ *************************************************************************     void StopSound(void);      \/\/ *************************************************************************     \/\/ ***   Mute sound function   *********************************************     \/\/ *************************************************************************     void Mute(bool mute_flag);      \/\/ *************************************************************************     \/\/ ***   Is sound played function   ****************************************     \/\/ *************************************************************************     bool IsSoundPlayed(void);    private:     \/\/ Timer handle     TIM_HandleTypeDef* htim = SOUND_HTIM;     \/\/ Timer channel     uint32_t channel = SOUND_CHANNEL;          \/\/ Ticks variable     uint32_t last_wake_ticks = 0U;      \/\/ Pointer to table contains melody     const uint16_t* sound_table = nullptr;     \/\/ Size of table     uint16_t sound_table_size = 0U;     \/\/ Current position     uint16_t sound_table_position = 0U;     \/\/ Current frequency delay     uint16_t current_delay = 0U;     \/\/ Time for one frequency in ms     uint32_t delay_ms = 100U;     \/\/ Repeat flag     bool repeat = false;      \/\/ Mute flag     bool mute = false;      \/\/ Mutex to synchronize when playing melody frames     RtosMutex melody_mutex;      \/\/ Semaphore for start play sound     RtosSemaphore sound_update;      \/\/ *************************************************************************     \/\/ ***   Process Button Input function   ***********************************     \/\/ *************************************************************************     void Tone(uint16_t freq);      \/\/ *************************************************************************     \/\/ ** Private constructor. Only GetInstance() allow to access this class. **     \/\/ *************************************************************************     SoundDrv() : AppTask(SOUND_DRV_TASK_STACK_SIZE, SOUND_DRV_TASK_PRIORITY,                          \"SoundDrv\") {}; };  #endif<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  \u0417\u0430\u0434\u0430\u0447\u0430 \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f <b>\u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0432\u043e\u043e\u0434\u0430<\/b> \u0442\u043e\u0436\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0430. \u0418\u0437 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0445 \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u0432 \u0430\u0432\u0442\u043e\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u044f: \u0432\u043d\u0430\u0447\u0430\u043b\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0410\u0426\u041f \u0438\u0437\u043c\u0435\u0440\u044f\u0435\u043c \u043d\u0430\u043f\u0440\u044f\u0436\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u043e\u043d\u043e \u0432 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u0445 \u043e\u0442 25% \u0434\u043e 75% \u043e\u0442 \u043f\u0438\u0442\u0430\u044e\u0449\u0435\u0433\u043e \u043d\u0430\u043f\u0440\u044f\u0436\u0435\u043d\u0438\u044f \u2014 \u0432\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0430\u043d\u0430\u043b\u043e\u0433\u043e\u0432\u044b\u0439 \u0434\u0436\u043e\u0439\u0441\u0442\u0438\u043a, \u0438\u043d\u0430\u0447\u0435 \u043a\u043d\u043e\u043f\u043a\u0438 \u0438\u043b\u0438 \u044d\u043d\u043a\u043e\u0434\u0435\u0440. \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u043d\u0435 \u0434\u0436\u043e\u0439\u0441\u0442\u0438\u043a, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0447\u0435\u0442\u0432\u0435\u0440\u0442\u0443\u044e \u043b\u0438\u043d\u0438\u044e I\/O \u043c\u043e\u0434\u0443\u043b\u044f: \u0435\u0441\u043b\u0438 \u043d\u0430 \u043d\u0435\u0439 \u0432\u044b\u0441\u043e\u043a\u0438\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u2014 \u044d\u0442\u043e \u043a\u043d\u043e\u043f\u043a\u0438(<i>\u0432\u0441\u0435 \u043a\u043d\u043e\u043f\u043a\u0438 \u043f\u043e\u0434\u0442\u044f\u043d\u0443\u0442\u044b \u043a \u043f\u0438\u0442\u0430\u043d\u0438\u044e \u0438 \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043a\u043d\u043e\u043f\u043a\u0438 \u0437\u0430\u043c\u044b\u043a\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u0437\u0435\u043c\u043b\u044e<\/i>), \u0435\u0441\u043b\u0438 \u043d\u0430 \u043d\u0435\u0439 \u043d\u0438\u0437\u043a\u0438\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u2014 \u044d\u0442\u043e \u044d\u043d\u043a\u043e\u0434\u0435\u0440(<i>\u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0430\u044f \u043a\u043d\u043e\u043f\u043a\u0430 \u00ab\u043f\u043e\u0434\u0442\u044f\u043d\u0443\u0442\u0430\u00bb \u043a \u0437\u0435\u043c\u043b\u0435 \u0438 \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u0437\u0430\u043c\u044b\u043a\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u043f\u0438\u0442\u0430\u043d\u0438\u0435<\/i>).  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Header<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">\/\/****************************************************************************** \/\/  @file InputDrv.h \/\/  @author Nicolai Shlapunov \/\/ \/\/  @details DevCore: Input Driver Class, header \/\/ \/\/  @section LICENSE \/\/ \/\/   Software License Agreement (Modified BSD License) \/\/ \/\/   Copyright (c) 2016, Devtronic &amp; Nicolai Shlapunov \/\/   All rights reserved. \/\/ \/\/   Redistribution and use in source and binary forms, with or without \/\/   modification, are permitted provided that the following conditions are met: \/\/ \/\/   1. Redistributions of source code must retain the above copyright \/\/      notice, this list of conditions and the following disclaimer. \/\/   2. Redistributions in binary form must reproduce the above copyright \/\/      notice, this list of conditions and the following disclaimer in the \/\/      documentation and\/or other materials provided with the distribution. \/\/   3. Neither the name of the Devtronic nor the names of its contributors \/\/      may be used to endorse or promote products derived from this software \/\/      without specific prior written permission. \/\/   4. Redistribution and use of this software other than as permitted under \/\/      this license is void and will automatically terminate your rights under \/\/      this license. \/\/ \/\/   THIS SOFTWARE IS PROVIDED BY DEVTRONIC ''AS IS'' AND ANY EXPRESS OR IMPLIED \/\/   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \/\/   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \/\/   IN NO EVENT SHALL DEVTRONIC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \/\/   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED \/\/   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR \/\/   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY \/\/   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING \/\/   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS \/\/   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \/\/ \/\/  @section SUPPORT \/\/ \/\/   Devtronic invests time and resources providing this open source code, \/\/   please support Devtronic and open-source hardware\/software by \/\/   donations and\/or purchasing products from Devtronic. \/\/ \/\/******************************************************************************  #ifndef InputDrv_h #define InputDrv_h  \/\/ ***************************************************************************** \/\/ ***   Includes   ************************************************************ \/\/ ***************************************************************************** #include \"DevCfg.h\" #include \"AppTask.h\"  \/\/ ***************************************************************************** \/\/ * Input Driver Class. This class implement work with user input elements like  \/\/ * buttons and encoders. class InputDrv : public AppTask {   public:     \/\/ *************************************************************************     \/\/ ***   Enum with all buttons   *******************************************     \/\/ *************************************************************************     typedef enum      {       EXT_LEFT,  \/\/ Left ext port       EXT_RIGHT, \/\/ Right ext port       EXT_MAX    \/\/ Ext port count     } PortType;      \/\/ *************************************************************************     \/\/ ***   Enum with all devices types   *************************************     \/\/ *************************************************************************     typedef enum      {       EXT_DEV_NONE, \/\/ No device       EXT_DEV_BTN,  \/\/ Buttons(cross)       EXT_DEV_ENC,  \/\/ Encoder       EXT_DEV_JOY,  \/\/ Joystick       EXT_DEV_MAX   \/\/ Device types count     } ExtDeviceType;          \/\/ *************************************************************************     \/\/ ***   Enum with all buttons   *******************************************     \/\/ *************************************************************************     typedef enum      {       BTN_UP,    \/\/ Up button       BTN_LEFT,  \/\/ Left button       BTN_DOWN,  \/\/ Down button       BTN_RIGHT, \/\/ Right button       BTN_MAX    \/\/ Buttons count     } ButtonType;      \/\/ *************************************************************************     \/\/ ***   Enum with all encoder buttons   ***********************************     \/\/ *************************************************************************     typedef enum     {       ENC_BTN_ENT,   \/\/ Press on the knob       ENC_BTN_BACK,  \/\/ Small button       ENC_BTN_MAX    \/\/ Buttons count     } EncButtonType;      \/\/ *************************************************************************     \/\/ ***   Get Instance   ****************************************************     \/\/ *************************************************************************     \/\/ * This class is singleton. For use this class you must call GetInstance()     \/\/ * to receive reference to Input Driver class     static InputDrv&amp; GetInstance(void);      \/\/ *************************************************************************     \/\/ ***   Init Input Driver Task   ******************************************     \/\/ *************************************************************************     \/\/ * This function initialize Input Driver class. If htim provided, this      \/\/ * timer will be used instead FreeRTOS task.     virtual void InitTask(TIM_HandleTypeDef* htm, ADC_HandleTypeDef* had);      \/\/ *************************************************************************     \/\/ ***   Input Driver Setup   **********************************************     \/\/ *************************************************************************     virtual Result Setup();      \/\/ *************************************************************************     \/\/ ***   Input Driver Loop   ***********************************************     \/\/ *************************************************************************     \/\/ * If FreeRTOS task used, this function just call ProcessInput() with 1 ms     \/\/ * period. If FreeRTOS tick is 1 ms - this task must have highest priority      virtual Result Loop();      \/\/ *************************************************************************     \/\/ ***   Process Input function   ******************************************     \/\/ *************************************************************************     \/\/ * Main class function - must call periodically for process user input.     \/\/ * If timer used, this function must be called from interrupt handler.     void ProcessInput(void);      \/\/ *************************************************************************     \/\/ ***   Process Encoders Input function   *********************************     \/\/ *************************************************************************     void ProcessEncodersInput(void);      \/\/ *************************************************************************     \/\/ ***   Get device type   *************************************************     \/\/ *************************************************************************     ExtDeviceType GetDeviceType(PortType port);      \/\/ *************************************************************************     \/\/ ***   Get button state   ************************************************     \/\/ *************************************************************************     \/\/ Return button state: true - pressed, false - unpressed     bool GetButtonState(PortType port, ButtonType button);          \/\/ *************************************************************************     \/\/ ***   Get button state   ************************************************     \/\/ *************************************************************************     \/\/ Return button state change flag: true - changed, false - not changed     bool GetButtonState(PortType port, ButtonType button, bool&amp; btn_state);      \/\/ *************************************************************************     \/\/ ***   Get encoder counts from last call   *******************************     \/\/ *************************************************************************     \/\/ * Return state of encoder. Class counts encoder clicks and stored inside.     \/\/ * This function substract from current encoder counter last_enc_val and     \/\/ * return it to user. Before return last_enc_val will be assigned to     \/\/ * current encoder counter.     int32_t GetEncoderState(PortType port, int32_t&amp; last_enc_val);      \/\/ *************************************************************************     \/\/ ***   Get button state   ************************************************     \/\/ *************************************************************************     \/\/ Return button state: true - pressed, false - unpressed     bool GetEncoderButtonState(PortType port, EncButtonType button);      \/\/ *************************************************************************     \/\/ ***   Get encoder button state   ****************************************     \/\/ *************************************************************************     \/\/ Return button state: true - pressed, false - unpressed     bool GetEncoderButtonState(PortType port, EncButtonType button, bool&amp; btn_state);      \/\/ *************************************************************************     \/\/ ***   Get joystick counts from last call   ******************************     \/\/ *************************************************************************     void GetJoystickState(PortType port, int32_t&amp; x, int32_t&amp; y);      \/\/ *************************************************************************     \/\/ ***   SetJoystickCalibrationConsts   ************************************     \/\/ *************************************************************************     \/\/ * Set calibration constants. Must be call for calibration joystick.     void SetJoystickCalibrationConsts(PortType port, int32_t x_mid,                                       int32_t x_kmin, int32_t x_kmax,                                       int32_t y_mid, int32_t y_kmin,                                       int32_t y_kmax);      \/\/ *************************************************************************     \/\/ ***   Get joystick button state   ***************************************     \/\/ *************************************************************************     \/\/ Return button state: true - pressed, false - unpressed     bool GetJoystickButtonState(PortType port);      \/\/ *************************************************************************     \/\/ ***   Get joystick button state   ***************************************     \/\/ *************************************************************************     \/\/ Return button state: true - pressed, false - unpressed     bool GetJoystickButtonState(PortType port, bool&amp; btn_state);    private:     \/\/ How many cycles button must change state before state will be changed in     \/\/ result returned by GetButtonState() function. For reduce debouncing     const static uint32_t BUTTON_READ_DELAY = 4U;     \/\/ Coefficient for calibration     const static int32_t COEF = 100;      \/\/ ADC max value - 12 bit     const static int32_t ADC_MAX_VAL = 0xFFF;     \/\/ Joystich threshold     const static int32_t JOY_THRESHOLD = 1000;      \/\/ Ticks variable     uint32_t last_wake_ticks = 0U;      \/\/ *************************************************************************     \/\/ ***   Structure to describe button   ************************************     \/\/ *************************************************************************     typedef struct     {       bool btn_state;           \/\/ Button state returned by GetButtonState() function       bool btn_state_tmp;       \/\/ Temporary button state for reduce debouncing       uint8_t btn_state_cnt;    \/\/ Counter for reduce debouncing       GPIO_TypeDef* button_port;\/\/ Button port       uint16_t button_pin;      \/\/ Button pin       GPIO_PinState pin_state;  \/\/ High\/low on input treated as pressed     } ButtonProfile;      \/\/ *************************************************************************     \/\/ ***   Structure to describe encoder   ***********************************     \/\/ *************************************************************************     typedef struct     {       \/\/ Encoder rotation       int32_t enc_cnt;            \/\/ Encoder counter       uint8_t enc_state;          \/\/ Current state of encder clock &amp; data pins       GPIO_TypeDef* enc_clk_port; \/\/ Encoder clock port       uint16_t enc_clk_pin;       \/\/ Encoder clock pin       GPIO_TypeDef* enc_data_port;\/\/ Encoder data port       uint16_t enc_data_pin;      \/\/ Encoder data pin     } EncoderProfile;      \/\/ *************************************************************************     \/\/ ***   Structure to describe joysticks   *********************************     \/\/ *************************************************************************     typedef struct     {       int32_t x_ch_val;     \/\/ Joystick X axis value       uint32_t x_channel;   \/\/ Joystick X axis ADC channel       GPIO_TypeDef* x_port; \/\/ Joystick X axis port       uint16_t x_pin;       \/\/ Joystick X axis pin        int32_t bx;           \/\/ Joystick X offset       int32_t kxmin;        \/\/ Joystick X coefficient       int32_t kxmax;        \/\/ Joystick X coefficient       bool x_inverted;      \/\/ Joystick X inverted flag       int32_t y_ch_val;     \/\/ Joystick Y axis value       uint32_t y_channel;   \/\/ Joystick Y axis ADC channel       GPIO_TypeDef* y_port; \/\/ Joystick Y axis port       uint16_t y_pin;       \/\/ Joystick Y axis pin       int32_t by;           \/\/ Joystick Y offset       int32_t kymin;        \/\/ Joystick Y coefficient       int32_t kymax;        \/\/ Joystick Y coefficient       bool y_inverted;      \/\/ Joystick Y inverted flag     } JoystickProfile;      \/\/ *************************************************************************     \/\/ ***   Structure to describe encoders   **********************************     \/\/ *************************************************************************     typedef struct     {       EncoderProfile enc;       ButtonProfile  btn[ENC_BTN_MAX];     } DevEncoders;      \/\/ *************************************************************************     \/\/ ***   Structure to describe encoders   **********************************     \/\/ *************************************************************************     typedef struct     {       JoystickProfile joy;       ButtonProfile   btn;     } DevJoysticks;      \/\/ *************************************************************************     \/\/ ***   Structure to describe buttons   ***********************************     \/\/ *************************************************************************     typedef struct     {       ButtonProfile button[BTN_MAX];     } DevButtons;      \/\/ ***   Array describes types of connected devices  ***********************     ExtDeviceType devices[EXT_MAX];      \/\/ ***   Structures array for describe buttons inputs  *********************     DevButtons buttons[EXT_MAX] =     {       \/\/ Left device       {{{false, false, 0, EXT_L1_GPIO_Port, EXT_L1_Pin, GPIO_PIN_RESET},         {false, false, 0, EXT_L2_GPIO_Port, EXT_L2_Pin, GPIO_PIN_RESET},         {false, false, 0, EXT_L3_GPIO_Port, EXT_L3_Pin, GPIO_PIN_RESET},         {false, false, 0, EXT_L4_GPIO_Port, EXT_L4_Pin, GPIO_PIN_RESET}}},       \/\/ Right device       {{{false, false, 0, EXT_R1_GPIO_Port, EXT_R1_Pin, GPIO_PIN_RESET},         {false, false, 0, EXT_R2_GPIO_Port, EXT_R2_Pin, GPIO_PIN_RESET},         {false, false, 0, EXT_R3_GPIO_Port, EXT_R3_Pin, GPIO_PIN_RESET},         {false, false, 0, EXT_R4_GPIO_Port, EXT_R4_Pin, GPIO_PIN_RESET}}}     };      \/\/ ***   Structures array for describe encoders inputs  ********************     DevEncoders encoders[EXT_MAX] =     {       \/\/ Left device       {{0, 0, EXT_L1_GPIO_Port, EXT_L1_Pin, EXT_L2_GPIO_Port, EXT_L2_Pin}, \/\/ Encoder        {{false, false, 0, EXT_L3_GPIO_Port, EXT_L3_Pin, GPIO_PIN_RESET},   \/\/ Button Enter         {false, false, 0, EXT_L4_GPIO_Port, EXT_L4_Pin, GPIO_PIN_SET}}},   \/\/ Button Back       \/\/ Right device       {{0, 0, EXT_R1_GPIO_Port, EXT_R1_Pin, EXT_R2_GPIO_Port, EXT_R2_Pin}, \/\/ Encoder        {{false, false, 0, EXT_R3_GPIO_Port, EXT_R3_Pin, GPIO_PIN_RESET},   \/\/ Button Enter         {false, false, 0, EXT_R4_GPIO_Port, EXT_R4_Pin, GPIO_PIN_SET}}}    \/\/ Button Back     };      \/\/ ***   Structures array for describe encoders inputs  ********************     DevJoysticks joysticks[EXT_MAX] =     {       \/\/ Left device       {{0, ADC_CHANNEL_11, EXT_L2_GPIO_Port, EXT_L2_Pin, 0, COEF, COEF, false, \/\/ Joystick         0, ADC_CHANNEL_10, EXT_L1_GPIO_Port, EXT_L1_Pin, 0, COEF, COEF, true},        {false, false, 0, EXT_L3_GPIO_Port, EXT_L3_Pin, GPIO_PIN_RESET}},       \/\/ Button       \/\/ Right device       {{0, ADC_CHANNEL_13, EXT_R2_GPIO_Port, EXT_R2_Pin, 0, COEF, COEF, false, \/\/ Joystick         0, ADC_CHANNEL_12, EXT_R1_GPIO_Port, EXT_R1_Pin, 0, COEF, COEF, true},        {false, false, 0, EXT_R3_GPIO_Port, EXT_R3_Pin, GPIO_PIN_RESET}}        \/\/ Button     };       \/\/ Handle to timer used for process encoders input     TIM_HandleTypeDef* htim = nullptr;     \/\/ Handle to timer used for process encoders input     ADC_HandleTypeDef* hadc = nullptr;      \/\/ *************************************************************************     \/\/ ***   Process Button Input function   ***********************************     \/\/ *************************************************************************     void ProcessButtonInput(ButtonProfile&amp; button);      \/\/ *************************************************************************     \/\/ ***   Process Encoder Input function   **********************************     \/\/ *************************************************************************     void ProcessEncoderInput(EncoderProfile&amp; encoder);      \/\/ *************************************************************************     \/\/ ***   Process Joystick Input function   *********************************     \/\/ *************************************************************************     void ProcessJoystickInput(JoystickProfile&amp; joysticks, PortType port);      \/\/ *************************************************************************     \/\/ ***   Emulate buttons using joystick function   *************************     \/\/ *************************************************************************     void EmulateButtonsByJoystick(PortType port);      \/\/ *************************************************************************     \/\/ ***   Emulate encoders using buttons function   *************************     \/\/ *************************************************************************     void EmulateEncodersByButtons(PortType port);      \/\/ *************************************************************************     \/\/ ***   Configure inputs devices types   **********************************     \/\/ *************************************************************************     ExtDeviceType DetectDeviceType(PortType port);      \/\/ *************************************************************************     \/\/ ***   Configure ADC   ***************************************************     \/\/ *************************************************************************     void ConfigADC(ExtDeviceType dev_left, ExtDeviceType dev_right);      \/\/ *************************************************************************     \/\/ ***   Configure inputs for read digital\/analog data   *******************     \/\/ *************************************************************************     void ConfigInputIO(bool is_digital, PortType port);      \/\/ *************************************************************************     \/\/ ** Private constructor. Only GetInstance() allow to access this class. **     \/\/ *************************************************************************     InputDrv() : AppTask(INPUT_DRV_TASK_STACK_SIZE, INPUT_DRV_TASK_PRIORITY,                          \"InputDrv\") {}; };  #endif<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  \u0417\u0430\u0434\u0430\u0447\u0430 <b>\u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u044d\u043a\u0440\u0430\u043d\u0430<\/b> \u2014 \u0441\u0430\u043c\u0430\u044f \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430. \u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u044d\u043a\u0440\u0430\u043d 320x240x16bit, \u0438\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e <b>153600 \u0431\u0430\u0439\u0442<\/b> \u0434\u043b\u044f \u0444\u0440\u0435\u0439\u043c\u0431\u0443\u0444\u0435\u0440\u0430. \u042d\u0442\u043e \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043c\u043d\u043e\u0433\u043e, \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0433\u0440\u043e\u043c\u043d\u043e \u2014 \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0435 \u0432\u0441\u0435\u0433\u043e 192\u043a \u041e\u0417\u0423, \u0430 \u0432 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430\u0445 \u043f\u043e\u043f\u0440\u043e\u0449\u0435 \u043c\u043e\u0436\u0435\u0442 \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430. \u041a\u0430\u043a \u0436\u0435 \u0431\u044b\u0442\u044c? \u041e\u0442\u0432\u0435\u0442 \u043f\u0440\u043e\u0441\u0442: \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u044d\u043a\u0440\u0430\u043d \u043f\u043e \u0447\u0430\u0441\u0442\u044f\u043c! \u041d\u043e \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c-\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e \u0440\u0430\u0437\u043d\u043e\u043c\u0443\u2026<br \/>  \u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u044f \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043b \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u0430\u043a \u0438 \u0432\u0441\u0435 \u0433\u0435\u043d\u0438\u0430\u043b\u044c\u043d\u043e\u0435. \u041e\u043d\u0430 \u0438\u043c\u0435\u0435\u0442 \u0431\u0443\u0444\u0435\u0440 \u043d\u0430 \u0434\u0432\u0435 \u044d\u043a\u0440\u0430\u043d\u043d\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438. \u0412 \u043e\u0434\u043d\u0443 \u0441\u0442\u0440\u043e\u043a\u0443 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0432\u0441\u0435 \u0447\u0442\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0451 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d \u0447\u0435\u0440\u0435\u0437 SPI \u0432 DMA \u0440\u0435\u0436\u0438\u043c\u0435, \u0430 \u0441\u0430\u043c\u0438 \u0432 \u044d\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0434\u0433\u043e\u0442\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443.<br \/>  \u041e\u0442\u043a\u0443\u0434\u0430 \u0436\u0435 \u0437\u0430\u0434\u0430\u0447\u0430 \u0437\u043d\u0430\u0435\u0442 \u0447\u0442\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0432 \u0441\u0442\u0440\u043e\u043a\u0435 \u0438 \u043a\u0430\u043a \u0435\u0451 \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c? \u0410 \u043e\u043d\u0430 <b>\u043d\u0435 \u0437\u043d\u0430\u0435\u0442!<\/b> \u041d\u043e \u0443 \u043d\u0435\u0435 \u0435\u0441\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u043d\u0430\u044e\u0442 \u043a\u0430\u043a \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0431\u044f. \u041a\u0430\u0436\u0434\u044b\u0439 \u0442\u0430\u043a\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442\u0441\u044f \u043e\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 <b>VisObject<\/b>.  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Header<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">\/\/****************************************************************************** \/\/  @file VisObject.h \/\/  @author Nicolai Shlapunov \/\/ \/\/  @details DevCore: Visual Object Base Class, header \/\/ \/\/  @section LICENSE \/\/ \/\/   Software License Agreement (BSD License) \/\/ \/\/   Copyright (c) 2016, Devtronic &amp; Nicolai Shlapunov \/\/   All rights reserved. \/\/ \/\/   Redistribution and use in source and binary forms, with or without \/\/   modification, are permitted provided that the following conditions are met: \/\/   1. Redistributions of source code must retain the above copyright \/\/      notice, this list of conditions and the following disclaimer. \/\/   2. Redistributions in binary form must reproduce the above copyright \/\/      notice, this list of conditions and the following disclaimer in the \/\/      documentation and\/or other materials provided with the distribution. \/\/   3. Neither the name of the Devtronic nor the names of its contributors \/\/      may be used to endorse or promote products derived from this software \/\/      without specific prior written permission. \/\/ \/\/   THIS SOFTWARE IS PROVIDED BY DEVTRONIC ''AS IS'' AND ANY EXPRESS OR IMPLIED \/\/   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \/\/   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \/\/   IN NO EVENT SHALL DEVTRONIC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \/\/   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED \/\/   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR \/\/   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY \/\/   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING \/\/   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS \/\/   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \/\/ \/\/******************************************************************************  #ifndef VisObject_h #define VisObject_h  \/\/ ***************************************************************************** \/\/ ***   Includes   ************************************************************ \/\/ ***************************************************************************** #include \"DevCfg.h\"  \/\/ ***************************************************************************** \/\/ * VisObject class. This class implements base Visual Objects properties. class VisObject {   public:     \/\/ *************************************************************************     \/\/ ***   Action   **********************************************************     \/\/ *************************************************************************      typedef enum     {       ACT_TOUCH,   \/\/ When object touched       ACT_UNTOUCH, \/\/ When object detouched       ACT_MOVE,    \/\/ When object moved on object       ACT_MOVEIN,  \/\/ When object moved in to object       ACT_MOVEOUT, \/\/ When object moved out of object       ACT_MAX      \/\/ Total possible actions     } ActionType;      \/\/ *************************************************************************     \/\/ ***   VisObject   *******************************************************     \/\/ *************************************************************************      VisObject() {};      \/\/ *************************************************************************     \/\/ ***   ~VisObject   ******************************************************     \/\/ *************************************************************************     \/\/ * Destructor. Call DelVisObjectFromList() from DisplayDrv class for     \/\/ * remove from list before delete and delete semaphore.     virtual ~VisObject();      \/\/ *************************************************************************     \/\/ ***   LockVisObject   ***************************************************     \/\/ *************************************************************************     void LockVisObject();      \/\/ *************************************************************************     \/\/ ***   UnlockVisObject   *************************************************     \/\/ *************************************************************************     void UnlockVisObject();      \/\/ *************************************************************************     \/\/ ***   Show   ************************************************************     \/\/ *************************************************************************     \/\/ * Show VisObject on screen. This function call AddVisObjectToList() from     \/\/ * DisplayDrv class. When this function calls first time, user must     \/\/ * provide Z level. In future user can call this function without     \/\/ * parameters - previously set Z will be used.     virtual void Show(uint32_t z_pos = 0);      \/\/ *************************************************************************     \/\/ ***   Hide   ************************************************************     \/\/ *************************************************************************     \/\/ * Hide VisObject from screen. This function call DelVisObjectFromList()     \/\/ * from DisplayDrv class.     virtual void Hide(void);          \/\/ *************************************************************************     \/\/ ***   IsShow   **********************************************************     \/\/ *************************************************************************     \/\/ * Check status of Show Visual Object. Return true if object in DisplayDrv list.     virtual bool IsShow(void);      \/\/ *************************************************************************     \/\/ ***   Move   ************************************************************     \/\/ *************************************************************************     \/\/ * Move object on screen. Set new x and y coordinates. If flag is set -      \/\/ * move is relative, not absolute.     virtual void Move(int32_t x, int32_t y, bool is_delta = false);      \/\/ *************************************************************************     \/\/ ***   DrawInBufH   ******************************************************     \/\/ *************************************************************************     \/\/ * Draw one horizontal line of object in specified buffer.     \/\/ * Each derived class must implement this function.     virtual void DrawInBufH(uint16_t* buf, int32_t n, int32_t row, int32_t start_y = 0) = 0;      \/\/ *************************************************************************     \/\/ ***   DrawInBufW   ******************************************************     \/\/ *************************************************************************     \/\/ * Draw one vertical line of object in specified buffer.     \/\/ * Each derived class must implement this function.     virtual void DrawInBufW(uint16_t* buf, int32_t n, int32_t line, int32_t start_x = 0) = 0;      \/\/ *************************************************************************     \/\/ ***   Action   **********************************************************     \/\/ *************************************************************************     virtual void Action(ActionType action, int32_t tx, int32_t ty);      \/\/ *************************************************************************     \/\/ ***   Return Start X coordinate   ***************************************     \/\/ *************************************************************************     virtual int32_t GetStartX(void) {return x_start;};      \/\/ *************************************************************************     \/\/ ***   Return Start Y coordinate   ***************************************     \/\/ *************************************************************************     virtual int32_t GetStartY(void) {return y_start;};      \/\/ *************************************************************************     \/\/ ***   Return End X coordinate   *****************************************     \/\/ *************************************************************************     virtual int32_t GetEndX(void) {return x_end;};      \/\/ *************************************************************************     \/\/ ***   Return End Y coordinate   *****************************************     \/\/ *************************************************************************     virtual int32_t GetEndY(void) {return y_end;};      \/\/ *************************************************************************     \/\/ ***   Return Width of object   ******************************************     \/\/ *************************************************************************     virtual int32_t GetWidth(void) {return width;};      \/\/ *************************************************************************     \/\/ ***   Return Height of object   *****************************************     \/\/ *************************************************************************     virtual int32_t GetHeight(void) {return height;};    protected:     \/\/ *************************************************************************     \/\/ ***   Object parameters   ***********************************************     \/\/ *************************************************************************      \/\/ X and Y start coordinates of object     int16_t x_start = 0, y_start = 0;     \/\/ X and Y end coordinates of object     int16_t x_end = 0, y_end = 0;     \/\/ Width and Height of object     int16_t width = 0, height = 0;     \/\/ Rotation of object     int8_t rotation = 0;     \/\/ Object active     bool active = false;    private:     \/\/ *************************************************************************     \/\/ ***   Object parameters   ***********************************************     \/\/ *************************************************************************     \/\/ * Only base class and DisplayDrv have access to this parameters      \/\/ Z position of object     uint16_t z = 0;     \/\/ Pointer to next object. This pointer need to maker object list. Object     \/\/ can be added only to one list.     VisObject* p_next = nullptr;     \/\/ Pointer to next object. This pointer need to maker object list. Object     \/\/ can be added only to one list.     VisObject* p_prev = nullptr;      \/\/ DisplayDrv is friend for access to pointers and Z     friend class DisplayDrv; };  #endif<\/code><\/pre>\n<\/div>\n<\/div>\n<p>\u0417\u0430\u0434\u0430\u0447\u0430 \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u044d\u043a\u0440\u0430\u043d\u0430 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u043e \u0441\u043f\u0438\u0441\u043a\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e DrawInBufW() \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u044f \u0435\u0439 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0431\u0443\u0444\u0435\u0440, \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0442\u043e\u0447\u0435\u043a, \u0440\u0438\u0441\u0443\u0435\u043c\u0443\u044e \u043b\u0438\u043d\u0438\u044e \u0438 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u044e(<i>\u043f\u043e\u043a\u0430 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0431\u044b\u043b\u0430 \u0438\u0434\u0435\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0436\u0438\u043c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u044d\u043a\u0440\u0430\u043d\u0430 \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u00ab\u043e\u043a\u043d\u0430\u00bb<\/i>). \u0424\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0440\u0438\u0441\u0443\u0435\u0442 \u0441\u0435\u0431\u044f \u0441\u0430\u043c \u043f\u043e\u0432\u0435\u0440\u0445 \u0434\u0440\u0443\u0433\u0438\u0445 \u0443\u0436\u0435 \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0438 \u043b\u0435\u0433\u043a\u043e \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0432 \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u044f \u0438\u0445 \u0432 \u043d\u0443\u0436\u043d\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0441\u043f\u0438\u0441\u043a\u0430.<br \/>  \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043b\u0435\u0433\u043a\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u2014 \u043f\u043e\u043b\u0443\u0447\u0438\u0432 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043e\u0442 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0442\u0430\u0447\u0441\u043a\u0440\u0438\u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u044d\u043a\u0440\u0430\u043d\u0430 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0439\u0442\u0438\u0441\u044c \u043f\u043e \u043b\u0438\u0441\u0442\u0443 \u0441 \u043a\u043e\u043d\u0446\u0430 \u0432 \u043f\u043e\u0438\u0441\u043a\u0435 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0449\u0435\u0433\u043e \u0432 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043d\u0430\u0436\u0430\u0442\u0438\u044f. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0430\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f Action() \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430.<\/p>\n<p>  \u041d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0438\u043c\u0435\u044e\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0434\u043b\u044f \u0441\u0442\u0440\u043e\u043a, \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432(<i>\u043b\u0438\u043d\u0438\u044f, \u043a\u0432\u0430\u0434\u0440\u0430\u0442, \u043a\u0440\u0443\u0433<\/i>), \u043a\u0430\u0440\u0442\u0438\u043d\u043e\u043a \u0438 \u043a\u0430\u0440\u0442\u044b \u043f\u043b\u0438\u0442\u043e\u043a(<i>\u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438\u0433\u0440<\/i>).<\/p>\n<p>  \u0422\u0430\u043a \u0436\u0435 \u0432 <b>DevCore<\/b> \u0432\u0445\u043e\u0434\u0438\u0442 \u0435\u0449\u0435 \u043a\u043e\u0434 \u0434\u043b\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 UI(<i>\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043c\u0435\u043d\u044e<\/i>), \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043b\u044f \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0430 I2C, \u0434\u0440\u0430\u0439\u0432\u0435\u0440 I2C \u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0434\u0430\u0442\u0447\u0438\u043a\u043e\u043c BME280 \u0438 EEPROM 24\u0421256, \u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u0442\u0430\u043a \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0438 \u043f\u043e\u043a\u0430 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0443 \u2014 \u0438 \u0442\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043e\u0431\u044a\u0435\u043c\u043d\u043e.<\/p>\n<p>  \u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d <s>\u0431\u0435\u0437 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0438 \u0421\u041c\u0421<\/s> \u043d\u0430 <b>GitHub<\/b>: <a href=\"https:\/\/github.com\/nickshl\/devboy\">https:\/\/github.com\/nickshl\/devboy<\/a><\/p>\n<p>  <b>P.S.<\/b> \u0421\u0443\u0434\u044f \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f \u0438\u0434\u0435\u0442 \u043a Epic Fail&#8217;\u0443. \u0417\u0430 \u043f\u0435\u0440\u0432\u0443\u044e \u043d\u0435\u0434\u0435\u043b\u044e \u0432\u0441\u0435\u0433\u043e \u0442\u0440\u0438 \u0431\u0430\u043a\u0435\u0440\u0430, \u0438\u0437 \u043d\u0438\u0445 \u0434\u043e\u043b\u043b\u0430\u0440 \u043e\u0442 \u043a\u0430\u043a\u043e\u0433\u043e-\u0442\u043e &#171;<i>\u0418\u043d\u043d\u043e\u0432\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0444\u043e\u043d\u0434\u0430<\/i>&#171;, 180 \u0434\u043e\u043b\u043b\u0430\u0440\u043e\u0432 \u043e\u0442 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430 \u043d\u0430\u0432\u0435\u0440\u043d\u044f\u043a\u0430 \u0443\u0437\u043d\u0430\u0432\u0448\u0435\u0433\u043e \u043e\u0431 \u044d\u0442\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0438\u0437 \u0441\u0442\u0430\u0442\u044c\u0438 \u043d\u0430 \u0425\u0430\u0431\u0440(<i>\u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0442\u0435\u0431\u0435 \u0410\u043d\u0434\u0440\u0435\u0439!<\/i>) \u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u0442 \u043c\u043e\u0435\u0433\u043e \u043a\u043e\u043b\u043b\u0435\u0433\u0438 \u0438\u0437 \u0441\u043e\u0441\u0435\u0434\u043d\u0435\u0433\u043e \u043a\u044e\u0431\u0438\u043a\u043b\u0430.<br \/>  \u041d\u0435 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0434\u0435\u043d\u044c\u0433\u0438 \u2014 \u044d\u0442\u043e \u043d\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430. \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u2014 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0430 \u043a \u043f\u0440\u043e\u0435\u043a\u0442\u0443\u2026<\/div>\n<p>        <script class=\"js-mediator-script\">!function(e){function t(t,n){if(!(n in e)){for(var r,a=e.document,i=a.scripts,o=i.length;o--;)if(-1!==i[o].src.indexOf(t)){r=i[o];break}if(!r){r=a.createElement(\"script\"),r.type=\"text\/javascript\",r.async=!0,r.defer=!0,r.src=t,r.charset=\"UTF-8\";var d=function(){var e=a.getElementsByTagName(\"script\")[0];e.parentNode.insertBefore(r,e)};\"[object Opera]\"==e.opera?a.addEventListener?a.addEventListener(\"DOMContentLoaded\",d,!1):e.attachEvent(\"onload\",d):d()}}}t(\"\/\/mediator.mail.ru\/script\/2820404\/\",\"_mediator\")}(window);<\/script>     <br \/> \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\/post\/424309\/\"> https:\/\/habr.com\/post\/424309\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html js-mediator-article\"><b>\u041f\u0440\u0438\u0432\u0435\u0442, \u0434\u0440\u0443\u0437\u044c\u044f!<\/b><\/p>\n<p>  \u0421 \u0432\u0430\u043c\u0438 \u0441\u043d\u043e\u0432\u0430 \u041d\u0438\u043a\u043e\u043b\u0430\u0439, \u0432 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 &#171;<i><a href=\"https:\/\/habr.com\/post\/423499\/\">DevBoy \u2014 \u043a\u0430\u043a \u044f \u0441\u043e\u0437\u0434\u0430\u043b \u043f\u0440\u043e\u0435\u043a\u0442 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0441 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430 Kickstarter<\/a><\/i>&#187; \u0443\u043f\u043e\u0440 \u0434\u0435\u043b\u0430\u043b\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0430 \u0432\u043d\u0435\u0448\u043d\u0435\u043c \u0432\u0438\u0434\u0435 \u0438 \u0436\u0435\u043b\u0435\u0437\u0435, \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e &#171;<i>\u0432\u043d\u0443\u0442\u0440\u0438<\/i>&#187; \u0438 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u0443\u044e \u0447\u0430\u0441\u0442\u044c. <br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/6r\/n4\/u8\/6rn4u8jvzpd-c9_oykzqia4l8fk.jpeg\"><br \/>  \u041a\u043e\u043c\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u2014 \u043f\u0440\u043e\u0448\u0443 \u043f\u043e\u0434 \u043a\u0430\u0442.<\/p>\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-289851","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/289851","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=289851"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/289851\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=289851"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=289851"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=289851"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}