<?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>programação em tempo real - MCU &amp; FPGA</title>
	<atom:link href="https://mcu.tec.br/tags/programacao-em-tempo-real/feed/" rel="self" type="application/rss+xml" />
	<link>https://mcu.tec.br</link>
	<description>Microcontroladores &#38; FPGA</description>
	<lastBuildDate>Wed, 07 Jan 2026 00:43:30 +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>programação em tempo real - MCU &amp; FPGA</title>
	<link>https://mcu.tec.br</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Arquitetura Orientada a Eventos no FreeRTOS</title>
		<link>https://mcu.tec.br/rtos/arquitetura-orientada-a-eventos-no-freertos/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=arquitetura-orientada-a-eventos-no-freertos</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Fri, 20 Feb 2026 17:44:13 +0000</pubDate>
				<category><![CDATA[RTOS]]></category>
		<category><![CDATA[arquitetura orientada a eventos]]></category>
		<category><![CDATA[event groups]]></category>
		<category><![CDATA[filas FreeRTOS]]></category>
		<category><![CDATA[firmware reativo]]></category>
		<category><![CDATA[freertos]]></category>
		<category><![CDATA[message buffers]]></category>
		<category><![CDATA[programação em tempo real]]></category>
		<category><![CDATA[rtos]]></category>
		<category><![CDATA[sistemas determinísticos]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[software timers]]></category>
		<category><![CDATA[stream buffers]]></category>
		<category><![CDATA[task notifications]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1057</guid>

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


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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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

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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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

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



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



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



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

    vTaskNotifyGiveFromISR(eventTaskHandle, &amp;xHigherPriorityTaskWoken);

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



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



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



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



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



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

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

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



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



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



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



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



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

void vCommTask(void *pvParameters)
{
    uint32_t events;

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

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

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

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



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



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



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



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



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



<li>Zero uso de heap</li>



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



<li>Determinismo temporal elevado</li>



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



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



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



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



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



<hr class="wp-block-separator has-alpha-channel-opacity"/><p>The post <a href="https://mcu.tec.br/rtos/arquitetura-orientada-a-eventos-no-freertos/">Arquitetura Orientada a Eventos no FreeRTOS</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1057</post-id>	</item>
		<item>
		<title>Como Criar Tarefas e Soft Timers no FreeRTOS: Guia Prático e Didático para Sistemas Embarcados</title>
		<link>https://mcu.tec.br/rtos/como-criar-tarefas-e-soft-timers-no-freertos-guia-pratico-e-didatico-para-sistemas-embarcados/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=como-criar-tarefas-e-soft-timers-no-freertos-guia-pratico-e-didatico-para-sistemas-embarcados</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Fri, 09 Jan 2026 18:45:24 +0000</pubDate>
				<category><![CDATA[RTOS]]></category>
		<category><![CDATA[arquitetura embarcada]]></category>
		<category><![CDATA[escalonador FreeRTOS]]></category>
		<category><![CDATA[event groups]]></category>
		<category><![CDATA[filas FreeRTOS]]></category>
		<category><![CDATA[freertos]]></category>
		<category><![CDATA[heap FreeRTOS]]></category>
		<category><![CDATA[prioridades de tarefas]]></category>
		<category><![CDATA[programação em tempo real]]></category>
		<category><![CDATA[RTOS embarcado]]></category>
		<category><![CDATA[soft timers FreeRTOS]]></category>
		<category><![CDATA[stack no FreeRTOS]]></category>
		<category><![CDATA[tarefas no FreeRTOS]]></category>
		<category><![CDATA[task notification]]></category>
		<category><![CDATA[Timer Service Task]]></category>
		<category><![CDATA[timers de software]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1016</guid>

					<description><![CDATA[<p>Este artigo apresenta um guia completo e didático sobre como criar e gerenciar tarefas e soft timers no FreeRTOS, explicando conceitos fundamentais de escalonamento, prioridades, dimensionamento de stack e comunicação entre timers e tarefas. Com exemplos práticos em C para microcontroladores, o conteúdo mostra como estruturar arquiteturas embarcadas reais, eficientes e escaláveis, utilizando boas práticas de projeto para evitar bloqueios, reduzir consumo de CPU e aumentar a previsibilidade temporal. Ideal para estudantes, desenvolvedores de firmware e profissionais que desejam dominar o uso do FreeRTOS em aplicações embarcadas modernas.</p>
<p>The post <a href="https://mcu.tec.br/rtos/como-criar-tarefas-e-soft-timers-no-freertos-guia-pratico-e-didatico-para-sistemas-embarcados/">Como Criar Tarefas e Soft Timers no FreeRTOS: Guia Prático e Didático para Sistemas Embarcados</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<div class="root-eb-toc-8ti67 wp-block-essential-blocks-table-of-contents"><div class="eb-parent-wrapper eb-parent-eb-toc-8ti67 "><div class="eb-toc-container eb-toc-8ti67  eb-toc-is-not-sticky eb-toc-not-collapsible eb-toc-initially-not-collapsed eb-toc-scrollToTop style-1 list-style-none" data-scroll-top="false" data-scroll-top-icon="fas fa-angle-up" data-collapsible="false" data-sticky-hide-mobile="false" data-sticky="false" data-scroll-target="scroll_to_toc" data-copy-link="false" data-editor-type="" data-hide-desktop="false" data-hide-tab="false" data-hide-mobile="false" data-itemcollapsed="false" data-highlight-scroll="false"><div class="eb-toc-header"><h2 class="eb-toc-title">Table of Contents</h2></div><div class="eb-toc-wrapper " data-headers="[{&quot;level&quot;:2,&quot;content&quot;:&quot;Conceito de Tarefas no FreeRTOS e Estrutura B\u00e1sica&quot;,&quot;text&quot;:&quot;Conceito de Tarefas no FreeRTOS e Estrutura B\u00e1sica&quot;,&quot;link&quot;:&quot;eb-table-content-0&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Assinatura de uma tarefa no FreeRTOS&quot;,&quot;text&quot;:&quot;Assinatura de uma tarefa no FreeRTOS&quot;,&quot;link&quot;:&quot;assinatura-de-uma-tarefa-no-freertos&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Cria\u00e7\u00e3o de tarefas com xTaskCreate()&quot;,&quot;text&quot;:&quot;Cria\u00e7\u00e3o de tarefas com xTaskCreate()&quot;,&quot;link&quot;:&quot;eb-table-content-2&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo pr\u00e1tico: tarefa de LED&quot;,&quot;text&quot;:&quot;Exemplo pr\u00e1tico: tarefa de LED&quot;,&quot;link&quot;:&quot;eb-table-content-3&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Estados de uma tarefa no FreeRTOS&quot;,&quot;text&quot;:&quot;Estados de uma tarefa no FreeRTOS&quot;,&quot;link&quot;:&quot;estados-de-uma-tarefa-no-freertos&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;2 \u2013 Prioridades, Stack e Boas Pr\u00e1ticas na Cria\u00e7\u00e3o de Tarefas&quot;,&quot;text&quot;:&quot;2 \u2013 Prioridades, Stack e Boas Pr\u00e1ticas na Cria\u00e7\u00e3o de Tarefas&quot;,&quot;link&quot;:&quot;eb-table-content-5&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Prioridades de tarefas&quot;,&quot;text&quot;:&quot;Prioridades de tarefas&quot;,&quot;link&quot;:&quot;prioridades-de-tarefas&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Stack de tarefas: como dimensionar corretamente&quot;,&quot;text&quot;:&quot;Stack de tarefas: como dimensionar corretamente&quot;,&quot;link&quot;:&quot;stack-de-tarefas-como-dimensionar-corretamente&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Como estimar o tamanho da stack&quot;,&quot;text&quot;:&quot;Como estimar o tamanho da stack&quot;,&quot;link&quot;:&quot;como-estimar-o-tamanho-da-stack&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Stack overflow e mecanismos de prote\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Stack overflow e mecanismos de prote\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-9&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Heap e cria\u00e7\u00e3o din\u00e2mica de tarefas&quot;,&quot;text&quot;:&quot;Heap e cria\u00e7\u00e3o din\u00e2mica de tarefas&quot;,&quot;link&quot;:&quot;eb-table-content-10&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Boas pr\u00e1ticas fundamentais&quot;,&quot;text&quot;:&quot;Boas pr\u00e1ticas fundamentais&quot;,&quot;link&quot;:&quot;eb-table-content-11&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Soft Timers no FreeRTOS: Conceito, Arquitetura e Diferen\u00e7as para Tarefas&quot;,&quot;text&quot;:&quot;Soft Timers no FreeRTOS: Conceito, Arquitetura e Diferen\u00e7as para Tarefas&quot;,&quot;link&quot;:&quot;eb-table-content-12&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;O que \u00e9 um Soft Timer&quot;,&quot;text&quot;:&quot;O que \u00e9 um Soft Timer&quot;,&quot;link&quot;:&quot;eb-table-content-13&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Timer Service Task&quot;,&quot;text&quot;:&quot;Timer Service Task&quot;,&quot;link&quot;:&quot;timer-service-task&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Tipos de Soft Timers&quot;,&quot;text&quot;:&quot;Tipos de Soft Timers&quot;,&quot;link&quot;:&quot;tipos-de-soft-timers&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Cria\u00e7\u00e3o de um Soft Timer&quot;,&quot;text&quot;:&quot;Cria\u00e7\u00e3o de um Soft Timer&quot;,&quot;link&quot;:&quot;eb-table-content-16&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Exemplo pr\u00e1tico: Soft Timer peri\u00f3dico&quot;,&quot;text&quot;:&quot;Exemplo pr\u00e1tico: Soft Timer peri\u00f3dico&quot;,&quot;link&quot;:&quot;eb-table-content-17&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;O que N\u00c3O fazer em callbacks de Soft Timer&quot;,&quot;text&quot;:&quot;O que N\u00c3O fazer em callbacks de Soft Timer&quot;,&quot;link&quot;:&quot;eb-table-content-18&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Compara\u00e7\u00e3o: Tarefa vs Soft Timer&quot;,&quot;text&quot;:&quot;Compara\u00e7\u00e3o: Tarefa vs Soft Timer&quot;,&quot;link&quot;:&quot;eb-table-content-19&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Comunica\u00e7\u00e3o entre Soft Timers e Tarefas no FreeRTOS&quot;,&quot;text&quot;:&quot;Comunica\u00e7\u00e3o entre Soft Timers e Tarefas no FreeRTOS&quot;,&quot;link&quot;:&quot;eb-table-content-20&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Comunica\u00e7\u00e3o usando Task Notifications&quot;,&quot;text&quot;:&quot;Comunica\u00e7\u00e3o usando Task Notifications&quot;,&quot;link&quot;:&quot;eb-table-content-21&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Callback do timer notificando uma tarefa&quot;,&quot;text&quot;:&quot;Callback do timer notificando uma tarefa&quot;,&quot;link&quot;:&quot;callback-do-timer-notificando-uma-tarefa&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Tarefa aguardando a notifica\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Tarefa aguardando a notifica\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-23&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Comunica\u00e7\u00e3o usando Filas (Queues)&quot;,&quot;text&quot;:&quot;Comunica\u00e7\u00e3o usando Filas (Queues)&quot;,&quot;link&quot;:&quot;eb-table-content-24&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Callback enviando dados para a fila&quot;,&quot;text&quot;:&quot;Callback enviando dados para a fila&quot;,&quot;link&quot;:&quot;callback-enviando-dados-para-a-fila&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Tarefa consumindo a fila&quot;,&quot;text&quot;:&quot;Tarefa consumindo a fila&quot;,&quot;link&quot;:&quot;tarefa-consumindo-a-fila&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Comunica\u00e7\u00e3o usando Event Groups&quot;,&quot;text&quot;:&quot;Comunica\u00e7\u00e3o usando Event Groups&quot;,&quot;link&quot;:&quot;eb-table-content-27&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Callback setando um evento&quot;,&quot;text&quot;:&quot;Callback setando um evento&quot;,&quot;link&quot;:&quot;callback-setando-um-evento&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Tarefa aguardando o evento&quot;,&quot;text&quot;:&quot;Tarefa aguardando o evento&quot;,&quot;link&quot;:&quot;tarefa-aguardando-o-evento&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Compara\u00e7\u00e3o entre mecanismos&quot;,&quot;text&quot;:&quot;Compara\u00e7\u00e3o entre mecanismos&quot;,&quot;link&quot;:&quot;eb-table-content-30&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Padr\u00e3o arquitetural recomendado&quot;,&quot;text&quot;:&quot;Padr\u00e3o arquitetural recomendado&quot;,&quot;link&quot;:&quot;eb-table-content-31&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;5 \u2013 Exemplo Completo: Arquitetura Real com Tarefas e Soft Timers no FreeRTOS&quot;,&quot;text&quot;:&quot;5 \u2013 Exemplo Completo: Arquitetura Real com Tarefas e Soft Timers no FreeRTOS&quot;,&quot;link&quot;:&quot;5-exemplo-completo-arquitetura-real-com-tarefas-e-soft-timers-no-freertos&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Cen\u00e1rio proposto&quot;,&quot;text&quot;:&quot;Cen\u00e1rio proposto&quot;,&quot;link&quot;:&quot;eb-table-content-33&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Diagrama l\u00f3gico da arquitetura&quot;,&quot;text&quot;:&quot;Diagrama l\u00f3gico da arquitetura&quot;,&quot;link&quot;:&quot;eb-table-content-34&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;C\u00f3digo completo do exemplo&quot;,&quot;text&quot;:&quot;C\u00f3digo completo do exemplo&quot;,&quot;link&quot;:&quot;eb-table-content-35&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Handles globais&quot;,&quot;text&quot;:&quot;Handles globais&quot;,&quot;link&quot;:&quot;handles-globais&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Callback do Soft Timer&quot;,&quot;text&quot;:&quot;Callback do Soft Timer&quot;,&quot;link&quot;:&quot;callback-do-soft-timer&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Tarefa de processamento&quot;,&quot;text&quot;:&quot;Tarefa de processamento&quot;,&quot;link&quot;:&quot;tarefa-de-processamento&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Inicializa\u00e7\u00e3o do sistema&quot;,&quot;text&quot;:&quot;Inicializa\u00e7\u00e3o do sistema&quot;,&quot;link&quot;:&quot;eb-table-content-39&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;An\u00e1lise t\u00e9cnica da solu\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;An\u00e1lise t\u00e9cnica da solu\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-40&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Quando N\u00c3O usar Soft Timers&quot;,&quot;text&quot;:&quot;Quando N\u00c3O usar Soft Timers&quot;,&quot;link&quot;:&quot;eb-table-content-41&quot;}]" data-visible="[true,true,true,true,true,true]" data-delete-headers="[{&quot;label&quot;:&quot;Conceito de Tarefas no FreeRTOS e Estrutura B\u00e1sica&quot;,&quot;value&quot;:&quot;conceito-de-tarefas-no-freertos-e-estrutura-b\u00e1sica&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Assinatura de uma tarefa no FreeRTOS&quot;,&quot;value&quot;:&quot;assinatura-de-uma-tarefa-no-freertos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Cria\u00e7\u00e3o de tarefas com xTaskCreate()&quot;,&quot;value&quot;:&quot;cria\u00e7\u00e3o-de-tarefas-com-xtaskcreate&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo pr\u00e1tico: tarefa de LED&quot;,&quot;value&quot;:&quot;exemplo-pr\u00e1tico-tarefa-de-led&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Estados de uma tarefa no FreeRTOS&quot;,&quot;value&quot;:&quot;estados-de-uma-tarefa-no-freertos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2 \u2013 Prioridades, Stack e Boas Pr\u00e1ticas na Cria\u00e7\u00e3o de Tarefas&quot;,&quot;value&quot;:&quot;2-prioridades-stack-e-boas-pr\u00e1ticas-na-cria\u00e7\u00e3o-de-tarefas&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Prioridades de tarefas&quot;,&quot;value&quot;:&quot;prioridades-de-tarefas&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Stack de tarefas: como dimensionar corretamente&quot;,&quot;value&quot;:&quot;stack-de-tarefas-como-dimensionar-corretamente&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Como estimar o tamanho da stack&quot;,&quot;value&quot;:&quot;como-estimar-o-tamanho-da-stack&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Stack overflow e mecanismos de prote\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;stack-overflow-e-mecanismos-de-prote\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Heap e cria\u00e7\u00e3o din\u00e2mica de tarefas&quot;,&quot;value&quot;:&quot;heap-e-cria\u00e7\u00e3o-din\u00e2mica-de-tarefas&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Boas pr\u00e1ticas fundamentais&quot;,&quot;value&quot;:&quot;boas-pr\u00e1ticas-fundamentais&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Soft Timers no FreeRTOS: Conceito, Arquitetura e Diferen\u00e7as para Tarefas&quot;,&quot;value&quot;:&quot;soft-timers-no-freertos-conceito-arquitetura-e-diferen\u00e7as-para-tarefas&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;O que \u00e9 um Soft Timer&quot;,&quot;value&quot;:&quot;o-que-\u00e9-um-soft-timer&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Timer Service Task&quot;,&quot;value&quot;:&quot;timer-service-task&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Tipos de Soft Timers&quot;,&quot;value&quot;:&quot;tipos-de-soft-timers&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Cria\u00e7\u00e3o de um Soft Timer&quot;,&quot;value&quot;:&quot;cria\u00e7\u00e3o-de-um-soft-timer&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo pr\u00e1tico: Soft Timer peri\u00f3dico&quot;,&quot;value&quot;:&quot;exemplo-pr\u00e1tico-soft-timer-peri\u00f3dico&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;O que N\u00c3O fazer em callbacks de Soft Timer&quot;,&quot;value&quot;:&quot;o-que-n\u00e3o-fazer-em-callbacks-de-soft-timer&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Compara\u00e7\u00e3o: Tarefa vs Soft Timer&quot;,&quot;value&quot;:&quot;compara\u00e7\u00e3o-tarefa-vs-soft-timer&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Comunica\u00e7\u00e3o entre Soft Timers e Tarefas no FreeRTOS&quot;,&quot;value&quot;:&quot;comunica\u00e7\u00e3o-entre-soft-timers-e-tarefas-no-freertos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Comunica\u00e7\u00e3o usando Task Notifications&quot;,&quot;value&quot;:&quot;comunica\u00e7\u00e3o-usando-task-notifications&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Callback do timer notificando uma tarefa&quot;,&quot;value&quot;:&quot;callback-do-timer-notificando-uma-tarefa&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Tarefa aguardando a notifica\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;tarefa-aguardando-a-notifica\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Comunica\u00e7\u00e3o usando Filas (Queues)&quot;,&quot;value&quot;:&quot;comunica\u00e7\u00e3o-usando-filas-queues&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Callback enviando dados para a fila&quot;,&quot;value&quot;:&quot;callback-enviando-dados-para-a-fila&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Tarefa consumindo a fila&quot;,&quot;value&quot;:&quot;tarefa-consumindo-a-fila&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Comunica\u00e7\u00e3o usando Event Groups&quot;,&quot;value&quot;:&quot;comunica\u00e7\u00e3o-usando-event-groups&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Callback setando um evento&quot;,&quot;value&quot;:&quot;callback-setando-um-evento&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Tarefa aguardando o evento&quot;,&quot;value&quot;:&quot;tarefa-aguardando-o-evento&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Compara\u00e7\u00e3o entre mecanismos&quot;,&quot;value&quot;:&quot;compara\u00e7\u00e3o-entre-mecanismos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Padr\u00e3o arquitetural recomendado&quot;,&quot;value&quot;:&quot;padr\u00e3o-arquitetural-recomendado&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5 \u2013 Exemplo Completo: Arquitetura Real com Tarefas e Soft Timers no FreeRTOS&quot;,&quot;value&quot;:&quot;5-exemplo-completo-arquitetura-real-com-tarefas-e-soft-timers-no-freertos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Cen\u00e1rio proposto&quot;,&quot;value&quot;:&quot;cen\u00e1rio-proposto&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Diagrama l\u00f3gico da arquitetura&quot;,&quot;value&quot;:&quot;diagrama-l\u00f3gico-da-arquitetura&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;C\u00f3digo completo do exemplo&quot;,&quot;value&quot;:&quot;c\u00f3digo-completo-do-exemplo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Handles globais&quot;,&quot;value&quot;:&quot;handles-globais&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Callback do Soft Timer&quot;,&quot;value&quot;:&quot;callback-do-soft-timer&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Tarefa de processamento&quot;,&quot;value&quot;:&quot;tarefa-de-processamento&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Inicializa\u00e7\u00e3o do sistema&quot;,&quot;value&quot;:&quot;inicializa\u00e7\u00e3o-do-sistema&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;An\u00e1lise t\u00e9cnica da solu\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;an\u00e1lise-t\u00e9cnica-da-solu\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Quando N\u00c3O usar Soft Timers&quot;,&quot;value&quot;:&quot;quando-n\u00e3o-usar-soft-timers&quot;,&quot;isDelete&quot;:false}]" data-smooth="true" data-top-offset=""><div class="eb-toc__list-wrap"><ul class="eb-toc__list"><li><a href="#eb-table-content-0">Conceito de Tarefas no FreeRTOS e Estrutura Básica</a><ul class="eb-toc__list"><li><a href="#assinatura-de-uma-tarefa-no-freertos">Assinatura de uma tarefa no FreeRTOS</a><li><a href="#eb-table-content-2">Criação de tarefas com xTaskCreate()</a><li><a href="#eb-table-content-3">Exemplo prático: tarefa de LED</a><li><a href="#estados-de-uma-tarefa-no-freertos">Estados de uma tarefa no FreeRTOS</a></li></ul><li><a href="#eb-table-content-5">2 – Prioridades, Stack e Boas Práticas na Criação de Tarefas</a><ul class="eb-toc__list"><li><a href="#prioridades-de-tarefas">Prioridades de tarefas</a><li><a href="#stack-de-tarefas-como-dimensionar-corretamente">Stack de tarefas: como dimensionar corretamente</a><ul class="eb-toc__list"><li><a href="#como-estimar-o-tamanho-da-stack">Como estimar o tamanho da stack</a></li></ul><li><a href="#eb-table-content-9">Stack overflow e mecanismos de proteção</a><li><a href="#eb-table-content-10">Heap e criação dinâmica de tarefas</a><li><a href="#eb-table-content-11">Boas práticas fundamentais</a></li></ul><li><a href="#eb-table-content-12">Soft Timers no FreeRTOS: Conceito, Arquitetura e Diferenças para Tarefas</a><ul class="eb-toc__list"><li><a href="#eb-table-content-13">O que é um Soft Timer</a><li><a href="#timer-service-task">Timer Service Task</a><li><a href="#tipos-de-soft-timers">Tipos de Soft Timers</a><li><a href="#eb-table-content-16">Criação de um Soft Timer</a><li><a href="#eb-table-content-17">Exemplo prático: Soft Timer periódico</a><li><a href="#eb-table-content-18">O que NÃO fazer em callbacks de Soft Timer</a><li><a href="#eb-table-content-19">Comparação: Tarefa vs Soft Timer</a></li></ul><li><a href="#eb-table-content-20">Comunicação entre Soft Timers e Tarefas no FreeRTOS</a><ul class="eb-toc__list"><li><a href="#eb-table-content-21">Comunicação usando Task Notifications</a><ul class="eb-toc__list"><li><a href="#callback-do-timer-notificando-uma-tarefa">Callback do timer notificando uma tarefa</a><li><a href="#eb-table-content-23">Tarefa aguardando a notificação</a></li></ul><li><a href="#eb-table-content-24">Comunicação usando Filas (Queues)</a><ul class="eb-toc__list"><li><a href="#callback-enviando-dados-para-a-fila">Callback enviando dados para a fila</a><li><a href="#tarefa-consumindo-a-fila">Tarefa consumindo a fila</a></li></ul><li><a href="#eb-table-content-27">Comunicação usando Event Groups</a><ul class="eb-toc__list"><li><a href="#callback-setando-um-evento">Callback setando um evento</a><li><a href="#tarefa-aguardando-o-evento">Tarefa aguardando o evento</a></li></ul><li><a href="#eb-table-content-30">Comparação entre mecanismos</a><li><a href="#eb-table-content-31">Padrão arquitetural recomendado</a></li></ul><li><a href="#5-exemplo-completo-arquitetura-real-com-tarefas-e-soft-timers-no-freertos">5 – Exemplo Completo: Arquitetura Real com Tarefas e Soft Timers no FreeRTOS</a><ul class="eb-toc__list"><li><a href="#eb-table-content-33">Cenário proposto</a><li><a href="#eb-table-content-34">Diagrama lógico da arquitetura</a><li><a href="#eb-table-content-35">Código completo do exemplo</a><ul class="eb-toc__list"><li><a href="#handles-globais">Handles globais</a><li><a href="#callback-do-soft-timer">Callback do Soft Timer</a><li><a href="#tarefa-de-processamento">Tarefa de processamento</a><li><a href="#eb-table-content-39">Inicialização do sistema</a></li></ul><li><a href="#eb-table-content-40">Análise técnica da solução</a><li><a href="#eb-table-content-41">Quando NÃO usar Soft Timers</a></li></ul></ul></div></div></div></div></div>


<h2 class="wp-block-heading"><strong>Conceito de Tarefas no FreeRTOS e Estrutura Básica</strong></h2>



<p class="wp-block-paragraph">Em um RTOS (Real-Time Operating System), o conceito central não é mais o <em>superloop</em>, mas sim a <strong>tarefa</strong> (<em>task</em>). Uma tarefa representa uma unidade independente de execução, com seu próprio contexto de CPU (registradores), sua própria pilha (<em>stack</em>) e um estado bem definido dentro do escalonador (<em>scheduler</em>). No FreeRTOS, tarefas são implementadas como <strong>funções C que nunca retornam</strong>, pois o controle do fluxo de execução é feito exclusivamente pelo kernel.</p>



<p class="wp-block-paragraph">Do ponto de vista conceitual, uma tarefa pode ser vista como uma <em>thread cooperativa/preemptiva</em>, dependendo da configuração do sistema. O FreeRTOS utiliza escalonamento <strong>preemptivo por prioridade</strong> (opcionalmente cooperativo), onde a tarefa de maior prioridade pronta para execução assume o processador. Isso permite modelar sistemas embarcados de forma mais determinística, separando claramente aquisição de dados, processamento, comunicação e controle.</p>



<h3 class="wp-block-heading"><strong>Assinatura de uma tarefa no FreeRTOS</strong></h3>



<p class="wp-block-paragraph">Toda tarefa no FreeRTOS segue a mesma assinatura básica:</p>



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



<p class="wp-block-paragraph">Alguns pontos importantes que merecem atenção:</p>



<ul class="wp-block-list">
<li>A função <strong>não deve retornar</strong>.</li>



<li>O parâmetro <code>pvParameters</code> é um ponteiro genérico (<code>void*</code>) que permite passar dados para a tarefa no momento da criação.</li>



<li>O loop infinito não é opcional: ele garante que a tarefa continue viva enquanto o sistema estiver em execução.</li>



<li>Bloqueios devem ser feitos usando primitivas do RTOS (como <code>vTaskDelay()</code>), nunca com <em>busy wait</em>.</li>
</ul>



<h3 class="wp-block-heading"><strong>Criação de tarefas com <code>xTaskCreate()</code></strong></h3>



<p class="wp-block-paragraph">A API clássica para criação dinâmica de tarefas no FreeRTOS é a função <code>xTaskCreate()</code>:</p>



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



<p class="wp-block-paragraph">Vamos detalhar cada parâmetro com precisão técnica:</p>



<ul class="wp-block-list">
<li><strong><code>pxTaskCode</code></strong><br>Ponteiro para a função que implementa a tarefa.</li>



<li><strong><code>pcName</code></strong><br>Nome simbólico da tarefa. Útil para debug, <em>trace</em> e ferramentas como FreeRTOS+Trace.</li>



<li><strong><code>usStackDepth</code></strong><br>Tamanho da pilha da tarefa <strong>em palavras</strong>, não em bytes.<br>Em arquiteturas 32 bits (como Cortex-M), 1 palavra = 4 bytes.</li>



<li><strong><code>pvParameters</code></strong><br>Ponteiro genérico para dados passados à tarefa.</li>



<li><strong><code>uxPriority</code></strong><br>Prioridade da tarefa. Quanto maior o valor, maior a prioridade.</li>



<li><strong><code>pxCreatedTask</code></strong><br>Retorna um <em>handle</em> da tarefa criada, usado para controle posterior (suspender, deletar, notificar etc.).</li>
</ul>



<h3 class="wp-block-heading"><strong>Exemplo prático: tarefa de LED</strong></h3>



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

void vTaskBlink(void *pvParameters)
{
    (void) pvParameters;

    for (;;)
    {
        HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
        vTaskDelay(pdMS_TO_TICKS(500));
    }
}

void app_main(void)
{
    xTaskCreate(
        vTaskBlink,
        "Blink",
        128,
        NULL,
        1,
        NULL
    );

    vTaskStartScheduler();
}
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">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">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">vTaskBlink</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">pvParameters</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    (</span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">pvParameters</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">;;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">HAL_GPIO_TogglePin</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">GPIOC</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">GPIO_PIN_13</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">vTaskDelay</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">pdMS_TO_TICKS</span><span style="color: #D8DEE9FF">(</span><span style="color: #B48EAD">500</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: #81A1C1">void</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">xTaskCreate</span><span style="color: #D8DEE9FF">(</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">vTaskBlink</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Blink</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #B48EAD">128</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">NULL</span></span>
<span class="line"><span style="color: #D8DEE9FF">    )</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">vTaskStartScheduler</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Nesse exemplo:</p>



<ul class="wp-block-list">
<li>A tarefa <code>vTaskBlink</code> executa periodicamente a cada 500 ms.</li>



<li><code>vTaskDelay()</code> coloca a tarefa no estado <strong>Blocked</strong>, liberando a CPU para outras tarefas.</li>



<li><code>pdMS_TO_TICKS()</code> converte tempo em milissegundos para <em>ticks</em> do sistema, respeitando <code>configTICK_RATE_HZ</code>.</li>
</ul>



<h3 class="wp-block-heading"><strong>Estados de uma tarefa no FreeRTOS</strong></h3>



<p class="wp-block-paragraph">Internamente, o kernel gerencia cada tarefa em um dos seguintes estados principais:</p>



<ul class="wp-block-list">
<li><strong>Running</strong> – tarefa atualmente em execução.</li>



<li><strong>Ready</strong> – pronta para executar, aguardando CPU.</li>



<li><strong>Blocked</strong> – aguardando tempo, evento ou recurso.</li>



<li><strong>Suspended</strong> – explicitamente suspensa pelo usuário.</li>



<li><strong>Deleted</strong> – removida do sistema.</li>
</ul>



<p class="wp-block-paragraph">A criação correta das tarefas e o uso adequado de delays e sincronização é o que garante previsibilidade temporal, baixo consumo de CPU e bom comportamento em sistemas embarcados complexos.</p>



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



<p class="wp-block-paragraph">Perfeito, vamos avançar mantendo o mesmo rigor técnico e didático.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/><p>The post <a href="https://mcu.tec.br/rtos/como-criar-tarefas-e-soft-timers-no-freertos-guia-pratico-e-didatico-para-sistemas-embarcados/">Como Criar Tarefas e Soft Timers no FreeRTOS: Guia Prático e Didático para Sistemas Embarcados</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1016</post-id>	</item>
	</channel>
</rss>
