<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>sistemas embarcados - MCU &amp; FPGA</title>
	<atom:link href="https://mcu.tec.br/tags/sistemas-embarcados/feed/" rel="self" type="application/rss+xml" />
	<link>https://mcu.tec.br</link>
	<description>Microcontroladores &#38; FPGA</description>
	<lastBuildDate>Thu, 19 Mar 2026 22:44:47 +0000</lastBuildDate>
	<language>pt-BR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://mcu.tec.br/wp-content/uploads/2025/02/Robo-para-o-site-MCU.tec_.br-512x512-1-150x150.png</url>
	<title>sistemas embarcados - MCU &amp; FPGA</title>
	<link>https://mcu.tec.br</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Criando um Projeto Zephyr RTOS no Arduino DUE – Guia Completo e Didático</title>
		<link>https://mcu.tec.br/rtos/criando-um-projeto-zephyr-rtos-no-arduino-due-guia-completo-e-didatico/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=criando-um-projeto-zephyr-rtos-no-arduino-due-guia-completo-e-didatico</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Fri, 27 Mar 2026 09:01:10 +0000</pubDate>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[RTOS]]></category>
		<category><![CDATA[Arduino DUE]]></category>
		<category><![CDATA[ARM Cortex-M3]]></category>
		<category><![CDATA[firmware profissional]]></category>
		<category><![CDATA[rtos]]></category>
		<category><![CDATA[SAM3X8E]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[Zephyr Arduino]]></category>
		<category><![CDATA[Zephyr RTOS]]></category>
		<category><![CDATA[Zephyr tutorial]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1209</guid>

					<description><![CDATA[<p>Aprenda passo a passo como criar um projeto completo com Zephyr RTOS no Arduino DUE. Este tutorial detalhado e didático explica desde a estrutura do workspace, configuração do CMake e Kconfig, até a compilação, gravação e execução do firmware no microcontrolador SAM3X8E. Ideal para quem deseja sair do modelo Arduino tradicional e aprender RTOS profissional em ARM Cortex-M, com exemplos práticos, explicações profundas e foco em arquitetura de sistemas embarcados.</p>
<p>The post <a href="https://mcu.tec.br/rtos/criando-um-projeto-zephyr-rtos-no-arduino-due-guia-completo-e-didatico/">Criando um Projeto Zephyr RTOS no Arduino DUE – Guia Completo e Didático</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<div class="root-eb-toc-nkf1j wp-block-essential-blocks-table-of-contents"><div class="eb-parent-wrapper eb-parent-eb-toc-nkf1j "><div class="eb-toc-container eb-toc-nkf1j  eb-toc-is-not-sticky eb-toc-not-collapsible eb-toc-initially-not-collapsed eb-toc-scrollToTop style-1 list-style-none" data-scroll-top="false" data-scroll-top-icon="fas fa-angle-up" data-collapsible="false" data-sticky-hide-mobile="false" data-sticky="false" data-scroll-target="scroll_to_toc" data-copy-link="false" data-editor-type="" data-hide-desktop="false" data-hide-tab="false" data-hide-mobile="false" data-itemcollapsed="false" data-highlight-scroll="false"><div class="eb-toc-header"><h2 class="eb-toc-title">Table of Contents</h2></div><div class="eb-toc-wrapper " data-headers="[{&quot;level&quot;:2,&quot;content&quot;:&quot;1. Introdu\u00e7\u00e3o: por que usar Zephyr no Arduino DUE&quot;,&quot;text&quot;:&quot;1. Introdu\u00e7\u00e3o: por que usar Zephyr no Arduino DUE&quot;,&quot;link&quot;:&quot;eb-table-content-0&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;2. Vis\u00e3o geral do suporte do Zephyr ao Arduino DUE&quot;,&quot;text&quot;:&quot;2. Vis\u00e3o geral do suporte do Zephyr ao Arduino DUE&quot;,&quot;link&quot;:&quot;eb-table-content-1&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;3. Pr\u00e9-requisitos do ambiente de desenvolvimento&quot;,&quot;text&quot;:&quot;3. Pr\u00e9-requisitos do ambiente de desenvolvimento&quot;,&quot;link&quot;:&quot;eb-table-content-2&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;4. Estrutura recomendada de workspace&quot;,&quot;text&quot;:&quot;4. Estrutura recomendada de workspace&quot;,&quot;link&quot;:&quot;4-estrutura-recomendada-de-workspace&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;5. Criando o projeto do zero para o Arduino DUE&quot;,&quot;text&quot;:&quot;5. Criando o projeto do zero para o Arduino DUE&quot;,&quot;link&quot;:&quot;5-criando-o-projeto-do-zero-para-o-arduino-due&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.1 Criando o diret\u00f3rio da aplica\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;5.1 Criando o diret\u00f3rio da aplica\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-5&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.2 Estrutura m\u00ednima de um projeto Zephyr&quot;,&quot;text&quot;:&quot;5.2 Estrutura m\u00ednima de um projeto Zephyr&quot;,&quot;link&quot;:&quot;eb-table-content-6&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;6. Arquivo CMakeLists.txt: integra\u00e7\u00e3o com o Zephyr&quot;,&quot;text&quot;:&quot;6. Arquivo CMakeLists.txt: integra\u00e7\u00e3o com o Zephyr&quot;,&quot;link&quot;:&quot;eb-table-content-7&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;O que esse arquivo faz, exatamente?&quot;,&quot;text&quot;:&quot;O que esse arquivo faz, exatamente?&quot;,&quot;link&quot;:&quot;o-que-esse-arquivo-faz-exatamente&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;7. Arquivo prj.conf: configura\u00e7\u00e3o do kernel (Kconfig)&quot;,&quot;text&quot;:&quot;7. Arquivo prj.conf: configura\u00e7\u00e3o do kernel (Kconfig)&quot;,&quot;link&quot;:&quot;eb-table-content-9&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;8. Arquivo main.c: primeira aplica\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;8. Arquivo main.c: primeira aplica\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-10&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Conceitos importantes aqui&quot;,&quot;text&quot;:&quot;Conceitos importantes aqui&quot;,&quot;link&quot;:&quot;conceitos-importantes-aqui&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;9. Compilando o projeto para o Arduino DUE&quot;,&quot;text&quot;:&quot;9. Compilando o projeto para o Arduino DUE&quot;,&quot;link&quot;:&quot;9-compilando-o-projeto-para-o-arduino-due&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;10. Gravando o firmware no Arduino DUE&quot;,&quot;text&quot;:&quot;10. Gravando o firmware no Arduino DUE&quot;,&quot;link&quot;:&quot;10-gravando-o-firmware-no-arduino-due&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;11. Pr\u00f3ximos passos&quot;,&quot;text&quot;:&quot;11. Pr\u00f3ximos passos&quot;,&quot;link&quot;:&quot;eb-table-content-14&quot;}]" data-visible="[true,true,true,true,true,true]" data-delete-headers="[{&quot;label&quot;:&quot;1. Introdu\u00e7\u00e3o: por que usar Zephyr no Arduino DUE&quot;,&quot;value&quot;:&quot;1-introdu\u00e7\u00e3o-por-que-usar-zephyr-no-arduino-due&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2. Vis\u00e3o geral do suporte do Zephyr ao Arduino DUE&quot;,&quot;value&quot;:&quot;2-vis\u00e3o-geral-do-suporte-do-zephyr-ao-arduino-due&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3. Pr\u00e9-requisitos do ambiente de desenvolvimento&quot;,&quot;value&quot;:&quot;3-pr\u00e9-requisitos-do-ambiente-de-desenvolvimento&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4. Estrutura recomendada de workspace&quot;,&quot;value&quot;:&quot;4-estrutura-recomendada-de-workspace&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5. Criando o projeto do zero para o Arduino DUE&quot;,&quot;value&quot;:&quot;5-criando-o-projeto-do-zero-para-o-arduino-due&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.1 Criando o diret\u00f3rio da aplica\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;51-criando-o-diret\u00f3rio-da-aplica\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.2 Estrutura m\u00ednima de um projeto Zephyr&quot;,&quot;value&quot;:&quot;52-estrutura-m\u00ednima-de-um-projeto-zephyr&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;6. Arquivo CMakeLists.txt: integra\u00e7\u00e3o com o Zephyr&quot;,&quot;value&quot;:&quot;6-arquivo-cmakeliststxt-integra\u00e7\u00e3o-com-o-zephyr&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;O que esse arquivo faz, exatamente?&quot;,&quot;value&quot;:&quot;o-que-esse-arquivo-faz-exatamente&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;7. Arquivo prj.conf: configura\u00e7\u00e3o do kernel (Kconfig)&quot;,&quot;value&quot;:&quot;7-arquivo-prjconf-configura\u00e7\u00e3o-do-kernel-kconfig&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;8. Arquivo main.c: primeira aplica\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;8-arquivo-mainc-primeira-aplica\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Conceitos importantes aqui&quot;,&quot;value&quot;:&quot;conceitos-importantes-aqui&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;9. Compilando o projeto para o Arduino DUE&quot;,&quot;value&quot;:&quot;9-compilando-o-projeto-para-o-arduino-due&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;10. Gravando o firmware no Arduino DUE&quot;,&quot;value&quot;:&quot;10-gravando-o-firmware-no-arduino-due&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;11. Pr\u00f3ximos passos&quot;,&quot;value&quot;:&quot;11-pr\u00f3ximos-passos&quot;,&quot;isDelete&quot;:false}]" data-smooth="true" data-top-offset=""><div class="eb-toc__list-wrap"><ul class="eb-toc__list"><li><a href="#eb-table-content-0">1. Introdução: por que usar Zephyr no Arduino DUE</a><li><a href="#eb-table-content-1">2. Visão geral do suporte do Zephyr ao Arduino DUE</a><li><a href="#eb-table-content-2">3. Pré-requisitos do ambiente de desenvolvimento</a><li><a href="#4-estrutura-recomendada-de-workspace">4. Estrutura recomendada de workspace</a><li><a href="#5-criando-o-projeto-do-zero-para-o-arduino-due">5. Criando o projeto do zero para o Arduino DUE</a><ul class="eb-toc__list"><li><a href="#eb-table-content-5">5.1 Criando o diretório da aplicação</a><li><a href="#eb-table-content-6">5.2 Estrutura mínima de um projeto Zephyr</a></li></ul><li><a href="#eb-table-content-7">6. Arquivo CMakeLists.txt: integração com o Zephyr</a><ul class="eb-toc__list"><li><a href="#o-que-esse-arquivo-faz-exatamente">O que esse arquivo faz, exatamente?</a></li></ul><li><a href="#eb-table-content-9">7. Arquivo prj.conf: configuração do kernel (Kconfig)</a><li><a href="#eb-table-content-10">8. Arquivo main.c: primeira aplicação</a><ul class="eb-toc__list"><li><a href="#conceitos-importantes-aqui">Conceitos importantes aqui</a></li></ul><li><a href="#9-compilando-o-projeto-para-o-arduino-due">9. Compilando o projeto para o Arduino DUE</a><li><a href="#10-gravando-o-firmware-no-arduino-due">10. Gravando o firmware no Arduino DUE</a><li><a href="#eb-table-content-14">11. Próximos passos</a></ul></div></div></div></div></div>


<h2 class="wp-block-heading">1. Introdução: por que usar Zephyr no Arduino DUE</h2>



<p class="wp-block-paragraph">O <strong>Zephyr Project</strong> é um sistema operacional de tempo real (RTOS – <em>Real-Time Operating System</em>) moderno, modular e altamente configurável, projetado para sistemas embarcados que exigem previsibilidade temporal, portabilidade e escalabilidade. Diferente do ecossistema Arduino tradicional — baseado em <em>superloop</em> e bibliotecas monolíticas — o Zephyr oferece um modelo arquitetural profissional, alinhado a práticas industriais, como <em>device tree</em>, <em>Kconfig</em>, <em>CMake</em> e um kernel preemptivo completo.</p>



<p class="wp-block-paragraph">O <strong>Arduino DUE</strong> ocupa um espaço interessante nesse contexto. Baseado no microcontrolador <strong>Atmel/Microchip SAM3X8E</strong>, um ARM Cortex-M3 de 32 bits operando a 84 MHz, ele oferece recursos raros no “mundo Arduino”: barramento externo, controlador DMA (Direct Memory Access), múltiplas UARTs, SPI, TWI (I²C – <em>Inter-Integrated Circuit</em>), além de USB nativo (<em>USB OTG</em>). Esses recursos fazem do DUE uma excelente plataforma didática para aprender Zephyr em um hardware amplamente conhecido.</p>



<p class="wp-block-paragraph">Neste artigo, você aprenderá <strong>passo a passo, de forma minuciosa</strong>, como criar um projeto Zephyr totalmente funcional para o Arduino DUE, utilizando <strong>todos os recursos documentados oficialmente</strong> pela fundação Zephyr para essa placa. O foco não será apenas “compilar e rodar”, mas <strong>entender a arquitetura do projeto</strong>, as decisões de configuração e o papel de cada arquivo envolvido.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">2. Visão geral do suporte do Zephyr ao Arduino DUE</h2>



<p class="wp-block-paragraph">Antes de escrever qualquer linha de código, é fundamental entender <strong>como o Zephyr enxerga o Arduino DUE</strong>. No Zephyr, placas não são tratadas como “kits genéricos”, mas como <strong>descrições formais de hardware</strong>, compostas por:</p>



<ul class="wp-block-list">
<li><strong>Board Definition</strong>: define CPU, clock, memória e periféricos básicos</li>



<li><strong>Device Tree (DTS)</strong>: descreve os dispositivos de hardware de forma declarativa</li>



<li><strong>Kconfig da placa</strong>: habilita ou restringe funcionalidades do kernel</li>



<li><strong>Arquivos de build</strong>: integram a placa ao sistema CMake do Zephyr</li>
</ul>



<p class="wp-block-paragraph">No caso do Arduino DUE, o Zephyr fornece oficialmente:</p>



<ul class="wp-block-list">
<li>Arquivo de <em>board</em> baseado no <strong>SAM3X8E</strong></li>



<li>Mapeamento correto de pinos compatível com o layout do DUE</li>



<li>Suporte a:
<ul class="wp-block-list">
<li>GPIO (General Purpose Input/Output)</li>



<li>UART (console serial)</li>



<li>SPI</li>



<li>I²C (TWI no SAM)</li>



<li>Temporizadores e <em>SysTick</em></li>
</ul>
</li>



<li>Programação via <strong>porta USB de programação</strong> (a mesma usada com o bossac)</li>
</ul>



<p class="wp-block-paragraph">Isso significa que <strong>não é necessário criar uma placa customizada</strong> para começar: o Arduino DUE já está plenamente integrado ao ecossistema Zephyr.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">3. Pré-requisitos do ambiente de desenvolvimento</h2>



<p class="wp-block-paragraph">Antes de criar o projeto, o ambiente Zephyr <strong>precisa estar corretamente instalado</strong>. Assumiremos aqui que você já leu os artigos anteriores da série e possui:</p>



<ul class="wp-block-list">
<li>Linux (Ubuntu 22.04 ou superior recomendado)</li>



<li>Python 3.10+</li>



<li><code>west</code> (ferramenta de meta-build do Zephyr)</li>



<li>Zephyr SDK instalada</li>



<li>Toolchain ARM embarcada funcional</li>
</ul>



<p class="wp-block-paragraph">Para validar rapidamente se o ambiente está correto, execute:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>west --version
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">west --version</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">E depois:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>west boards | grep due
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">west boards | grep due</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Se o ambiente estiver correto, você verá a placa <strong>arduino_due</strong> listada entre as placas suportadas. Esse comando é extremamente importante: ele confirma que o Zephyr <strong>reconhece oficialmente</strong> o Arduino DUE no seu workspace.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">4. Estrutura recomendada de workspace</h2>



<p class="wp-block-paragraph">Um erro comum entre iniciantes é misturar código de aplicação com o repositório do Zephyr. A abordagem correta é usar um <strong>workspace limpo</strong>, com a seguinte estrutura conceitual:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>zephyr-workspace/
├── zephyr/              # Código-fonte do Zephyr RTOS
├── modules/             # Módulos externos (opcional)
├── bootloader/          # Bootloaders (opcional)
└── arduino_due_app/     # SUA aplicação
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">zephyr-workspace/</span></span>
<span class="line"><span style="color: #D8DEE9FF">├── zephyr/              # Código-fonte do Zephyr RTOS</span></span>
<span class="line"><span style="color: #D8DEE9FF">├── modules/             # Módulos externos (opcional)</span></span>
<span class="line"><span style="color: #D8DEE9FF">├── bootloader/          # Bootloaders (opcional)</span></span>
<span class="line"><span style="color: #D8DEE9FF">└── arduino_due_app/     # SUA aplicação</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Dentro da pasta <code>arduino_due_app</code>, ficará <strong>apenas o código da aplicação</strong>, sem dependências diretas do kernel. Essa separação é crucial para manter o projeto sustentável e escalável.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">5. Criando o projeto do zero para o Arduino DUE</h2>



<p class="wp-block-paragraph">Agora vamos criar efetivamente o projeto.</p>



<h3 class="wp-block-heading">5.1 Criando o diretório da aplicação</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>mkdir arduino_due_app
cd arduino_due_app
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">mkdir arduino_due_app</span></span>
<span class="line"><span style="color: #D8DEE9FF">cd arduino_due_app</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading">5.2 Estrutura mínima de um projeto Zephyr</h3>



<p class="wp-block-paragraph">Crie a seguinte estrutura inicial:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>arduino_due_app/
├── CMakeLists.txt
├── prj.conf
└── src/
    └── main.c
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">arduino_due_app/</span></span>
<span class="line"><span style="color: #D8DEE9FF">├── CMakeLists.txt</span></span>
<span class="line"><span style="color: #D8DEE9FF">├── prj.conf</span></span>
<span class="line"><span style="color: #D8DEE9FF">└── src/</span></span>
<span class="line"><span style="color: #D8DEE9FF">    └── main.c</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Essa é a <strong>estrutura mínima obrigatória</strong> para qualquer aplicação Zephyr.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">6. Arquivo <code>CMakeLists.txt</code>: integração com o Zephyr</h2>



<p class="wp-block-paragraph">Crie o arquivo <code>CMakeLists.txt</code> com o conteúdo:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(arduino_due_app)

target_sources(app PRIVATE src/main.c)
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">cmake_minimum_required(VERSION 3.20.0)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})</span></span>
<span class="line"><span style="color: #D8DEE9FF">project(arduino_due_app)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">target_sources(app PRIVATE src/main.c)</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading">O que esse arquivo faz, exatamente?</h3>



<ul class="wp-block-list">
<li><code>cmake_minimum_required</code>: garante compatibilidade mínima do CMake</li>



<li><code>find_package(Zephyr ...)</code>: importa todo o sistema de build do Zephyr</li>



<li><code>project(...)</code>: define o nome lógico do projeto</li>



<li><code>target_sources(...)</code>: registra os arquivos C da aplicação</li>
</ul>



<p class="wp-block-paragraph">Aqui ocorre algo importante: <strong>você não define compilador, flags ou linker script</strong>. Tudo isso é herdado automaticamente da definição da placa (<code>arduino_due</code>) e do kernel.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">7. Arquivo <code>prj.conf</code>: configuração do kernel (Kconfig)</h2>



<p class="wp-block-paragraph">O <code>prj.conf</code> controla <strong>quais partes do kernel Zephyr serão compiladas</strong>.</p>



<p class="wp-block-paragraph">Comece com o mínimo funcional:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>CONFIG_PRINTK=y
CONFIG_SERIAL=y
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">CONFIG_PRINTK=y</span></span>
<span class="line"><span style="color: #D8DEE9FF">CONFIG_SERIAL=y</span></span>
<span class="line"><span style="color: #D8DEE9FF">CONFIG_CONSOLE=y</span></span>
<span class="line"><span style="color: #D8DEE9FF">CONFIG_UART_CONSOLE=y</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Essas opções habilitam:</p>



<ul class="wp-block-list">
<li><code>printk()</code> – saída básica de debug</li>



<li>Driver de porta serial</li>



<li>Console padrão via UART</li>
</ul>



<p class="wp-block-paragraph">No Arduino DUE, isso será mapeado automaticamente para a UART correta definida no <em>device tree</em> da placa.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">8. Arquivo <code>main.c</code>: primeira aplicação</h2>



<p class="wp-block-paragraph">Crie <code>src/main.c</code>:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>#include &lt;zephyr/kernel.h>
#include &lt;zephyr/sys/printk.h>

int main(void)
{
    printk("Zephyr rodando no Arduino DUE!\n");

    while (1) {
        printk("Tick\n");
        k_sleep(K_SECONDS(1));
    }

    return 0;
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">#include &lt;zephyr/kernel.h&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">#include &lt;zephyr/sys/printk.h&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">int main(void)</span></span>
<span class="line"><span style="color: #D8DEE9FF">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    printk(&quot;Zephyr rodando no Arduino DUE!\n&quot;);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    while (1) {</span></span>
<span class="line"><span style="color: #D8DEE9FF">        printk(&quot;Tick\n&quot;);</span></span>
<span class="line"><span style="color: #D8DEE9FF">        k_sleep(K_SECONDS(1));</span></span>
<span class="line"><span style="color: #D8DEE9FF">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    return 0;</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading">Conceitos importantes aqui</h3>



<ul class="wp-block-list">
<li><code>#include &lt;zephyr/kernel.h&gt;</code>: acesso ao kernel, threads e temporização</li>



<li><code>printk()</code>: saída síncrona simples (não é <code>printf</code>)</li>



<li><code>k_sleep()</code>: API de temporização do kernel</li>



<li><code>main()</code> <strong>existe</strong>, mas não é o ponto de entrada real — o kernel já está inicializado antes dela ser chamada</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">9. Compilando o projeto para o Arduino DUE</h2>



<p class="wp-block-paragraph">Agora vem a parte crítica: <strong>build correto para a placa certa</strong>.</p>



<p class="wp-block-paragraph">Dentro da pasta <code>arduino_due_app</code>:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>west build -b arduino_due
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">west build -b arduino_due</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">O Zephyr irá:</p>



<ol class="wp-block-list">
<li>Ler a definição da placa Arduino DUE</li>



<li>Selecionar o SoC SAM3X8E</li>



<li>Configurar clocks, memória e periféricos</li>



<li>Gerar o firmware final</li>
</ol>



<p class="wp-block-paragraph">Se tudo estiver correto, o build terminará sem erros.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">10. Gravando o firmware no Arduino DUE</h2>



<p class="wp-block-paragraph">O Arduino DUE utiliza o <strong>bootloader SAM-BA</strong>, compatível com a ferramenta <code>bossac</code>.</p>



<p class="wp-block-paragraph">Com a placa conectada via <strong>porta USB de programação</strong>, execute:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>west flash
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">west flash</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">O Zephyr cuidará automaticamente do processo de gravação usando o método correto definido para a placa.</p>



<p class="wp-block-paragraph">Após o reset, abra um terminal serial:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>minicom -D /dev/ttyACM0 -b 115200
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">minicom -D /dev/ttyACM0 -b 115200</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Você deverá ver:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>Zephyr rodando no Arduino DUE!
Tick
Tick
Tick
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">Zephyr rodando no Arduino DUE!</span></span>
<span class="line"><span style="color: #D8DEE9FF">Tick</span></span>
<span class="line"><span style="color: #D8DEE9FF">Tick</span></span>
<span class="line"><span style="color: #D8DEE9FF">Tick</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">11. Próximos passos</h2>



<p class="wp-block-paragraph">A partir daqui, você já tem:</p>



<ul class="wp-block-list">
<li>Um projeto Zephyr funcional</li>



<li>Build e flash corretamente configurados</li>



<li>Console serial ativo</li>



<li>Base sólida para evoluir</li>
</ul>



<p class="wp-block-paragraph">Nos próximos artigos, podemos avançar para:</p>



<ul class="wp-block-list">
<li>Device Tree do Arduino DUE em detalhes</li>



<li>GPIO e LEDs</li>



<li>UARTs adicionais</li>



<li>SPI e I²C</li>



<li>Timers e interrupções</li>



<li>Multithreading real no Cortex-M3</li>
</ul>



<p class="wp-block-paragraph"></p><p>The post <a href="https://mcu.tec.br/rtos/criando-um-projeto-zephyr-rtos-no-arduino-due-guia-completo-e-didatico/">Criando um Projeto Zephyr RTOS no Arduino DUE – Guia Completo e Didático</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1209</post-id>	</item>
		<item>
		<title>Estratégia Profissional de Gestão de Código com Git em Projetos Individuais e em Equipe</title>
		<link>https://mcu.tec.br/geral/estrategia-profissional-de-gestao-de-codigo-com-git-em-projetos-individuais-e-em-equipe/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=estrategia-profissional-de-gestao-de-codigo-com-git-em-projetos-individuais-e-em-equipe</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Thu, 19 Mar 2026 22:44:34 +0000</pubDate>
				<category><![CDATA[geral]]></category>
		<category><![CDATA[arquitetura de software]]></category>
		<category><![CDATA[boas práticas git]]></category>
		<category><![CDATA[controle de versão]]></category>
		<category><![CDATA[Engenharia de Software]]></category>
		<category><![CDATA[estratégia git]]></category>
		<category><![CDATA[freertos]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[git branches]]></category>
		<category><![CDATA[git issues]]></category>
		<category><![CDATA[git para equipes]]></category>
		<category><![CDATA[git tags]]></category>
		<category><![CDATA[github workflow]]></category>
		<category><![CDATA[rastreabilidade de código]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[versionamento de código]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1417</guid>

					<description><![CDATA[<p>Aprenda uma estratégia profissional de uso do Git para projetos individuais e em equipe, com foco em organização de branches, uso avançado de tags, integração com issues no GitHub e boas práticas de arquitetura de software. Este guia detalhado aborda desde o controle de versões até a rastreabilidade completa do código, incluindo cenários com múltiplos repositórios e aplicações em sistemas embarcados com FreeRTOS, garantindo maior estabilidade, organização e produtividade no desenvolvimento.</p>
<p>The post <a href="https://mcu.tec.br/geral/estrategia-profissional-de-gestao-de-codigo-com-git-em-projetos-individuais-e-em-equipe/">Estratégia Profissional de Gestão de Código com Git em Projetos Individuais e em Equipe</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<div class="root-eb-toc-yd4rg wp-block-essential-blocks-table-of-contents"><div class="eb-parent-wrapper eb-parent-eb-toc-yd4rg "><div class="eb-toc-container eb-toc-yd4rg  eb-toc-is-not-sticky eb-toc-not-collapsible eb-toc-initially-not-collapsed eb-toc-scrollToTop style-1 list-style-none" data-scroll-top="false" data-scroll-top-icon="fas fa-angle-up" data-collapsible="false" data-sticky-hide-mobile="false" data-sticky="false" data-scroll-target="scroll_to_toc" data-copy-link="false" data-editor-type="" data-hide-desktop="false" data-hide-tab="false" data-hide-mobile="false" data-itemcollapsed="false" data-highlight-scroll="false"><div class="eb-toc-header"><h2 class="eb-toc-title">Table of Contents</h2></div><div class="eb-toc-wrapper " data-headers="[{&quot;level&quot;:2,&quot;content&quot;:&quot;Introdu\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Introdu\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-0&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Arquitetura de Branches: Main, Vers\u00f5es e Funcionalidades&quot;,&quot;text&quot;:&quot;Arquitetura de Branches: Main, Vers\u00f5es e Funcionalidades&quot;,&quot;link&quot;:&quot;eb-table-content-1&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Cria\u00e7\u00e3o de Branches a partir do Main&quot;,&quot;text&quot;:&quot;Cria\u00e7\u00e3o de Branches a partir do Main&quot;,&quot;link&quot;:&quot;eb-table-content-2&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Branch por Funcionalidade vs Branch por Vers\u00e3o&quot;,&quot;text&quot;:&quot;Branch por Funcionalidade vs Branch por Vers\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-3&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Mesclagem (Merge) com o Main&quot;,&quot;text&quot;:&quot;Mesclagem (Merge) com o Main&quot;,&quot;link&quot;:&quot;mesclagem-merge-com-o-main&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Atualiza\u00e7\u00e3o entre Vers\u00f5es em Paralelo&quot;,&quot;text&quot;:&quot;Atualiza\u00e7\u00e3o entre Vers\u00f5es em Paralelo&quot;,&quot;link&quot;:&quot;eb-table-content-5&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Considera\u00e7\u00f5es Arquiteturais&quot;,&quot;text&quot;:&quot;Considera\u00e7\u00f5es Arquiteturais&quot;,&quot;link&quot;:&quot;eb-table-content-6&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Uso de Tags para Controle de Vers\u00f5es, Eventos e Marcos do Projeto&quot;,&quot;text&quot;:&quot;Uso de Tags para Controle de Vers\u00f5es, Eventos e Marcos do Projeto&quot;,&quot;link&quot;:&quot;eb-table-content-7&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Integra\u00e7\u00e3o com Issues e Rastreabilidade de Commits no GitHub&quot;,&quot;text&quot;:&quot;Integra\u00e7\u00e3o com Issues e Rastreabilidade de Commits no GitHub&quot;,&quot;link&quot;:&quot;eb-table-content-8&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Branch vinculado \u00e0 Issue&quot;,&quot;text&quot;:&quot;Branch vinculado \u00e0 Issue&quot;,&quot;link&quot;:&quot;eb-table-content-9&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Commits com refer\u00eancia \u00e0 Issue&quot;,&quot;text&quot;:&quot;Commits com refer\u00eancia \u00e0 Issue&quot;,&quot;link&quot;:&quot;eb-table-content-10&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Uso combinado com Pull Requests&quot;,&quot;text&quot;:&quot;Uso combinado com Pull Requests&quot;,&quot;link&quot;:&quot;uso-combinado-com-pull-requests&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Rastreabilidade Completa&quot;,&quot;text&quot;:&quot;Rastreabilidade Completa&quot;,&quot;link&quot;:&quot;rastreabilidade-completa&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Integra\u00e7\u00e3o com Documenta\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Integra\u00e7\u00e3o com Documenta\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-13&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Considera\u00e7\u00f5es Avan\u00e7adas&quot;,&quot;text&quot;:&quot;Considera\u00e7\u00f5es Avan\u00e7adas&quot;,&quot;link&quot;:&quot;eb-table-content-14&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Uso de Dois Reposit\u00f3rios: Ambiente de Desenvolvimento (origin_dev) e Produ\u00e7\u00e3o (origin)&quot;,&quot;text&quot;:&quot;Uso de Dois Reposit\u00f3rios: Ambiente de Desenvolvimento (origin_dev) e Produ\u00e7\u00e3o (origin)&quot;,&quot;link&quot;:&quot;eb-table-content-15&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Estrutura Geral da Estrat\u00e9gia&quot;,&quot;text&quot;:&quot;Estrutura Geral da Estrat\u00e9gia&quot;,&quot;link&quot;:&quot;eb-table-content-16&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Fluxo de Desenvolvimento no origin_dev&quot;,&quot;text&quot;:&quot;Fluxo de Desenvolvimento no origin_dev&quot;,&quot;link&quot;:&quot;fluxo-de-desenvolvimento-no-origin_dev&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Cria\u00e7\u00e3o do Branch de Vers\u00e3o&quot;,&quot;text&quot;:&quot;Cria\u00e7\u00e3o do Branch de Vers\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-18&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Valida\u00e7\u00e3o da Vers\u00e3o&quot;,&quot;text&quot;:&quot;Valida\u00e7\u00e3o da Vers\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-19&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Promo\u00e7\u00e3o para Produ\u00e7\u00e3o (origin)&quot;,&quot;text&quot;:&quot;Promo\u00e7\u00e3o para Produ\u00e7\u00e3o (origin)&quot;,&quot;link&quot;:&quot;eb-table-content-20&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Sincroniza\u00e7\u00e3o entre Ambientes&quot;,&quot;text&quot;:&quot;Sincroniza\u00e7\u00e3o entre Ambientes&quot;,&quot;link&quot;:&quot;eb-table-content-21&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;An\u00e1lise Cr\u00edtica da Estrat\u00e9gia&quot;,&quot;text&quot;:&quot;An\u00e1lise Cr\u00edtica da Estrat\u00e9gia&quot;,&quot;link&quot;:&quot;eb-table-content-22&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Organiza\u00e7\u00e3o Arquitetural do C\u00f3digo e sua Rela\u00e7\u00e3o Direta com o Git&quot;,&quot;text&quot;:&quot;Organiza\u00e7\u00e3o Arquitetural do C\u00f3digo e sua Rela\u00e7\u00e3o Direta com o Git&quot;,&quot;link&quot;:&quot;eb-table-content-23&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Modulariza\u00e7\u00e3o como Estrat\u00e9gia de Versionamento&quot;,&quot;text&quot;:&quot;Modulariza\u00e7\u00e3o como Estrat\u00e9gia de Versionamento&quot;,&quot;link&quot;:&quot;eb-table-content-24&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Isolamento de Responsabilidades&quot;,&quot;text&quot;:&quot;Isolamento de Responsabilidades&quot;,&quot;link&quot;:&quot;isolamento-de-responsabilidades&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Impacto Direto no Git&quot;,&quot;text&quot;:&quot;Impacto Direto no Git&quot;,&quot;link&quot;:&quot;impacto-direto-no-git&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Organiza\u00e7\u00e3o por Diret\u00f3rios e Contexto&quot;,&quot;text&quot;:&quot;Organiza\u00e7\u00e3o por Diret\u00f3rios e Contexto&quot;,&quot;link&quot;:&quot;eb-table-content-27&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Rela\u00e7\u00e3o com Branches e Features&quot;,&quot;text&quot;:&quot;Rela\u00e7\u00e3o com Branches e Features&quot;,&quot;link&quot;:&quot;eb-table-content-28&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Integra\u00e7\u00e3o com Testes e Valida\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Integra\u00e7\u00e3o com Testes e Valida\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-29&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Considera\u00e7\u00f5es Cr\u00edticas&quot;,&quot;text&quot;:&quot;Considera\u00e7\u00f5es Cr\u00edticas&quot;,&quot;link&quot;:&quot;eb-table-content-30&quot;}]" data-visible="[true,true,true,true,true,true]" data-delete-headers="[{&quot;label&quot;:&quot;Introdu\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;introdu\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Arquitetura de Branches: Main, Vers\u00f5es e Funcionalidades&quot;,&quot;value&quot;:&quot;arquitetura-de-branches-main-vers\u00f5es-e-funcionalidades&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Cria\u00e7\u00e3o de Branches a partir do Main&quot;,&quot;value&quot;:&quot;cria\u00e7\u00e3o-de-branches-a-partir-do-main&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Branch por Funcionalidade vs Branch por Vers\u00e3o&quot;,&quot;value&quot;:&quot;branch-por-funcionalidade-vs-branch-por-vers\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Mesclagem (Merge) com o Main&quot;,&quot;value&quot;:&quot;mesclagem-merge-com-o-main&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Atualiza\u00e7\u00e3o entre Vers\u00f5es em Paralelo&quot;,&quot;value&quot;:&quot;atualiza\u00e7\u00e3o-entre-vers\u00f5es-em-paralelo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Considera\u00e7\u00f5es Arquiteturais&quot;,&quot;value&quot;:&quot;considera\u00e7\u00f5es-arquiteturais&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Uso de Tags para Controle de Vers\u00f5es, Eventos e Marcos do Projeto&quot;,&quot;value&quot;:&quot;uso-de-tags-para-controle-de-vers\u00f5es-eventos-e-marcos-do-projeto&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Integra\u00e7\u00e3o com Issues e Rastreabilidade de Commits no GitHub&quot;,&quot;value&quot;:&quot;integra\u00e7\u00e3o-com-issues-e-rastreabilidade-de-commits-no-github&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Branch vinculado \u00e0 Issue&quot;,&quot;value&quot;:&quot;branch-vinculado-\u00e0-issue&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Commits com refer\u00eancia \u00e0 Issue&quot;,&quot;value&quot;:&quot;commits-com-refer\u00eancia-\u00e0-issue&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Uso combinado com Pull Requests&quot;,&quot;value&quot;:&quot;uso-combinado-com-pull-requests&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Rastreabilidade Completa&quot;,&quot;value&quot;:&quot;rastreabilidade-completa&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Integra\u00e7\u00e3o com Documenta\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;integra\u00e7\u00e3o-com-documenta\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Considera\u00e7\u00f5es Avan\u00e7adas&quot;,&quot;value&quot;:&quot;considera\u00e7\u00f5es-avan\u00e7adas&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Uso de Dois Reposit\u00f3rios: Ambiente de Desenvolvimento (origin_dev) e Produ\u00e7\u00e3o (origin)&quot;,&quot;value&quot;:&quot;uso-de-dois-reposit\u00f3rios-ambiente-de-desenvolvimento-origin_dev-e-produ\u00e7\u00e3o-origin&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Estrutura Geral da Estrat\u00e9gia&quot;,&quot;value&quot;:&quot;estrutura-geral-da-estrat\u00e9gia&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Fluxo de Desenvolvimento no origin_dev&quot;,&quot;value&quot;:&quot;fluxo-de-desenvolvimento-no-origin_dev&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Cria\u00e7\u00e3o do Branch de Vers\u00e3o&quot;,&quot;value&quot;:&quot;cria\u00e7\u00e3o-do-branch-de-vers\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Valida\u00e7\u00e3o da Vers\u00e3o&quot;,&quot;value&quot;:&quot;valida\u00e7\u00e3o-da-vers\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Promo\u00e7\u00e3o para Produ\u00e7\u00e3o (origin)&quot;,&quot;value&quot;:&quot;promo\u00e7\u00e3o-para-produ\u00e7\u00e3o-origin&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Sincroniza\u00e7\u00e3o entre Ambientes&quot;,&quot;value&quot;:&quot;sincroniza\u00e7\u00e3o-entre-ambientes&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;An\u00e1lise Cr\u00edtica da Estrat\u00e9gia&quot;,&quot;value&quot;:&quot;an\u00e1lise-cr\u00edtica-da-estrat\u00e9gia&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Organiza\u00e7\u00e3o Arquitetural do C\u00f3digo e sua Rela\u00e7\u00e3o Direta com o Git&quot;,&quot;value&quot;:&quot;organiza\u00e7\u00e3o-arquitetural-do-c\u00f3digo-e-sua-rela\u00e7\u00e3o-direta-com-o-git&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Modulariza\u00e7\u00e3o como Estrat\u00e9gia de Versionamento&quot;,&quot;value&quot;:&quot;modulariza\u00e7\u00e3o-como-estrat\u00e9gia-de-versionamento&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Isolamento de Responsabilidades&quot;,&quot;value&quot;:&quot;isolamento-de-responsabilidades&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Impacto Direto no Git&quot;,&quot;value&quot;:&quot;impacto-direto-no-git&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Organiza\u00e7\u00e3o por Diret\u00f3rios e Contexto&quot;,&quot;value&quot;:&quot;organiza\u00e7\u00e3o-por-diret\u00f3rios-e-contexto&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Rela\u00e7\u00e3o com Branches e Features&quot;,&quot;value&quot;:&quot;rela\u00e7\u00e3o-com-branches-e-features&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Integra\u00e7\u00e3o com Testes e Valida\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;integra\u00e7\u00e3o-com-testes-e-valida\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Considera\u00e7\u00f5es Cr\u00edticas&quot;,&quot;value&quot;:&quot;considera\u00e7\u00f5es-cr\u00edticas&quot;,&quot;isDelete&quot;:false}]" data-smooth="true" data-top-offset=""><div class="eb-toc__list-wrap"><ul class="eb-toc__list"><li><a href="#eb-table-content-0">Introdução</a><li><a href="#eb-table-content-1">Arquitetura de Branches: Main, Versões e Funcionalidades</a><ul class="eb-toc__list"><li><a href="#eb-table-content-2">Criação de Branches a partir do Main</a><li><a href="#eb-table-content-3">Branch por Funcionalidade vs Branch por Versão</a><li><a href="#mesclagem-merge-com-o-main">Mesclagem (Merge) com o Main</a><li><a href="#eb-table-content-5">Atualização entre Versões em Paralelo</a><li><a href="#eb-table-content-6">Considerações Arquiteturais</a></li></ul><li><a href="#eb-table-content-7">Uso de Tags para Controle de Versões, Eventos e Marcos do Projeto</a><li><a href="#eb-table-content-8">Integração com Issues e Rastreabilidade de Commits no GitHub</a><ul class="eb-toc__list"><li><a href="#eb-table-content-9">Branch vinculado à Issue</a><li><a href="#eb-table-content-10">Commits com referência à Issue</a><li><a href="#uso-combinado-com-pull-requests">Uso combinado com Pull Requests</a><li><a href="#rastreabilidade-completa">Rastreabilidade Completa</a><li><a href="#eb-table-content-13">Integração com Documentação</a><li><a href="#eb-table-content-14">Considerações Avançadas</a></li></ul><li><a href="#eb-table-content-15">Uso de Dois Repositórios: Ambiente de Desenvolvimento (origin_dev) e Produção (origin)</a><ul class="eb-toc__list"><li><a href="#eb-table-content-16">Estrutura Geral da Estratégia</a><li><a href="#fluxo-de-desenvolvimento-no-origin_dev">Fluxo de Desenvolvimento no origin_dev</a><li><a href="#eb-table-content-18">Criação do Branch de Versão</a><li><a href="#eb-table-content-19">Validação da Versão</a><li><a href="#eb-table-content-20">Promoção para Produção (origin)</a><li><a href="#eb-table-content-21">Sincronização entre Ambientes</a><li><a href="#eb-table-content-22">Análise Crítica da Estratégia</a></li></ul><li><a href="#eb-table-content-23">Organização Arquitetural do Código e sua Relação Direta com o Git</a><ul class="eb-toc__list"><li><a href="#eb-table-content-24">Modularização como Estratégia de Versionamento</a><li><a href="#isolamento-de-responsabilidades">Isolamento de Responsabilidades</a><li><a href="#impacto-direto-no-git">Impacto Direto no Git</a><li><a href="#eb-table-content-27">Organização por Diretórios e Contexto</a><li><a href="#eb-table-content-28">Relação com Branches e Features</a><li><a href="#eb-table-content-29">Integração com Testes e Validação</a><li><a href="#eb-table-content-30">Considerações Críticas</a></li></ul></ul></div></div></div></div></div>


<h2 class="wp-block-heading">Introdução</h2>



<p class="wp-block-paragraph">O <strong>Git</strong> tornou-se o sistema de controle de versão mais utilizado no desenvolvimento de software moderno. Ele permite que desenvolvedores acompanhem alterações no código, trabalhem em equipe de forma organizada e mantenham histórico detalhado de todas as modificações realizadas em um projeto. No entanto, embora o Git ofereça um conjunto poderoso de ferramentas, seu uso eficaz depende muito da <strong>estratégia adotada pela equipe ou pelo desenvolvedor</strong>.</p>



<p class="wp-block-paragraph">Em muitos projetos, especialmente aqueles relacionados a <strong>sistemas embarcados, firmware e aplicações críticas</strong>, como os que envolvem microcontroladores, RTOS ou arquiteturas distribuídas, a forma como o código é organizado dentro do Git pode impactar diretamente na <strong>qualidade do software, na rastreabilidade das mudanças e na capacidade de manutenção do projeto ao longo do tempo</strong>.</p>



<p class="wp-block-paragraph">Uma estratégia bem definida de uso do Git permite resolver diversos problemas comuns no desenvolvimento colaborativo. Entre esses problemas estão conflitos frequentes de código, dificuldade em identificar quando uma funcionalidade foi introduzida, ausência de rastreabilidade entre commits e tarefas de desenvolvimento, e dificuldades para manter versões estáveis do software enquanto novas funcionalidades continuam sendo implementadas.</p>



<p class="wp-block-paragraph">Ao longo da experiência prática em projetos individuais e também em equipes dentro de empresas, desenvolvi uma abordagem de organização baseada em <strong>branches de versões, branches de funcionalidades, uso disciplinado de tags e integração com sistemas de issues</strong>, especialmente no GitHub. Essa abordagem busca equilibrar três aspectos fundamentais do desenvolvimento moderno: <strong>estabilidade da versão em produção, evolução contínua do software e rastreabilidade completa das alterações realizadas</strong>.</p>



<p class="wp-block-paragraph">Além disso, essa estratégia também considera cenários mais complexos de desenvolvimento, como ambientes onde existem <strong>dois repositórios distintos — um para desenvolvimento e outro para produção — e também a necessidade de manter simultaneamente múltiplas versões do software</strong>, algo comum em produtos embarcados que permanecem anos no mercado recebendo atualizações incrementais.</p>



<p class="wp-block-paragraph">Neste artigo será apresentada, de forma didática e detalhada, uma estratégia prática de organização de projetos com Git, incluindo o uso de <strong>branches, tags, commits estruturados, integração com issues e organização arquitetural do código</strong>. Também serão apresentados os comandos fundamentais do Git necessários para implementar essa estratégia no dia a dia do desenvolvimento.</p>



<p class="wp-block-paragraph">O objetivo não é apenas explicar os comandos, mas mostrar <strong>como construir um fluxo de trabalho que permita manter o projeto organizado, escalável e rastreável</strong>, mesmo em projetos grandes ou em equipes distribuídas.</p>



<p class="wp-block-paragraph">Na próxima seção será apresentada a base dessa estratégia: <strong>a organização do repositório a partir do branch principal (Main) e a criação de branches para versões e funcionalidades</strong>.</p><p>The post <a href="https://mcu.tec.br/geral/estrategia-profissional-de-gestao-de-codigo-com-git-em-projetos-individuais-e-em-equipe/">Estratégia Profissional de Gestão de Código com Git em Projetos Individuais e em Equipe</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1417</post-id>	</item>
		<item>
		<title>FreeRTOS: Uso Correto de Queue com Múltiplos Consumidores</title>
		<link>https://mcu.tec.br/rtos/freertos-uso-correto-de-queue-com-multiplos-consumidores/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=freertos-uso-correto-de-queue-com-multiplos-consumidores</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Fri, 27 Feb 2026 19:03:41 +0000</pubDate>
				<category><![CDATA[RTOS]]></category>
		<category><![CDATA[comunicação entre tarefas]]></category>
		<category><![CDATA[escalonador FreeRTOS]]></category>
		<category><![CDATA[event groups]]></category>
		<category><![CDATA[filas em RTOS]]></category>
		<category><![CDATA[freertos]]></category>
		<category><![CDATA[múltiplos consumidores]]></category>
		<category><![CDATA[queue FreeRTOS]]></category>
		<category><![CDATA[RTOS em microcontroladores]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[task notifications]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1059</guid>

					<description><![CDATA[<p>Aprenda como usar corretamente Queue com múltiplos consumidores no FreeRTOS. Entenda o impacto do escalonador, riscos de starvation, perda de eventos e quando usar alternativas como Event Groups e Task Notifications para criar firmwares robustos e previsíveis.</p>
<p>The post <a href="https://mcu.tec.br/rtos/freertos-uso-correto-de-queue-com-multiplos-consumidores/">FreeRTOS: Uso Correto de Queue com Múltiplos Consumidores</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<div class="root-eb-toc-gumxp wp-block-essential-blocks-table-of-contents"><div class="eb-parent-wrapper eb-parent-eb-toc-gumxp "><div class="eb-toc-container eb-toc-gumxp  eb-toc-is-not-sticky eb-toc-not-collapsible eb-toc-initially-not-collapsed eb-toc-scrollToTop style-1 list-style-none" data-scroll-top="false" data-scroll-top-icon="fas fa-angle-up" data-collapsible="false" data-sticky-hide-mobile="false" data-sticky="false" data-scroll-target="scroll_to_toc" data-copy-link="false" data-editor-type="" data-hide-desktop="false" data-hide-tab="false" data-hide-mobile="false" data-itemcollapsed="false" data-highlight-scroll="false"><div class="eb-toc-header"><h2 class="eb-toc-title">Table of Contents</h2></div><div class="eb-toc-wrapper " data-headers="[{&quot;level&quot;:3,&quot;content&quot;:&quot;Introdu\u00e7\u00e3o: filas no FreeRTOS e o cen\u00e1rio de m\u00faltiplos consumidores&quot;,&quot;text&quot;:&quot;Introdu\u00e7\u00e3o: filas no FreeRTOS e o cen\u00e1rio de m\u00faltiplos consumidores&quot;,&quot;link&quot;:&quot;eb-table-content-0&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Modelos cl\u00e1ssicos de m\u00faltiplos consumidores e o impacto no escalonador&quot;,&quot;text&quot;:&quot;Modelos cl\u00e1ssicos de m\u00faltiplos consumidores e o impacto no escalonador&quot;,&quot;link&quot;:&quot;eb-table-content-1&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Cuidados essenciais e armadilhas comuns ao usar Queue com v\u00e1rios consumidores&quot;,&quot;text&quot;:&quot;Cuidados essenciais e armadilhas comuns ao usar Queue com v\u00e1rios consumidores&quot;,&quot;link&quot;:&quot;eb-table-content-2&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Alternativas arquiteturais quando m\u00faltiplos consumidores precisam do mesmo evento&quot;,&quot;text&quot;:&quot;Alternativas arquiteturais quando m\u00faltiplos consumidores precisam do mesmo evento&quot;,&quot;link&quot;:&quot;eb-table-content-3&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Boas pr\u00e1ticas, diretrizes de projeto e fechamento&quot;,&quot;text&quot;:&quot;Boas pr\u00e1ticas, diretrizes de projeto e fechamento&quot;,&quot;link&quot;:&quot;eb-table-content-4&quot;}]" data-visible="[true,true,true,true,true,true]" data-delete-headers="[{&quot;label&quot;:&quot;Introdu\u00e7\u00e3o: filas no FreeRTOS e o cen\u00e1rio de m\u00faltiplos consumidores&quot;,&quot;value&quot;:&quot;introdu\u00e7\u00e3o-filas-no-freertos-e-o-cen\u00e1rio-de-m\u00faltiplos-consumidores&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Modelos cl\u00e1ssicos de m\u00faltiplos consumidores e o impacto no escalonador&quot;,&quot;value&quot;:&quot;modelos-cl\u00e1ssicos-de-m\u00faltiplos-consumidores-e-o-impacto-no-escalonador&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Cuidados essenciais e armadilhas comuns ao usar Queue com v\u00e1rios consumidores&quot;,&quot;value&quot;:&quot;cuidados-essenciais-e-armadilhas-comuns-ao-usar-queue-com-v\u00e1rios-consumidores&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Alternativas arquiteturais quando m\u00faltiplos consumidores precisam do mesmo evento&quot;,&quot;value&quot;:&quot;alternativas-arquiteturais-quando-m\u00faltiplos-consumidores-precisam-do-mesmo-evento&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Boas pr\u00e1ticas, diretrizes de projeto e fechamento&quot;,&quot;value&quot;:&quot;boas-pr\u00e1ticas-diretrizes-de-projeto-e-fechamento&quot;,&quot;isDelete&quot;:false}]" data-smooth="true" data-top-offset=""><div class="eb-toc__list-wrap"><ul class="eb-toc__list"><li><a href="#eb-table-content-0">Introdução: filas no FreeRTOS e o cenário de múltiplos consumidores</a><li><a href="#eb-table-content-1">Modelos clássicos de múltiplos consumidores e o impacto no escalonador</a><li><a href="#eb-table-content-2">Cuidados essenciais e armadilhas comuns ao usar Queue com vários consumidores</a><li><a href="#eb-table-content-3">Alternativas arquiteturais quando múltiplos consumidores precisam do mesmo evento</a><li><a href="#eb-table-content-4">Boas práticas, diretrizes de projeto e fechamento</a></ul></div></div></div></div></div>


<h3 class="wp-block-heading">Introdução: filas no FreeRTOS e o cenário de múltiplos consumidores</h3>



<p class="wp-block-paragraph">No FreeRTOS, <strong>Queue</strong> é um dos mecanismos centrais de comunicação e sincronização entre tarefas. Diferente de simples buffers, uma fila carrega não apenas dados, mas também <strong>semântica de sincronização</strong>, permitindo que tarefas produtoras e consumidoras operem de forma desacoplada no tempo. Em sistemas reais — especialmente em firmware para sensores, comunicação, aquisição de dados e pipelines de processamento — é muito comum termos <strong>um produtor e vários consumidores</strong>, todos interessados nos dados que chegam pela mesma fila.</p>



<p class="wp-block-paragraph">O primeiro ponto importante, e frequentemente negligenciado, é que <strong>uma Queue do FreeRTOS não é um mecanismo de broadcast</strong>. Ela segue estritamente o modelo <em>FIFO</em> (First-In, First-Out) com <strong>remoção destrutiva do item</strong>. Isso significa que, quando múltiplas tarefas consumidoras bloqueiam na mesma fila, <strong>apenas uma delas receberá cada item enviado</strong>, e essa escolha é feita pelo escalonador com base em prioridade e estado das tarefas. Esse detalhe muda completamente a forma como o sistema deve ser arquitetado.</p>



<p class="wp-block-paragraph">Esse comportamento é ideal quando os consumidores representam <strong>workers concorrentes</strong>, ou seja, tarefas equivalentes que disputam trabalho. Um exemplo clássico é um sistema em que uma interrupção de ADC empilha amostras em uma fila, e várias tarefas de processamento estatístico competem para consumir esses dados. Nesse caso, a fila atua como um <em>work queue</em>, balanceando carga automaticamente entre os consumidores.</p>



<p class="wp-block-paragraph">Por outro lado, quando o objetivo é que <strong>todos os consumidores vejam todos os eventos</strong>, a Queue isoladamente é a escolha errada. Muitos bugs em sistemas embarcados com FreeRTOS surgem exatamente desse equívoco conceitual: o desenvolvedor assume que várias tarefas “escutando” a mesma fila receberão as mesmas mensagens, o que simplesmente não acontece. Esse erro se manifesta como perda intermitente de eventos, estados inconsistentes e falhas difíceis de reproduzir.</p>



<p class="wp-block-paragraph">Para ilustrar o cenário correto de múltiplos consumidores concorrentes, considere o exemplo abaixo, onde várias tarefas processam mensagens vindas de um único produtor:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>typedef struct {
    uint32_t id;
    uint16_t value;
} message_t;

QueueHandle_t xQueue;

void vProducerTask(void *pvParameters)
{
    message_t msg;
    uint32_t counter = 0;

    for (;;)
    {
        msg.id = counter++;
        msg.value = counter * 10;

        xQueueSend(xQueue, &amp;msg, portMAX_DELAY);
        vTaskDelay(pdMS_TO_TICKS(100));
    }
}

void vConsumerTask(void *pvParameters)
{
    message_t msg;

    for (;;)
    {
        if (xQueueReceive(xQueue, &amp;msg, portMAX_DELAY) == pdPASS)
        {
            /* Cada mensagem será processada por APENAS um consumidor */
            process_message(&amp;msg);
        }
    }
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">typedef</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">uint32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">id</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">value</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">message_t</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">QueueHandle_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">xQueue</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">vProducerTask</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">pvParameters</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">message_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">msg</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">uint32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">counter</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">;;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">msg</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">id</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">counter</span><span style="color: #81A1C1">++;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">msg</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">value</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">counter</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">10</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">xQueueSend</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">xQueue</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">msg</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">portMAX_DELAY</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">vTaskDelay</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">pdMS_TO_TICKS</span><span style="color: #D8DEE9FF">(</span><span style="color: #B48EAD">100</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">vConsumerTask</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">pvParameters</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">message_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">msg</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">;;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #88C0D0">xQueueReceive</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">xQueue</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">msg</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">portMAX_DELAY</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">==</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pdPASS</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #616E88">/* Cada mensagem será processada por APENAS um consumidor */</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">process_message</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">msg</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Nesse modelo, várias instâncias de <code>vConsumerTask</code> podem ser criadas, e cada mensagem enviada pelo produtor será entregue a apenas uma delas. O FreeRTOS garante exclusão mútua implícita no acesso à fila, evitando a necessidade de mutex para esse fluxo específico.</p>



<p class="wp-block-paragraph">Nesta artigo, vamos aprofundar <strong>quando esse modelo é ideal</strong>, <strong>quais implicações surgem em termos de escalonamento, prioridade e starvation</strong>, <strong>como evitar armadilhas comuns</strong>, e <strong>quais alternativas arquiteturais devem ser usadas quando o requisito é difusão (fan-out) e não competição</strong>.</p><p>The post <a href="https://mcu.tec.br/rtos/freertos-uso-correto-de-queue-com-multiplos-consumidores/">FreeRTOS: Uso Correto de Queue com Múltiplos Consumidores</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1059</post-id>	</item>
		<item>
		<title>Filtro notch discreto (notch IIR) e média sincronizada (sync averaging)</title>
		<link>https://mcu.tec.br/algoritimos/filstros/filtro-notch-discreto-notch-iir-e-media-sincronizada-sync-averaging/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=filtro-notch-discreto-notch-iir-e-media-sincronizada-sync-averaging</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Tue, 24 Feb 2026 14:23:52 +0000</pubDate>
				<category><![CDATA[Filstros]]></category>
		<category><![CDATA[ADC DMA microcontrolador]]></category>
		<category><![CDATA[análise de sinais repetitivos]]></category>
		<category><![CDATA[Biquad]]></category>
		<category><![CDATA[biquad digital]]></category>
		<category><![CDATA[DSP em microcontroladores]]></category>
		<category><![CDATA[encoder sincronização]]></category>
		<category><![CDATA[esp32]]></category>
		<category><![CDATA[filtro digital]]></category>
		<category><![CDATA[filtro digital em C]]></category>
		<category><![CDATA[filtro notch IIR]]></category>
		<category><![CDATA[firmware tempo real]]></category>
		<category><![CDATA[média sincronizada]]></category>
		<category><![CDATA[microcontroladores]]></category>
		<category><![CDATA[processamento de sinais]]></category>
		<category><![CDATA[processamento digital de sinais embarcados]]></category>
		<category><![CDATA[remoção de 60Hz]]></category>
		<category><![CDATA[RP2040]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[SNR em sistemas embarcados]]></category>
		<category><![CDATA[stm32]]></category>
		<category><![CDATA[synchronous averaging]]></category>
		<category><![CDATA[tempo real]]></category>
		<category><![CDATA[zero crossing]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1356</guid>

					<description><![CDATA[<p>Fechando a ideia: o notch discreto e a média sincronizada resolvem problemas parecidos (melhorar a qualidade do sinal), mas por “mecanismos” bem diferentes, e isso muda totalmente quando cada um é a melhor escolha. O notch é a ferramenta certa quando você conhece uma frequência indesejada bem definida e relativamente estável e quer arrancá-la do sinal com o mínimo de impacto no restante do espectro. Em firmware, isso costuma ser “hum” de 50/60 Hz, tons de chaveamento, ou uma ressonância estreita que aparece como pico bem localizado. O ponto crítico é que o notch é tão bom quanto a precisão do seu (f_0) e a escolha de (Q): se a interferência varia de frequência, um notch muito estreito deixa passar; se você alarga demais, começa a “machucar” conteúdo útil perto de (f_0). Além disso, como é um IIR, você precisa cuidar de estabilidade numérica e do formato de implementação (a forma direta II transposta tende a ser mais robusta em ponto flutuante e também costuma ser a melhor porta de entrada para depois migrar para ponto fixo).</p>
<p>Já a média sincronizada não é “um filtro de frequência” no sentido clássico; ela é uma técnica de extração por coerência: tudo que está alinhado com o período de referência fica mais forte, e o que não está alinhado tende a desaparecer. Por isso ela é superior quando o sinal útil é repetitivo e você tem um marcador de fase confiável, como encoder em máquina rotativa, o próprio PWM em conversores/inversores, ou zero-cross da rede. O ganho prático é enorme porque ela aumenta SNR sem precisar “inventar” um modelo espectral do ruído, mas ela também tem uma fragilidade: se o sincronismo for ruim (jitter, período variável, marcador inconsistente) a média “borrará” a forma de onda e pode até criar artefatos que parecem sinal real. Em projetos de rede elétrica, por exemplo, se você fixa (N) como “amostras por ciclo” sem acompanhar a variação real da frequência, a média começa a perder fase ao longo dos ciclos; nesse caso, ou você mede o período e ajusta (N) dinamicamente, ou você reamostra o ciclo para um grid fixo antes de acumular.</p>
<p>Na prática, em pipeline embarcado, uma combinação muito comum é usar notch primeiro para remover uma interferência tonal forte e depois usar média sincronizada para revelar a forma repetitiva de interesse com ruído bem mais baixo. Isso funciona especialmente bem quando a interferência não é coerente com o período que você está usando para sincronizar; se for coerente, a média pode reforçar a interferência, e aí o notch vira praticamente obrigatório antes. Se o seu sistema estiver no limite de CPU, o notch custa um número fixo e pequeno de multiplicações por amostra, enquanto a média sincronizada pode custar pouco por amostra mas “cobra” um custo por período quando você atualiza a forma média; dá para manter determinismo atualizando médias de forma incremental, ou reduzindo taxa, ou usando buffers e processamento em tarefa de menor prioridade.</p>
<p>Se você me disser qual é o seu caso (por exemplo: remover 60 Hz do ADC de shunt, ou extrair assinatura de vibração sincronizada com encoder, ou limpar ripple de PWM), eu adapto os coeficientes, a estratégia de sincronismo e o código para um cenário mais “pé no chão” com ADC+DMA, saturação, e versão em ponto fixo (Q31) pronta para rodar liso em Cortex-M.</p>
<p>The post <a href="https://mcu.tec.br/algoritimos/filstros/filtro-notch-discreto-notch-iir-e-media-sincronizada-sync-averaging/">Filtro notch discreto (notch IIR) e média sincronizada (sync averaging)</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">Em sistemas embarcados, “tirar uma frequência específica do sinal” costuma aparecer em dois cenários muito práticos: remover uma interferência estreita e persistente (por exemplo, 50/60 Hz de rede, ou um tom de comutação) e aumentar SNR (relação sinal-ruído) quando o fenômeno de interesse é repetitivo e existe uma referência de fase (por exemplo, rotação com encoder, comutação PWM, ou zero-cross da rede). O filtro notch discreto resolve muito bem o primeiro caso porque ele cria uma atenuação profunda numa frequência central (f_0) com pouca alteração do resto do espectro. Já a média sincronizada resolve muito bem o segundo porque ela soma ciclos “alinhados” no tempo/fase, reforçando o componente coerente e cancelando ruído não correlacionado e componentes que não encaixam exatamente naquele período.</p>



<p class="wp-block-paragraph">Quando o firmware precisa ser previsível (tempo real), o desenho do filtro não é só “matemático”: você escolhe estruturas e limites para garantir custo computacional constante, estado pequeno e estabilidade numérica, principalmente se você for para ponto fixo ou tiver ADC+DMA alimentando o pipeline. (Essa preocupação de arquitetura e previsibilidade é típica de projetos de tempo real.)</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">1) Notch discreto: o “biquad” que apaga uma frequência</h2>



<p class="wp-block-paragraph">Um notch digital clássico pode ser implementado como um biquad IIR (segunda ordem) com zeros exatamente na frequência que você quer cancelar e polos próximos, controlando a largura do “buraco” via fator de qualidade (Q). Quanto maior o (Q), mais estreito é o notch (ótimo para interferência tonal estável), mas maior a sensibilidade a variação de (f_0) e a quantização dos coeficientes. Em termos práticos: para hum de rede em 60 Hz, se o sinal tiver variação de frequência (rede oscilando, ou a interferência “escorregando”), um (Q) alto demais pode deixar “vazar” parte do ruído. Para tom de comutação de um inversor ou fonte chaveada, se o clock for estável, dá para usar (Q) alto e atacar de forma cirúrgica.</p>



<p class="wp-block-paragraph">O biquad notch mais comum pode ser escrito como:</p>



<p class="wp-block-paragraph">\[<br>H(z)=\frac{1 &#8211; 2\cos(\omega_0)z^{-1} + z^{-2}}{1 &#8211; 2r\cos(\omega_0)z^{-1} + r^2 z^{-2}}<br>\]



<p class="wp-block-paragraph">onde \(\omega_0=2\pi f_0/F_s\) e (r) controla a “proximidade” dos polos aos zeros (quanto mais perto de 1, mais estreito e mais profundo). Uma ligação prática entre (r) e (Q) é aproximar a largura de banda por \(BW \approx f_0/Q\) e usar \(r \approx e^{-\pi BW/F_s}\). Isso funciona muito bem para firmware porque você calcula coeficientes uma vez (ou quando \(f_0\) muda) e o processamento por amostra fica constante.</p>



<h3 class="wp-block-heading">Código em C: biquad notch (float) com inicialização por \(F_s, f_0, Q\)</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>#include &lt;math.h>
#include &lt;stdint.h>

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

typedef struct {
    // Coeficientes normalizados (a0 = 1)
    float b0, b1, b2;
    float a1, a2;

    // Estados (forma direta II transposta)
    float z1, z2;
} NotchBiquad;

/**
 * @brief Inicializa um filtro notch IIR (biquad) em forma direta II transposta.
 * @param f     Ponteiro para a estrutura do filtro.
 * @param Fs    Frequência de amostragem (Hz).
 * @param f0    Frequência central do notch (Hz).
 * @param Q     Fator de qualidade (adimensional). Ex.: 10..50 típicos.
 *
 * Observação prática:
 *  - Q maior => notch mais estreito, mais sensível a variações de f0 e quantização.
 *  - Q menor => notch mais largo, remove mais “vizinhança” de frequências.
 */
static inline void notch_init(NotchBiquad *f, float Fs, float f0, float Q)
{
    const float w0 = 2.0f * (float)M_PI * (f0 / Fs);

    // Largura de banda aproximada (Hz)
    const float BW = f0 / Q;

    // Polo raio r (aprox.) -> define a largura do notch
    const float r = expf(-(float)M_PI * (BW / Fs));

    const float c = cosf(w0);

    // Numerador (zeros no círculo unitário em ±w0)
    const float b0 = 1.0f;
    const float b1 = -2.0f * c;
    const float b2 = 1.0f;

    // Denominador (polos em raio r)
    const float a0 = 1.0f;
    const float a1 = -2.0f * r * c;
    const float a2 = r * r;

    // Normaliza por a0 (a0=1 aqui, mas mantemos o padrão)
    f->b0 = b0 / a0;
    f->b1 = b1 / a0;
    f->b2 = b2 / a0;
    f->a1 = a1 / a0;
    f->a2 = a2 / a0;

    f->z1 = 0.0f;
    f->z2 = 0.0f;
}

/**
 * @brief Processa 1 amostra pelo biquad notch (DF-II Transposta).
 * @param f Estrutura do filtro.
 * @param x Amostra de entrada.
 * @return  Amostra filtrada.
 */
static inline float notch_process(NotchBiquad *f, float x)
{
    // DF-II transposta:
    // y = b0*x + z1
    // z1 = b1*x - a1*y + z2
    // z2 = b2*x - a2*y
    const float y = (f->b0 * x) + f->z1;
    const float z1 = (f->b1 * x) - (f->a1 * y) + f->z2;
    const float z2 = (f->b2 * x) - (f->a2 * y);

    f->z1 = z1;
    f->z2 = z2;
    return y;
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9">math</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">h</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9">stdint</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">h</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">ifndef</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">M_PI</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">M_PI</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">3.14159265358979323846</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">endif</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">typedef</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Coeficientes normalizados (a0 = 1)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">b0</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">b1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">b2</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a2</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Estados (forma direta II transposta)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z2</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NotchBiquad</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">/**</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">brief</span><span style="color: #616E88"> Inicializa um filtro notch IIR (biquad) em forma direta II transposta.</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">f</span><span style="color: #616E88">     Ponteiro para a estrutura do filtro.</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">Fs</span><span style="color: #616E88">    Frequência de amostragem (Hz).</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">f0</span><span style="color: #616E88">    Frequência central do notch (Hz).</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">Q</span><span style="color: #616E88">     Fator de qualidade (adimensional). Ex.: 10..50 típicos.</span></span>
<span class="line"><span style="color: #616E88"> *</span></span>
<span class="line"><span style="color: #616E88"> * Observação prática:</span></span>
<span class="line"><span style="color: #616E88"> *  - Q maior =&gt; notch mais estreito, mais sensível a variações de f0 e quantização.</span></span>
<span class="line"><span style="color: #616E88"> *  - Q menor =&gt; notch mais largo, remove mais “vizinhança” de frequências.</span></span>
<span class="line"><span style="color: #616E88"> */</span></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">inline</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">notch_init</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">NotchBiquad</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Fs</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">f0</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Q</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> w0 </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> 2</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">M_PI</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">f0</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Fs</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Largura de banda aproximada (Hz)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> BW </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">f0</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Q</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Polo raio r (aprox.) -&gt; define a largura do notch</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> r </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">expf</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">M_PI</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">BW</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Fs</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> c </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">cosf</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">w0</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Numerador (zeros no círculo unitário em ±w0)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> b0 </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> 1</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> b1 </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">2</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">c</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> b2 </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> 1</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Denominador (polos em raio r)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> a0 </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> 1</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> a1 </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">2</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">r</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">c</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> a2 </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">r</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">r</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Normaliza por a0 (a0=1 aqui, mas mantemos o padrão)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">b0</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">b0</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">b1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">b1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">b2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">b2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">a1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">a2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a0</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">z1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> 0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">z2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> 0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">/**</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">brief</span><span style="color: #616E88"> Processa 1 amostra pelo biquad notch (DF-II Transposta).</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">f</span><span style="color: #616E88"> Estrutura do filtro.</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">x</span><span style="color: #616E88"> Amostra de entrada.</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">return</span><span style="color: #616E88">  Amostra filtrada.</span></span>
<span class="line"><span style="color: #616E88"> */</span></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">inline</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">notch_process</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">NotchBiquad</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// DF-II transposta:</span></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// y = b0*x + z1</span></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// z1 = b1*x - a1*y + z2</span></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// z2 = b2*x - a2*y</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> y </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">b0</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">z1</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> z1 </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">b1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">a1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">y</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">z2</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> z2 </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">b2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">a2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">y</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">z1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z1</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">f</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">z2</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z2</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">y</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph"><strong>Melhores usos do notch:</strong> quando você conhece (ou mede) a frequência indesejada e ela é estreita, relativamente estável e você quer preservar quase tudo ao redor. Em instrumentação, isso aparece em leitura de shunt/ADC contaminada por rede; em áudio, hum; em controle, ressonância mecânica estreita (desde que não destrua margem de fase indevidamente); em eletrônica de potência, uma componente tonal em corrente/tensão.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">2) Média sincronizada: “soma coerente” alinhada à fase</h2>



<p class="wp-block-paragraph">A média sincronizada (às vezes chamada de synchronous averaging, time synchronous averaging) não é “só uma média móvel”. A sacada é que você escolhe uma janela exatamente igual a um período do fenômeno repetitivo (ou múltiplos inteiros) e reinicia/alinha essa janela usando um evento de referência: um zero-cross, um pulso de encoder, um índice, ou um marcador derivado do PWM. Se você tem (N) amostras por período e faz uma média sobre (K) períodos alinhados, o componente que se repete com a mesma fase soma e cresce proporcionalmente, enquanto ruído aleatório cai como (\sqrt{K}) no RMS. Além disso, componentes que não “encaixam” naquele período tendem a se cancelar.</p>



<p class="wp-block-paragraph">Em termos de filtro, isso se comporta como um filtro tipo comb (pente) extremamente eficiente para rejeitar tudo que não é coerente com o período escolhido. A diferença para um notch é que você não está mirando uma única frequência: você está favorecendo toda a forma de onda repetitiva no domínio do tempo, desde que sincronizada.</p>



<h3 class="wp-block-heading">Código em C: média sincronizada por períodos (com referência externa)</h3>



<p class="wp-block-paragraph">A seguir vai uma implementação simples (e bem útil) para firmware: você acumula amostras de cada posição dentro do período e, a cada período completo, você atualiza a média. Isso é perfeito quando você tem um “gatilho de início de período” (por exemplo, interrupção de índice do encoder ou zero-cross).</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>#include &lt;stdint.h>
#include &lt;string.h>

typedef struct {
    uint16_t N;          // amostras por período
    uint16_t idx;        // posição atual no período &#91;0..N-1&#93;
    uint32_t K;          // quantos períodos já acumulados (limite/controle externo)

    // Buffers de acumulação (use int64 se seu range for grande)
    int64_t *acc;        // soma por posição
    int32_t *avg;        // média por posição (resultado)
} SyncAvg;

/**
 * @brief Inicializa a média sincronizada.
 * @param s       Estrutura.
 * @param acc     Buffer de acumulação de tamanho N (int64_t).
 * @param avg     Buffer de saída média de tamanho N (int32_t).
 * @param N       Amostras por período.
 */
static inline void syncavg_init(SyncAvg *s, int64_t *acc, int32_t *avg, uint16_t N)
{
    s->N = N;
    s->idx = 0;
    s->K = 0;
    s->acc = acc;
    s->avg = avg;

    memset(s->acc, 0, (size_t)N * sizeof(int64_t));
    memset(s->avg, 0, (size_t)N * sizeof(int32_t));
}

/**
 * @brief Deve ser chamado quando ocorre o "marcador" de início de período (ex.: zero-cross ou índice do encoder).
 *        Isso força alinhamento de fase.
 */
static inline void syncavg_period_reset(SyncAvg *s)
{
    s->idx = 0;
}

/**
 * @brief Alimenta a média sincronizada com uma amostra do ADC já alinhada ao relógio de amostragem.
 * @param s Estrutura.
 * @param x Amostra (ex.: ADC já convertido para int32).
 *
 * Funcionamento:
 *  - A cada amostra, acumula na posição idx.
 *  - Ao completar N amostras, fecha um período e atualiza avg[].
 *  - A referência de fase vem de syncavg_period_reset() (externa).
 */
static inline void syncavg_push_sample(SyncAvg *s, int32_t x)
{
    s->acc&#91;s->idx&#93; += (int64_t)x;
    s->idx++;

    if (s->idx >= s->N) {
        s->idx = 0;
        s->K++;

        // Atualiza a média inteira por posição (custo O(N) por período).
        // Se N for grande e seu MCU for apertado, dá para atualizar de forma incremental.
        for (uint16_t i = 0; i &lt; s->N; i++) {
            s->avg&#91;i&#93; = (int32_t)(s->acc&#91;i&#93; / (int64_t)s->K);
        }
    }
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9">stdint</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">h</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9">string</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">h</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">typedef</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">          </span><span style="color: #616E88">// amostras por período</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">idx</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">        </span><span style="color: #616E88">// posição atual no período &#91;0..N-1&#93;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">uint32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">K</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">          </span><span style="color: #616E88">// quantos períodos já acumulados (limite/controle externo)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Buffers de acumulação (use int64 se seu range for grande)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">int64_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">acc</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">        </span><span style="color: #616E88">// soma por posição</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">int32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">avg</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">        </span><span style="color: #616E88">// média por posição (resultado)</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">SyncAvg</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">/**</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">brief</span><span style="color: #616E88"> Inicializa a média sincronizada.</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">s</span><span style="color: #616E88">       Estrutura.</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">acc</span><span style="color: #616E88">     Buffer de acumulação de tamanho N (int64_t).</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">avg</span><span style="color: #616E88">     Buffer de saída média de tamanho N (int32_t).</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">N</span><span style="color: #616E88">       Amostras por período.</span></span>
<span class="line"><span style="color: #616E88"> */</span></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">inline</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">syncavg_init</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">SyncAvg</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">s</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">int64_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">acc</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">int32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">avg</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">N</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">idx</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">K</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">acc</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">acc</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">avg</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">avg</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">memset</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">acc</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">size_t</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">N</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">sizeof</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">int64_t</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">memset</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">avg</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">size_t</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">N</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">sizeof</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">int32_t</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">/**</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">brief</span><span style="color: #616E88"> Deve ser chamado quando ocorre o &quot;marcador&quot; de início de período (ex.: zero-cross ou índice do encoder).</span></span>
<span class="line"><span style="color: #616E88"> *        Isso força alinhamento de fase.</span></span>
<span class="line"><span style="color: #616E88"> */</span></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">inline</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">syncavg_period_reset</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">SyncAvg</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">s</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">idx</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">/**</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">brief</span><span style="color: #616E88"> Alimenta a média sincronizada com uma amostra do ADC já alinhada ao relógio de amostragem.</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">s</span><span style="color: #616E88"> Estrutura.</span></span>
<span class="line"><span style="color: #616E88"> * </span><span style="color: #ECEFF4">@</span><span style="color: #8FBCBB">param</span><span style="color: #616E88"> </span><span style="color: #D8DEE9">x</span><span style="color: #616E88"> Amostra (ex.: ADC já convertido para int32).</span></span>
<span class="line"><span style="color: #616E88"> *</span></span>
<span class="line"><span style="color: #616E88"> * Funcionamento:</span></span>
<span class="line"><span style="color: #616E88"> *  - A cada amostra, acumula na posição idx.</span></span>
<span class="line"><span style="color: #616E88"> *  - Ao completar N amostras, fecha um período e atualiza avg[].</span></span>
<span class="line"><span style="color: #616E88"> *  - A referência de fase vem de syncavg_period_reset() (externa).</span></span>
<span class="line"><span style="color: #616E88"> */</span></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">inline</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">syncavg_push_sample</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">SyncAvg</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">s</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">int32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">acc</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">idx</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">+=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int64_t</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">x</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">idx</span><span style="color: #81A1C1">++;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">idx</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">N</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">idx</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">K</span><span style="color: #81A1C1">++;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">        </span><span style="color: #616E88">// Atualiza a média inteira por posição (custo O(N) por período).</span></span>
<span class="line"><span style="color: #ECEFF4">        </span><span style="color: #616E88">// Se N for grande e seu MCU for apertado, dá para atualizar de forma incremental.</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">N</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #81A1C1">++</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">avg</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int32_t</span><span style="color: #D8DEE9FF">)(</span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">acc</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int64_t</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">K</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph"><strong>Melhores usos da média sincronizada:</strong> quando existe um evento/clock de referência que define o período do fenômeno e você quer extrair o comportamento repetitivo com máxima imunidade a ruído. Isso aparece em análise vibroacústica sincronizada com rotação (encoder), em medição de ripple sincronizada com PWM, em leitura de sinais biomédicos quando há marcador, e em sistemas de potência quando você quer “ver” a forma média ao longo de ciclos de rede sem ser enganado por ruído ou eventos transientes fora de fase.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">3) Exemplo prático combinando os dois: remover hum e depois reforçar a forma repetitiva</h2>



<p class="wp-block-paragraph">Em pipeline real, é comum usar notch primeiro para derrubar uma interferência tonal forte e, em seguida, média sincronizada para aumentar SNR do que restou (principalmente se o sinal útil é repetitivo e você tem referência). A ordem pode inverter dependendo do caso: se a interferência também for coerente com o mesmo período, a média pode reforçá-la, então o notch antes costuma ser mais seguro.</p>



<p class="wp-block-paragraph">Abaixo, um esqueleto de uso. Imagine ADC a 4 kHz, hum em 60 Hz, e você quer fazer média sincronizada por ciclo de 60 Hz usando zero-cross (logo \(N \approx 4000/60 \approx 66\) amostras por ciclo; na prática você ajusta para manter N inteiro e usar PLL/medição de período se a rede variar).</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>#include &lt;stdio.h>

// Reaproveita NotchBiquad e SyncAvg já definidos acima.

#define FS_HZ        4000.0f
#define NOTCH_F0_HZ  60.0f
#define NOTCH_Q      25.0f

#define N_SAMPLES_PER_PERIOD  66  // exemplo (depende do seu sincronismo real)

static int64_t acc_buf&#91;N_SAMPLES_PER_PERIOD&#93;;
static int32_t avg_buf&#91;N_SAMPLES_PER_PERIOD&#93;;

int main(void)
{
    NotchBiquad notch;
    notch_init(&amp;notch, FS_HZ, NOTCH_F0_HZ, NOTCH_Q);

    SyncAvg s;
    syncavg_init(&amp;s, acc_buf, avg_buf, N_SAMPLES_PER_PERIOD);

    // Exemplo: loop de aquisição (mock)
    for (int n = 0; n &lt; 20000; n++) {
        // Em firmware real: x_raw vem do ADC (DMA buffer), e zero-cross chama syncavg_period_reset(&amp;s)
        int32_t x_raw = (int32_t)(1000 * sinf(2.0f * (float)M_PI * 10.0f * (n / FS_HZ))); // sinal útil 10 Hz
        x_raw += (int32_t)(300 * sinf(2.0f * (float)M_PI * 60.0f * (n / FS_HZ)));        // hum 60 Hz

        // Notch (float) -> converte de volta para int32
        float y_notch = notch_process(&amp;notch, (float)x_raw);
        int32_t y = (int32_t)y_notch;

        // Evento externo de sincronismo: aqui é só demonstração (a cada N amostras)
        if ((n % N_SAMPLES_PER_PERIOD) == 0) {
            syncavg_period_reset(&amp;s);
        }

        // Média sincronizada
        syncavg_push_sample(&amp;s, y);

        // Quando s.K aumenta, avg_buf contém a forma média por período
        if (s.K > 0 &amp;&amp; (n % (N_SAMPLES_PER_PERIOD * 20)) == 0) {
            printf("K=%lu, avg&#91;0&#93;=%ld, avg&#91;10&#93;=%ld\n",
                   (unsigned long)s.K, (long)avg_buf&#91;0&#93;, (long)avg_buf&#91;10&#93;);
        }
    }

    return 0;
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9">stdio</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">h</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// Reaproveita NotchBiquad e SyncAvg já definidos acima.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">FS_HZ</span><span style="color: #D8DEE9FF">        4000</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NOTCH_F0_HZ</span><span style="color: #D8DEE9FF">  60</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NOTCH_Q</span><span style="color: #D8DEE9FF">      25</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N_SAMPLES_PER_PERIOD</span><span style="color: #D8DEE9FF">  </span><span style="color: #B48EAD">66</span><span style="color: #D8DEE9FF">  </span><span style="color: #616E88">// exemplo (depende do seu sincronismo real)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">int64_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">acc_buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">N_SAMPLES_PER_PERIOD</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">int32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">avg_buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">N_SAMPLES_PER_PERIOD</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">main</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">NotchBiquad</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">notch</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">notch_init</span><span style="color: #D8DEE9FF">(¬</span><span style="color: #D8DEE9">ch</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">FS_HZ</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NOTCH_F0_HZ</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NOTCH_Q</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">SyncAvg</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">s</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">syncavg_init</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">s</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">acc_buf</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">avg_buf</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N_SAMPLES_PER_PERIOD</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">    </span><span style="color: #616E88">// Exemplo: loop de aquisição (mock)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">20000</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #81A1C1">++</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #ECEFF4">        </span><span style="color: #616E88">// Em firmware real: x_raw vem do ADC (DMA buffer), e zero-cross chama syncavg_period_reset(&amp;s)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">int32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">x_raw</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int32_t</span><span style="color: #D8DEE9FF">)(</span><span style="color: #B48EAD">1000</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">sinf</span><span style="color: #D8DEE9FF">(2</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">M_PI</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> 10</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">FS_HZ</span><span style="color: #D8DEE9FF">)))</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// sinal útil 10 Hz</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">x_raw</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int32_t</span><span style="color: #D8DEE9FF">)(</span><span style="color: #B48EAD">300</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">sinf</span><span style="color: #D8DEE9FF">(2</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">M_PI</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> 60</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">0</span><span style="color: #D8DEE9">f</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">FS_HZ</span><span style="color: #D8DEE9FF">)))</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">        </span><span style="color: #616E88">// hum 60 Hz</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">        </span><span style="color: #616E88">// Notch (float) -&gt; converte de volta para int32</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">y_notch</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">notch_process</span><span style="color: #D8DEE9FF">(¬</span><span style="color: #D8DEE9">ch</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">float</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">x_raw</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">int32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">y</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">int32_t</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">y_notch</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">        </span><span style="color: #616E88">// Evento externo de sincronismo: aqui é só demonstração (a cada N amostras)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> ((</span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">%</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">N_SAMPLES_PER_PERIOD</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">==</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">syncavg_period_reset</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">s</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">        </span><span style="color: #616E88">// Média sincronizada</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">syncavg_push_sample</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">s</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">y</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">        </span><span style="color: #616E88">// Quando s.K aumenta, avg_buf contém a forma média por período</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">s</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">K</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;&amp;</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">%</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">N_SAMPLES_PER_PERIOD</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">20</span><span style="color: #D8DEE9FF">)) </span><span style="color: #81A1C1">==</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">printf</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">K=%lu, avg&#91;0&#93;=%ld, avg&#91;10&#93;=%ld</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                   (</span><span style="color: #D8DEE9">unsigned</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">long</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">s</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">K</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">long</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">avg_buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">long</span><span style="color: #D8DEE9FF">)</span><span style="color: #D8DEE9">avg_buf</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #B48EAD">10</span><span style="color: #D8DEE9FF">&#93;)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Fechando a ideia: o notch discreto e a média sincronizada resolvem problemas parecidos (melhorar a qualidade do sinal), mas por “mecanismos” bem diferentes, e isso muda totalmente quando cada um é a melhor escolha. O notch é a ferramenta certa quando você conhece uma frequência indesejada bem definida e relativamente estável e quer arrancá-la do sinal com o mínimo de impacto no restante do espectro. Em firmware, isso costuma ser “hum” de 50/60 Hz, tons de chaveamento, ou uma ressonância estreita que aparece como pico bem localizado. O ponto crítico é que o notch é tão bom quanto a precisão do seu (f_0) e a escolha de (Q): se a interferência varia de frequência, um notch muito estreito deixa passar; se você alarga demais, começa a “machucar” conteúdo útil perto de (f_0). Além disso, como é um IIR, você precisa cuidar de estabilidade numérica e do formato de implementação (a forma direta II transposta tende a ser mais robusta em ponto flutuante e também costuma ser a melhor porta de entrada para depois migrar para ponto fixo).</p>



<p class="wp-block-paragraph">Já a média sincronizada não é “um filtro de frequência” no sentido clássico; ela é uma técnica de extração por coerência: tudo que está alinhado com o período de referência fica mais forte, e o que não está alinhado tende a desaparecer. Por isso ela é superior quando o sinal útil é repetitivo e você tem um marcador de fase confiável, como encoder em máquina rotativa, o próprio PWM em conversores/inversores, ou zero-cross da rede. O ganho prático é enorme porque ela aumenta SNR sem precisar “inventar” um modelo espectral do ruído, mas ela também tem uma fragilidade: se o sincronismo for ruim (jitter, período variável, marcador inconsistente) a média “borrará” a forma de onda e pode até criar artefatos que parecem sinal real. Em projetos de rede elétrica, por exemplo, se você fixa (N) como “amostras por ciclo” sem acompanhar a variação real da frequência, a média começa a perder fase ao longo dos ciclos; nesse caso, ou você mede o período e ajusta (N) dinamicamente, ou você reamostra o ciclo para um grid fixo antes de acumular.</p>



<p class="wp-block-paragraph">Na prática, em pipeline embarcado, uma combinação muito comum é usar notch primeiro para remover uma interferência tonal forte e depois usar média sincronizada para revelar a forma repetitiva de interesse com ruído bem mais baixo. Isso funciona especialmente bem quando a interferência não é coerente com o período que você está usando para sincronizar; se for coerente, a média pode reforçar a interferência, e aí o notch vira praticamente obrigatório antes. Se o seu sistema estiver no limite de CPU, o notch custa um número fixo e pequeno de multiplicações por amostra, enquanto a média sincronizada pode custar pouco por amostra mas “cobra” um custo por período quando você atualiza a forma média; dá para manter determinismo atualizando médias de forma incremental, ou reduzindo taxa, ou usando buffers e processamento em tarefa de menor prioridade.</p><p>The post <a href="https://mcu.tec.br/algoritimos/filstros/filtro-notch-discreto-notch-iir-e-media-sincronizada-sync-averaging/">Filtro notch discreto (notch IIR) e média sincronizada (sync averaging)</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1356</post-id>	</item>
		<item>
		<title>Processadores Especializados em DSP (DCP) em Sistemas Embarcados</title>
		<link>https://mcu.tec.br/microcontroladores/processadores-especializados-em-dsp-dcp-em-sistemas-embarcados/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=processadores-especializados-em-dsp-dcp-em-sistemas-embarcados</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Sat, 21 Feb 2026 11:31:42 +0000</pubDate>
				<category><![CDATA[microcontroladores]]></category>
		<category><![CDATA[arquitetura Harvard modificada]]></category>
		<category><![CDATA[controle de motores FOC]]></category>
		<category><![CDATA[DCP]]></category>
		<category><![CDATA[desempenho por watt]]></category>
		<category><![CDATA[DSP vs CPU]]></category>
		<category><![CDATA[eficiência energética em DSP]]></category>
		<category><![CDATA[fft em microcontroladores]]></category>
		<category><![CDATA[processadores DSP]]></category>
		<category><![CDATA[processamento digital de sinais]]></category>
		<category><![CDATA[processamento na borda]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[unidade MAC]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1383</guid>

					<description><![CDATA[<p>Este artigo apresenta uma análise técnica e didática sobre o uso de processadores especializados em DSP (DCP) em sistemas embarcados modernos. São exploradas as diferenças arquiteturais entre CPUs convencionais e processadores dedicados de sinal, destacando unidades MAC, arquitetura Harvard modificada, aritmética saturada e suporte a ponto fixo e ponto flutuante. O conteúdo aborda aplicações práticas em áudio, controle de motores, análise de vibração e comunicação digital, além de discutir desempenho por watt e eficiência energética em processamento na borda. Ideal para engenheiros, desenvolvedores de firmware e profissionais que projetam sistemas embarcados de alta performance.</p>
<p>The post <a href="https://mcu.tec.br/microcontroladores/processadores-especializados-em-dsp-dcp-em-sistemas-embarcados/">Processadores Especializados em DSP (DCP) em Sistemas Embarcados</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<div class="root-eb-toc-yp681 wp-block-essential-blocks-table-of-contents"><div class="eb-parent-wrapper eb-parent-eb-toc-yp681 "><div class="eb-toc-container eb-toc-yp681  eb-toc-is-not-sticky eb-toc-not-collapsible eb-toc-initially-not-collapsed eb-toc-scrollToTop style-1 list-style-none" data-scroll-top="false" data-scroll-top-icon="fas fa-angle-up" data-collapsible="false" data-sticky-hide-mobile="false" data-sticky="false" data-scroll-target="scroll_to_toc" data-copy-link="false" data-editor-type="" data-hide-desktop="false" data-hide-tab="false" data-hide-mobile="false" data-itemcollapsed="false" data-highlight-scroll="false"><div class="eb-toc-header"><h2 class="eb-toc-title">Table of Contents</h2></div><div class="eb-toc-wrapper " data-headers="[{&quot;level&quot;:3,&quot;content&quot;:&quot;Introdu\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Introdu\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-0&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Arquitetura de CPUs Convencionais versus Processadores Especializados em DSP (DCP)&quot;,&quot;text&quot;:&quot;Arquitetura de CPUs Convencionais versus Processadores Especializados em DSP (DCP)&quot;,&quot;link&quot;:&quot;arquitetura-de-cpus-convencionais-versus-processadores-especializados-em-dsp-dcp&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Elementos Internos de um Processador Especializado em DSP (DCP)&quot;,&quot;text&quot;:&quot;Elementos Internos de um Processador Especializado em DSP (DCP)&quot;,&quot;link&quot;:&quot;elementos-internos-de-um-processador-especializado-em-dsp-dcp&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Aplica\u00e7\u00f5es Pr\u00e1ticas de Processadores Especializados em DSP em Sistemas Embarcados&quot;,&quot;text&quot;:&quot;Aplica\u00e7\u00f5es Pr\u00e1ticas de Processadores Especializados em DSP em Sistemas Embarcados&quot;,&quot;link&quot;:&quot;eb-table-content-3&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Efici\u00eancia Energ\u00e9tica e Desempenho por Watt em DCPs&quot;,&quot;text&quot;:&quot;Efici\u00eancia Energ\u00e9tica e Desempenho por Watt em DCPs&quot;,&quot;link&quot;:&quot;eb-table-content-4&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Quando Utilizar um Microcontrolador com Extens\u00f5es DSP e Quando Optar por um DCP Dedicado&quot;,&quot;text&quot;:&quot;Quando Utilizar um Microcontrolador com Extens\u00f5es DSP e Quando Optar por um DCP Dedicado&quot;,&quot;link&quot;:&quot;eb-table-content-5&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Conclus\u00e3o&quot;,&quot;text&quot;:&quot;Conclus\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-6&quot;}]" data-visible="[true,true,true,true,true,true]" data-delete-headers="[{&quot;label&quot;:&quot;Introdu\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;introdu\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Arquitetura de CPUs Convencionais versus Processadores Especializados em DSP (DCP)&quot;,&quot;value&quot;:&quot;arquitetura-de-cpus-convencionais-versus-processadores-especializados-em-dsp-dcp&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Elementos Internos de um Processador Especializado em DSP (DCP)&quot;,&quot;value&quot;:&quot;elementos-internos-de-um-processador-especializado-em-dsp-dcp&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Aplica\u00e7\u00f5es Pr\u00e1ticas de Processadores Especializados em DSP em Sistemas Embarcados&quot;,&quot;value&quot;:&quot;aplica\u00e7\u00f5es-pr\u00e1ticas-de-processadores-especializados-em-dsp-em-sistemas-embarcados&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Efici\u00eancia Energ\u00e9tica e Desempenho por Watt em DCPs&quot;,&quot;value&quot;:&quot;efici\u00eancia-energ\u00e9tica-e-desempenho-por-watt-em-dcps&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Quando Utilizar um Microcontrolador com Extens\u00f5es DSP e Quando Optar por um DCP Dedicado&quot;,&quot;value&quot;:&quot;quando-utilizar-um-microcontrolador-com-extens\u00f5es-dsp-e-quando-optar-por-um-dcp-dedicado&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Conclus\u00e3o&quot;,&quot;value&quot;:&quot;conclus\u00e3o&quot;,&quot;isDelete&quot;:false}]" data-smooth="true" data-top-offset=""><div class="eb-toc__list-wrap"><ul class="eb-toc__list"><li><a href="#eb-table-content-0">Introdução</a><li><a href="#arquitetura-de-cpus-convencionais-versus-processadores-especializados-em-dsp-dcp">Arquitetura de CPUs Convencionais versus Processadores Especializados em DSP (DCP)</a><li><a href="#elementos-internos-de-um-processador-especializado-em-dsp-dcp">Elementos Internos de um Processador Especializado em DSP (DCP)</a><li><a href="#eb-table-content-3">Aplicações Práticas de Processadores Especializados em DSP em Sistemas Embarcados</a><li><a href="#eb-table-content-4">Eficiência Energética e Desempenho por Watt em DCPs</a><li><a href="#eb-table-content-5">Quando Utilizar um Microcontrolador com Extensões DSP e Quando Optar por um DCP Dedicado</a><li><a href="#eb-table-content-6">Conclusão</a></ul></div></div></div></div></div>


<h3 class="wp-block-heading">Introdução</h3>



<p class="wp-block-paragraph">O processamento digital de sinais é um dos pilares da eletrônica moderna. Desde sistemas de áudio e comunicação sem fio até controle industrial e monitoramento de vibração, praticamente todo sistema embarcado contemporâneo precisa, em algum nível, manipular sinais digitais de forma eficiente. Entretanto, quando esse processamento se torna matematicamente intensivo — envolvendo filtragem digital, transformadas rápidas de Fourier (FFT), correlação, convolução ou controle em tempo real — microcontroladores convencionais podem não oferecer desempenho adequado ou eficiência energética suficiente.</p>



<p class="wp-block-paragraph">É nesse contexto que surgem os processadores especializados em DSP, que aqui chamaremos de DCP (Digital Signal Processors / Digital Signal Processing Cores). Com base no artigo técnico publicado pela Analog Devices na revista Analog Dialogue, analisaremos de forma didática o papel desses processadores, suas arquiteturas internas e as vantagens que oferecem quando comparados a CPUs tradicionais em sistemas embarcados.</p><p>The post <a href="https://mcu.tec.br/microcontroladores/processadores-especializados-em-dsp-dcp-em-sistemas-embarcados/">Processadores Especializados em DSP (DCP) em Sistemas Embarcados</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1383</post-id>	</item>
		<item>
		<title>Arquitetura Orientada a Eventos no FreeRTOS</title>
		<link>https://mcu.tec.br/rtos/arquitetura-orientada-a-eventos-no-freertos/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=arquitetura-orientada-a-eventos-no-freertos</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Fri, 20 Feb 2026 17:44:13 +0000</pubDate>
				<category><![CDATA[RTOS]]></category>
		<category><![CDATA[arquitetura orientada a eventos]]></category>
		<category><![CDATA[event groups]]></category>
		<category><![CDATA[filas FreeRTOS]]></category>
		<category><![CDATA[firmware reativo]]></category>
		<category><![CDATA[freertos]]></category>
		<category><![CDATA[message buffers]]></category>
		<category><![CDATA[programação em tempo real]]></category>
		<category><![CDATA[rtos]]></category>
		<category><![CDATA[sistemas determinísticos]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[software timers]]></category>
		<category><![CDATA[stream buffers]]></category>
		<category><![CDATA[task notifications]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1057</guid>

					<description><![CDATA[<p>Meta descrição (≥ 600 caracteres):<br />
Este artigo apresenta uma abordagem técnica e didática sobre arquitetura orientada a eventos no FreeRTOS, explicando como projetar firmwares reativos, determinísticos e eficientes para sistemas embarcados. São analisados em profundidade os principais mecanismos do FreeRTOS, como Task Notifications, Event Groups, Queues, Stream Buffers, Message Buffers e Software Timers, sempre sob a ótica de engenharia de software embarcado. O texto demonstra como combinar corretamente esses mecanismos para evitar polling, reduzir consumo de CPU e energia, minimizar latência e melhorar a manutenção do código. Com exemplos práticos em C, análise de padrões arquiteturais e discussão dos erros mais comuns, o artigo serve como guia completo para desenvolvedores que desejam construir sistemas escaláveis, previsíveis e alinhados às melhores práticas de tempo real.</p>
<p>The post <a href="https://mcu.tec.br/rtos/arquitetura-orientada-a-eventos-no-freertos/">Arquitetura Orientada a Eventos no FreeRTOS</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<div class="root-eb-toc-zyou1 wp-block-essential-blocks-table-of-contents"><div class="eb-parent-wrapper eb-parent-eb-toc-zyou1 "><div class="eb-toc-container eb-toc-zyou1  eb-toc-is-not-sticky eb-toc-not-collapsible eb-toc-initially-not-collapsed eb-toc-scrollToTop style-1 list-style-none" data-scroll-top="false" data-scroll-top-icon="fas fa-angle-up" data-collapsible="false" data-sticky-hide-mobile="false" data-sticky="false" data-scroll-target="scroll_to_toc" data-copy-link="false" data-editor-type="" data-hide-desktop="false" data-hide-tab="false" data-hide-mobile="false" data-itemcollapsed="false" data-highlight-scroll="false"><div class="eb-toc-header"><h2 class="eb-toc-title">Table of Contents</h2></div><div class="eb-toc-wrapper " data-headers="[{&quot;level&quot;:3,&quot;content&quot;:&quot;Introdu\u00e7\u00e3o e Motiva\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Introdu\u00e7\u00e3o e Motiva\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-0&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;O que vem a seguir&quot;,&quot;text&quot;:&quot;O que vem a seguir&quot;,&quot;link&quot;:&quot;o-que-vem-a-seguir&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Modelo Conceitual da Arquitetura Orientada a Eventos&quot;,&quot;text&quot;:&quot;Modelo Conceitual da Arquitetura Orientada a Eventos&quot;,&quot;link&quot;:&quot;modelo-conceitual-da-arquitetura-orientada-a-eventos&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Fluxo t\u00edpico de eventos no FreeRTOS&quot;,&quot;text&quot;:&quot;Fluxo t\u00edpico de eventos no FreeRTOS&quot;,&quot;link&quot;:&quot;eb-table-content-3&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo conceitual simplificado&quot;,&quot;text&quot;:&quot;Exemplo conceitual simplificado&quot;,&quot;link&quot;:&quot;exemplo-conceitual-simplificado&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Implica\u00e7\u00f5es arquiteturais importantes&quot;,&quot;text&quot;:&quot;Implica\u00e7\u00f5es arquiteturais importantes&quot;,&quot;link&quot;:&quot;eb-table-content-5&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Task Notifications como Mecanismo Central de Eventos&quot;,&quot;text&quot;:&quot;Task Notifications como Mecanismo Central de Eventos&quot;,&quot;link&quot;:&quot;task-notifications-como-mecanismo-central-de-eventos&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Modelo mental correto para Task Notifications&quot;,&quot;text&quot;:&quot;Modelo mental correto para Task Notifications&quot;,&quot;link&quot;:&quot;modelo-mental-correto-para-task-notifications&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo 1 \u2014 Evento simples (sinaliza\u00e7\u00e3o pura)&quot;,&quot;text&quot;:&quot;Exemplo 1 \u2014 Evento simples (sinaliza\u00e7\u00e3o pura)&quot;,&quot;link&quot;:&quot;eb-table-content-8&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo 2 \u2014 Contador de eventos acumulados&quot;,&quot;text&quot;:&quot;Exemplo 2 \u2014 Contador de eventos acumulados&quot;,&quot;link&quot;:&quot;exemplo-2-contador-de-eventos-acumulados&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo 3 \u2014 Task Notification como bitmap de eventos&quot;,&quot;text&quot;:&quot;Exemplo 3 \u2014 Task Notification como bitmap de eventos&quot;,&quot;link&quot;:&quot;exemplo-3-task-notification-como-bitmap-de-eventos&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Vantagens arquiteturais das Task Notifications&quot;,&quot;text&quot;:&quot;Vantagens arquiteturais das Task Notifications&quot;,&quot;link&quot;:&quot;vantagens-arquiteturais-das-task-notifications&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Event Groups: Coordena\u00e7\u00e3o de M\u00faltiplos Eventos&quot;,&quot;text&quot;:&quot;Event Groups: Coordena\u00e7\u00e3o de M\u00faltiplos Eventos&quot;,&quot;link&quot;:&quot;eb-table-content-12&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Modelo de uso correto para Event Groups&quot;,&quot;text&quot;:&quot;Modelo de uso correto para Event Groups&quot;,&quot;link&quot;:&quot;modelo-de-uso-correto-para-event-groups&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo 1 \u2014 Aguardando m\u00faltiplos eventos simult\u00e2neos&quot;,&quot;text&quot;:&quot;Exemplo 1 \u2014 Aguardando m\u00faltiplos eventos simult\u00e2neos&quot;,&quot;link&quot;:&quot;eb-table-content-14&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo 2 \u2014 Sinaliza\u00e7\u00e3o parcial e limpeza autom\u00e1tica&quot;,&quot;text&quot;:&quot;Exemplo 2 \u2014 Sinaliza\u00e7\u00e3o parcial e limpeza autom\u00e1tica&quot;,&quot;link&quot;:&quot;eb-table-content-15&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Uso em ISRs&quot;,&quot;text&quot;:&quot;Uso em ISRs&quot;,&quot;link&quot;:&quot;uso-em-isrs&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Armadilhas comuns no uso de Event Groups&quot;,&quot;text&quot;:&quot;Armadilhas comuns no uso de Event Groups&quot;,&quot;link&quot;:&quot;armadilhas-comuns-no-uso-de-event-groups&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Queues e Message Passing em Arquiteturas Orientadas a Eventos&quot;,&quot;text&quot;:&quot;Queues e Message Passing em Arquiteturas Orientadas a Eventos&quot;,&quot;link&quot;:&quot;queues-e-message-passing-em-arquiteturas-orientadas-a-eventos&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Modelo conceitual de filas orientadas a eventos&quot;,&quot;text&quot;:&quot;Modelo conceitual de filas orientadas a eventos&quot;,&quot;link&quot;:&quot;modelo-conceitual-de-filas-orientadas-a-eventos&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo 1 \u2014 Evento com payload (ISR \u2192 Task)&quot;,&quot;text&quot;:&quot;Exemplo 1 \u2014 Evento com payload (ISR \u2192 Task)&quot;,&quot;link&quot;:&quot;eb-table-content-20&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo 2 \u2014 Fila como buffer de desacoplamento&quot;,&quot;text&quot;:&quot;Exemplo 2 \u2014 Fila como buffer de desacoplamento&quot;,&quot;link&quot;:&quot;exemplo-2-fila-como-buffer-de-desacoplamento&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Uso combinado: Queue + Task Notification&quot;,&quot;text&quot;:&quot;Uso combinado: Queue + Task Notification&quot;,&quot;link&quot;:&quot;uso-combinado-queue-task-notification&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Implica\u00e7\u00f5es de projeto e dimensionamento&quot;,&quot;text&quot;:&quot;Implica\u00e7\u00f5es de projeto e dimensionamento&quot;,&quot;link&quot;:&quot;eb-table-content-23&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Stream Buffers e Message Buffers para Fluxos de Eventos&quot;,&quot;text&quot;:&quot;Stream Buffers e Message Buffers para Fluxos de Eventos&quot;,&quot;link&quot;:&quot;stream-buffers-e-message-buffers-para-fluxos-de-eventos&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Stream Buffers \u2014 Eventos como fluxo cont\u00ednuo&quot;,&quot;text&quot;:&quot;Stream Buffers \u2014 Eventos como fluxo cont\u00ednuo&quot;,&quot;link&quot;:&quot;eb-table-content-25&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo 1 \u2014 Stream Buffer com UART&quot;,&quot;text&quot;:&quot;Exemplo 1 \u2014 Stream Buffer com UART&quot;,&quot;link&quot;:&quot;exemplo-1-stream-buffer-com-uart&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Thresholds e controle de lat\u00eancia&quot;,&quot;text&quot;:&quot;Thresholds e controle de lat\u00eancia&quot;,&quot;link&quot;:&quot;eb-table-content-27&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Message Buffers \u2014 Eventos com mensagens vari\u00e1veis&quot;,&quot;text&quot;:&quot;Message Buffers \u2014 Eventos com mensagens vari\u00e1veis&quot;,&quot;link&quot;:&quot;eb-table-content-28&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo 2 \u2014 Message Buffer para comandos&quot;,&quot;text&quot;:&quot;Exemplo 2 \u2014 Message Buffer para comandos&quot;,&quot;link&quot;:&quot;exemplo-2-message-buffer-para-comandos&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Compara\u00e7\u00e3o arquitetural&quot;,&quot;text&quot;:&quot;Compara\u00e7\u00e3o arquitetural&quot;,&quot;link&quot;:&quot;eb-table-content-30&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Armadilhas comuns&quot;,&quot;text&quot;:&quot;Armadilhas comuns&quot;,&quot;link&quot;:&quot;armadilhas-comuns&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Software Timers como Geradores de Eventos Temporais&quot;,&quot;text&quot;:&quot;Software Timers como Geradores de Eventos Temporais&quot;,&quot;link&quot;:&quot;software-timers-como-geradores-de-eventos-temporais&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Modelo conceitual correto para Software Timers&quot;,&quot;text&quot;:&quot;Modelo conceitual correto para Software Timers&quot;,&quot;link&quot;:&quot;modelo-conceitual-correto-para-software-timers&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo 1 \u2014 Timer gerando evento simples&quot;,&quot;text&quot;:&quot;Exemplo 1 \u2014 Timer gerando evento simples&quot;,&quot;link&quot;:&quot;exemplo-1-timer-gerando-evento-simples&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo 2 \u2014 Timer peri\u00f3dico como evento de sistema&quot;,&quot;text&quot;:&quot;Exemplo 2 \u2014 Timer peri\u00f3dico como evento de sistema&quot;,&quot;link&quot;:&quot;eb-table-content-35&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo 3 \u2014 Timer como agendador leve de eventos&quot;,&quot;text&quot;:&quot;Exemplo 3 \u2014 Timer como agendador leve de eventos&quot;,&quot;link&quot;:&quot;exemplo-3-timer-como-agendador-leve-de-eventos&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Prioridade da Timer Service Task&quot;,&quot;text&quot;:&quot;Prioridade da Timer Service Task&quot;,&quot;link&quot;:&quot;prioridade-da-timer-service-task&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Integra\u00e7\u00e3o com arquiteturas orientadas a eventos&quot;,&quot;text&quot;:&quot;Integra\u00e7\u00e3o com arquiteturas orientadas a eventos&quot;,&quot;link&quot;:&quot;eb-table-content-38&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Composi\u00e7\u00e3o Arquitetural de Eventos no FreeRTOS&quot;,&quot;text&quot;:&quot;Composi\u00e7\u00e3o Arquitetural de Eventos no FreeRTOS&quot;,&quot;link&quot;:&quot;eb-table-content-39&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Padr\u00e3o 1 \u2014 ISR m\u00ednima + Evento Direcionado&quot;,&quot;text&quot;:&quot;Padr\u00e3o 1 \u2014 ISR m\u00ednima + Evento Direcionado&quot;,&quot;link&quot;:&quot;eb-table-content-40&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Padr\u00e3o 2 \u2014 Evento acorda, fila transporta&quot;,&quot;text&quot;:&quot;Padr\u00e3o 2 \u2014 Evento acorda, fila transporta&quot;,&quot;link&quot;:&quot;eb-table-content-41&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Padr\u00e3o 3 \u2014 Event Group como estado global, n\u00e3o evento&quot;,&quot;text&quot;:&quot;Padr\u00e3o 3 \u2014 Event Group como estado global, n\u00e3o evento&quot;,&quot;link&quot;:&quot;eb-table-content-42&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Padr\u00e3o 4 \u2014 Timer \u2192 Evento \u2192 Task&quot;,&quot;text&quot;:&quot;Padr\u00e3o 4 \u2014 Timer \u2192 Evento \u2192 Task&quot;,&quot;link&quot;:&quot;eb-table-content-43&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Padr\u00e3o 5 \u2014 M\u00e1quina de estados orientada a eventos&quot;,&quot;text&quot;:&quot;Padr\u00e3o 5 \u2014 M\u00e1quina de estados orientada a eventos&quot;,&quot;link&quot;:&quot;eb-table-content-44&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Princ\u00edpios arquiteturais que emergem&quot;,&quot;text&quot;:&quot;Princ\u00edpios arquiteturais que emergem&quot;,&quot;link&quot;:&quot;eb-table-content-45&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Erros Arquiteturais Comuns e Como Evit\u00e1-los&quot;,&quot;text&quot;:&quot;Erros Arquiteturais Comuns e Como Evit\u00e1-los&quot;,&quot;link&quot;:&quot;eb-table-content-46&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Erro 1 \u2014 Polling disfar\u00e7ado de arquitetura orientada a eventos&quot;,&quot;text&quot;:&quot;Erro 1 \u2014 Polling disfar\u00e7ado de arquitetura orientada a eventos&quot;,&quot;link&quot;:&quot;eb-table-content-47&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Erro 2 \u2014 L\u00f3gica pesada dentro de ISRs&quot;,&quot;text&quot;:&quot;Erro 2 \u2014 L\u00f3gica pesada dentro de ISRs&quot;,&quot;link&quot;:&quot;eb-table-content-48&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Erro 3 \u2014 Uso excessivo de Event Groups como fila de eventos&quot;,&quot;text&quot;:&quot;Erro 3 \u2014 Uso excessivo de Event Groups como fila de eventos&quot;,&quot;link&quot;:&quot;erro-3-uso-excessivo-de-event-groups-como-fila-de-eventos&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Erro 4 \u2014 Fila gen\u00e9rica para tudo&quot;,&quot;text&quot;:&quot;Erro 4 \u2014 Fila gen\u00e9rica para tudo&quot;,&quot;link&quot;:&quot;eb-table-content-50&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Erro 5 \u2014 Tasks que nunca bloqueiam&quot;,&quot;text&quot;:&quot;Erro 5 \u2014 Tasks que nunca bloqueiam&quot;,&quot;link&quot;:&quot;erro-5-tasks-que-nunca-bloqueiam&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Erro 6 \u2014 Misturar estado e evento&quot;,&quot;text&quot;:&quot;Erro 6 \u2014 Misturar estado e evento&quot;,&quot;link&quot;:&quot;erro-6-misturar-estado-e-evento&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Erro 7 \u2014 Overengineering de eventos&quot;,&quot;text&quot;:&quot;Erro 7 \u2014 Overengineering de eventos&quot;,&quot;link&quot;:&quot;erro-7-overengineering-de-eventos&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Checklist arquitetural pr\u00e1tico&quot;,&quot;text&quot;:&quot;Checklist arquitetural pr\u00e1tico&quot;,&quot;link&quot;:&quot;eb-table-content-54&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Conclus\u00e3o T\u00e9cnica, Boas Pr\u00e1ticas e Impacto no Projeto&quot;,&quot;text&quot;:&quot;Conclus\u00e3o T\u00e9cnica, Boas Pr\u00e1ticas e Impacto no Projeto&quot;,&quot;link&quot;:&quot;eb-table-content-55&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Boas pr\u00e1ticas consolidadas&quot;,&quot;text&quot;:&quot;Boas pr\u00e1ticas consolidadas&quot;,&quot;link&quot;:&quot;eb-table-content-56&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Arquitetura orientada a eventos como base para escalabilidade&quot;,&quot;text&quot;:&quot;Arquitetura orientada a eventos como base para escalabilidade&quot;,&quot;link&quot;:&quot;arquitetura-orientada-a-eventos-como-base-para-escalabilidade&quot;}]" data-visible="[true,true,true,true,true,true]" data-delete-headers="[{&quot;label&quot;:&quot;Introdu\u00e7\u00e3o e Motiva\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;introdu\u00e7\u00e3o-e-motiva\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;O que vem a seguir&quot;,&quot;value&quot;:&quot;o-que-vem-a-seguir&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Modelo Conceitual da Arquitetura Orientada a Eventos&quot;,&quot;value&quot;:&quot;modelo-conceitual-da-arquitetura-orientada-a-eventos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Fluxo t\u00edpico de eventos no FreeRTOS&quot;,&quot;value&quot;:&quot;fluxo-t\u00edpico-de-eventos-no-freertos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo conceitual simplificado&quot;,&quot;value&quot;:&quot;exemplo-conceitual-simplificado&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Implica\u00e7\u00f5es arquiteturais importantes&quot;,&quot;value&quot;:&quot;implica\u00e7\u00f5es-arquiteturais-importantes&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Task Notifications como Mecanismo Central de Eventos&quot;,&quot;value&quot;:&quot;task-notifications-como-mecanismo-central-de-eventos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Modelo mental correto para Task Notifications&quot;,&quot;value&quot;:&quot;modelo-mental-correto-para-task-notifications&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo 1 \u2014 Evento simples (sinaliza\u00e7\u00e3o pura)&quot;,&quot;value&quot;:&quot;exemplo-1-evento-simples-sinaliza\u00e7\u00e3o-pura&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo 2 \u2014 Contador de eventos acumulados&quot;,&quot;value&quot;:&quot;exemplo-2-contador-de-eventos-acumulados&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo 3 \u2014 Task Notification como bitmap de eventos&quot;,&quot;value&quot;:&quot;exemplo-3-task-notification-como-bitmap-de-eventos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Vantagens arquiteturais das Task Notifications&quot;,&quot;value&quot;:&quot;vantagens-arquiteturais-das-task-notifications&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Event Groups: Coordena\u00e7\u00e3o de M\u00faltiplos Eventos&quot;,&quot;value&quot;:&quot;event-groups-coordena\u00e7\u00e3o-de-m\u00faltiplos-eventos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Modelo de uso correto para Event Groups&quot;,&quot;value&quot;:&quot;modelo-de-uso-correto-para-event-groups&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo 1 \u2014 Aguardando m\u00faltiplos eventos simult\u00e2neos&quot;,&quot;value&quot;:&quot;exemplo-1-aguardando-m\u00faltiplos-eventos-simult\u00e2neos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo 2 \u2014 Sinaliza\u00e7\u00e3o parcial e limpeza autom\u00e1tica&quot;,&quot;value&quot;:&quot;exemplo-2-sinaliza\u00e7\u00e3o-parcial-e-limpeza-autom\u00e1tica&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Uso em ISRs&quot;,&quot;value&quot;:&quot;uso-em-isrs&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Armadilhas comuns no uso de Event Groups&quot;,&quot;value&quot;:&quot;armadilhas-comuns-no-uso-de-event-groups&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Queues e Message Passing em Arquiteturas Orientadas a Eventos&quot;,&quot;value&quot;:&quot;queues-e-message-passing-em-arquiteturas-orientadas-a-eventos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Modelo conceitual de filas orientadas a eventos&quot;,&quot;value&quot;:&quot;modelo-conceitual-de-filas-orientadas-a-eventos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo 1 \u2014 Evento com payload (ISR \u2192 Task)&quot;,&quot;value&quot;:&quot;exemplo-1-evento-com-payload-isr-\u2192-task&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo 2 \u2014 Fila como buffer de desacoplamento&quot;,&quot;value&quot;:&quot;exemplo-2-fila-como-buffer-de-desacoplamento&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Uso combinado: Queue + Task Notification&quot;,&quot;value&quot;:&quot;uso-combinado-queue-task-notification&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Implica\u00e7\u00f5es de projeto e dimensionamento&quot;,&quot;value&quot;:&quot;implica\u00e7\u00f5es-de-projeto-e-dimensionamento&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Stream Buffers e Message Buffers para Fluxos de Eventos&quot;,&quot;value&quot;:&quot;stream-buffers-e-message-buffers-para-fluxos-de-eventos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Stream Buffers \u2014 Eventos como fluxo cont\u00ednuo&quot;,&quot;value&quot;:&quot;stream-buffers-eventos-como-fluxo-cont\u00ednuo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo 1 \u2014 Stream Buffer com UART&quot;,&quot;value&quot;:&quot;exemplo-1-stream-buffer-com-uart&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Thresholds e controle de lat\u00eancia&quot;,&quot;value&quot;:&quot;thresholds-e-controle-de-lat\u00eancia&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Message Buffers \u2014 Eventos com mensagens vari\u00e1veis&quot;,&quot;value&quot;:&quot;message-buffers-eventos-com-mensagens-vari\u00e1veis&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo 2 \u2014 Message Buffer para comandos&quot;,&quot;value&quot;:&quot;exemplo-2-message-buffer-para-comandos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Compara\u00e7\u00e3o arquitetural&quot;,&quot;value&quot;:&quot;compara\u00e7\u00e3o-arquitetural&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Armadilhas comuns&quot;,&quot;value&quot;:&quot;armadilhas-comuns&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Software Timers como Geradores de Eventos Temporais&quot;,&quot;value&quot;:&quot;software-timers-como-geradores-de-eventos-temporais&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Modelo conceitual correto para Software Timers&quot;,&quot;value&quot;:&quot;modelo-conceitual-correto-para-software-timers&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo 1 \u2014 Timer gerando evento simples&quot;,&quot;value&quot;:&quot;exemplo-1-timer-gerando-evento-simples&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo 2 \u2014 Timer peri\u00f3dico como evento de sistema&quot;,&quot;value&quot;:&quot;exemplo-2-timer-peri\u00f3dico-como-evento-de-sistema&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo 3 \u2014 Timer como agendador leve de eventos&quot;,&quot;value&quot;:&quot;exemplo-3-timer-como-agendador-leve-de-eventos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Prioridade da Timer Service Task&quot;,&quot;value&quot;:&quot;prioridade-da-timer-service-task&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Integra\u00e7\u00e3o com arquiteturas orientadas a eventos&quot;,&quot;value&quot;:&quot;integra\u00e7\u00e3o-com-arquiteturas-orientadas-a-eventos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Composi\u00e7\u00e3o Arquitetural de Eventos no FreeRTOS&quot;,&quot;value&quot;:&quot;composi\u00e7\u00e3o-arquitetural-de-eventos-no-freertos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Padr\u00e3o 1 \u2014 ISR m\u00ednima + Evento Direcionado&quot;,&quot;value&quot;:&quot;padr\u00e3o-1-isr-m\u00ednima-evento-direcionado&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Padr\u00e3o 2 \u2014 Evento acorda, fila transporta&quot;,&quot;value&quot;:&quot;padr\u00e3o-2-evento-acorda-fila-transporta&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Padr\u00e3o 3 \u2014 Event Group como estado global, n\u00e3o evento&quot;,&quot;value&quot;:&quot;padr\u00e3o-3-event-group-como-estado-global-n\u00e3o-evento&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Padr\u00e3o 4 \u2014 Timer \u2192 Evento \u2192 Task&quot;,&quot;value&quot;:&quot;padr\u00e3o-4-timer-\u2192-evento-\u2192-task&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Padr\u00e3o 5 \u2014 M\u00e1quina de estados orientada a eventos&quot;,&quot;value&quot;:&quot;padr\u00e3o-5-m\u00e1quina-de-estados-orientada-a-eventos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Princ\u00edpios arquiteturais que emergem&quot;,&quot;value&quot;:&quot;princ\u00edpios-arquiteturais-que-emergem&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Erros Arquiteturais Comuns e Como Evit\u00e1-los&quot;,&quot;value&quot;:&quot;erros-arquiteturais-comuns-e-como-evit\u00e1-los&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Erro 1 \u2014 Polling disfar\u00e7ado de arquitetura orientada a eventos&quot;,&quot;value&quot;:&quot;erro-1-polling-disfar\u00e7ado-de-arquitetura-orientada-a-eventos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Erro 2 \u2014 L\u00f3gica pesada dentro de ISRs&quot;,&quot;value&quot;:&quot;erro-2-l\u00f3gica-pesada-dentro-de-isrs&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Erro 3 \u2014 Uso excessivo de Event Groups como fila de eventos&quot;,&quot;value&quot;:&quot;erro-3-uso-excessivo-de-event-groups-como-fila-de-eventos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Erro 4 \u2014 Fila gen\u00e9rica para tudo&quot;,&quot;value&quot;:&quot;erro-4-fila-gen\u00e9rica-para-tudo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Erro 5 \u2014 Tasks que nunca bloqueiam&quot;,&quot;value&quot;:&quot;erro-5-tasks-que-nunca-bloqueiam&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Erro 6 \u2014 Misturar estado e evento&quot;,&quot;value&quot;:&quot;erro-6-misturar-estado-e-evento&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Erro 7 \u2014 Overengineering de eventos&quot;,&quot;value&quot;:&quot;erro-7-overengineering-de-eventos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Checklist arquitetural pr\u00e1tico&quot;,&quot;value&quot;:&quot;checklist-arquitetural-pr\u00e1tico&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Conclus\u00e3o T\u00e9cnica, Boas Pr\u00e1ticas e Impacto no Projeto&quot;,&quot;value&quot;:&quot;conclus\u00e3o-t\u00e9cnica-boas-pr\u00e1ticas-e-impacto-no-projeto&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Boas pr\u00e1ticas consolidadas&quot;,&quot;value&quot;:&quot;boas-pr\u00e1ticas-consolidadas&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Arquitetura orientada a eventos como base para escalabilidade&quot;,&quot;value&quot;:&quot;arquitetura-orientada-a-eventos-como-base-para-escalabilidade&quot;,&quot;isDelete&quot;:false}]" data-smooth="true" data-top-offset=""><div class="eb-toc__list-wrap"><ul class="eb-toc__list"><li><a href="#eb-table-content-0">Introdução e Motivação</a><li><a href="#o-que-vem-a-seguir">O que vem a seguir</a><li><a href="#modelo-conceitual-da-arquitetura-orientada-a-eventos">Modelo Conceitual da Arquitetura Orientada a Eventos</a><li><a href="#eb-table-content-3">Fluxo típico de eventos no FreeRTOS</a><li><a href="#exemplo-conceitual-simplificado">Exemplo conceitual simplificado</a><li><a href="#eb-table-content-5">Implicações arquiteturais importantes</a><li><a href="#task-notifications-como-mecanismo-central-de-eventos">Task Notifications como Mecanismo Central de Eventos</a><li><a href="#modelo-mental-correto-para-task-notifications">Modelo mental correto para Task Notifications</a><li><a href="#eb-table-content-8">Exemplo 1 — Evento simples (sinalização pura)</a><li><a href="#exemplo-2-contador-de-eventos-acumulados">Exemplo 2 — Contador de eventos acumulados</a><li><a href="#exemplo-3-task-notification-como-bitmap-de-eventos">Exemplo 3 — Task Notification como bitmap de eventos</a><li><a href="#vantagens-arquiteturais-das-task-notifications">Vantagens arquiteturais das Task Notifications</a><li><a href="#eb-table-content-12">Event Groups: Coordenação de Múltiplos Eventos</a><li><a href="#modelo-de-uso-correto-para-event-groups">Modelo de uso correto para Event Groups</a><li><a href="#eb-table-content-14">Exemplo 1 — Aguardando múltiplos eventos simultâneos</a><li><a href="#eb-table-content-15">Exemplo 2 — Sinalização parcial e limpeza automática</a><li><a href="#uso-em-isrs">Uso em ISRs</a><li><a href="#armadilhas-comuns-no-uso-de-event-groups">Armadilhas comuns no uso de Event Groups</a><li><a href="#queues-e-message-passing-em-arquiteturas-orientadas-a-eventos">Queues e Message Passing em Arquiteturas Orientadas a Eventos</a><li><a href="#modelo-conceitual-de-filas-orientadas-a-eventos">Modelo conceitual de filas orientadas a eventos</a><li><a href="#eb-table-content-20">Exemplo 1 — Evento com payload (ISR → Task)</a><li><a href="#exemplo-2-fila-como-buffer-de-desacoplamento">Exemplo 2 — Fila como buffer de desacoplamento</a><li><a href="#uso-combinado-queue-task-notification">Uso combinado: Queue + Task Notification</a><li><a href="#eb-table-content-23">Implicações de projeto e dimensionamento</a><li><a href="#stream-buffers-e-message-buffers-para-fluxos-de-eventos">Stream Buffers e Message Buffers para Fluxos de Eventos</a><li><a href="#eb-table-content-25">Stream Buffers — Eventos como fluxo contínuo</a><li><a href="#exemplo-1-stream-buffer-com-uart">Exemplo 1 — Stream Buffer com UART</a><li><a href="#eb-table-content-27">Thresholds e controle de latência</a><li><a href="#eb-table-content-28">Message Buffers — Eventos com mensagens variáveis</a><li><a href="#exemplo-2-message-buffer-para-comandos">Exemplo 2 — Message Buffer para comandos</a><li><a href="#eb-table-content-30">Comparação arquitetural</a><li><a href="#armadilhas-comuns">Armadilhas comuns</a><li><a href="#software-timers-como-geradores-de-eventos-temporais">Software Timers como Geradores de Eventos Temporais</a><li><a href="#modelo-conceitual-correto-para-software-timers">Modelo conceitual correto para Software Timers</a><li><a href="#exemplo-1-timer-gerando-evento-simples">Exemplo 1 — Timer gerando evento simples</a><li><a href="#eb-table-content-35">Exemplo 2 — Timer periódico como evento de sistema</a><li><a href="#exemplo-3-timer-como-agendador-leve-de-eventos">Exemplo 3 — Timer como agendador leve de eventos</a><li><a href="#prioridade-da-timer-service-task">Prioridade da Timer Service Task</a><li><a href="#eb-table-content-38">Integração com arquiteturas orientadas a eventos</a><li><a href="#eb-table-content-39">Composição Arquitetural de Eventos no FreeRTOS</a><li><a href="#eb-table-content-40">Padrão 1 — ISR mínima + Evento Direcionado</a><li><a href="#eb-table-content-41">Padrão 2 — Evento acorda, fila transporta</a><li><a href="#eb-table-content-42">Padrão 3 — Event Group como estado global, não evento</a><li><a href="#eb-table-content-43">Padrão 4 — Timer → Evento → Task</a><li><a href="#eb-table-content-44">Padrão 5 — Máquina de estados orientada a eventos</a><li><a href="#eb-table-content-45">Princípios arquiteturais que emergem</a><li><a href="#eb-table-content-46">Erros Arquiteturais Comuns e Como Evitá-los</a><li><a href="#eb-table-content-47">Erro 1 — Polling disfarçado de arquitetura orientada a eventos</a><li><a href="#eb-table-content-48">Erro 2 — Lógica pesada dentro de ISRs</a><li><a href="#erro-3-uso-excessivo-de-event-groups-como-fila-de-eventos">Erro 3 — Uso excessivo de Event Groups como fila de eventos</a><li><a href="#eb-table-content-50">Erro 4 — Fila genérica para tudo</a><li><a href="#erro-5-tasks-que-nunca-bloqueiam">Erro 5 — Tasks que nunca bloqueiam</a><li><a href="#erro-6-misturar-estado-e-evento">Erro 6 — Misturar estado e evento</a><li><a href="#erro-7-overengineering-de-eventos">Erro 7 — Overengineering de eventos</a><li><a href="#eb-table-content-54">Checklist arquitetural prático</a><li><a href="#eb-table-content-55">Conclusão Técnica, Boas Práticas e Impacto no Projeto</a><li><a href="#eb-table-content-56">Boas práticas consolidadas</a><li><a href="#arquitetura-orientada-a-eventos-como-base-para-escalabilidade">Arquitetura orientada a eventos como base para escalabilidade</a></ul></div></div></div></div></div>


<h3 class="wp-block-heading"><strong>Introdução e Motivação</strong></h3>



<p class="wp-block-paragraph">Em sistemas embarcados modernos, especialmente aqueles baseados em <strong>FreeRTOS</strong>, a forma como o firmware reage ao mundo externo é tão importante quanto o código em si. Sensores, comunicação, interrupções, timers e pilhas de protocolo geram estímulos de forma assíncrona, e arquiteturas tradicionais baseadas apenas em <em>superloop</em> rapidamente se tornam difíceis de manter, escalar e depurar. É nesse contexto que surge a <strong>Arquitetura Orientada a Eventos (Event-Driven Architecture – EDA)</strong>.</p>



<p class="wp-block-paragraph">No FreeRTOS, uma arquitetura orientada a eventos não é um “modo especial” do sistema operacional, mas sim uma <strong>estratégia de organização do firmware</strong>, onde tarefas permanecem bloqueadas aguardando eventos específicos e acordam apenas quando algo relevante ocorre. Esses eventos podem ser sinais de interrupção, mensagens, flags, notificações, timers ou dados disponíveis em buffers. O resultado é um sistema <strong>reativo, determinístico e eficiente em consumo de CPU</strong>.</p>



<p class="wp-block-paragraph">Do ponto de vista de engenharia, essa abordagem resolve três problemas clássicos:</p>



<ol class="wp-block-list">
<li><strong>Desperdício de CPU</strong> causado por polling constante</li>



<li><strong>Acoplamento excessivo</strong> entre módulos</li>



<li><strong>Dificuldade de sincronização</strong> entre múltiplas fontes de eventos</li>
</ol>



<p class="wp-block-paragraph">Ao adotar uma arquitetura orientada a eventos, o firmware passa a se comportar como um <strong>conjunto de agentes cooperativos</strong>, cada tarefa com responsabilidade clara, reagindo apenas aos eventos que lhe dizem respeito. Isso melhora a legibilidade do código, reduz latência média de resposta e facilita testes unitários e manutenção evolutiva.</p>



<p class="wp-block-paragraph">No FreeRTOS, essa arquitetura é viabilizada por um conjunto muito poderoso de primitivas nativas: <strong>Task Notifications</strong>, <strong>Queues</strong>, <strong>Event Groups</strong>, <strong>Stream Buffers</strong>, <strong>Message Buffers</strong> e <strong>Software Timers</strong>. Cada uma delas atende a um tipo específico de evento e será explorada detalhadamente ao longo deste artigo, sempre com exemplos práticos e contextualizados.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>O que vem a seguir</strong></h3>



<p class="wp-block-paragraph">Na próxima seção, entraremos no <strong>modelo conceitual da Arquitetura Orientada a Eventos no FreeRTOS</strong>, explicando como eventos fluem pelo sistema, como tarefas devem ser estruturadas e como evitar armadilhas comuns, como <em>event storms</em>, inversão de prioridade e acoplamento indireto.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Modelo Conceitual da Arquitetura Orientada a Eventos</strong></h3>



<p class="wp-block-paragraph">Em uma arquitetura orientada a eventos no FreeRTOS, o sistema deixa de ser centrado em fluxo sequencial de execução e passa a ser organizado em torno de <strong>eventos que representam fatos relevantes do sistema</strong>. Um evento pode significar “um dado chegou”, “um tempo expirou”, “um periférico terminou uma operação” ou “uma condição de estado foi satisfeita”. O papel central do RTOS é <strong>suspender tarefas até que esses eventos ocorram</strong>, garantindo previsibilidade temporal e uso eficiente do processador.</p>



<p class="wp-block-paragraph">Do ponto de vista conceitual, essa arquitetura pode ser dividida em três elementos fundamentais: <strong>produtores de eventos</strong>, <strong>mecanismos de transporte de eventos</strong> e <strong>consumidores de eventos</strong>. Produtores normalmente são ISRs, timers de software, drivers ou tarefas de baixo nível. O transporte é feito pelas primitivas do FreeRTOS, enquanto os consumidores são tarefas que encapsulam lógica de negócio ou processamento de dados. Esse desacoplamento é essencial para sistemas escaláveis.</p>



<p class="wp-block-paragraph">Um princípio importante é que <strong>tarefas orientadas a eventos devem permanecer bloqueadas na maior parte do tempo</strong>. Em FreeRTOS, isso significa usar chamadas bloqueantes como <code>xQueueReceive()</code>, <code>xEventGroupWaitBits()</code> ou <code>ulTaskNotifyTake()</code>, sempre com <code>portMAX_DELAY</code> ou tempos bem definidos. Dessa forma, não há polling ativo, e o escalonador pode dedicar CPU apenas às tarefas que realmente precisam executar naquele instante.</p>



<p class="wp-block-paragraph">Outro ponto crítico do modelo é que <strong>eventos não devem carregar lógica</strong>, apenas sinalização e dados mínimos. A decisão do que fazer em resposta a um evento pertence à tarefa consumidora. Isso evita que ISRs fiquem complexas e garante que decisões de alto nível ocorram sempre em contexto de tarefa, onde mutexes, alocação de memória e chamadas de API são seguras.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Fluxo típico de eventos no FreeRTOS</strong></h3>



<p class="wp-block-paragraph">Um fluxo clássico em arquitetura orientada a eventos segue o seguinte encadeamento lógico:</p>



<ol class="wp-block-list">
<li>Um periférico gera uma interrupção (por exemplo, UART RX completa).</li>



<li>A ISR sinaliza o evento usando uma primitiva segura para interrupções.</li>



<li>O kernel do FreeRTOS desbloqueia a tarefa interessada.</li>



<li>A tarefa acorda, processa o evento e retorna ao estado bloqueado.</li>
</ol>



<p class="wp-block-paragraph">Esse modelo cria um sistema <strong>reativo e previsível</strong>, onde a latência entre o evento e o processamento é controlada diretamente pela prioridade da tarefa e pela duração das ISRs. Em projetos bem arquitetados, o tempo gasto dentro da interrupção é mínimo, e todo o processamento ocorre em nível de tarefa.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Exemplo conceitual simplificado</strong></h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>void vUartTask(void *pvParameters)
{
    uint8_t rxByte;

    for (;;)
    {
        if (xQueueReceive(uartRxQueue, &amp;rxByte, portMAX_DELAY) == pdPASS)
        {
            processUartByte(rxByte);
        }
    }
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">vUartTask</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">pvParameters</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">uint8_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">rxByte</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">;;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #88C0D0">xQueueReceive</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">uartRxQueue</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">rxByte</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">portMAX_DELAY</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">==</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pdPASS</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">processUartByte</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">rxByte</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Neste exemplo, a tarefa <code>vUartTask</code> não executa continuamente. Ela permanece bloqueada até que um byte seja colocado na fila por uma ISR ou outra tarefa. Isso caracteriza perfeitamente o modelo orientado a eventos: <strong>o evento é a chegada de um dado</strong>, e a tarefa existe apenas para reagir a ele.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Implicações arquiteturais importantes</strong></h3>



<p class="wp-block-paragraph">Ao adotar esse modelo, algumas decisões de projeto tornam-se fundamentais. A granularidade dos eventos deve ser cuidadosamente escolhida: eventos muito genéricos levam a tarefas complexas e difíceis de testar; eventos excessivamente específicos geram sobrecarga e fragmentação. Além disso, o uso correto de prioridades é crucial para garantir que eventos críticos sejam tratados com menor latência.</p>



<p class="wp-block-paragraph">Outro aspecto frequentemente negligenciado é o tratamento de <strong>eventos concorrentes</strong>. O FreeRTOS permite que múltiplos eventos acordem a mesma tarefa, mas o firmware deve ser capaz de lidar com isso de forma determinística, normalmente utilizando estruturas de estado bem definidas ou <em>state machines</em> orientadas a eventos.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph">Na <strong>próxima seção</strong>, entraremos nos <strong>mecanismos de eventos disponíveis no FreeRTOS</strong>, começando pelo mais eficiente e subutilizado deles: <strong>Task Notifications</strong>, analisando seu funcionamento interno, vantagens, limitações e padrões de uso.</p>



<p class="wp-block-paragraph">Excelente, seguimos.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Task Notifications como Mecanismo Central de Eventos</strong></h3>



<p class="wp-block-paragraph">Entre todos os mecanismos oferecidos pelo FreeRTOS, as <strong>Task Notifications</strong> são, do ponto de vista arquitetural, a forma mais eficiente de implementar uma arquitetura orientada a eventos. Elas funcionam como um <strong>canal direto ponto-a-ponto entre o kernel e uma tarefa</strong>, sem a sobrecarga de filas, sem alocação dinâmica e com latência mínima.</p>



<p class="wp-block-paragraph">Cada tarefa no FreeRTOS possui internamente um <strong>array de notificações</strong> (desde o FreeRTOS 10), onde cada entrada contém um valor de 32 bits e um estado. Isso transforma a task notification em algo conceitualmente próximo a um <strong>registrador de eventos privado da tarefa</strong>. Esse detalhe é fundamental para entender por que esse mecanismo é tão eficiente e, ao mesmo tempo, tão poderoso.</p>



<p class="wp-block-paragraph">Diferente de filas ou event groups, <strong>uma task notification não é compartilhada</strong>. Ela pertence a uma única tarefa. Isso força uma arquitetura mais limpa, onde existe um mapeamento explícito entre <em>quem produz</em> e <em>quem consome</em> o evento. Em arquiteturas bem desenhadas, isso reduz drasticamente o acoplamento implícito e elimina ambiguidades.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Modelo mental correto para Task Notifications</strong></h3>



<p class="wp-block-paragraph">É comum iniciantes tratarem task notifications como “um semáforo mais rápido”. Embora isso seja parcialmente verdadeiro, essa visão é limitada. O modelo correto é pensar nelas como:</p>



<ul class="wp-block-list">
<li>Um <strong>evento binário</strong> (acordar ou não acordar a task)</li>



<li>Um <strong>contador</strong> (quantidade de eventos acumulados)</li>



<li>Um <strong>bitmap de flags</strong></li>



<li>Um <strong>payload de 32 bits</strong></li>
</ul>



<p class="wp-block-paragraph">Tudo isso usando a <strong>mesma infraestrutura</strong>, dependendo apenas da API utilizada.</p>



<p class="wp-block-paragraph">Essa flexibilidade permite criar arquiteturas orientadas a eventos extremamente compactas, onde um único mecanismo substitui filas, semáforos e flags em muitos cenários.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Exemplo 1 — Evento simples (sinalização pura)</strong></h3>



<p class="wp-block-paragraph">Neste primeiro exemplo, uma ISR sinaliza que um evento ocorreu, e a tarefa apenas reage.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>void vEventTask(void *pvParameters)
{
    for (;;)
    {
        ulTaskNotifyTake(pdTRUE, portMAX_DELAY);

        handleEvent();
    }
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">vEventTask</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">pvParameters</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">;;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">ulTaskNotifyTake</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">pdTRUE</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">portMAX_DELAY</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">handleEvent</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">A função <code>ulTaskNotifyTake()</code> bloqueia a tarefa até que uma notificação seja recebida. O parâmetro <code>pdTRUE</code> indica que o contador interno será limpo ao acordar, garantindo comportamento de evento simples.</p>



<p class="wp-block-paragraph">A ISR responsável pelo evento:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>void EXTI_IRQHandler(void)
{
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;

    vTaskNotifyGiveFromISR(eventTaskHandle, &amp;xHigherPriorityTaskWoken);

    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">EXTI_IRQHandler</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">BaseType_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">xHigherPriorityTaskWoken</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pdFALSE</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">vTaskNotifyGiveFromISR</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">eventTaskHandle</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">xHigherPriorityTaskWoken</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">portYIELD_FROM_ISR</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">xHigherPriorityTaskWoken</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Aqui, o evento é produzido de forma segura em contexto de interrupção, e o kernel pode realizar <em>context switch</em> imediato se a prioridade justificar. Esse padrão é ideal para eventos como botão pressionado, fim de conversão ADC ou término de DMA.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Exemplo 2 — Contador de eventos acumulados</strong></h3>



<p class="wp-block-paragraph">Em cenários onde múltiplos eventos podem ocorrer antes da tarefa acordar, a task notification pode atuar como <strong>contador</strong>.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>void vLoggerTask(void *pvParameters)
{
    uint32_t events;

    for (;;)
    {
        events = ulTaskNotifyTake(pdFALSE, portMAX_DELAY);

        while (events--)
        {
            logEvent();
        }
    }
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">vLoggerTask</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">pvParameters</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">uint32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">events</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">;;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">events</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">ulTaskNotifyTake</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">pdFALSE</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">portMAX_DELAY</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">while</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">events</span><span style="color: #81A1C1">--</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">logEvent</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Ao usar <code>pdFALSE</code>, o contador não é automaticamente zerado. O valor retornado indica quantos eventos ocorreram desde a última leitura. Isso é extremamente útil em sistemas com bursts de eventos, como recepção de pacotes ou amostras rápidas de sensores.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Exemplo 3 — Task Notification como bitmap de eventos</strong></h3>



<p class="wp-block-paragraph">Outra aplicação avançada é usar o valor de 32 bits como <strong>mapa de bits de eventos</strong>, substituindo completamente os Event Groups quando o evento é destinado a uma única tarefa.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>#define EVT_RX_READY   (1 &lt;&lt; 0)
#define EVT_TX_DONE   (1 &lt;&lt; 1)
#define EVT_ERROR     (1 &lt;&lt; 2)

void vCommTask(void *pvParameters)
{
    uint32_t events;

    for (;;)
    {
        xTaskNotifyWait(0x00, 0xFFFFFFFF, &amp;events, portMAX_DELAY);

        if (events &amp; EVT_RX_READY)
            handleRx();

        if (events &amp; EVT_TX_DONE)
            handleTxDone();

        if (events &amp; EVT_ERROR)
            handleError();
    }
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">EVT_RX_READY</span><span style="color: #D8DEE9FF">   (</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">EVT_TX_DONE</span><span style="color: #D8DEE9FF">   (</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">EVT_ERROR</span><span style="color: #D8DEE9FF">     (</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">vCommTask</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">pvParameters</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">uint32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">events</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">;;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">xTaskNotifyWait</span><span style="color: #D8DEE9FF">(</span><span style="color: #B48EAD">0x00</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0xFFFFFFFF</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">events</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">portMAX_DELAY</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">events</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">EVT_RX_READY</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">handleRx</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">events</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">EVT_TX_DONE</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">handleTxDone</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">events</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">EVT_ERROR</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">handleError</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Esse padrão cria uma <strong>máquina de eventos compacta</strong>, extremamente eficiente e fácil de analisar em termos de latência e consumo de recursos.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading"><strong>Vantagens arquiteturais das Task Notifications</strong></h3>



<p class="wp-block-paragraph">Do ponto de vista de engenharia de sistemas, as task notifications oferecem:</p>



<ul class="wp-block-list">
<li>Menor latência entre evento e execução</li>



<li>Zero uso de heap</li>



<li>Menor footprint de memória</li>



<li>Determinismo temporal elevado</li>



<li>Código mais explícito e fácil de rastrear</li>
</ul>



<p class="wp-block-paragraph">Por esse motivo, em arquiteturas orientadas a eventos bem projetadas, <strong>task notifications devem ser a primeira opção</strong>, e não a última.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph">Na <strong>próxima seção</strong>, vamos tratar de <strong>Event Groups</strong>, explicando quando eles são necessários, como evitá-los em excesso e como integrá-los corretamente em uma arquitetura orientada a eventos sem criar dependências implícitas.</p>



<p class="wp-block-paragraph">Seguimos.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/><p>The post <a href="https://mcu.tec.br/rtos/arquitetura-orientada-a-eventos-no-freertos/">Arquitetura Orientada a Eventos no FreeRTOS</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1057</post-id>	</item>
		<item>
		<title>Participe em nossa comunidade no Whatsapp</title>
		<link>https://mcu.tec.br/geral/participe-em-nossa-comunidade-no-whatsapp/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=participe-em-nossa-comunidade-no-whatsapp</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Sun, 15 Feb 2026 12:53:41 +0000</pubDate>
				<category><![CDATA[geral]]></category>
		<category><![CDATA[AIoT]]></category>
		<category><![CDATA[arquitetura embarcada]]></category>
		<category><![CDATA[comunidade técnica]]></category>
		<category><![CDATA[desenvolvimento embarcado]]></category>
		<category><![CDATA[edge computing]]></category>
		<category><![CDATA[eletrônica digital]]></category>
		<category><![CDATA[firmware]]></category>
		<category><![CDATA[FPGA]]></category>
		<category><![CDATA[grupo WhatsApp engenharia]]></category>
		<category><![CDATA[hardware digital]]></category>
		<category><![CDATA[HDL]]></category>
		<category><![CDATA[IoT]]></category>
		<category><![CDATA[MCU]]></category>
		<category><![CDATA[microcontroladores]]></category>
		<category><![CDATA[processamento de sinais]]></category>
		<category><![CDATA[rtos]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[Verilog]]></category>
		<category><![CDATA[VHDL]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1344</guid>

					<description><![CDATA[<p>Participe da Comunidade MCU e FPGA no WhatsApp e conecte-se com desenvolvedores, engenheiros, estudantes e pesquisadores que atuam com microcontroladores, FPGAs e todo o ecossistema de sistemas embarcados. Um espaço colaborativo para troca de experiências, discussão técnica sobre firmware, hardware digital, IoT, AIoT, protocolos industriais, processamento de sinais, arquiteturas embarcadas, HDL, RTOS e muito mais. Compartilhe projetos, tire dúvidas, amplie seu networking técnico e evolua junto com profissionais que vivem a engenharia na prática. Entre agora e ajude a fortalecer o ecossistema brasileiro de tecnologia embarcada.</p>
<p>The post <a href="https://mcu.tec.br/geral/participe-em-nossa-comunidade-no-whatsapp/">Participe em nossa comunidade no Whatsapp</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f680.png" alt="🚀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Faça Parte da Nossa Comunidade MCU &amp; FPGA!</strong></p>



<p class="wp-block-paragraph">Se você é apaixonado por microcontroladores, FPGAs, sistemas embarcados, eletrônica digital, IoT, AIoT, protocolos industriais, processamento de sinais ou arquitetura de hardware, este é o seu lugar.</p>



<p class="wp-block-paragraph">Criamos um espaço colaborativo no WhatsApp para reunir desenvolvedores, estudantes, pesquisadores e entusiastas que desejam evoluir juntos no universo de <strong>MCU e FPGA e todo o seu ecossistema</strong> — do firmware ao hardware, do bare-metal ao RTOS, do HDL ao edge computing.</p>



<p class="wp-block-paragraph">Aqui você poderá:</p>



<p class="wp-block-paragraph">• Trocar experiências práticas<br>• Tirar dúvidas técnicas<br>• Compartilhar projetos e artigos<br>• Discutir arquiteturas e boas práticas<br>• Conhecer novas ferramentas e tecnologias<br>• Expandir sua rede profissional</p>



<p class="wp-block-paragraph">Nosso objetivo é construir uma comunidade técnica forte, colaborativa e orientada ao crescimento real.</p>



<p class="wp-block-paragraph"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f449.png" alt="👉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Entre agora pelo link:</strong><br><a href="https://chat.whatsapp.com/BYXrqPHsRO5FTP7ap7X5yq">https://chat.whatsapp.com/BYXrqPHsRO5FTP7ap7X5yq</a></p>



<p class="wp-block-paragraph">Se você acredita na força do conhecimento compartilhado, convide também seus amigos, colegas de trabalho e membros de outros grupos técnicos. Quanto mais mentes engajadas, mais rico será o aprendizado de todos.</p>



<p class="wp-block-paragraph">Vamos fortalecer o ecossistema de MCU &amp; FPGA juntos.</p><p>The post <a href="https://mcu.tec.br/geral/participe-em-nossa-comunidade-no-whatsapp/">Participe em nossa comunidade no Whatsapp</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1344</post-id>	</item>
		<item>
		<title>FreeRTOS: Stream Buffers, comparação com Queues e critérios de escolha</title>
		<link>https://mcu.tec.br/rtos/freertos-stream-buffers-comparacao-com-queues-e-criterios-de-escolha/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=freertos-stream-buffers-comparacao-com-queues-e-criterios-de-escolha</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Fri, 13 Feb 2026 16:10:46 +0000</pubDate>
				<category><![CDATA[RTOS]]></category>
		<category><![CDATA[buffers circulares]]></category>
		<category><![CDATA[comunicação entre tarefas]]></category>
		<category><![CDATA[desempenho em tempo real]]></category>
		<category><![CDATA[freertos]]></category>
		<category><![CDATA[ISR FreeRTOS]]></category>
		<category><![CDATA[producer consumer]]></category>
		<category><![CDATA[queue FreeRTOS]]></category>
		<category><![CDATA[rtos]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[stream buffer]]></category>
		<category><![CDATA[UART FreeRTOS]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1050</guid>

					<description><![CDATA[<p>Neste artigo técnico e didático, exploramos em profundidade o uso de Stream Buffers no FreeRTOS, explicando seu funcionamento interno, comparando-os detalhadamente com Queues e apresentando critérios claros para escolher o mecanismo correto em sistemas embarcados. O conteúdo aborda desempenho, latência, uso de memória, topologia produtor–consumidor, boas práticas, armadilhas comuns e exemplos de código em C voltados a aplicações reais como UART, sensores e pipelines de dados em tempo real.</p>
<p>The post <a href="https://mcu.tec.br/rtos/freertos-stream-buffers-comparacao-com-queues-e-criterios-de-escolha/">FreeRTOS: Stream Buffers, comparação com Queues e critérios de escolha</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<div class="root-eb-toc-x3mpg wp-block-essential-blocks-table-of-contents"><div class="eb-parent-wrapper eb-parent-eb-toc-x3mpg "><div class="eb-toc-container eb-toc-x3mpg  eb-toc-is-not-sticky eb-toc-not-collapsible eb-toc-initially-not-collapsed eb-toc-scrollToTop style-1 list-style-none" data-scroll-top="false" data-scroll-top-icon="fas fa-angle-up" data-collapsible="false" data-sticky-hide-mobile="false" data-sticky="false" data-scroll-target="scroll_to_toc" data-copy-link="false" data-editor-type="" data-hide-desktop="false" data-hide-tab="false" data-hide-mobile="false" data-itemcollapsed="false" data-highlight-scroll="false"><div class="eb-toc-header"><h2 class="eb-toc-title">Table of Contents</h2></div><div class="eb-toc-wrapper " data-headers="[{&quot;level&quot;:3,&quot;content&quot;:&quot;Introdu\u00e7\u00e3o: comunica\u00e7\u00e3o entre tarefas no FreeRTOS&quot;,&quot;text&quot;:&quot;Introdu\u00e7\u00e3o: comunica\u00e7\u00e3o entre tarefas no FreeRTOS&quot;,&quot;link&quot;:&quot;eb-table-content-0&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;O que s\u00e3o Stream Buffers no FreeRTOS e como eles funcionam internamente&quot;,&quot;text&quot;:&quot;O que s\u00e3o Stream Buffers no FreeRTOS e como eles funcionam internamente&quot;,&quot;link&quot;:&quot;eb-table-content-1&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo b\u00e1sico: cria\u00e7\u00e3o de um Stream Buffer&quot;,&quot;text&quot;:&quot;Exemplo b\u00e1sico: cria\u00e7\u00e3o de um Stream Buffer&quot;,&quot;link&quot;:&quot;eb-table-content-2&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo de escrita em uma tarefa produtora&quot;,&quot;text&quot;:&quot;Exemplo de escrita em uma tarefa produtora&quot;,&quot;link&quot;:&quot;exemplo-de-escrita-em-uma-tarefa-produtora&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo de leitura em uma tarefa consumidora&quot;,&quot;text&quot;:&quot;Exemplo de leitura em uma tarefa consumidora&quot;,&quot;link&quot;:&quot;exemplo-de-leitura-em-uma-tarefa-consumidora&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Queues no FreeRTOS: modelo de dados, garantias e custos ocultos&quot;,&quot;text&quot;:&quot;Queues no FreeRTOS: modelo de dados, garantias e custos ocultos&quot;,&quot;link&quot;:&quot;queues-no-freertos-modelo-de-dados-garantias-e-custos-ocultos&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo b\u00e1sico: cria\u00e7\u00e3o de uma Queue&quot;,&quot;text&quot;:&quot;Exemplo b\u00e1sico: cria\u00e7\u00e3o de uma Queue&quot;,&quot;link&quot;:&quot;eb-table-content-6&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Envio de dados para a Queue&quot;,&quot;text&quot;:&quot;Envio de dados para a Queue&quot;,&quot;link&quot;:&quot;envio-de-dados-para-a-queue&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Recep\u00e7\u00e3o de dados da Queue&quot;,&quot;text&quot;:&quot;Recep\u00e7\u00e3o de dados da Queue&quot;,&quot;link&quot;:&quot;eb-table-content-8&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Custos ocultos das Queues&quot;,&quot;text&quot;:&quot;Custos ocultos das Queues&quot;,&quot;link&quot;:&quot;custos-ocultos-das-queues&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Stream Buffers vs Queues: compara\u00e7\u00e3o t\u00e9cnica detalhada e crit\u00e9rios de escolha&quot;,&quot;text&quot;:&quot;Stream Buffers vs Queues: compara\u00e7\u00e3o t\u00e9cnica detalhada e crit\u00e9rios de escolha&quot;,&quot;link&quot;:&quot;eb-table-content-10&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Compara\u00e7\u00e3o estrutural&quot;,&quot;text&quot;:&quot;Compara\u00e7\u00e3o estrutural&quot;,&quot;link&quot;:&quot;eb-table-content-11&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Crit\u00e9rio 1: natureza do dado&quot;,&quot;text&quot;:&quot;Crit\u00e9rio 1: natureza do dado&quot;,&quot;link&quot;:&quot;eb-table-content-12&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Crit\u00e9rio 2: desempenho e lat\u00eancia&quot;,&quot;text&quot;:&quot;Crit\u00e9rio 2: desempenho e lat\u00eancia&quot;,&quot;link&quot;:&quot;eb-table-content-13&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Crit\u00e9rio 3: topologia produtor\u2013consumidor&quot;,&quot;text&quot;:&quot;Crit\u00e9rio 3: topologia produtor\u2013consumidor&quot;,&quot;link&quot;:&quot;eb-table-content-14&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo comparativo: UART RX&quot;,&quot;text&quot;:&quot;Exemplo comparativo: UART RX&quot;,&quot;link&quot;:&quot;exemplo-comparativo-uart-rx&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Padr\u00f5es de uso, boas pr\u00e1ticas e armadilhas comuns com Stream Buffers&quot;,&quot;text&quot;:&quot;Padr\u00f5es de uso, boas pr\u00e1ticas e armadilhas comuns com Stream Buffers&quot;,&quot;link&quot;:&quot;eb-table-content-16&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Boa pr\u00e1tica 1: dimensionamento correto do buffer&quot;,&quot;text&quot;:&quot;Boa pr\u00e1tica 1: dimensionamento correto do buffer&quot;,&quot;link&quot;:&quot;eb-table-content-17&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Boa pr\u00e1tica 2: uso consciente do trigger level&quot;,&quot;text&quot;:&quot;Boa pr\u00e1tica 2: uso consciente do trigger level&quot;,&quot;link&quot;:&quot;eb-table-content-18&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Boa pr\u00e1tica 3: sempre respeitar o modelo 1\u21921&quot;,&quot;text&quot;:&quot;Boa pr\u00e1tica 3: sempre respeitar o modelo 1\u21921&quot;,&quot;link&quot;:&quot;eb-table-content-19&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Armadilha 1: tratar Stream Buffer como Message Queue&quot;,&quot;text&quot;:&quot;Armadilha 1: tratar Stream Buffer como Message Queue&quot;,&quot;link&quot;:&quot;armadilha-1-tratar-stream-buffer-como-message-queue&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Armadilha 2: ignorar retornos das fun\u00e7\u00f5es&quot;,&quot;text&quot;:&quot;Armadilha 2: ignorar retornos das fun\u00e7\u00f5es&quot;,&quot;link&quot;:&quot;eb-table-content-21&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Armadilha 3: usar delays em vez de bloqueio&quot;,&quot;text&quot;:&quot;Armadilha 3: usar delays em vez de bloqueio&quot;,&quot;link&quot;:&quot;armadilha-3-usar-delays-em-vez-de-bloqueio&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Conclus\u00e3o t\u00e9cnica e diretrizes finais de projeto&quot;,&quot;text&quot;:&quot;Conclus\u00e3o t\u00e9cnica e diretrizes finais de projeto&quot;,&quot;link&quot;:&quot;eb-table-content-23&quot;}]" data-visible="[true,true,true,true,true,true]" data-delete-headers="[{&quot;label&quot;:&quot;Introdu\u00e7\u00e3o: comunica\u00e7\u00e3o entre tarefas no FreeRTOS&quot;,&quot;value&quot;:&quot;introdu\u00e7\u00e3o-comunica\u00e7\u00e3o-entre-tarefas-no-freertos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;O que s\u00e3o Stream Buffers no FreeRTOS e como eles funcionam internamente&quot;,&quot;value&quot;:&quot;o-que-s\u00e3o-stream-buffers-no-freertos-e-como-eles-funcionam-internamente&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo b\u00e1sico: cria\u00e7\u00e3o de um Stream Buffer&quot;,&quot;value&quot;:&quot;exemplo-b\u00e1sico-cria\u00e7\u00e3o-de-um-stream-buffer&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo de escrita em uma tarefa produtora&quot;,&quot;value&quot;:&quot;exemplo-de-escrita-em-uma-tarefa-produtora&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo de leitura em uma tarefa consumidora&quot;,&quot;value&quot;:&quot;exemplo-de-leitura-em-uma-tarefa-consumidora&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Queues no FreeRTOS: modelo de dados, garantias e custos ocultos&quot;,&quot;value&quot;:&quot;queues-no-freertos-modelo-de-dados-garantias-e-custos-ocultos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo b\u00e1sico: cria\u00e7\u00e3o de uma Queue&quot;,&quot;value&quot;:&quot;exemplo-b\u00e1sico-cria\u00e7\u00e3o-de-uma-queue&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Envio de dados para a Queue&quot;,&quot;value&quot;:&quot;envio-de-dados-para-a-queue&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Recep\u00e7\u00e3o de dados da Queue&quot;,&quot;value&quot;:&quot;recep\u00e7\u00e3o-de-dados-da-queue&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Custos ocultos das Queues&quot;,&quot;value&quot;:&quot;custos-ocultos-das-queues&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Stream Buffers vs Queues: compara\u00e7\u00e3o t\u00e9cnica detalhada e crit\u00e9rios de escolha&quot;,&quot;value&quot;:&quot;stream-buffers-vs-queues-compara\u00e7\u00e3o-t\u00e9cnica-detalhada-e-crit\u00e9rios-de-escolha&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Compara\u00e7\u00e3o estrutural&quot;,&quot;value&quot;:&quot;compara\u00e7\u00e3o-estrutural&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Crit\u00e9rio 1: natureza do dado&quot;,&quot;value&quot;:&quot;crit\u00e9rio-1-natureza-do-dado&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Crit\u00e9rio 2: desempenho e lat\u00eancia&quot;,&quot;value&quot;:&quot;crit\u00e9rio-2-desempenho-e-lat\u00eancia&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Crit\u00e9rio 3: topologia produtor\u2013consumidor&quot;,&quot;value&quot;:&quot;crit\u00e9rio-3-topologia-produtorconsumidor&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo comparativo: UART RX&quot;,&quot;value&quot;:&quot;exemplo-comparativo-uart-rx&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Padr\u00f5es de uso, boas pr\u00e1ticas e armadilhas comuns com Stream Buffers&quot;,&quot;value&quot;:&quot;padr\u00f5es-de-uso-boas-pr\u00e1ticas-e-armadilhas-comuns-com-stream-buffers&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Boa pr\u00e1tica 1: dimensionamento correto do buffer&quot;,&quot;value&quot;:&quot;boa-pr\u00e1tica-1-dimensionamento-correto-do-buffer&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Boa pr\u00e1tica 2: uso consciente do trigger level&quot;,&quot;value&quot;:&quot;boa-pr\u00e1tica-2-uso-consciente-do-trigger-level&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Boa pr\u00e1tica 3: sempre respeitar o modelo 1\u21921&quot;,&quot;value&quot;:&quot;boa-pr\u00e1tica-3-sempre-respeitar-o-modelo-1\u21921&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Armadilha 1: tratar Stream Buffer como Message Queue&quot;,&quot;value&quot;:&quot;armadilha-1-tratar-stream-buffer-como-message-queue&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Armadilha 2: ignorar retornos das fun\u00e7\u00f5es&quot;,&quot;value&quot;:&quot;armadilha-2-ignorar-retornos-das-fun\u00e7\u00f5es&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Armadilha 3: usar delays em vez de bloqueio&quot;,&quot;value&quot;:&quot;armadilha-3-usar-delays-em-vez-de-bloqueio&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Conclus\u00e3o t\u00e9cnica e diretrizes finais de projeto&quot;,&quot;value&quot;:&quot;conclus\u00e3o-t\u00e9cnica-e-diretrizes-finais-de-projeto&quot;,&quot;isDelete&quot;:false}]" data-smooth="true" data-top-offset=""><div class="eb-toc__list-wrap"><ul class="eb-toc__list"><li><a href="#eb-table-content-0">Introdução: comunicação entre tarefas no FreeRTOS</a><li><a href="#eb-table-content-1">O que são Stream Buffers no FreeRTOS e como eles funcionam internamente</a><ul class="eb-toc__list"><li><a href="#eb-table-content-2">Exemplo básico: criação de um Stream Buffer</a><li><a href="#exemplo-de-escrita-em-uma-tarefa-produtora">Exemplo de escrita em uma tarefa produtora</a><li><a href="#exemplo-de-leitura-em-uma-tarefa-consumidora">Exemplo de leitura em uma tarefa consumidora</a></li></ul><li><a href="#queues-no-freertos-modelo-de-dados-garantias-e-custos-ocultos">Queues no FreeRTOS: modelo de dados, garantias e custos ocultos</a><ul class="eb-toc__list"><li><a href="#eb-table-content-6">Exemplo básico: criação de uma Queue</a><li><a href="#envio-de-dados-para-a-queue">Envio de dados para a Queue</a><li><a href="#eb-table-content-8">Recepção de dados da Queue</a><li><a href="#custos-ocultos-das-queues">Custos ocultos das Queues</a></li></ul><li><a href="#eb-table-content-10">Stream Buffers vs Queues: comparação técnica detalhada e critérios de escolha</a><ul class="eb-toc__list"><li><a href="#eb-table-content-11">Comparação estrutural</a><li><a href="#eb-table-content-12">Critério 1: natureza do dado</a><li><a href="#eb-table-content-13">Critério 2: desempenho e latência</a><li><a href="#eb-table-content-14">Critério 3: topologia produtor–consumidor</a><li><a href="#exemplo-comparativo-uart-rx">Exemplo comparativo: UART RX</a></li></ul><li><a href="#eb-table-content-16">Padrões de uso, boas práticas e armadilhas comuns com Stream Buffers</a><ul class="eb-toc__list"><li><a href="#eb-table-content-17">Boa prática 1: dimensionamento correto do buffer</a><li><a href="#eb-table-content-18">Boa prática 2: uso consciente do trigger level</a><li><a href="#eb-table-content-19">Boa prática 3: sempre respeitar o modelo 1→1</a><li><a href="#armadilha-1-tratar-stream-buffer-como-message-queue">Armadilha 1: tratar Stream Buffer como Message Queue</a><li><a href="#eb-table-content-21">Armadilha 2: ignorar retornos das funções</a><li><a href="#armadilha-3-usar-delays-em-vez-de-bloqueio">Armadilha 3: usar delays em vez de bloqueio</a></li></ul><li><a href="#eb-table-content-23">Conclusão técnica e diretrizes finais de projeto</a></ul></div></div></div></div></div>


<h3 class="wp-block-heading"><strong>Introdução: comunicação entre tarefas no FreeRTOS</strong></h3>



<p class="wp-block-paragraph">Em sistemas embarcados baseados em <em>Real-Time Operating Systems</em> (RTOS), a comunicação entre tarefas (<em>tasks</em>) e entre interrupções (<em>ISRs – Interrupt Service Routines</em>) é um dos pilares da arquitetura de software. No FreeRTOS, essa comunicação pode ocorrer por diversos mecanismos: <em>queues</em>, <em>semaphores</em>, <em>event groups</em>, <em>task notifications</em> e, mais recentemente, <em>stream buffers</em> e <em>message buffers</em>. Cada um desses mecanismos foi projetado para atender a padrões específicos de troca de dados, com impactos diretos em desempenho, uso de memória, latência e complexidade do código.</p>



<p class="wp-block-paragraph">Historicamente, as <em>queues</em> foram o principal mecanismo para troca de dados entre tarefas no FreeRTOS. Elas oferecem uma semântica clara, segura e genérica, permitindo o envio de estruturas de dados completas entre produtores e consumidores. No entanto, conforme sistemas embarcados passaram a lidar com <strong>fluxos contínuos de dados</strong> — como áudio, streams de sensores, bytes vindos de UART, SPI, USB ou stacks de rede —, tornou-se evidente que o modelo tradicional de <em>queue</em> não era o mais eficiente para esse tipo de cenário.</p>



<p class="wp-block-paragraph">É nesse contexto que surgem os <strong>Stream Buffers</strong>, introduzidos para lidar com <strong>dados orientados a fluxo</strong>, onde o mais importante não é a fronteira entre mensagens, mas sim a sequência contínua de bytes. Diferentemente das <em>queues</em>, que operam com itens discretos e de tamanho fixo, os <em>stream buffers</em> operam como um <strong>buffer circular de bytes</strong>, permitindo escrita e leitura parcial, com controle fino sobre bloqueio, timeout e sincronização entre tarefas e ISRs.</p>



<p class="wp-block-paragraph">Nesta série de artigos sobre FreeRTOS, esta seção tem como objetivo introduzir formalmente o conceito de <em>stream buffers</em>, posicioná-los corretamente dentro do ecossistema de mecanismos de comunicação do sistema operacional e preparar o terreno para uma comparação técnica aprofundada com <em>queues</em>. Ao longo das próximas seções, veremos <strong>como funcionam internamente</strong>, <strong>quando usá-los</strong>, <strong>quando evitá-los</strong> e <strong>como escrever código eficiente e seguro</strong> usando esse recurso.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/><p>The post <a href="https://mcu.tec.br/rtos/freertos-stream-buffers-comparacao-com-queues-e-criterios-de-escolha/">FreeRTOS: Stream Buffers, comparação com Queues e critérios de escolha</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1050</post-id>	</item>
		<item>
		<title>Comparativo Técnico de Microcontroladores: ESP32, STM32, Arduino, RP2040 e nRF52</title>
		<link>https://mcu.tec.br/microcontroladores/comparativo-tecnico-de-microcontroladores-esp32-stm32-arduino-rp2040-e-nrf52/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=comparativo-tecnico-de-microcontroladores-esp32-stm32-arduino-rp2040-e-nrf52</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Tue, 10 Feb 2026 10:59:31 +0000</pubDate>
				<category><![CDATA[microcontroladores]]></category>
		<category><![CDATA[Arduino AVR]]></category>
		<category><![CDATA[baixo consumo]]></category>
		<category><![CDATA[bluetooth low energy]]></category>
		<category><![CDATA[controle industrial]]></category>
		<category><![CDATA[engenharia eletrônica]]></category>
		<category><![CDATA[esp32]]></category>
		<category><![CDATA[firmware embarcado]]></category>
		<category><![CDATA[IoT]]></category>
		<category><![CDATA[nRF52]]></category>
		<category><![CDATA[RP2040]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[stm32]]></category>
		<category><![CDATA[wi-fi embarcado]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1291</guid>

					<description><![CDATA[<p>Este artigo apresenta uma análise comparativa e didática entre os principais microcontroladores do mercado — ESP32, STM32, Arduino (AVR), RP2040 e nRF52. O texto explora arquitetura, desempenho, consumo energético, conectividade e contexto de uso de cada família, ajudando engenheiros, estudantes e desenvolvedores a escolherem a plataforma mais adequada para projetos de IoT, sistemas industriais, dispositivos embarcados de baixo consumo e aplicações educacionais. O conteúdo é técnico, claro e orientado à tomada de decisão consciente em engenharia de sistemas embarcado</p>
<p>The post <a href="https://mcu.tec.br/microcontroladores/comparativo-tecnico-de-microcontroladores-esp32-stm32-arduino-rp2040-e-nrf52/">Comparativo Técnico de Microcontroladores: ESP32, STM32, Arduino, RP2040 e nRF52</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<div class="root-eb-toc-poauy wp-block-essential-blocks-table-of-contents"><div class="eb-parent-wrapper eb-parent-eb-toc-poauy "><div class="eb-toc-container eb-toc-poauy  eb-toc-is-not-sticky eb-toc-not-collapsible eb-toc-initially-not-collapsed eb-toc-scrollToTop style-1 list-style-none" data-scroll-top="false" data-scroll-top-icon="fas fa-angle-up" data-collapsible="false" data-sticky-hide-mobile="false" data-sticky="false" data-scroll-target="scroll_to_toc" data-copy-link="false" data-editor-type="" data-hide-desktop="false" data-hide-tab="false" data-hide-mobile="false" data-itemcollapsed="false" data-highlight-scroll="false"><div class="eb-toc-header"><h2 class="eb-toc-title">Table of Contents</h2></div><div class="eb-toc-wrapper " data-headers="[{&quot;level&quot;:2,&quot;content&quot;:&quot;Introdu\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Introdu\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-0&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;ESP32 \u2013 Conectividade Integrada e Foco em IoT&quot;,&quot;text&quot;:&quot;ESP32 \u2013 Conectividade Integrada e Foco em IoT&quot;,&quot;link&quot;:&quot;esp32-conectividade-integrada-e-foco-em-iot&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;STM32 \u2013 Desempenho, Escalabilidade e Foco Industrial&quot;,&quot;text&quot;:&quot;STM32 \u2013 Desempenho, Escalabilidade e Foco Industrial&quot;,&quot;link&quot;:&quot;stm32-desempenho-escalabilidade-e-foco-industrial&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Arduino (AVR) \u2013 Simplicidade, Acesso e Limita\u00e7\u00f5es Arquiteturais&quot;,&quot;text&quot;:&quot;Arduino (AVR) \u2013 Simplicidade, Acesso e Limita\u00e7\u00f5es Arquiteturais&quot;,&quot;link&quot;:&quot;eb-table-content-3&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;RP2040 \u2013 Arquitetura Moderna, PIO e Flexibilidade a Baixo Custo&quot;,&quot;text&quot;:&quot;RP2040 \u2013 Arquitetura Moderna, PIO e Flexibilidade a Baixo Custo&quot;,&quot;link&quot;:&quot;rp2040-arquitetura-moderna-pio-e-flexibilidade-a-baixo-custo&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;nRF52 \u2013 Ultra Baixo Consumo e Comunica\u00e7\u00e3o Bluetooth Low Energy&quot;,&quot;text&quot;:&quot;nRF52 \u2013 Ultra Baixo Consumo e Comunica\u00e7\u00e3o Bluetooth Low Energy&quot;,&quot;link&quot;:&quot;eb-table-content-5&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Tabela Comparativa T\u00e9cnica entre as Plataformas&quot;,&quot;text&quot;:&quot;Tabela Comparativa T\u00e9cnica entre as Plataformas&quot;,&quot;link&quot;:&quot;eb-table-content-6&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Leitura cr\u00edtica da tabela&quot;,&quot;text&quot;:&quot;Leitura cr\u00edtica da tabela&quot;,&quot;link&quot;:&quot;eb-table-content-7&quot;}]" data-visible="[true,true,true,true,true,true]" data-delete-headers="[{&quot;label&quot;:&quot;Introdu\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;introdu\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;ESP32 \u2013 Conectividade Integrada e Foco em IoT&quot;,&quot;value&quot;:&quot;esp32-conectividade-integrada-e-foco-em-iot&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;STM32 \u2013 Desempenho, Escalabilidade e Foco Industrial&quot;,&quot;value&quot;:&quot;stm32-desempenho-escalabilidade-e-foco-industrial&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Arduino (AVR) \u2013 Simplicidade, Acesso e Limita\u00e7\u00f5es Arquiteturais&quot;,&quot;value&quot;:&quot;arduino-avr-simplicidade-acesso-e-limita\u00e7\u00f5es-arquiteturais&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;RP2040 \u2013 Arquitetura Moderna, PIO e Flexibilidade a Baixo Custo&quot;,&quot;value&quot;:&quot;rp2040-arquitetura-moderna-pio-e-flexibilidade-a-baixo-custo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;nRF52 \u2013 Ultra Baixo Consumo e Comunica\u00e7\u00e3o Bluetooth Low Energy&quot;,&quot;value&quot;:&quot;nrf52-ultra-baixo-consumo-e-comunica\u00e7\u00e3o-bluetooth-low-energy&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Tabela Comparativa T\u00e9cnica entre as Plataformas&quot;,&quot;value&quot;:&quot;tabela-comparativa-t\u00e9cnica-entre-as-plataformas&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Leitura cr\u00edtica da tabela&quot;,&quot;value&quot;:&quot;leitura-cr\u00edtica-da-tabela&quot;,&quot;isDelete&quot;:false}]" data-smooth="true" data-top-offset=""><div class="eb-toc__list-wrap"><ul class="eb-toc__list"><li><a href="#eb-table-content-0">Introdução</a><li><a href="#esp32-conectividade-integrada-e-foco-em-iot">ESP32 – Conectividade Integrada e Foco em IoT</a><li><a href="#stm32-desempenho-escalabilidade-e-foco-industrial">STM32 – Desempenho, Escalabilidade e Foco Industrial</a><li><a href="#eb-table-content-3">Arduino (AVR) – Simplicidade, Acesso e Limitações Arquiteturais</a><li><a href="#rp2040-arquitetura-moderna-pio-e-flexibilidade-a-baixo-custo">RP2040 – Arquitetura Moderna, PIO e Flexibilidade a Baixo Custo</a><li><a href="#eb-table-content-5">nRF52 – Ultra Baixo Consumo e Comunicação Bluetooth Low Energy</a><li><a href="#eb-table-content-6">Tabela Comparativa Técnica entre as Plataformas</a><ul class="eb-toc__list"><li><a href="#eb-table-content-7">Leitura crítica da tabela</a></li></ul></ul></div></div></div></div></div>


<h2 class="wp-block-heading">Introdução</h2>



<p class="wp-block-paragraph">A escolha de um microcontrolador é uma das decisões mais críticas no desenvolvimento de sistemas embarcados, pois impacta diretamente o custo, o consumo de energia, a complexidade do firmware, a conectividade disponível e até mesmo a viabilidade do produto final. Nos últimos anos, o mercado passou a oferecer famílias extremamente distintas, que atendem desde projetos educacionais e protótipos rápidos até aplicações industriais, IoT em larga escala e dispositivos vestíveis de ultra-baixo consumo.</p>



<p class="wp-block-paragraph">Neste artigo comparativo, analisamos cinco plataformas amplamente utilizadas — <strong>ESP32</strong>, <strong>STM32</strong>, <strong>Arduino (AVR)</strong>, <strong>RP2040</strong> e <strong>nRF52</strong> — destacando suas arquiteturas, capacidades de processamento, conectividade, consumo energético e contextos de uso. O objetivo não é eleger um “melhor” microcontrolador, mas fornecer critérios técnicos claros para que o engenheiro ou desenvolvedor escolha a solução mais adequada ao seu projeto.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/><p>The post <a href="https://mcu.tec.br/microcontroladores/comparativo-tecnico-de-microcontroladores-esp32-stm32-arduino-rp2040-e-nrf52/">Comparativo Técnico de Microcontroladores: ESP32, STM32, Arduino, RP2040 e nRF52</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1291</post-id>	</item>
		<item>
		<title>Os Melhores Sites sobre Microcontroladores, Sistemas Embarcados e IoT em 2026</title>
		<link>https://mcu.tec.br/geral/os-melhores-sites-sobre-microcontroladores-sistemas-embarcados-e-iot-em-2026/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=os-melhores-sites-sobre-microcontroladores-sistemas-embarcados-e-iot-em-2026</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Sun, 08 Feb 2026 00:07:52 +0000</pubDate>
				<category><![CDATA[geral]]></category>
		<category><![CDATA[ARM Cortex]]></category>
		<category><![CDATA[AVR]]></category>
		<category><![CDATA[datasheets]]></category>
		<category><![CDATA[desenvolvimento embarcado]]></category>
		<category><![CDATA[documentação técnica]]></category>
		<category><![CDATA[eletrônica embarcada]]></category>
		<category><![CDATA[engenharia eletrônica]]></category>
		<category><![CDATA[esp32]]></category>
		<category><![CDATA[firmware]]></category>
		<category><![CDATA[FPGA]]></category>
		<category><![CDATA[IoT]]></category>
		<category><![CDATA[kits de desenvolvimento]]></category>
		<category><![CDATA[MCU]]></category>
		<category><![CDATA[microcontroladores]]></category>
		<category><![CDATA[PIC]]></category>
		<category><![CDATA[portais de eletrônica]]></category>
		<category><![CDATA[RISC-V]]></category>
		<category><![CDATA[rtos]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[stm32]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1275</guid>

					<description><![CDATA[<p>Este artigo apresenta uma curadoria criteriosa e atualizada dos melhores sites sobre microcontroladores, sistemas embarcados e IoT, reunindo portais educacionais, fabricantes, distribuidores e plataformas técnicas amplamente reconhecidas no Brasil e no exterior. O conteúdo foi organizado para atender estudantes, makers, engenheiros de firmware e profissionais da indústria, oferecendo acesso direto a artigos técnicos, documentação oficial, cursos, kits de desenvolvimento e pesquisa de componentes. Entre os destaques estão portais especializados como Embarcados, MCU.TEC, Instituto Newton C. Braga, além de fabricantes como Microchip, STMicroelectronics, Renesas e Texas Instruments. O artigo também inclui lojas brasileiras de referência e plataformas globais como Octopart, Digi-Key e Mouser, facilitando desde o aprendizado até o desenvolvimento profissional e industrial de soluções embarcadas. Trata-se de um guia essencial para quem busca fontes confiáveis, técnicas e atualizadas no ecossistema de microcontroladores e eletrônica aplicada.</p>
<p>The post <a href="https://mcu.tec.br/geral/os-melhores-sites-sobre-microcontroladores-sistemas-embarcados-e-iot-em-2026/">Os Melhores Sites sobre Microcontroladores, Sistemas Embarcados e IoT em 2026</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4d8.png" alt="📘" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Conteúdo Educacional e Técnico (Portais e Comunidades)</h2>



<ul class="wp-block-list">
<li><strong>Embarcados</strong><br><a href="https://www.embarcados.com.br/">https://www.embarcados.com.br</a><br>Principal portal brasileiro sobre sistemas embarcados, microcontroladores, RTOS, Linux embarcado e indústria. Excelente equilíbrio entre teoria, prática e mercado.</li>



<li><strong>MCU.TEC</strong><br><a href="https://mcu.tec.br/">https://mcu.tec.br</a><br>Conteúdo técnico aprofundado sobre microcontroladores, FPGA, RTOS, protocolos, eletrônica aplicada e integração com IA. Forte foco em didática e engenharia real.</li>



<li><strong>Microgenios</strong><br><a href="https://www.microgenios.com.br/">https://www.microgenios.com.br</a><br>Cursos, treinamentos e artigos focados em PIC, Arduino, ESP32 e IoT, com abordagem prática para iniciantes e intermediários.</li>



<li><strong>Instituto Newton C. Braga</strong><br><a href="https://www.newtoncbraga.com.br/">https://www.newtoncbraga.com.br</a><br>Acervo clássico e extremamente vasto de eletrônica, incluindo microcontroladores, sensores, fontes e RF. Um verdadeiro repositório histórico-técnico.</li>



<li><strong>Vichinsky</strong><br><a href="https://www.vichinsky.com/">https://www.vichinsky.com</a><br>Conteúdo técnico voltado a PIC (especialmente PIC18F2550), 8051 e Arduino, com exemplos diretos e foco em firmware bare-metal.</li>



<li><strong>All About Circuits</strong><br><a href="https://www.allaboutcircuits.com/">https://www.allaboutcircuits.com</a><br>Um dos melhores sites internacionais para eletrônica e microcontroladores, com artigos técnicos, fóruns e análises profundas.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3ed.png" alt="🏭" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Fabricantes e Documentação Oficial</h2>



<ul class="wp-block-list">
<li><strong>Microchip Technology</strong><br><a href="https://www.microchip.com/">https://www.microchip.com</a><br>Documentação oficial de PIC, AVR (Atmel), SAM e ferramentas como MPLAB X. Fonte primária obrigatória para quem trabalha com PIC e AVR.</li>



<li><strong>STMicroelectronics</strong><br><a href="https://www.st.com/">https://www.st.com</a><br>Referência absoluta para STM32, HAL, LL, CubeMX e ecossistema ARM Cortex-M e Cortex-A.</li>



<li><strong>NXP Semiconductors</strong><br><a href="https://www.nxp.com/">https://www.nxp.com</a><br>Forte em microcontroladores industriais, automotivos, i.MX, LPC e segurança embarcada.</li>



<li><strong>Renesas Electronics</strong><br><a href="https://www.renesas.com/">https://www.renesas.com</a><br>Destaque para famílias RA, RX e RZ, muito usadas em aplicações industriais e IoT avançado.</li>



<li><strong>Texas Instruments</strong><br><a href="https://www.ti.com/">https://www.ti.com</a><br>MSP430, Sitara, documentação exemplar e application notes de alto nível.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f6d2.png" alt="🛒" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Lojas e Kits de Desenvolvimento (Brasil)</h2>



<ul class="wp-block-list">
<li><strong>AutoCore Robótica</strong><br><a href="https://www.autocorerobotica.com.br/">https://www.autocorerobotica.com.br</a><br>Venda de microcontroladores, módulos ESP, sensores e kits educacionais.</li>



<li><strong>Baú da Eletrônica</strong><br><a href="https://www.baudaeletronica.com.br/">https://www.baudaeletronica.com.br</a><br>Grande variedade de CIs, microcontroladores, ferramentas e componentes.</li>



<li><strong>ACEPIC Tecnologia</strong><br><a href="https://www.acepic.com.br/">https://www.acepic.com.br</a><br>Especializada em kits, treinamentos e soluções educacionais para PIC, ESP32 e sistemas embarcados.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f50d.png" alt="🔍" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Plataformas de Pesquisa e Datasheets</h2>



<ul class="wp-block-list">
<li><strong>Octopart</strong><br><a href="https://octopart.com/">https://octopart.com</a><br>Essencial para pesquisa de microcontroladores, comparação de preços, estoque global e acesso rápido a datasheets oficiais.</li>



<li><strong>Digi-Key</strong><br><a href="https://www.digikey.com/">https://www.digikey.com</a><br>Além da loja, possui uma biblioteca técnica riquíssima (TechForum, artigos, vídeos).</li>



<li><strong>Mouser Electronics</strong><br><a href="https://www.mouser.com/">https://www.mouser.com</a><br>Excelente para lançamentos recentes, application notes e kits de desenvolvimento.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/><p>The post <a href="https://mcu.tec.br/geral/os-melhores-sites-sobre-microcontroladores-sistemas-embarcados-e-iot-em-2026/">Os Melhores Sites sobre Microcontroladores, Sistemas Embarcados e IoT em 2026</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1275</post-id>	</item>
	</channel>
</rss>
