<?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>interrupções - MCU &amp; FPGA</title>
	<atom:link href="https://mcu.tec.br/tags/interrupcoes/feed/" rel="self" type="application/rss+xml" />
	<link>https://mcu.tec.br</link>
	<description>Microcontroladores &#38; FPGA</description>
	<lastBuildDate>Mon, 10 Feb 2025 20:08:44 +0000</lastBuildDate>
	<language>pt-BR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1</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>interrupções - MCU &amp; FPGA</title>
	<link>https://mcu.tec.br</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title></title>
		<link>https://mcu.tec.br/rtos/66-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=66-2</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Mon, 10 Feb 2025 19:57:35 +0000</pubDate>
				<category><![CDATA[RTOS]]></category>
		<category><![CDATA[barramento de comunicação]]></category>
		<category><![CDATA[comunicação I2C]]></category>
		<category><![CDATA[comunicação SPI]]></category>
		<category><![CDATA[controle de concorrência]]></category>
		<category><![CDATA[desenvolvimento embarcado]]></category>
		<category><![CDATA[exclusão mútua]]></category>
		<category><![CDATA[freertos]]></category>
		<category><![CDATA[interrupções]]></category>
		<category><![CDATA[microcontroladores]]></category>
		<category><![CDATA[multitarefa]]></category>
		<category><![CDATA[multitasking]]></category>
		<category><![CDATA[mutex]]></category>
		<category><![CDATA[programação em C]]></category>
		<category><![CDATA[programação embarcada]]></category>
		<category><![CDATA[rtos]]></category>
		<category><![CDATA[semáforo]]></category>
		<category><![CDATA[sincronização de tarefas]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[stm32]]></category>
		<category><![CDATA[STM32F411RE]]></category>
		<category><![CDATA[suspensão do escalonador]]></category>
		<category><![CDATA[tempo real]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=66</guid>

					<description><![CDATA[<p>A programação multitarefa traz diversos desafios, e um dos principais é a sincronização de tarefas que acessam recursos compartilhados. Quando múltiplas threads ou processos precisam interagir com os mesmos dados ou dispositivos, é essencial garantir que essa interação ocorra de forma segura, evitando condições de corrida e corrupção de dados. Para isso, três técnicas são [&#8230;]</p>
<p>The post <a href="https://mcu.tec.br/rtos/66-2/"></a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">A programação multitarefa traz diversos desafios, e um dos principais é a sincronização de tarefas que acessam recursos compartilhados. Quando múltiplas threads ou processos precisam interagir com os mesmos dados ou dispositivos, é essencial garantir que essa interação ocorra de forma segura, evitando condições de corrida e corrupção de dados.</p>



<p class="wp-block-paragraph">Para isso, três técnicas são amplamente utilizadas: <em>mutex</em>, <em>semáforos</em> e a suspensão do escalonador. Cada uma dessas abordagens tem seu melhor momento de aplicação e, se usada de maneira inadequada, pode levar a problemas de desempenho ou até mesmo a falhas difíceis de depurar. Neste artigo, exploraremos quando e como usar cada uma delas, incluindo exemplos práticos para facilitar a compreensão.</p>



<h2 class="wp-block-heading"><strong>Mutex: Exclusão Mútua para Recursos Compartilhados</strong></h2>



<p class="wp-block-paragraph">O <em>mutex</em> (mutual exclusion) é um mecanismo utilizado para garantir que apenas uma tarefa por vez tenha acesso a um recurso compartilhado. Ele funciona como um cadeado: a primeira tarefa que o adquire pode continuar a execução, enquanto as demais precisam aguardar sua liberação.</p>



<h3 class="wp-block-heading"><strong>Quando Usar Mutex</strong></h3>



<ul class="wp-block-list">
<li>Quando há um recurso que <strong>não pode ser acessado simultaneamente</strong> por mais de uma tarefa.</li>



<li>Para garantir <strong>consistência de dados</strong> ao modificar variáveis compartilhadas.</li>



<li>Em sistemas operacionais com <strong>preempção</strong> habilitada, onde uma tarefa pode ser interrompida a qualquer momento.</li>
</ul>



<h3 class="wp-block-heading"><strong>Quando Evitar Mutex</strong></h3>



<ul class="wp-block-list">
<li>Quando há <strong>altíssima concorrência</strong>, pois as tarefas podem passar muito tempo bloqueadas, reduzindo o desempenho.</li>



<li>Quando um recurso pode ser acessado de forma <strong>não exclusiva</strong>, ou seja, múltiplas tarefas podem lê-lo sem problemas.</li>



<li>Quando há risco de <strong>deadlocks</strong>, onde múltiplas tarefas ficam bloqueadas esperando a liberação de mutexes que nunca ocorrerão.</li>
</ul>



<h3 class="wp-block-heading"><strong>Exemplo de Uso de Mutex no STM32F411RE com FreeRTOS</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" data-code="#include &quot;FreeRTOS.h&quot;
#include &quot;task.h&quot;
#include &quot;semphr.h&quot;
#include &quot;stm32f4xx.h&quot;

SemaphoreHandle_t xMutex;
int shared_resource = 0;

void Task1(void *pvParameters) {
    while(1) {
         if (xSemaphoreTake(xMutex, portMAX_DELAY)) {
                    shared_resource++;
                    printf(&quot;Task1: Recurso compartilhado = %d\n&quot;, shared_resource);
                    xSemaphoreGive(xMutex);
          }
          vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

void Task2(void *pvParameters) {
    while(1) {
            if (xSemaphoreTake(xMutex, portMAX_DELAY)) {
                      shared_resource--;
                      printf(&quot;Task2: Recurso compartilhado = %d\n&quot;, shared_resource);
                      xSemaphoreGive(xMutex);
            }
           vTaskDelay(pdMS_TO_TICKS(500));
     }
}

int main() {
    xMutex = xSemaphoreCreateMutex();
    if (xMutex != NULL) {
            xTaskCreate(Task1, &quot;Task 1&quot;, 128, NULL, 1, NULL);
            xTaskCreate(Task2, &quot;Task 2&quot;, 128, NULL, 1, NULL);
            vTaskStartScheduler()
    }
    while(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: #5E81AC; font-weight: bold">#</span><span style="color: #81A1C1">include</span><span style="color: #8FBCBB"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">FreeRTOS.h</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #5E81AC; font-weight: bold">#</span><span style="color: #81A1C1">include</span><span style="color: #8FBCBB"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">task.h</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #5E81AC; font-weight: bold">#</span><span style="color: #81A1C1">include</span><span style="color: #8FBCBB"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">semphr.h</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #5E81AC; font-weight: bold">#</span><span style="color: #81A1C1">include</span><span style="color: #8FBCBB"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">stm32f4xx.h</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #8FBCBB">SemaphoreHandle_t</span><span style="color: #D8DEE9FF"> xMutex</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">int</span><span style="color: #D8DEE9FF"> shared_resource </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: #ECEFF4">(</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: #ECEFF4">)</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: #ECEFF4">(</span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">)</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: #ECEFF4">(</span><span style="color: #88C0D0">xSemaphoreTake</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">xMutex</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> portMAX_DELAY</span><span style="color: #ECEFF4">))</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">                    shared_resource</span><span style="color: #81A1C1">++;</span></span>
<span class="line"><span style="color: #D8DEE9FF">                    </span><span style="color: #88C0D0">printf</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Task1: Recurso compartilhado = %d</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> shared_resource</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">                    </span><span style="color: #88C0D0">xSemaphoreGive</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">xMutex</span><span style="color: #ECEFF4">)</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: #88C0D0">vTaskDelay</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">pdMS_TO_TICKS</span><span style="color: #ECEFF4">(</span><span style="color: #B48EAD">1000</span><span style="color: #ECEFF4">))</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: #ECEFF4">(</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: #ECEFF4">)</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: #ECEFF4">(</span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">)</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: #ECEFF4">(</span><span style="color: #88C0D0">xSemaphoreTake</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">xMutex</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> portMAX_DELAY</span><span style="color: #ECEFF4">))</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">                      shared_resource</span><span style="color: #81A1C1">--;</span></span>
<span class="line"><span style="color: #D8DEE9FF">                      </span><span style="color: #88C0D0">printf</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Task2: Recurso compartilhado = %d</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> shared_resource</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">                      </span><span style="color: #88C0D0">xSemaphoreGive</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">xMutex</span><span style="color: #ECEFF4">)</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: #88C0D0">vTaskDelay</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">pdMS_TO_TICKS</span><span style="color: #ECEFF4">(</span><span style="color: #B48EAD">500</span><span style="color: #ECEFF4">))</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">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">main</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    xMutex </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">xSemaphoreCreateMutex</span><span style="color: #ECEFF4">()</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: #ECEFF4">(</span><span style="color: #D8DEE9FF">xMutex </span><span style="color: #81A1C1">!=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">NULL</span><span style="color: #ECEFF4">)</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: #ECEFF4">(</span><span style="color: #D8DEE9FF">Task1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Task 1</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">128</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">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: #81A1C1">NULL</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">xTaskCreate</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">Task2</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Task 2</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">128</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">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: #81A1C1">NULL</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">vTaskStartScheduler</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: #D8DEE9FF">    </span><span style="color: #81A1C1">while</span><span style="color: #ECEFF4">(</span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span></code></pre></div>



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



<h2 class="wp-block-heading"><strong>Semáforos: Controle de Fluxo e Contagem de Recursos</strong></h2>



<p class="wp-block-paragraph">Os <em>semáforos</em> são estruturas mais flexíveis que os mutexes e podem ser usados para diferentes propósitos. Eles operam com um contador interno, que pode permitir múltiplas tarefas acessando um mesmo recurso, dependendo da configuração.</p>



<h3 class="wp-block-heading"><strong>Quando Usar Semáforos</strong></h3>



<ul class="wp-block-list">
<li>Para <strong>controlar múltiplas instâncias</strong> de um recurso compartilhado, como um conjunto de conexões disponíveis em um servidor.</li>



<li>Para <strong>sincronizar tarefas</strong>, permitindo que uma aguarde a outra concluir uma operação antes de continuar.</li>



<li>Em sistemas embarcados onde múltiplas tarefas precisam se comunicar sem causar bloqueios desnecessários.</li>
</ul>



<h3 class="wp-block-heading"><strong>Quando Evitar Semáforos</strong></h3>



<ul class="wp-block-list">
<li>Quando há necessidade de <strong>exclusão mútua</strong>. Um semáforo mal configurado pode permitir que múltiplas tarefas acessem um recurso crítico simultaneamente.</li>



<li>Quando o código não foi planejado corretamente, podendo levar a <strong>inconsistências difíceis de depurar</strong>.</li>



<li>Quando há possibilidade de <strong>inversão de prioridade</strong>, onde tarefas de baixa prioridade podem atrasar a execução de tarefas mais importantes.</li>
</ul>



<h3 class="wp-block-heading"><strong>Exemplo de Uso de Semáforo no STM32F411RE com FreeRTOS</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" data-code="#include &quot;FreeRTOS.h&quot;
#include &quot;task.h&quot;
#include &quot;semphr.h&quot;
#include &quot;stm32f4xx.h&quot;

SemaphoreHandle_t xSemaphore;
int shared_counter = 0;

void Task1(void *pvParameters) {
    while(1) {
        if (xSemaphoreTake(xSemaphore, portMAX_DELAY)) {
            shared_counter++;
            printf(&quot;Task1: Contador = %d\n&quot;, shared_counter);
            xSemaphoreGive(xSemaphore);
        }
        vTaskDelay(pdMS_TO_TICKS(500));
    }
}

void Task2(void *pvParameters) {
    while(1) {
        if (xSemaphoreTake(xSemaphore, portMAX_DELAY)) {
            shared_counter--;
            printf(&quot;Task2: Contador = %d\n&quot;, shared_counter);
            xSemaphoreGive(xSemaphore);
        }
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

int main() {
    xSemaphore = xSemaphoreCreateBinary();
    xSemaphoreGive(xSemaphore);
    if (xSemaphore != NULL) {
        xTaskCreate(Task1, &quot;Task 1&quot;, 128, NULL, 1, NULL);
        xTaskCreate(Task2, &quot;Task 2&quot;, 128, NULL, 1, NULL);
        vTaskStartScheduler();
    }
    while(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: #5E81AC; font-weight: bold">#</span><span style="color: #81A1C1">include</span><span style="color: #8FBCBB"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">FreeRTOS.h</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #5E81AC; font-weight: bold">#</span><span style="color: #81A1C1">include</span><span style="color: #8FBCBB"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">task.h</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #5E81AC; font-weight: bold">#</span><span style="color: #81A1C1">include</span><span style="color: #8FBCBB"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">semphr.h</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #5E81AC; font-weight: bold">#</span><span style="color: #81A1C1">include</span><span style="color: #8FBCBB"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">stm32f4xx.h</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #8FBCBB">SemaphoreHandle_t</span><span style="color: #D8DEE9FF"> xSemaphore</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">int</span><span style="color: #D8DEE9FF"> shared_counter </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: #ECEFF4">(</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: #ECEFF4">)</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: #ECEFF4">(</span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">)</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: #ECEFF4">(</span><span style="color: #88C0D0">xSemaphoreTake</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">xSemaphore</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> portMAX_DELAY</span><span style="color: #ECEFF4">))</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">            shared_counter</span><span style="color: #81A1C1">++;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">printf</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Task1: Contador = %d</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> shared_counter</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">xSemaphoreGive</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">xSemaphore</span><span style="color: #ECEFF4">)</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: #88C0D0">vTaskDelay</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">pdMS_TO_TICKS</span><span style="color: #ECEFF4">(</span><span style="color: #B48EAD">500</span><span style="color: #ECEFF4">))</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: #ECEFF4">(</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: #ECEFF4">)</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: #ECEFF4">(</span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">)</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: #ECEFF4">(</span><span style="color: #88C0D0">xSemaphoreTake</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">xSemaphore</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> portMAX_DELAY</span><span style="color: #ECEFF4">))</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">            shared_counter</span><span style="color: #81A1C1">--;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">printf</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Task2: Contador = %d</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> shared_counter</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">xSemaphoreGive</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">xSemaphore</span><span style="color: #ECEFF4">)</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: #88C0D0">vTaskDelay</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">pdMS_TO_TICKS</span><span style="color: #ECEFF4">(</span><span style="color: #B48EAD">1000</span><span style="color: #ECEFF4">))</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">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">main</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    xSemaphore </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">xSemaphoreCreateBinary</span><span style="color: #ECEFF4">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">xSemaphoreGive</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">xSemaphore</span><span style="color: #ECEFF4">)</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: #ECEFF4">(</span><span style="color: #D8DEE9FF">xSemaphore </span><span style="color: #81A1C1">!=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">NULL</span><span style="color: #ECEFF4">)</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: #ECEFF4">(</span><span style="color: #D8DEE9FF">Task1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Task 1</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">128</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">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: #81A1C1">NULL</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">xTaskCreate</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">Task2</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Task 2</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">128</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">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: #81A1C1">NULL</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">vTaskStartScheduler</span><span style="color: #ECEFF4">()</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">while</span><span style="color: #ECEFF4">(</span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<h2 class="wp-block-heading"><strong>Suspensão do Escalonador: Controle Total com Custo Alto</strong></h2>



<p class="wp-block-paragraph">A suspensão do escalonador (<em>scheduler lock</em>) é uma abordagem mais extrema, onde o sistema operacional pausa a troca de tarefas, garantindo que a tarefa em execução complete seu trabalho sem interrupções.</p>



<h3 class="wp-block-heading"><strong>Quando Usar a Suspensão do Escalonador</strong></h3>



<ul class="wp-block-list">
<li>Quando uma operação crítica <strong>precisa ser executada em um curto período de tempo</strong> e <strong>não pode ser interrompida</strong>.</li>



<li>Para <strong>seções de código extremamente curtas</strong> e atômicas, onde o impacto da suspensão do escalonador é mínimo.</li>



<li>Em sistemas <em>bare-metal</em> sem suporte a mutexes ou semáforos.</li>
</ul>



<h3 class="wp-block-heading"><strong>Quando Evitar a Suspensão do Escalonador</strong></h3>



<ul class="wp-block-list">
<li>Quando há <strong>tarefas de tempo real</strong> que precisam responder rapidamente a eventos externos.</li>



<li>Se o código protegido for <strong>muito longo</strong>, pois a suspensão prolongada do escalonador pode causar degradação significativa no desempenho do sistema.</li>



<li>Em sistemas onde múltiplas CPUs são usadas, pois suspender o escalonador em um núcleo não impede que outros núcleos executem tarefas concorrentes.</li>
</ul>



<h3 class="wp-block-heading"><strong>Exemplo de Suspensão do Escalonador no STM32F411RE com FreeRTOS</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" data-code="#include &quot;FreeRTOS.h&quot;
#include &quot;task.h&quot;

void CriticalTask(void *pvParameters) {
    while(1) {
        vTaskSuspendAll(); // Suspende o escalonador
        // Código crítico
        printf(&quot;Executando tarefa crítica\n&quot;);
        xTaskResumeAll(); // Retoma o escalonador
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

int main() {
    xTaskCreate(CriticalTask, &quot;Critical Task&quot;, 128, NULL, 1, NULL);
    vTaskStartScheduler();
    while(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: #5E81AC; font-weight: bold">#</span><span style="color: #81A1C1">include</span><span style="color: #8FBCBB"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">FreeRTOS.h</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #5E81AC; font-weight: bold">#</span><span style="color: #81A1C1">include</span><span style="color: #8FBCBB"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">task.h</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">CriticalTask</span><span style="color: #ECEFF4">(</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: #ECEFF4">)</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: #ECEFF4">(</span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">vTaskSuspendAll</span><span style="color: #ECEFF4">()</span><span style="color: #81A1C1">;</span><span style="color: #616E88"> // Suspende o escalonador</span></span>
<span class="line"><span style="color: #ECEFF4">        </span><span style="color: #616E88">// Código crítico</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">printf</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Executando tarefa crítica</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">xTaskResumeAll</span><span style="color: #ECEFF4">()</span><span style="color: #81A1C1">;</span><span style="color: #616E88"> // Retoma o escalonador</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">vTaskDelay</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">pdMS_TO_TICKS</span><span style="color: #ECEFF4">(</span><span style="color: #B48EAD">1000</span><span style="color: #ECEFF4">))</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">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">main</span><span style="color: #ECEFF4">()</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: #ECEFF4">(</span><span style="color: #D8DEE9FF">CriticalTask</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Critical Task</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">128</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">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: #81A1C1">NULL</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">vTaskStartScheduler</span><span style="color: #ECEFF4">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">while</span><span style="color: #ECEFF4">(</span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<h2 class="wp-block-heading"><strong>Abordagem para Dispositivos I2C e SPI</strong></h2>



<p class="wp-block-paragraph">Os protocolos de comunicação como <strong>I2C</strong> e <strong>SPI</strong> são amplamente utilizados em sistemas embarcados para comunicação entre microcontroladores e periféricos. A abordagem correta para controle de concorrência depende do tipo de comunicação e do contexto de uso.</p>



<h3 class="wp-block-heading"><strong>I2C com Mutex no STM32F411RE</strong></h3>



<p class="wp-block-paragraph">O protocolo <strong>I2C</strong> é um barramento compartilhado onde múltiplos dispositivos podem estar conectados ao mesmo controlador. Como apenas um dispositivo pode realizar a comunicação por vez, o uso de <strong>mutex</strong> é essencial para evitar colisões entre tarefas concorrentes que tentam acessar o barramento ao mesmo tempo.</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="#include &quot;stm32f4xx_hal.h&quot;
#include &quot;FreeRTOS.h&quot;
#include &quot;semphr.h&quot;

I2C_HandleTypeDef hi2c1;
SemaphoreHandle_t i2cMutex;

void I2C_Write(uint16_t devAddress, uint8_t *data, uint16_t size) {
    if (xSemaphoreTake(i2cMutex, portMAX_DELAY)) {
        HAL_I2C_Master_Transmit(&amp;hi2c1, devAddress, data, size, HAL_MAX_DELAY);
        xSemaphoreGive(i2cMutex);
    }
}
" 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: #5E81AC; font-weight: bold">#</span><span style="color: #81A1C1">include</span><span style="color: #8FBCBB"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">stm32f4xx_hal.h</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #5E81AC; font-weight: bold">#</span><span style="color: #81A1C1">include</span><span style="color: #8FBCBB"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">FreeRTOS.h</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #5E81AC; font-weight: bold">#</span><span style="color: #81A1C1">include</span><span style="color: #8FBCBB"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">semphr.h</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">I2C_HandleTypeDef hi2c1</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #8FBCBB">SemaphoreHandle_t</span><span style="color: #D8DEE9FF"> i2cMutex</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">I2C_Write</span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">devAddress</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">uint8_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">data</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">size</span><span style="color: #ECEFF4">)</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: #ECEFF4">(</span><span style="color: #88C0D0">xSemaphoreTake</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">i2cMutex</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> portMAX_DELAY</span><span style="color: #ECEFF4">))</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">HAL_I2C_Master_Transmit</span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9FF">hi2c1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> devAddress</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> data</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> size</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> HAL_MAX_DELAY</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">xSemaphoreGive</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">i2cMutex</span><span style="color: #ECEFF4">)</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>



<h3 class="wp-block-heading"><strong>SPI com Mutex no STM32F411RE</strong></h3>



<p class="wp-block-paragraph">O protocolo <strong>SPI</strong> geralmente é mais rápido que o I2C, mas também pode sofrer de concorrência quando múltiplas tarefas tentam acessá-lo simultaneamente. O uso de <strong>mutex</strong> impede que duas tarefas interfiram uma na outra enquanto utilizam o barramento SPI.</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="#include &quot;stm32f4xx_hal.h&quot;
#include &quot;FreeRTOS.h&quot;
#include &quot;semphr.h&quot;

SPI_HandleTypeDef hspi1;
SemaphoreHandle_t spiMutex;

void SPI_Write(uint8_t *data, uint16_t size) {
    if (xSemaphoreTake(spiMutex, portMAX_DELAY)) {
        HAL_SPI_Transmit(&amp;hspi1, data, size, HAL_MAX_DELAY);
        xSemaphoreGive(spiMutex);
    }
}
" 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: #5E81AC; font-weight: bold">#</span><span style="color: #81A1C1">include</span><span style="color: #8FBCBB"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">stm32f4xx_hal.h</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #5E81AC; font-weight: bold">#</span><span style="color: #81A1C1">include</span><span style="color: #8FBCBB"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">FreeRTOS.h</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #5E81AC; font-weight: bold">#</span><span style="color: #81A1C1">include</span><span style="color: #8FBCBB"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">semphr.h</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">SPI_HandleTypeDef hspi1</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #8FBCBB">SemaphoreHandle_t</span><span style="color: #D8DEE9FF"> spiMutex</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">SPI_Write</span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">uint8_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">data</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">uint16_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">size</span><span style="color: #ECEFF4">)</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: #ECEFF4">(</span><span style="color: #88C0D0">xSemaphoreTake</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">spiMutex</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> portMAX_DELAY</span><span style="color: #ECEFF4">))</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">HAL_SPI_Transmit</span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9FF">hspi1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> data</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> size</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> HAL_MAX_DELAY</span><span style="color: #ECEFF4">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">xSemaphoreGive</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">spiMutex</span><span style="color: #ECEFF4">)</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>



<h3 class="wp-block-heading"><strong>Melhor Abordagem</strong></h3>



<ul class="wp-block-list">
<li><strong>I2C</strong>: Como é um barramento compartilhado entre múltiplos dispositivos, <strong>usar um mutex</strong> é essencial para evitar colisões.</li>



<li><strong>SPI</strong>: Em ambientes multitarefa, o <strong>uso de mutex</strong> também é recomendado para evitar que diferentes tarefas tentem acessar o mesmo barramento ao mesmo tempo.</li>



<li><strong>Semáforos</strong> podem ser usados para sincronizar eventos, como a recepção de dados em interrupções.</li>
</ul>



<p class="wp-block-paragraph">Essas práticas garantem que a comunicação com dispositivos externos ocorra de maneira segura e eficiente, sem causar falhas no sistema.</p>



<h2 class="wp-block-heading"><strong>Conclusão</strong></h2>



<p class="wp-block-paragraph">Escolher a técnica correta para o controle de concorrência é essencial para garantir a estabilidade e o desempenho de sistemas multitarefa. Como visto ao longo deste artigo:</p>



<ul class="wp-block-list">
<li><strong>Mutexes</strong> são ideais para garantir exclusão mútua, prevenindo que múltiplas tarefas modifiquem simultaneamente um mesmo recurso compartilhado.</li>



<li><strong>Semáforos</strong> são úteis tanto para controle de múltiplas instâncias de um recurso quanto para sincronização de tarefas.</li>



<li><strong>A suspensão do escalonador</strong> deve ser usada com cuidado, sendo útil apenas em situações críticas onde uma interrupção durante a execução pode causar problemas graves.</li>
</ul>



<p class="wp-block-paragraph">Quando se trata de dispositivos como <strong>I2C</strong> e <strong>SPI</strong>, a escolha de mutexes para proteger o barramento e garantir a integridade da comunicação é a abordagem mais recomendada, enquanto semáforos podem ser úteis para coordenar eventos assíncronos.</p>



<p class="wp-block-paragraph">Entender essas técnicas e aplicá-las corretamente resulta em sistemas mais eficientes, confiáveis e fáceis de manter. O uso adequado de mutexes, semáforos e a suspensão do escalonador garante que aplicações multitarefa operem de maneira fluida, sem impactos negativos na performance do sistema.</p>



<p class="wp-block-paragraph">Com isso, esperamos que este artigo tenha esclarecido as principais diferenças entre essas abordagens e ajudado a tomar decisões mais informadas no desenvolvimento de sistemas embarcados e aplicações multitarefa.</p><p>The post <a href="https://mcu.tec.br/rtos/66-2/"></a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">66</post-id>	</item>
	</channel>
</rss>
