<?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>grupos de eventos - MCU &amp; FPGA</title>
	<atom:link href="https://mcu.tec.br/tags/grupos-de-eventos/feed/" rel="self" type="application/rss+xml" />
	<link>https://mcu.tec.br</link>
	<description>Microcontroladores &#38; FPGA</description>
	<lastBuildDate>Thu, 02 Jan 2025 21:46:23 +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>grupos de eventos - MCU &amp; FPGA</title>
	<link>https://mcu.tec.br</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Introdução ao FreeRTOS no ESP32: Controle Multicore e Recursos Avançados</title>
		<link>https://mcu.tec.br/multithreads-e-multicore/introducao-ao-freertos-no-esp32-controle-multicore-e-recursos-avancados/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=introducao-ao-freertos-no-esp32-controle-multicore-e-recursos-avancados</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Thu, 02 Jan 2025 21:28:15 +0000</pubDate>
				<category><![CDATA[Multithreads e Multicore]]></category>
		<category><![CDATA[atomic]]></category>
		<category><![CDATA[C11]]></category>
		<category><![CDATA[condições de corrida]]></category>
		<category><![CDATA[controle exclusivo.]]></category>
		<category><![CDATA[deadlock]]></category>
		<category><![CDATA[esp32]]></category>
		<category><![CDATA[freertos]]></category>
		<category><![CDATA[funções críticas]]></category>
		<category><![CDATA[grupos de eventos]]></category>
		<category><![CDATA[multicore]]></category>
		<category><![CDATA[multitarefa]]></category>
		<category><![CDATA[mutexes]]></category>
		<category><![CDATA[portENTER_CRITICAL]]></category>
		<category><![CDATA[portEXIT_CRITICAL]]></category>
		<category><![CDATA[semáforos]]></category>
		<category><![CDATA[sincronização]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[vPortCPUInitializeMutex]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=46</guid>

					<description><![CDATA[<p>Este artigo explora o uso avançado do FreeRTOS no ESP32 para sistemas multicore, abordando funções críticas como vPortCPUInitializeMutex, portENTER_CRITICAL e portEXIT_CRITICAL. Ele compara essas ferramentas com a diretiva atomic do C e apresenta outros métodos de sincronização, como semáforos, mutexes e grupos de eventos, destacando práticas recomendadas para garantir desempenho, confiabilidade e segurança em projetos embarcados.</p>
<p>The post <a href="https://mcu.tec.br/multithreads-e-multicore/introducao-ao-freertos-no-esp32-controle-multicore-e-recursos-avancados/">Introdução ao FreeRTOS no ESP32: Controle Multicore e Recursos Avançados</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">O ESP32 é um microcontrolador poderoso com suporte a dois núcleos, permitindo que tarefas sejam distribuídas de maneira eficiente. Para aproveitar ao máximo esse recurso, o uso do FreeRTOS é essencial. O FreeRTOS é um sistema operacional de tempo real amplamente utilizado, que oferece mecanismos para gerenciar tarefas, recursos e sincronização.</p>



<p class="wp-block-paragraph">Neste artigo, exploraremos como o FreeRTOS interage com o ESP32 no contexto multicore, com foco nas funções avançadas como <code>vPortCPUInitializeMutex</code>, <code>portENTER_CRITICAL</code> e <code>portEXIT_CRITICAL</code>. Também faremos uma comparação com a diretiva <code>atomic</code> do C e apresentaremos outros métodos de gerenciamento de recursos e sincronização, como semáforos e mutexes, para ilustrar as melhores práticas e implicações de uso.</p>



<p class="wp-block-paragraph">Nosso objetivo é explicar cada recurso de forma clara e detalhada, com exemplos práticos que demonstram como implementar esses mecanismos no ESP32. Ao final, você terá uma visão completa das opções disponíveis e entenderá como escolher a abordagem ideal para o seu projeto.</p>



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



<h2 class="wp-block-heading">Entendendo as Funções de Controle Crítico no FreeRTOS</h2>



<p class="wp-block-paragraph">Ao trabalhar com sistemas multicore, como o ESP32, é fundamental garantir que determinados trechos de código sejam executados de forma atômica, ou seja, sem interrupções e sem acesso simultâneo por outro núcleo ou tarefa. O FreeRTOS fornece diversas ferramentas para isso, e nesta seção abordaremos três delas: <code>vPortCPUInitializeMutex</code>, <code>portENTER_CRITICAL</code> e <code>portEXIT_CRITICAL</code>.</p>



<h3 class="wp-block-heading">vPortCPUInitializeMutex</h3>



<p class="wp-block-paragraph">A função <code>vPortCPUInitializeMutex</code> é utilizada para inicializar mutexes que podem ser acessados de forma segura entre múltiplos núcleos. Essa função é essencial para garantir que um recurso seja utilizado por apenas uma tarefa de cada vez, independentemente do núcleo em execução.</p>



<h4 class="wp-block-heading">Exemplo de uso:</h4>



<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" data-code="#include &quot;freertos/FreeRTOS.h&quot;&lt;br&gt;#include &quot;freertos/task.h&quot;
#include &quot;freertos/semphr.h&quot;

portMUX_TYPE myMutex = portMUX_INITIALIZER_UNLOCKED;

void task1(void *pvParameters) {
    while (true) {
            portENTER_CRITICAL(&amp;myMutex);     // Entra na seção crítica
            printf(&quot;Tarefa 1 está executando em núcleo %d\n&quot;, xPortGetCoreID());
            portEXIT_CRITICAL(&amp;myMutex);      // Sai da seção crítica
            vTaskDelay(100 / portTICK_PERIOD_MS);
    }
}

void app_main() {
    vPortCPUInitializeMutex(&amp;myMutex); // Inicializa o mutex para controle multicore
    
    xTaskCreatePinnedToCore(task1, &quot;Task1&quot;, 2048, NULL, 1, NULL, 0);
}" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><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: #ECEFF4">&quot;</span><span style="color: #A3BE8C">freertos/FreeRTOS.h</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9">br</span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">freertos/task.h</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">freertos/semphr.h</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">portMUX_TYPE</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">myMutex</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">portMUX_INITIALIZER_UNLOCKED</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">task1</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 style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">while</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">true</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">portENTER_CRITICAL</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">myMutex</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">     </span><span style="color: #616E88">// Entra na seção crítica</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">Tarefa 1 está executando em núcleo %d</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">xPortGetCoreID</span><span style="color: #D8DEE9FF">())</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">portEXIT_CRITICAL</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">myMutex</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">      </span><span style="color: #616E88">// Sai da seção crítica</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">vTaskDelay</span><span style="color: #D8DEE9FF">(</span><span style="color: #B48EAD">100</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">portTICK_PERIOD_MS</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">app_main</span><span style="color: #D8DEE9FF">() </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">vPortCPUInitializeMutex</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">myMutex</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// Inicializa o mutex para controle multicore</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">xTaskCreatePinnedToCore</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">task1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Task1</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2048</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span></code></pre></div>



<h3 class="wp-block-heading">portENTER_CRITICAL e portEXIT_CRITICAL</h3>



<p class="wp-block-paragraph">As funções <code>portENTER_CRITICAL</code> e <code>portEXIT_CRITICAL</code> são usadas para proteger seções críticas de código, desativando interrupções e garantindo que nenhum outro código ou núcleo interfira enquanto a seção crítica é executada.</p>



<h4 class="wp-block-heading">Exemplo de uso:</h4>



<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" data-code="portMUX_TYPE criticalMux = portMUX_INITIALIZER_UNLOCKED;

void task2(void *pvParameters) {
    while (true) {
        portENTER_CRITICAL(&amp;criticalMux);
        // Código que deve ser executado sem interferências
        printf(&quot;Tarefa 2 executando em núcleo %d\n&quot;, xPortGetCoreID());
        portEXIT_CRITICAL(&amp;criticalMux);
        vTaskDelay(200 / portTICK_PERIOD_MS);
    }
}

void app_main() {
    xTaskCreatePinnedToCore(task2, &quot;Task2&quot;, 2048, NULL, 1, NULL, 1);
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><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">portMUX_TYPE</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">criticalMux</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">portMUX_INITIALIZER_UNLOCKED</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">task2</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 style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">while</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">true</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">portENTER_CRITICAL</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">criticalMux</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">        </span><span style="color: #616E88">// Código que deve ser executado sem interferências</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">Tarefa 2 executando em núcleo %d</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">xPortGetCoreID</span><span style="color: #D8DEE9FF">())</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">portEXIT_CRITICAL</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">criticalMux</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: #B48EAD">200</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">portTICK_PERIOD_MS</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">app_main</span><span style="color: #D8DEE9FF">() </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">xTaskCreatePinnedToCore</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">task2</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Task2</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2048</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</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>



<h3 class="wp-block-heading">Implicações do Uso no Contexto Multicore</h3>



<ul class="wp-block-list">
<li><strong>Desempenho:</strong> Desativar interrupções pode causar atrasos, especialmente em sistemas com alta carga.</li>



<li><strong>Concorrência:</strong> Garantir acesso exclusivo evita condições de corrida (race conditions), mas deve ser usado com cuidado para não causar deadlocks.</li>



<li><strong>Multicore:</strong> No ESP32, essas funções garantem consistência ao sincronizar tarefas entre os dois núcleos, mas o uso excessivo pode prejudicar o desempenho.</li>
</ul>



<p class="wp-block-paragraph">Nesta seção, exploramos como essas funções permitem gerenciar acesso a recursos em um sistema multicore. Na próxima seção, faremos uma comparação entre essas abordagens e a diretiva <code>atomic</code> do C.</p>



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



<h2 class="wp-block-heading">Comparação com a Diretiva <code>atomic</code> do C</h2>



<p class="wp-block-paragraph">A diretiva <code>atomic</code>, introduzida no padrão C11, é uma alternativa moderna para lidar com operações atômicas. Ela oferece uma abordagem mais direta para certas tarefas em sistemas embarcados e multicore, como o ESP32. Nesta seção, compararemos as funções de controle crítico do FreeRTOS com a diretiva <code>atomic</code>, discutindo suas vantagens, limitações e melhores práticas.</p>



<h3 class="wp-block-heading">O Que é a Diretiva <code>atomic</code>?</h3>



<p class="wp-block-paragraph">A diretiva <code>atomic</code> permite realizar operações em variáveis de forma atômica, sem a necessidade de bloqueios explícitos ou desativação de interrupções. Isso é especialmente útil para incrementar, decrementar ou alterar valores compartilhados entre tarefas ou núcleos.</p>



<h4 class="wp-block-heading">Exemplo de uso com <code>atomic</code>:</h4>



<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" data-code="#include <stdatomic.h&gt;

atomic_int sharedCounter = 0;

void task1(void *pvParameters) {
    while (true) {
        atomic_fetch_add(&amp;sharedCounter, 1); // Incrementa de forma atômica
        printf(&quot;Tarefa 1 incrementou o contador: %d\n&quot;, sharedCounter);
        vTaskDelay(100 / portTICK_PERIOD_MS);
    }
}

void task2(void *pvParameters) {
    while (true) {
        atomic_fetch_sub(&amp;sharedCounter, 1); // Decrementa de forma atômica
        printf(&quot;Tarefa 2 decrementou o contador: %d\n&quot;, sharedCounter);
        vTaskDelay(150 / portTICK_PERIOD_MS);
    }
}

void app_main() {
    xTaskCreate(task1, &quot;Task1&quot;, 2048, NULL, 1, NULL);
    xTaskCreate(task2, &quot;Task2&quot;, 2048, NULL, 1, NULL);
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><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">stdatomic</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">atomic_int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">sharedCounter</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: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">task1</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 style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">while</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">true</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">atomic_fetch_add</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">sharedCounter</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// Incrementa de forma atômica</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">Tarefa 1 incrementou o contador: %d</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">sharedCounter</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: #B48EAD">100</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">portTICK_PERIOD_MS</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">task2</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 style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">while</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">true</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">atomic_fetch_sub</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">sharedCounter</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// Decrementa de forma atômica</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">Tarefa 2 decrementou o contador: %d</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">sharedCounter</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: #B48EAD">150</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">portTICK_PERIOD_MS</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">app_main</span><span style="color: #D8DEE9FF">() </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">xTaskCreate</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">task1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Task1</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2048</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">xTaskCreate</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">task2</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Task2</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2048</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</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>



<h3 class="wp-block-heading">Comparação com Controle Crítico no FreeRTOS</h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th><strong>Aspecto</strong></th><th><strong>Funções do FreeRTOS</strong></th><th><strong>Diretiva <code>atomic</code></strong></th></tr></thead><tbody><tr><td><strong>Complexidade</strong></td><td>Requer inicialização de mutex e controle manual</td><td>Mais simples, direto no código</td></tr><tr><td><strong>Escopo</strong></td><td>Abrange qualquer tipo de recurso ou código</td><td>Limitado a variáveis</td></tr><tr><td><strong>Desempenho</strong></td><td>Pode ser mais lento devido ao bloqueio e desbloqueio</td><td>Geralmente mais rápido para variáveis</td></tr><tr><td><strong>Compatibilidade</strong></td><td>Específico do FreeRTOS</td><td>Requer suporte do compilador (C11)</td></tr><tr><td><strong>Multicore</strong></td><td>Sincroniza entre núcleos com controle explícito</td><td>Sincronização implícita</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">Quando Usar Cada Abordagem?</h3>



<ol class="wp-block-list">
<li><strong>Diretiva <code>atomic</code>:</strong>
<ul class="wp-block-list">
<li>Operações simples em variáveis, como incrementos e decrementos.</li>



<li>Cenários em que o desempenho é crítico e o suporte a C11 está garantido.</li>
</ul>
</li>



<li><strong>Funções do FreeRTOS:</strong>
<ul class="wp-block-list">
<li>Controle de acesso a recursos complexos, como periféricos ou blocos de código.</li>



<li>Garantia de exclusividade entre tarefas e núcleos.</li>
</ul>
</li>
</ol>



<h3 class="wp-block-heading">Exemplo Combinando Abordagens</h3>



<p class="wp-block-paragraph">É possível usar ambas as abordagens em um mesmo projeto, dependendo do tipo de recurso sendo protegido.</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" data-code="atomic_int sharedCounter = 0;
portMUX_TYPE criticalMux = portMUX_INITIALIZER_UNLOCKED;

void task3(void *pvParameters) {
    while (true) {
        portENTER_CRITICAL(&amp;criticalMux);
        atomic_fetch_add(&amp;sharedCounter, 1);
        printf(&quot;Task3 executando com valor atômico: %d\n&quot;, sharedCounter);
        portEXIT_CRITICAL(&amp;criticalMux);
        vTaskDelay(200 / portTICK_PERIOD_MS);
    }
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><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">atomic_int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">sharedCounter</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: #D8DEE9">portMUX_TYPE</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">criticalMux</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">portMUX_INITIALIZER_UNLOCKED</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">task3</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 style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">while</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">true</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">portENTER_CRITICAL</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">criticalMux</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">atomic_fetch_add</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">sharedCounter</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</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">Task3 executando com valor atômico: %d</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">sharedCounter</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">portEXIT_CRITICAL</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">criticalMux</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: #B48EAD">200</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">portTICK_PERIOD_MS</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>



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



<h2 class="wp-block-heading">Outros Métodos de Sincronização no FreeRTOS</h2>



<p class="wp-block-paragraph">Além das funções de controle crítico e da diretiva <code>atomic</code>, o FreeRTOS oferece uma ampla gama de ferramentas para gerenciar a sincronização em sistemas embarcados multicore, como semáforos, mutexes e grupos de eventos. Nesta seção, abordaremos esses métodos, explicando seu funcionamento, vantagens e situações ideais de uso.</p>



<h3 class="wp-block-heading">1. Semáforos</h3>



<p class="wp-block-paragraph">Os semáforos são usados para sinalizar eventos ou gerenciar o acesso a recursos compartilhados. Eles podem ser binários (simples) ou de contagem (que permite múltiplos sinais).</p>



<h4 class="wp-block-heading">Exemplo: Semáforo Binário</h4>



<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" data-code="#include &quot;freertos/FreeRTOS.h&quot;
#include &quot;freertos/task.h&quot;
#include &quot;freertos/semphr.h&quot;

SemaphoreHandle_t binarySemaphore;

void producerTask(void *pvParameters) {
    while (true) {
        printf(&quot;Produzindo um evento\n&quot;);
        xSemaphoreGive(binarySemaphore); // Sinaliza que o recurso está disponível
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

void consumerTask(void *pvParameters) {
    while (true) {
        if (xSemaphoreTake(binarySemaphore, portMAX_DELAY)) { // Aguarda o sinal
            printf(&quot;Consumindo o evento\n&quot;);
        }
    }
}

void app_main() {
    binarySemaphore = xSemaphoreCreateBinary();
    xTaskCreate(producerTask, &quot;Producer&quot;, 2048, NULL, 1, NULL);
    xTaskCreate(consumerTask, &quot;Consumer&quot;, 2048, NULL, 1, NULL);
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><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: #ECEFF4">&quot;</span><span style="color: #A3BE8C">freertos/FreeRTOS.h</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">freertos/task.h</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">freertos/semphr.h</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">SemaphoreHandle_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">binarySemaphore</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">producerTask</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 style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">while</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">true</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">Produzindo um evento</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">xSemaphoreGive</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">binarySemaphore</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// Sinaliza que o recurso está disponível</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">vTaskDelay</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: #D8DEE9">portTICK_PERIOD_MS</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">consumerTask</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 style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">while</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">true</span><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">xSemaphoreTake</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">binarySemaphore</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: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// Aguarda o sinal</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">Consumindo o evento</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</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>
<span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">app_main</span><span style="color: #D8DEE9FF">() </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">binarySemaphore</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">xSemaphoreCreateBinary</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">xTaskCreate</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">producerTask</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Producer</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2048</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">xTaskCreate</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">consumerTask</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Consumer</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2048</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</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>



<h3 class="wp-block-heading">2. Mutexes</h3>



<p class="wp-block-paragraph">Os mutexes (Mutual Exclusion) são utilizados para garantir acesso exclusivo a um recurso. Diferente de semáforos, eles podem detectar e evitar inversões de prioridade.</p>



<h4 class="wp-block-heading">Exemplo: Uso de Mutex</h4>



<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" data-code="SemaphoreHandle_t resourceMutex;

void writerTask(void *pvParameters) {
    while (true) {
        if (xSemaphoreTake(resourceMutex, portMAX_DELAY)) {
            printf(&quot;Tarefa escrevendo no recurso\n&quot;);
            vTaskDelay(500 / portTICK_PERIOD_MS);
            xSemaphoreGive(resourceMutex);
        }
    }
}

void readerTask(void *pvParameters) {
    while (true) {
        if (xSemaphoreTake(resourceMutex, portMAX_DELAY)) {
            printf(&quot;Tarefa lendo o recurso\n&quot;);
            vTaskDelay(300 / portTICK_PERIOD_MS);
            xSemaphoreGive(resourceMutex);
        }
    }
}

void app_main() {
    resourceMutex = xSemaphoreCreateMutex();
    xTaskCreate(writerTask, &quot;Writer&quot;, 2048, NULL, 1, NULL);
    xTaskCreate(readerTask, &quot;Reader&quot;, 2048, NULL, 1, NULL);
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><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">SemaphoreHandle_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">resourceMutex</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">writerTask</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 style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">while</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">true</span><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">xSemaphoreTake</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">resourceMutex</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: #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">Tarefa escrevendo no recurso</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</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: #B48EAD">500</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">portTICK_PERIOD_MS</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">xSemaphoreGive</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">resourceMutex</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>
<span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">readerTask</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 style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">while</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">true</span><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">xSemaphoreTake</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">resourceMutex</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: #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">Tarefa lendo o recurso</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</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: #B48EAD">300</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">portTICK_PERIOD_MS</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">xSemaphoreGive</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">resourceMutex</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>
<span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">app_main</span><span style="color: #D8DEE9FF">() </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">resourceMutex</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">xSemaphoreCreateMutex</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">xTaskCreate</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">writerTask</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Writer</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2048</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">xTaskCreate</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">readerTask</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Reader</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2048</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</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>



<h3 class="wp-block-heading">3. Grupos de Eventos</h3>



<p class="wp-block-paragraph">Os grupos de eventos permitem sincronizar tarefas usando bits de evento. Cada tarefa pode aguardar por um ou mais bits específicos, facilitando a coordenação.</p>



<h4 class="wp-block-heading">Exemplo: Grupo de Eventos</h4>



<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" data-code="#include &quot;freertos/event_groups.h&quot;

EventGroupHandle_t eventGroup;

#define EVENT_BIT_0 (1 << 0)
#define EVENT_BIT_1 (1 << 1)

void taskA(void *pvParameters) {
    while (true) {
        printf(&quot;Tarefa A sinalizando evento 0\n&quot;);
        xEventGroupSetBits(eventGroup, EVENT_BIT_0);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

void taskB(void *pvParameters) {
    while (true) {
        EventBits_t bits = xEventGroupWaitBits(eventGroup, EVENT_BIT_0 | EVENT_BIT_1, pdTRUE, pdFALSE, portMAX_DELAY);
        if (bits &amp; EVENT_BIT_0) {
            printf(&quot;Evento 0 detectado pela tarefa B\n&quot;);
        }
        if (bits &amp; EVENT_BIT_1) {
            printf(&quot;Evento 1 detectado pela tarefa B\n&quot;);
        }
    }
}

void app_main() {
    eventGroup = xEventGroupCreate();
    xTaskCreate(taskA, &quot;TaskA&quot;, 2048, NULL, 1, NULL);
    xTaskCreate(taskB, &quot;TaskB&quot;, 2048, NULL, 1, NULL);
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><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: #ECEFF4">&quot;</span><span style="color: #A3BE8C">freertos/event_groups.h</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">EventGroupHandle_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">eventGroup</span><span style="color: #81A1C1">;</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: #88C0D0">EVENT_BIT_0</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">EVENT_BIT_1</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>
<span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">taskA</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 style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">while</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">true</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">Tarefa A sinalizando evento 0</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">xEventGroupSetBits</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">eventGroup</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">EVENT_BIT_0</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: #B48EAD">1000</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">portTICK_PERIOD_MS</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">taskB</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 style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">while</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">true</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">EventBits_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">bits</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">xEventGroupWaitBits</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">eventGroup</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">EVENT_BIT_0</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">|</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">EVENT_BIT_1</span><span style="color: #ECEFF4">,</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">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 style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">bits</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">EVENT_BIT_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">Evento 0 detectado pela tarefa B</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</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: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">bits</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">EVENT_BIT_1</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">Evento 1 detectado pela tarefa B</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</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>
<span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">app_main</span><span style="color: #D8DEE9FF">() </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">eventGroup</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">xEventGroupCreate</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">xTaskCreate</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">taskA</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">TaskA</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2048</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">xTaskCreate</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">taskB</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">TaskB</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2048</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</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>



<h3 class="wp-block-heading">Comparação dos Métodos</h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th><strong>Método</strong></th><th><strong>Uso Ideal</strong></th><th><strong>Vantagens</strong></th><th><strong>Desvantagens</strong></th></tr></thead><tbody><tr><td><strong>Semáforos</strong></td><td>Sinalização de eventos simples</td><td>Fácil de usar, versátil</td><td>Pode não evitar inversão de prioridade</td></tr><tr><td><strong>Mutexes</strong></td><td>Controle exclusivo de recursos</td><td>Evita inversão de prioridade</td><td>Pode causar deadlocks</td></tr><tr><td><strong>Grupos de Eventos</strong></td><td>Sincronização com múltiplos sinais</td><td>Alta flexibilidade</td><td>Maior uso de memória e complexidade</td></tr></tbody></table></figure>



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



<p class="wp-block-paragraph">Com essas ferramentas, o FreeRTOS permite uma gestão robusta de sincronização em sistemas multicore.</p>



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



<h2 class="wp-block-heading">Conclusão e Melhores Práticas</h2>



<p class="wp-block-paragraph">Neste artigo, exploramos como o FreeRTOS pode ser usado para gerenciar tarefas e recursos em sistemas multicore como o ESP32. Abordamos funções avançadas como <code>vPortCPUInitializeMutex</code>, <code>portENTER_CRITICAL</code> e <code>portEXIT_CRITICAL</code>, além de compará-las com a diretiva <code>atomic</code> do C e outros métodos de sincronização, como semáforos, mutexes e grupos de eventos.</p>



<h3 class="wp-block-heading">Principais Pontos Abordados</h3>



<ul class="wp-block-list">
<li><strong>Controle Crítico:</strong> As funções do FreeRTOS são poderosas para proteger recursos compartilhados, mas exigem um planejamento cuidadoso para evitar problemas como deadlocks e impacto no desempenho.</li>



<li><strong>Diretiva <code>atomic</code>:</strong> Uma alternativa simples e eficiente para operações em variáveis, adequada para cenários onde o suporte a C11 está disponível.</li>



<li><strong>Métodos de Sincronização:</strong> Semáforos, mutexes e grupos de eventos oferecem flexibilidade para gerenciar tarefas e recursos, permitindo projetar sistemas robustos e escaláveis.</li>
</ul>



<h3 class="wp-block-heading">Melhores Práticas no Uso do FreeRTOS no ESP32</h3>



<ol class="wp-block-list">
<li><strong>Escolha a Ferramenta Certa para Cada Situação:</strong>
<ul class="wp-block-list">
<li>Use <code>atomic</code> para operações simples em variáveis.</li>



<li>Use mutexes para controlar acesso exclusivo a recursos complexos.</li>



<li>Use semáforos e grupos de eventos para sincronização entre tarefas.</li>
</ul>
</li>



<li><strong>Evite Bloqueios Excessivos:</strong>
<ul class="wp-block-list">
<li>Limite o tempo dentro de seções críticas para minimizar atrasos.</li>



<li>Prefira abordagens não bloqueantes sempre que possível.</li>
</ul>
</li>



<li><strong>Planeje para o Contexto Multicore:</strong>
<ul class="wp-block-list">
<li>Verifique se o código é seguro para execução em múltiplos núcleos.</li>



<li>Use as ferramentas do FreeRTOS para garantir consistência e evitar condições de corrida.</li>
</ul>
</li>



<li><strong>Teste Extensivamente:</strong>
<ul class="wp-block-list">
<li>Simule cenários com alta carga para identificar possíveis falhas de sincronização.</li>



<li>Verifique o desempenho em diferentes condições para evitar gargalos.</li>
</ul>
</li>



<li><strong>Documente o Código:</strong>
<ul class="wp-block-list">
<li>Inclua comentários claros sobre o propósito de cada ferramenta usada.</li>



<li>Explique o motivo de escolhas específicas, como o uso de semáforos ou mutexes.</li>
</ul>
</li>
</ol>



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



<p class="wp-block-paragraph">Com as ferramentas apresentadas, você estará preparado para projetar sistemas confiáveis e eficientes no ESP32, aproveitando ao máximo as funcionalidades multicore do FreeRTOS.</p>



<p class="wp-block-paragraph">Esperamos que este artigo tenha sido útil e que você possa aplicá-lo em seus projetos. Caso tenha dúvidas ou sugestões, deixe seu comentário no site!</p><p>The post <a href="https://mcu.tec.br/multithreads-e-multicore/introducao-ao-freertos-no-esp32-controle-multicore-e-recursos-avancados/">Introdução ao FreeRTOS no ESP32: Controle Multicore e Recursos Avançados</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">46</post-id>	</item>
	</channel>
</rss>
