<?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>Zephyr RTOS - MCU &amp; FPGA</title>
	<atom:link href="https://mcu.tec.br/tags/zephyr-rtos/feed/" rel="self" type="application/rss+xml" />
	<link>https://mcu.tec.br</link>
	<description>Microcontroladores &#38; FPGA</description>
	<lastBuildDate>Sat, 21 Feb 2026 17:26:31 +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>Zephyr RTOS - MCU &amp; FPGA</title>
	<link>https://mcu.tec.br</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Zephyr e Integração Avançada: Interrupções + Soft Timers + Workqueues</title>
		<link>https://mcu.tec.br/geral/zephyr-e-integracao-avancada-interrupcoes-soft-timers-workqueues/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=zephyr-e-integracao-avancada-interrupcoes-soft-timers-workqueues</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Fri, 10 Apr 2026 14:49:36 +0000</pubDate>
				<category><![CDATA[geral]]></category>
		<category><![CDATA[RTOS]]></category>
		<category><![CDATA[arquitetura de firmware]]></category>
		<category><![CDATA[boas práticas Zephyr]]></category>
		<category><![CDATA[event driven firmware]]></category>
		<category><![CDATA[firmware escalável]]></category>
		<category><![CDATA[firmware industrial]]></category>
		<category><![CDATA[firmware robusto]]></category>
		<category><![CDATA[interrupções Zephyr]]></category>
		<category><![CDATA[IoT de produção]]></category>
		<category><![CDATA[pipelines de eventos]]></category>
		<category><![CDATA[rtos para iot]]></category>
		<category><![CDATA[sistemas embarcados industriais]]></category>
		<category><![CDATA[soft timers zephyr]]></category>
		<category><![CDATA[workqueues Zephyr]]></category>
		<category><![CDATA[Zephyr k_timer]]></category>
		<category><![CDATA[Zephyr k_work]]></category>
		<category><![CDATA[Zephyr RTOS]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1247</guid>

					<description><![CDATA[<p>O Zephyr RTOS oferece mecanismos poderosos para o desenvolvimento de firmware industrial e IoT de produção. Neste artigo, apresentamos de forma didática e aprofundada como integrar interrupções, soft timers (k_timer) e workqueues (k_work) para projetar pipelines de eventos robustos, escaláveis e previsíveis. O conteúdo explora boas práticas arquiteturais, anti-padrões comuns, controle de prioridade, backpressure e estratégias de recuperação de falhas, com exemplos reais em C. Ideal para engenheiros de sistemas embarcados que desejam evoluir de firmwares reativos simples para arquiteturas industriais confiáveis baseadas em eventos.</p>
<p>The post <a href="https://mcu.tec.br/geral/zephyr-e-integracao-avancada-interrupcoes-soft-timers-workqueues/">Zephyr e Integração Avançada: Interrupções + Soft Timers + Workqueues</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<div class="root-eb-toc-f87wq wp-block-essential-blocks-table-of-contents"><div class="eb-parent-wrapper eb-parent-eb-toc-f87wq "><div class="eb-toc-container eb-toc-f87wq  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;2 \u2014 Interrup\u00e7\u00f5es no Zephyr&quot;,&quot;text&quot;:&quot;2 \u2014 Interrup\u00e7\u00f5es no Zephyr&quot;,&quot;link&quot;:&quot;eb-table-content-0&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;O papel correto das ISRs em pipelines de eventos robustos&quot;,&quot;text&quot;:&quot;O papel correto das ISRs em pipelines de eventos robustos&quot;,&quot;link&quot;:&quot;o-papel-correto-das-isrs-em-pipelines-de-eventos-robustos&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.1 O erro cl\u00e1ssico: ISR como \u201cmini-thread\u201d&quot;,&quot;text&quot;:&quot;2.1 O erro cl\u00e1ssico: ISR como \u201cmini-thread\u201d&quot;,&quot;link&quot;:&quot;eb-table-content-2&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.2 O que uma ISR pode fazer no Zephyr&quot;,&quot;text&quot;:&quot;2.2 O que uma ISR pode fazer no Zephyr&quot;,&quot;link&quot;:&quot;22-o-que-uma-isr-pode-fazer-no-zephyr&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.3 Exemplo 1 \u2014 Interrup\u00e7\u00e3o de GPIO bem projetada&quot;,&quot;text&quot;:&quot;2.3 Exemplo 1 \u2014 Interrup\u00e7\u00e3o de GPIO bem projetada&quot;,&quot;link&quot;:&quot;eb-table-content-4&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Configura\u00e7\u00e3o do callback de interrup\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Configura\u00e7\u00e3o do callback de interrup\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-5&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Inicializa\u00e7\u00e3o do GPIO&quot;,&quot;text&quot;:&quot;Inicializa\u00e7\u00e3o do GPIO&quot;,&quot;link&quot;:&quot;eb-table-content-6&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.4 A thread consumidora do evento&quot;,&quot;text&quot;:&quot;2.4 A thread consumidora do evento&quot;,&quot;link&quot;:&quot;24-a-thread-consumidora-do-evento&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.5 Regra de ouro para ISRs em firmware industrial&quot;,&quot;text&quot;:&quot;2.5 Regra de ouro para ISRs em firmware industrial&quot;,&quot;link&quot;:&quot;25-regra-de-ouro-para-isrs-em-firmware-industrial&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;3 \u2014 Soft Timers no Zephyr&quot;,&quot;text&quot;:&quot;3 \u2014 Soft Timers no Zephyr&quot;,&quot;link&quot;:&quot;3-soft-timers-no-zephyr&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Tempo como evento, n\u00e3o como delay&quot;,&quot;text&quot;:&quot;Tempo como evento, n\u00e3o como delay&quot;,&quot;link&quot;:&quot;eb-table-content-10&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.1 O erro comum: k_sleep() como l\u00f3gica&quot;,&quot;text&quot;:&quot;3.1 O erro comum: k_sleep() como l\u00f3gica&quot;,&quot;link&quot;:&quot;eb-table-content-11&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.2 Conceito de Soft Timer no Zephyr&quot;,&quot;text&quot;:&quot;3.2 Conceito de Soft Timer no Zephyr&quot;,&quot;link&quot;:&quot;32-conceito-de-soft-timer-no-zephyr&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.3 Exemplo 2 \u2014 Timer como fonte de eventos&quot;,&quot;text&quot;:&quot;3.3 Exemplo 2 \u2014 Timer como fonte de eventos&quot;,&quot;link&quot;:&quot;33-exemplo-2-timer-como-fonte-de-eventos&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Defini\u00e7\u00e3o do timer&quot;,&quot;text&quot;:&quot;Defini\u00e7\u00e3o do timer&quot;,&quot;link&quot;:&quot;eb-table-content-14&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Inicializa\u00e7\u00e3o do timer&quot;,&quot;text&quot;:&quot;Inicializa\u00e7\u00e3o do timer&quot;,&quot;link&quot;:&quot;eb-table-content-15&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.4 Consumindo eventos temporais&quot;,&quot;text&quot;:&quot;3.4 Consumindo eventos temporais&quot;,&quot;link&quot;:&quot;34-consumindo-eventos-temporais&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.5 Soft Timer como etapa do pipeline&quot;,&quot;text&quot;:&quot;3.5 Soft Timer como etapa do pipeline&quot;,&quot;link&quot;:&quot;35-soft-timer-como-etapa-do-pipeline&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.6 Regra de ouro dos Soft Timers&quot;,&quot;text&quot;:&quot;3.6 Regra de ouro dos Soft Timers&quot;,&quot;link&quot;:&quot;36-regra-de-ouro-dos-soft-timers&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;4 \u2014 Workqueues no Zephyr&quot;,&quot;text&quot;:&quot;4 \u2014 Workqueues no Zephyr&quot;,&quot;link&quot;:&quot;4-workqueues-no-zephyr&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Processamento desacoplado, escal\u00e1vel e seguro&quot;,&quot;text&quot;:&quot;Processamento desacoplado, escal\u00e1vel e seguro&quot;,&quot;link&quot;:&quot;eb-table-content-20&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.1 O que \u00e9 uma Workqueue, de fato&quot;,&quot;text&quot;:&quot;4.1 O que \u00e9 uma Workqueue, de fato&quot;,&quot;link&quot;:&quot;eb-table-content-21&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.2 O erro comum: jogar tudo na system workqueue&quot;,&quot;text&quot;:&quot;4.2 O erro comum: jogar tudo na system workqueue&quot;,&quot;link&quot;:&quot;42-o-erro-comum-jogar-tudo-na-system-workqueue&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.3 Criando uma Workqueue dedicada&quot;,&quot;text&quot;:&quot;4.3 Criando uma Workqueue dedicada&quot;,&quot;link&quot;:&quot;43-criando-uma-workqueue-dedicada&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Defini\u00e7\u00e3o da workqueue&quot;,&quot;text&quot;:&quot;Defini\u00e7\u00e3o da workqueue&quot;,&quot;link&quot;:&quot;eb-table-content-24&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Inicializa\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Inicializa\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-25&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.4 Criando um work item&quot;,&quot;text&quot;:&quot;4.4 Criando um work item&quot;,&quot;link&quot;:&quot;44-criando-um-work-item&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.5 Integrando eventos \u2192 workqueues&quot;,&quot;text&quot;:&quot;4.5 Integrando eventos \u2192 workqueues&quot;,&quot;link&quot;:&quot;eb-table-content-27&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;ISR \u2192 Timer \u2192 Workqueue&quot;,&quot;text&quot;:&quot;ISR \u2192 Timer \u2192 Workqueue&quot;,&quot;link&quot;:&quot;eb-table-content-28&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.6 Workqueues como est\u00e1gios de pipeline&quot;,&quot;text&quot;:&quot;4.6 Workqueues como est\u00e1gios de pipeline&quot;,&quot;link&quot;:&quot;eb-table-content-29&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.7 Regra de ouro das Workqueues&quot;,&quot;text&quot;:&quot;4.7 Regra de ouro das Workqueues&quot;,&quot;link&quot;:&quot;47-regra-de-ouro-das-workqueues&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;5 \u2014 Desenhando pipelines completos de eventos no Zephyr&quot;,&quot;text&quot;:&quot;5 \u2014 Desenhando pipelines completos de eventos no Zephyr&quot;,&quot;link&quot;:&quot;5-desenhando-pipelines-completos-de-eventos-no-zephyr&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Do evento f\u00edsico ao processamento industrial robusto&quot;,&quot;text&quot;:&quot;Do evento f\u00edsico ao processamento industrial robusto&quot;,&quot;link&quot;:&quot;eb-table-content-32&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.1 O modelo mental correto: firmware como fluxo de eventos&quot;,&quot;text&quot;:&quot;5.1 O modelo mental correto: firmware como fluxo de eventos&quot;,&quot;link&quot;:&quot;51-o-modelo-mental-correto-firmware-como-fluxo-de-eventos&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.2 Pipeline can\u00f4nico no Zephyr&quot;,&quot;text&quot;:&quot;5.2 Pipeline can\u00f4nico no Zephyr&quot;,&quot;link&quot;:&quot;eb-table-content-34&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.3 Implementa\u00e7\u00e3o passo a passo&quot;,&quot;text&quot;:&quot;5.3 Implementa\u00e7\u00e3o passo a passo&quot;,&quot;link&quot;:&quot;eb-table-content-35&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;1\ufe0f\u20e3 Interrup\u00e7\u00e3o: entrada do pipeline&quot;,&quot;text&quot;:&quot;1\ufe0f\u20e3 Interrup\u00e7\u00e3o: entrada do pipeline&quot;,&quot;link&quot;:&quot;eb-table-content-36&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;2\ufe0f\u20e3 Soft Timer: debounce e normaliza\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;2\ufe0f\u20e3 Soft Timer: debounce e normaliza\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-37&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;3\ufe0f\u20e3 Workqueue: processamento real&quot;,&quot;text&quot;:&quot;3\ufe0f\u20e3 Workqueue: processamento real&quot;,&quot;link&quot;:&quot;eb-table-content-38&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;4\ufe0f\u20e3 Workqueue de comunica\u00e7\u00e3o (opcional, mas comum)&quot;,&quot;text&quot;:&quot;4\ufe0f\u20e3 Workqueue de comunica\u00e7\u00e3o (opcional, mas comum)&quot;,&quot;link&quot;:&quot;eb-table-content-39&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.4 Por que esse pipeline \u00e9 robusto&quot;,&quot;text&quot;:&quot;5.4 Por que esse pipeline \u00e9 robusto&quot;,&quot;link&quot;:&quot;eb-table-content-40&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.5 Anti-padr\u00f5es comuns (e perigosos)&quot;,&quot;text&quot;:&quot;5.5 Anti-padr\u00f5es comuns (e perigosos)&quot;,&quot;link&quot;:&quot;eb-table-content-41&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.6 Regra de ouro do pipeline no Zephyr&quot;,&quot;text&quot;:&quot;5.6 Regra de ouro do pipeline no Zephyr&quot;,&quot;link&quot;:&quot;56-regra-de-ouro-do-pipeline-no-zephyr&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;6 \u2014 Boas pr\u00e1ticas industriais&quot;,&quot;text&quot;:&quot;6 \u2014 Boas pr\u00e1ticas industriais&quot;,&quot;link&quot;:&quot;eb-table-content-43&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Prioridades, backpressure e recupera\u00e7\u00e3o de falhas&quot;,&quot;text&quot;:&quot;Prioridades, backpressure e recupera\u00e7\u00e3o de falhas&quot;,&quot;link&quot;:&quot;eb-table-content-44&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;6.1 Prioriza\u00e7\u00e3o correta: tempo \u00e9 um recurso finito&quot;,&quot;text&quot;:&quot;6.1 Prioriza\u00e7\u00e3o correta: tempo \u00e9 um recurso finito&quot;,&quot;link&quot;:&quot;eb-table-content-45&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Regra pr\u00e1tica de prioridade&quot;,&quot;text&quot;:&quot;Regra pr\u00e1tica de prioridade&quot;,&quot;link&quot;:&quot;eb-table-content-46&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;6.2 Exemplo \u2014 Workqueues com prioridades distintas&quot;,&quot;text&quot;:&quot;6.2 Exemplo \u2014 Workqueues com prioridades distintas&quot;,&quot;link&quot;:&quot;62-exemplo-workqueues-com-prioridades-distintas&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;6.3 Backpressure: quando eventos chegam r\u00e1pido demais&quot;,&quot;text&quot;:&quot;6.3 Backpressure: quando eventos chegam r\u00e1pido demais&quot;,&quot;link&quot;:&quot;eb-table-content-48&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Estrat\u00e9gias de backpressure no Zephyr&quot;,&quot;text&quot;:&quot;Estrat\u00e9gias de backpressure no Zephyr&quot;,&quot;link&quot;:&quot;eb-table-content-49&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;6.4 Exemplo \u2014 Limitando eventos com k_msgq&quot;,&quot;text&quot;:&quot;6.4 Exemplo \u2014 Limitando eventos com k_msgq&quot;,&quot;link&quot;:&quot;64-exemplo-limitando-eventos-com-k_msgq&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;6.5 Eventos colaps\u00e1veis (coalescing)&quot;,&quot;text&quot;:&quot;6.5 Eventos colaps\u00e1veis (coalescing)&quot;,&quot;link&quot;:&quot;eb-table-content-51&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;6.6 Recupera\u00e7\u00e3o de falhas no pipeline&quot;,&quot;text&quot;:&quot;6.6 Recupera\u00e7\u00e3o de falhas no pipeline&quot;,&quot;link&quot;:&quot;eb-table-content-52&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Exemplo \u2014 Timeout l\u00f3gico com timer&quot;,&quot;text&quot;:&quot;Exemplo \u2014 Timeout l\u00f3gico com timer&quot;,&quot;link&quot;:&quot;eb-table-content-53&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;6.7 Checklist industrial de robustez&quot;,&quot;text&quot;:&quot;6.7 Checklist industrial de robustez&quot;,&quot;link&quot;:&quot;67-checklist-industrial-de-robustez&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;7 \u2014 Estudo de caso completo&quot;,&quot;text&quot;:&quot;7 \u2014 Estudo de caso completo&quot;,&quot;link&quot;:&quot;7-estudo-de-caso-completo&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Pipeline Zephyr em um dispositivo IoT industrial (sensor \u2192 processamento \u2192 nuvem)&quot;,&quot;text&quot;:&quot;Pipeline Zephyr em um dispositivo IoT industrial (sensor \u2192 processamento \u2192 nuvem)&quot;,&quot;link&quot;:&quot;eb-table-content-56&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;7.1 Cen\u00e1rio do sistema&quot;,&quot;text&quot;:&quot;7.1 Cen\u00e1rio do sistema&quot;,&quot;link&quot;:&quot;eb-table-content-57&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;7.2 Arquitetura do pipeline&quot;,&quot;text&quot;:&quot;7.2 Arquitetura do pipeline&quot;,&quot;link&quot;:&quot;72-arquitetura-do-pipeline&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;7.3 Est\u00e1gio 1 \u2014 ISR (evento f\u00edsico)&quot;,&quot;text&quot;:&quot;7.3 Est\u00e1gio 1 \u2014 ISR (evento f\u00edsico)&quot;,&quot;link&quot;:&quot;eb-table-content-59&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;7.4 Est\u00e1gio 2 \u2014 Soft Timer (normaliza\u00e7\u00e3o temporal)&quot;,&quot;text&quot;:&quot;7.4 Est\u00e1gio 2 \u2014 Soft Timer (normaliza\u00e7\u00e3o temporal)&quot;,&quot;link&quot;:&quot;eb-table-content-60&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;7.5 Est\u00e1gio 3 \u2014 Workqueue de aquisi\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;7.5 Est\u00e1gio 3 \u2014 Workqueue de aquisi\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-61&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;7.6 Est\u00e1gio 4 \u2014 Workqueue de processamento&quot;,&quot;text&quot;:&quot;7.6 Est\u00e1gio 4 \u2014 Workqueue de processamento&quot;,&quot;link&quot;:&quot;eb-table-content-62&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;7.7 Est\u00e1gio 5 \u2014 Workqueue de comunica\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;7.7 Est\u00e1gio 5 \u2014 Workqueue de comunica\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-63&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;7.8 Controle de carga (backpressure)&quot;,&quot;text&quot;:&quot;7.8 Controle de carga (backpressure)&quot;,&quot;link&quot;:&quot;78-controle-de-carga-backpressure&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;7.9 Recupera\u00e7\u00e3o e robustez&quot;,&quot;text&quot;:&quot;7.9 Recupera\u00e7\u00e3o e robustez&quot;,&quot;link&quot;:&quot;eb-table-content-65&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;7.10 O que esse estudo de caso demonstra&quot;,&quot;text&quot;:&quot;7.10 O que esse estudo de caso demonstra&quot;,&quot;link&quot;:&quot;710-o-que-esse-estudo-de-caso-demonstra&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;8 \u2014 Conclus\u00e3o&quot;,&quot;text&quot;:&quot;8 \u2014 Conclus\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-67&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Padr\u00f5es mentais e checklist para firmware industrial com Zephyr&quot;,&quot;text&quot;:&quot;Padr\u00f5es mentais e checklist para firmware industrial com Zephyr&quot;,&quot;link&quot;:&quot;eb-table-content-68&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;8.1 O modelo mental correto (o que levar deste artigo)&quot;,&quot;text&quot;:&quot;8.1 O modelo mental correto (o que levar deste artigo)&quot;,&quot;link&quot;:&quot;81-o-modelo-mental-correto-o-que-levar-deste-artigo&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;8.2 Anti-padr\u00f5es finais a evitar&quot;,&quot;text&quot;:&quot;8.2 Anti-padr\u00f5es finais a evitar&quot;,&quot;link&quot;:&quot;eb-table-content-70&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;8.3 Checklist pr\u00e1tico de revis\u00e3o arquitetural&quot;,&quot;text&quot;:&quot;8.3 Checklist pr\u00e1tico de revis\u00e3o arquitetural&quot;,&quot;link&quot;:&quot;eb-table-content-71&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;8.4 Onde esse padr\u00e3o \u00e9 usado na pr\u00e1tica&quot;,&quot;text&quot;:&quot;8.4 Onde esse padr\u00e3o \u00e9 usado na pr\u00e1tica&quot;,&quot;link&quot;:&quot;eb-table-content-72&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;8.5 Encerramento&quot;,&quot;text&quot;:&quot;8.5 Encerramento&quot;,&quot;link&quot;:&quot;85-encerramento&quot;}]" data-visible="[true,true,true,true,true,true]" data-delete-headers="[{&quot;label&quot;:&quot;2 \u2014 Interrup\u00e7\u00f5es no Zephyr&quot;,&quot;value&quot;:&quot;2-interrup\u00e7\u00f5es-no-zephyr&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;O papel correto das ISRs em pipelines de eventos robustos&quot;,&quot;value&quot;:&quot;o-papel-correto-das-isrs-em-pipelines-de-eventos-robustos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.1 O erro cl\u00e1ssico: ISR como \u201cmini-thread\u201d&quot;,&quot;value&quot;:&quot;21-o-erro-cl\u00e1ssico-isr-como-mini-thread&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.2 O que uma ISR pode fazer no Zephyr&quot;,&quot;value&quot;:&quot;22-o-que-uma-isr-pode-fazer-no-zephyr&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.3 Exemplo 1 \u2014 Interrup\u00e7\u00e3o de GPIO bem projetada&quot;,&quot;value&quot;:&quot;23-exemplo-1-interrup\u00e7\u00e3o-de-gpio-bem-projetada&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Configura\u00e7\u00e3o do callback de interrup\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;configura\u00e7\u00e3o-do-callback-de-interrup\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Inicializa\u00e7\u00e3o do GPIO&quot;,&quot;value&quot;:&quot;inicializa\u00e7\u00e3o-do-gpio&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.4 A thread consumidora do evento&quot;,&quot;value&quot;:&quot;24-a-thread-consumidora-do-evento&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.5 Regra de ouro para ISRs em firmware industrial&quot;,&quot;value&quot;:&quot;25-regra-de-ouro-para-isrs-em-firmware-industrial&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3 \u2014 Soft Timers no Zephyr&quot;,&quot;value&quot;:&quot;3-soft-timers-no-zephyr&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Tempo como evento, n\u00e3o como delay&quot;,&quot;value&quot;:&quot;tempo-como-evento-n\u00e3o-como-delay&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.1 O erro comum: k_sleep() como l\u00f3gica&quot;,&quot;value&quot;:&quot;31-o-erro-comum-k_sleep-como-l\u00f3gica&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.2 Conceito de Soft Timer no Zephyr&quot;,&quot;value&quot;:&quot;32-conceito-de-soft-timer-no-zephyr&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.3 Exemplo 2 \u2014 Timer como fonte de eventos&quot;,&quot;value&quot;:&quot;33-exemplo-2-timer-como-fonte-de-eventos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Defini\u00e7\u00e3o do timer&quot;,&quot;value&quot;:&quot;defini\u00e7\u00e3o-do-timer&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Inicializa\u00e7\u00e3o do timer&quot;,&quot;value&quot;:&quot;inicializa\u00e7\u00e3o-do-timer&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.4 Consumindo eventos temporais&quot;,&quot;value&quot;:&quot;34-consumindo-eventos-temporais&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.5 Soft Timer como etapa do pipeline&quot;,&quot;value&quot;:&quot;35-soft-timer-como-etapa-do-pipeline&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.6 Regra de ouro dos Soft Timers&quot;,&quot;value&quot;:&quot;36-regra-de-ouro-dos-soft-timers&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4 \u2014 Workqueues no Zephyr&quot;,&quot;value&quot;:&quot;4-workqueues-no-zephyr&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Processamento desacoplado, escal\u00e1vel e seguro&quot;,&quot;value&quot;:&quot;processamento-desacoplado-escal\u00e1vel-e-seguro&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.1 O que \u00e9 uma Workqueue, de fato&quot;,&quot;value&quot;:&quot;41-o-que-\u00e9-uma-workqueue-de-fato&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.2 O erro comum: jogar tudo na system workqueue&quot;,&quot;value&quot;:&quot;42-o-erro-comum-jogar-tudo-na-system-workqueue&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.3 Criando uma Workqueue dedicada&quot;,&quot;value&quot;:&quot;43-criando-uma-workqueue-dedicada&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Defini\u00e7\u00e3o da workqueue&quot;,&quot;value&quot;:&quot;defini\u00e7\u00e3o-da-workqueue&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Inicializa\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;inicializa\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.4 Criando um work item&quot;,&quot;value&quot;:&quot;44-criando-um-work-item&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.5 Integrando eventos \u2192 workqueues&quot;,&quot;value&quot;:&quot;45-integrando-eventos-\u2192-workqueues&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;ISR \u2192 Timer \u2192 Workqueue&quot;,&quot;value&quot;:&quot;isr-\u2192-timer-\u2192-workqueue&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.6 Workqueues como est\u00e1gios de pipeline&quot;,&quot;value&quot;:&quot;46-workqueues-como-est\u00e1gios-de-pipeline&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.7 Regra de ouro das Workqueues&quot;,&quot;value&quot;:&quot;47-regra-de-ouro-das-workqueues&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5 \u2014 Desenhando pipelines completos de eventos no Zephyr&quot;,&quot;value&quot;:&quot;5-desenhando-pipelines-completos-de-eventos-no-zephyr&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Do evento f\u00edsico ao processamento industrial robusto&quot;,&quot;value&quot;:&quot;do-evento-f\u00edsico-ao-processamento-industrial-robusto&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.1 O modelo mental correto: firmware como fluxo de eventos&quot;,&quot;value&quot;:&quot;51-o-modelo-mental-correto-firmware-como-fluxo-de-eventos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.2 Pipeline can\u00f4nico no Zephyr&quot;,&quot;value&quot;:&quot;52-pipeline-can\u00f4nico-no-zephyr&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.3 Implementa\u00e7\u00e3o passo a passo&quot;,&quot;value&quot;:&quot;53-implementa\u00e7\u00e3o-passo-a-passo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1\ufe0f\u20e3 Interrup\u00e7\u00e3o: entrada do pipeline&quot;,&quot;value&quot;:&quot;1\ufe0f\u20e3-interrup\u00e7\u00e3o-entrada-do-pipeline&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2\ufe0f\u20e3 Soft Timer: debounce e normaliza\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;2\ufe0f\u20e3-soft-timer-debounce-e-normaliza\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3\ufe0f\u20e3 Workqueue: processamento real&quot;,&quot;value&quot;:&quot;3\ufe0f\u20e3-workqueue-processamento-real&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4\ufe0f\u20e3 Workqueue de comunica\u00e7\u00e3o (opcional, mas comum)&quot;,&quot;value&quot;:&quot;4\ufe0f\u20e3-workqueue-de-comunica\u00e7\u00e3o-opcional-mas-comum&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.4 Por que esse pipeline \u00e9 robusto&quot;,&quot;value&quot;:&quot;54-por-que-esse-pipeline-\u00e9-robusto&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.5 Anti-padr\u00f5es comuns (e perigosos)&quot;,&quot;value&quot;:&quot;55-anti-padr\u00f5es-comuns-e-perigosos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.6 Regra de ouro do pipeline no Zephyr&quot;,&quot;value&quot;:&quot;56-regra-de-ouro-do-pipeline-no-zephyr&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;6 \u2014 Boas pr\u00e1ticas industriais&quot;,&quot;value&quot;:&quot;6-boas-pr\u00e1ticas-industriais&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Prioridades, backpressure e recupera\u00e7\u00e3o de falhas&quot;,&quot;value&quot;:&quot;prioridades-backpressure-e-recupera\u00e7\u00e3o-de-falhas&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;6.1 Prioriza\u00e7\u00e3o correta: tempo \u00e9 um recurso finito&quot;,&quot;value&quot;:&quot;61-prioriza\u00e7\u00e3o-correta-tempo-\u00e9-um-recurso-finito&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Regra pr\u00e1tica de prioridade&quot;,&quot;value&quot;:&quot;regra-pr\u00e1tica-de-prioridade&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;6.2 Exemplo \u2014 Workqueues com prioridades distintas&quot;,&quot;value&quot;:&quot;62-exemplo-workqueues-com-prioridades-distintas&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;6.3 Backpressure: quando eventos chegam r\u00e1pido demais&quot;,&quot;value&quot;:&quot;63-backpressure-quando-eventos-chegam-r\u00e1pido-demais&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Estrat\u00e9gias de backpressure no Zephyr&quot;,&quot;value&quot;:&quot;estrat\u00e9gias-de-backpressure-no-zephyr&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;6.4 Exemplo \u2014 Limitando eventos com k_msgq&quot;,&quot;value&quot;:&quot;64-exemplo-limitando-eventos-com-k_msgq&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;6.5 Eventos colaps\u00e1veis (coalescing)&quot;,&quot;value&quot;:&quot;65-eventos-colaps\u00e1veis-coalescing&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;6.6 Recupera\u00e7\u00e3o de falhas no pipeline&quot;,&quot;value&quot;:&quot;66-recupera\u00e7\u00e3o-de-falhas-no-pipeline&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Exemplo \u2014 Timeout l\u00f3gico com timer&quot;,&quot;value&quot;:&quot;exemplo-timeout-l\u00f3gico-com-timer&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;6.7 Checklist industrial de robustez&quot;,&quot;value&quot;:&quot;67-checklist-industrial-de-robustez&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;7 \u2014 Estudo de caso completo&quot;,&quot;value&quot;:&quot;7-estudo-de-caso-completo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Pipeline Zephyr em um dispositivo IoT industrial (sensor \u2192 processamento \u2192 nuvem)&quot;,&quot;value&quot;:&quot;pipeline-zephyr-em-um-dispositivo-iot-industrial-sensor-\u2192-processamento-\u2192-nuvem&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;7.1 Cen\u00e1rio do sistema&quot;,&quot;value&quot;:&quot;71-cen\u00e1rio-do-sistema&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;7.2 Arquitetura do pipeline&quot;,&quot;value&quot;:&quot;72-arquitetura-do-pipeline&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;7.3 Est\u00e1gio 1 \u2014 ISR (evento f\u00edsico)&quot;,&quot;value&quot;:&quot;73-est\u00e1gio-1-isr-evento-f\u00edsico&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;7.4 Est\u00e1gio 2 \u2014 Soft Timer (normaliza\u00e7\u00e3o temporal)&quot;,&quot;value&quot;:&quot;74-est\u00e1gio-2-soft-timer-normaliza\u00e7\u00e3o-temporal&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;7.5 Est\u00e1gio 3 \u2014 Workqueue de aquisi\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;75-est\u00e1gio-3-workqueue-de-aquisi\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;7.6 Est\u00e1gio 4 \u2014 Workqueue de processamento&quot;,&quot;value&quot;:&quot;76-est\u00e1gio-4-workqueue-de-processamento&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;7.7 Est\u00e1gio 5 \u2014 Workqueue de comunica\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;77-est\u00e1gio-5-workqueue-de-comunica\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;7.8 Controle de carga (backpressure)&quot;,&quot;value&quot;:&quot;78-controle-de-carga-backpressure&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;7.9 Recupera\u00e7\u00e3o e robustez&quot;,&quot;value&quot;:&quot;79-recupera\u00e7\u00e3o-e-robustez&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;7.10 O que esse estudo de caso demonstra&quot;,&quot;value&quot;:&quot;710-o-que-esse-estudo-de-caso-demonstra&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;8 \u2014 Conclus\u00e3o&quot;,&quot;value&quot;:&quot;8-conclus\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Padr\u00f5es mentais e checklist para firmware industrial com Zephyr&quot;,&quot;value&quot;:&quot;padr\u00f5es-mentais-e-checklist-para-firmware-industrial-com-zephyr&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;8.1 O modelo mental correto (o que levar deste artigo)&quot;,&quot;value&quot;:&quot;81-o-modelo-mental-correto-o-que-levar-deste-artigo&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;8.2 Anti-padr\u00f5es finais a evitar&quot;,&quot;value&quot;:&quot;82-anti-padr\u00f5es-finais-a-evitar&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;8.3 Checklist pr\u00e1tico de revis\u00e3o arquitetural&quot;,&quot;value&quot;:&quot;83-checklist-pr\u00e1tico-de-revis\u00e3o-arquitetural&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;8.4 Onde esse padr\u00e3o \u00e9 usado na pr\u00e1tica&quot;,&quot;value&quot;:&quot;84-onde-esse-padr\u00e3o-\u00e9-usado-na-pr\u00e1tica&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;8.5 Encerramento&quot;,&quot;value&quot;:&quot;85-encerramento&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">2 — Interrupções no Zephyr</a><ul class="eb-toc__list"><li><a href="#o-papel-correto-das-isrs-em-pipelines-de-eventos-robustos">O papel correto das ISRs em pipelines de eventos robustos</a><li><a href="#eb-table-content-2">2.1 O erro clássico: ISR como “mini-thread”</a><li><a href="#22-o-que-uma-isr-pode-fazer-no-zephyr">2.2 O que uma ISR pode fazer no Zephyr</a><li><a href="#eb-table-content-4">2.3 Exemplo 1 — Interrupção de GPIO bem projetada</a><ul class="eb-toc__list"><li><a href="#eb-table-content-5">Configuração do callback de interrupção</a><li><a href="#eb-table-content-6">Inicialização do GPIO</a></li></ul><li><a href="#24-a-thread-consumidora-do-evento">2.4 A thread consumidora do evento</a><li><a href="#25-regra-de-ouro-para-isrs-em-firmware-industrial">2.5 Regra de ouro para ISRs em firmware industrial</a></li></ul><li><a href="#3-soft-timers-no-zephyr">3 — Soft Timers no Zephyr</a><ul class="eb-toc__list"><li><a href="#eb-table-content-10">Tempo como evento, não como delay</a><li><a href="#eb-table-content-11">3.1 O erro comum: k_sleep() como lógica</a><li><a href="#32-conceito-de-soft-timer-no-zephyr">3.2 Conceito de Soft Timer no Zephyr</a><li><a href="#33-exemplo-2-timer-como-fonte-de-eventos">3.3 Exemplo 2 — Timer como fonte de eventos</a><ul class="eb-toc__list"><li><a href="#eb-table-content-14">Definição do timer</a><li><a href="#eb-table-content-15">Inicialização do timer</a></li></ul><li><a href="#34-consumindo-eventos-temporais">3.4 Consumindo eventos temporais</a><li><a href="#35-soft-timer-como-etapa-do-pipeline">3.5 Soft Timer como etapa do pipeline</a><li><a href="#36-regra-de-ouro-dos-soft-timers">3.6 Regra de ouro dos Soft Timers</a></li></ul><li><a href="#4-workqueues-no-zephyr">4 — Workqueues no Zephyr</a><ul class="eb-toc__list"><li><a href="#eb-table-content-20">Processamento desacoplado, escalável e seguro</a><li><a href="#eb-table-content-21">4.1 O que é uma Workqueue, de fato</a><li><a href="#42-o-erro-comum-jogar-tudo-na-system-workqueue">4.2 O erro comum: jogar tudo na system workqueue</a><li><a href="#43-criando-uma-workqueue-dedicada">4.3 Criando uma Workqueue dedicada</a><ul class="eb-toc__list"><li><a href="#eb-table-content-24">Definição da workqueue</a><li><a href="#eb-table-content-25">Inicialização</a></li></ul><li><a href="#44-criando-um-work-item">4.4 Criando um work item</a><li><a href="#eb-table-content-27">4.5 Integrando eventos → workqueues</a><ul class="eb-toc__list"><li><a href="#eb-table-content-28">ISR → Timer → Workqueue</a></li></ul><li><a href="#eb-table-content-29">4.6 Workqueues como estágios de pipeline</a><li><a href="#47-regra-de-ouro-das-workqueues">4.7 Regra de ouro das Workqueues</a></li></ul><li><a href="#5-desenhando-pipelines-completos-de-eventos-no-zephyr">5 — Desenhando pipelines completos de eventos no Zephyr</a><ul class="eb-toc__list"><li><a href="#eb-table-content-32">Do evento físico ao processamento industrial robusto</a><li><a href="#51-o-modelo-mental-correto-firmware-como-fluxo-de-eventos">5.1 O modelo mental correto: firmware como fluxo de eventos</a><li><a href="#eb-table-content-34">5.2 Pipeline canônico no Zephyr</a><li><a href="#eb-table-content-35">5.3 Implementação passo a passo</a><ul class="eb-toc__list"><li><a href="#eb-table-content-36">1&#xfe0f;&#x20e3; Interrupção: entrada do pipeline</a><li><a href="#eb-table-content-37">2&#xfe0f;&#x20e3; Soft Timer: debounce e normalização</a><li><a href="#eb-table-content-38">3&#xfe0f;&#x20e3; Workqueue: processamento real</a><li><a href="#eb-table-content-39">4&#xfe0f;&#x20e3; Workqueue de comunicação (opcional, mas comum)</a></li></ul><li><a href="#eb-table-content-40">5.4 Por que esse pipeline é robusto</a><li><a href="#eb-table-content-41">5.5 Anti-padrões comuns (e perigosos)</a><li><a href="#56-regra-de-ouro-do-pipeline-no-zephyr">5.6 Regra de ouro do pipeline no Zephyr</a></li></ul><li><a href="#eb-table-content-43">6 — Boas práticas industriais</a><ul class="eb-toc__list"><li><a href="#eb-table-content-44">Prioridades, backpressure e recuperação de falhas</a><li><a href="#eb-table-content-45">6.1 Priorização correta: tempo é um recurso finito</a><ul class="eb-toc__list"><li><a href="#eb-table-content-46">Regra prática de prioridade</a></li></ul><li><a href="#62-exemplo-workqueues-com-prioridades-distintas">6.2 Exemplo — Workqueues com prioridades distintas</a><li><a href="#eb-table-content-48">6.3 Backpressure: quando eventos chegam rápido demais</a><ul class="eb-toc__list"><li><a href="#eb-table-content-49">Estratégias de backpressure no Zephyr</a></li></ul><li><a href="#64-exemplo-limitando-eventos-com-k_msgq">6.4 Exemplo — Limitando eventos com k_msgq</a><li><a href="#eb-table-content-51">6.5 Eventos colapsáveis (coalescing)</a><li><a href="#eb-table-content-52">6.6 Recuperação de falhas no pipeline</a><ul class="eb-toc__list"><li><a href="#eb-table-content-53">Exemplo — Timeout lógico com timer</a></li></ul><li><a href="#67-checklist-industrial-de-robustez">6.7 Checklist industrial de robustez</a></li></ul><li><a href="#7-estudo-de-caso-completo">7 — Estudo de caso completo</a><ul class="eb-toc__list"><li><a href="#eb-table-content-56">Pipeline Zephyr em um dispositivo IoT industrial (sensor → processamento → nuvem)</a><li><a href="#eb-table-content-57">7.1 Cenário do sistema</a><li><a href="#72-arquitetura-do-pipeline">7.2 Arquitetura do pipeline</a><li><a href="#eb-table-content-59">7.3 Estágio 1 — ISR (evento físico)</a><li><a href="#eb-table-content-60">7.4 Estágio 2 — Soft Timer (normalização temporal)</a><li><a href="#eb-table-content-61">7.5 Estágio 3 — Workqueue de aquisição</a><li><a href="#eb-table-content-62">7.6 Estágio 4 — Workqueue de processamento</a><li><a href="#eb-table-content-63">7.7 Estágio 5 — Workqueue de comunicação</a><li><a href="#78-controle-de-carga-backpressure">7.8 Controle de carga (backpressure)</a><li><a href="#eb-table-content-65">7.9 Recuperação e robustez</a><li><a href="#710-o-que-esse-estudo-de-caso-demonstra">7.10 O que esse estudo de caso demonstra</a></li></ul><li><a href="#eb-table-content-67">8 — Conclusão</a><ul class="eb-toc__list"><li><a href="#eb-table-content-68">Padrões mentais e checklist para firmware industrial com Zephyr</a><li><a href="#81-o-modelo-mental-correto-o-que-levar-deste-artigo">8.1 O modelo mental correto (o que levar deste artigo)</a><li><a href="#eb-table-content-70">8.2 Anti-padrões finais a evitar</a><li><a href="#eb-table-content-71">8.3 Checklist prático de revisão arquitetural</a><li><a href="#eb-table-content-72">8.4 Onde esse padrão é usado na prática</a><li><a href="#85-encerramento">8.5 Encerramento</a></li></ul></ul></div></div></div></div></div>


<p class="wp-block-paragraph">Em firmware <strong>industrial</strong> e <strong>IoT de produção</strong>, o problema raramente é “como ler um sensor” ou “como reagir a uma interrupção”. O desafio real está em <strong>como transformar eventos assíncronos e imprevisíveis</strong> (interrupções de hardware, timeouts, pacotes de rede, watchdogs) em <strong>fluxos determinísticos, observáveis e recuperáveis</strong> — sem violar latência, sem bloquear ISRs, sem explodir prioridade e sem criar acoplamentos frágeis entre camadas.</p>



<p class="wp-block-paragraph">O <strong>Zephyr RTOS</strong> se destaca exatamente por oferecer <strong>primitivas complementares</strong> — <em>Interrupções</em>, <em>Soft Timers</em> (<code>k_timer</code>) e <em>Workqueues</em> (<code>k_work</code>) — que, quando <strong>combinadas corretamente</strong>, permitem desenhar <strong>pipelines de eventos robustos</strong>, usados em produtos reais: gateways industriais, sensores remotos, equipamentos médicos, automação predial e dispositivos conectados operando por anos no campo.</p>



<p class="wp-block-paragraph">Este artigo não trata essas primitivas de forma isolada. O foco é <strong>arquitetural</strong>:<br>como <strong>compor</strong> essas ferramentas para criar <strong>fluxos de processamento desacoplados</strong>, previsíveis e testáveis, respeitando as regras fundamentais de sistemas embarcados modernos:</p>



<ul class="wp-block-list">
<li><strong>ISR mínima</strong>: interrupção apenas sinaliza, nunca processa.</li>



<li><strong>Tempo como evento</strong>: temporização explícita, não “sleep espalhado”.</li>



<li><strong>Processamento fora de ISR</strong>: trabalho pesado sempre em contexto de thread.</li>



<li><strong>Backpressure e ordenação</strong>: eventos fluem por etapas bem definidas.</li>



<li><strong>Escalabilidade</strong>: o desenho deve sobreviver ao crescimento do sistema.</li>
</ul>



<p class="wp-block-paragraph">Ao longo das próximas seções, vamos evoluir de um <strong>modelo mental</strong> até <strong>códigos concretos em C</strong>, mostrando:</p>



<ol class="wp-block-list">
<li>O papel correto de <strong>Interrupções</strong> no Zephyr.</li>



<li>Como <strong>Soft Timers</strong> viram fontes de eventos temporais confiáveis.</li>



<li>Como <strong>Workqueues</strong> funcionam como estágios de processamento.</li>



<li>Como integrar tudo isso em <strong>pipelines de eventos industriais</strong>, com exemplos reais de firmware.</li>
</ol>



<p class="wp-block-paragraph">A ideia é que, ao final, você não apenas “saiba usar” essas APIs, mas <strong>consiga enxergar a arquitetura</strong> por trás de um firmware profissional — aquele que não depende de sorte, nem de atrasos mágicos, nem de lógica escondida em ISR.</p><p>The post <a href="https://mcu.tec.br/geral/zephyr-e-integracao-avancada-interrupcoes-soft-timers-workqueues/">Zephyr e Integração Avançada: Interrupções + Soft Timers + Workqueues</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1247</post-id>	</item>
		<item>
		<title>Interrupções e Soft Timers no Zephyr OS</title>
		<link>https://mcu.tec.br/rtos/interrupcoes-e-soft-timers-no-zephyr-os/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=interrupcoes-e-soft-timers-no-zephyr-os</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Fri, 03 Apr 2026 14:04:49 +0000</pubDate>
				<category><![CDATA[RTOS]]></category>
		<category><![CDATA[firmware em tempo real]]></category>
		<category><![CDATA[gpio interrupt zephyr]]></category>
		<category><![CDATA[interrupções no zephyr]]></category>
		<category><![CDATA[isr zephyr]]></category>
		<category><![CDATA[k_timer zephyr]]></category>
		<category><![CDATA[programação embarcada com zephyr]]></category>
		<category><![CDATA[rtos para iot]]></category>
		<category><![CDATA[sistemas embarcados modernos]]></category>
		<category><![CDATA[soft timers zephyr]]></category>
		<category><![CDATA[zephyr kernel]]></category>
		<category><![CDATA[Zephyr OS]]></category>
		<category><![CDATA[Zephyr RTOS]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1244</guid>

					<description><![CDATA[<p>Este artigo apresenta um guia técnico e didático sobre o uso de interrupções de hardware e soft timers no Zephyr OS, um sistema operacional de tempo real amplamente utilizado em projetos de IoT e sistemas embarcados modernos. O conteúdo explora a filosofia do Zephyr para tratamento de eventos assíncronos, detalhando como funcionam as ISRs (Interrupt Service Routines), a integração com GPIOs, a sinalização correta de threads e o uso seguro de semáforos. Em seguida, o artigo aprofunda o uso de soft timers (k_timer), explicando sua arquitetura interna, diferenças em relação aos timers de hardware, modos de operação periódicos e one-shot, além de padrões recomendados para firmware escalável. Com exemplos práticos em C, o texto mostra como combinar interrupções, timers e threads para criar sistemas previsíveis, portáveis e robustos, alinhados às boas práticas de desenvolvimento profissional com Zephyr RTOS.</p>
<p>The post <a href="https://mcu.tec.br/rtos/interrupcoes-e-soft-timers-no-zephyr-os/">Interrupções e Soft Timers no Zephyr OS</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">Interrupções e Soft Timers no Zephyr OS: Guia Completo para Firmware em RTOS</p>



<p class="wp-block-paragraph"><strong>Frase-chave foco</strong></p>


<div class="root-eb-toc-iu744 wp-block-essential-blocks-table-of-contents"><div class="eb-parent-wrapper eb-parent-eb-toc-iu744 "><div class="eb-toc-container eb-toc-iu744  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;1 \u2013 Introdu\u00e7\u00e3o: o papel de Interrup\u00e7\u00f5es e Soft Timers em um RTOS moderno&quot;,&quot;text&quot;:&quot;1 \u2013 Introdu\u00e7\u00e3o: o papel de Interrup\u00e7\u00f5es e Soft Timers em um RTOS moderno&quot;,&quot;link&quot;:&quot;eb-table-content-0&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2 \u2013 Modelo de Interrup\u00e7\u00f5es no Zephyr: conceitos fundamentais&quot;,&quot;text&quot;:&quot;2 \u2013 Modelo de Interrup\u00e7\u00f5es no Zephyr: conceitos fundamentais&quot;,&quot;link&quot;:&quot;eb-table-content-1&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;O que \u00e9 uma ISR no Zephyr?&quot;,&quot;text&quot;:&quot;O que \u00e9 uma ISR no Zephyr?&quot;,&quot;link&quot;:&quot;eb-table-content-2&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3 \u2013 Conectando uma interrup\u00e7\u00e3o no Zephyr (exemplo com GPIO)&quot;,&quot;text&quot;:&quot;3 \u2013 Conectando uma interrup\u00e7\u00e3o no Zephyr (exemplo com GPIO)&quot;,&quot;link&quot;:&quot;eb-table-content-3&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Passo 1 \u2013 Defini\u00e7\u00e3o no Devicetree (conceito)&quot;,&quot;text&quot;:&quot;Passo 1 \u2013 Defini\u00e7\u00e3o no Devicetree (conceito)&quot;,&quot;link&quot;:&quot;eb-table-content-4&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Passo 2 \u2013 Estrutura de callback de GPIO&quot;,&quot;text&quot;:&quot;Passo 2 \u2013 Estrutura de callback de GPIO&quot;,&quot;link&quot;:&quot;passo-2-estrutura-de-callback-de-gpio&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Passo 3 \u2013 Implementa\u00e7\u00e3o da ISR&quot;,&quot;text&quot;:&quot;Passo 3 \u2013 Implementa\u00e7\u00e3o da ISR&quot;,&quot;link&quot;:&quot;eb-table-content-6&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Passo 4 \u2013 Configura\u00e7\u00e3o do GPIO e da interrup\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Passo 4 \u2013 Configura\u00e7\u00e3o do GPIO e da interrup\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-7&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4 \u2013 Arquitetura correta: ISR + sinaliza\u00e7\u00e3o de thread&quot;,&quot;text&quot;:&quot;4 \u2013 Arquitetura correta: ISR + sinaliza\u00e7\u00e3o de thread&quot;,&quot;link&quot;:&quot;eb-table-content-8&quot;}]" data-visible="[true,true,true,true,true,true]" data-delete-headers="[{&quot;label&quot;:&quot;1 \u2013 Introdu\u00e7\u00e3o: o papel de Interrup\u00e7\u00f5es e Soft Timers em um RTOS moderno&quot;,&quot;value&quot;:&quot;1-introdu\u00e7\u00e3o-o-papel-de-interrup\u00e7\u00f5es-e-soft-timers-em-um-rtos-moderno&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2 \u2013 Modelo de Interrup\u00e7\u00f5es no Zephyr: conceitos fundamentais&quot;,&quot;value&quot;:&quot;2-modelo-de-interrup\u00e7\u00f5es-no-zephyr-conceitos-fundamentais&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;O que \u00e9 uma ISR no Zephyr?&quot;,&quot;value&quot;:&quot;o-que-\u00e9-uma-isr-no-zephyr&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3 \u2013 Conectando uma interrup\u00e7\u00e3o no Zephyr (exemplo com GPIO)&quot;,&quot;value&quot;:&quot;3-conectando-uma-interrup\u00e7\u00e3o-no-zephyr-exemplo-com-gpio&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Passo 1 \u2013 Defini\u00e7\u00e3o no Devicetree (conceito)&quot;,&quot;value&quot;:&quot;passo-1-defini\u00e7\u00e3o-no-devicetree-conceito&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Passo 2 \u2013 Estrutura de callback de GPIO&quot;,&quot;value&quot;:&quot;passo-2-estrutura-de-callback-de-gpio&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Passo 3 \u2013 Implementa\u00e7\u00e3o da ISR&quot;,&quot;value&quot;:&quot;passo-3-implementa\u00e7\u00e3o-da-isr&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Passo 4 \u2013 Configura\u00e7\u00e3o do GPIO e da interrup\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;passo-4-configura\u00e7\u00e3o-do-gpio-e-da-interrup\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4 \u2013 Arquitetura correta: ISR + sinaliza\u00e7\u00e3o de thread&quot;,&quot;value&quot;:&quot;4-arquitetura-correta-isr-sinaliza\u00e7\u00e3o-de-thread&quot;,&quot;isDelete&quot;:false}]" data-smooth="true" data-top-offset=""><div class="eb-toc__list-wrap"><ul class="eb-toc__list"><li><a href="#eb-table-content-0">1 – Introdução: o papel de Interrupções e Soft Timers em um RTOS moderno</a><li><a href="#eb-table-content-1">2 – Modelo de Interrupções no Zephyr: conceitos fundamentais</a><ul class="eb-toc__list"><li><a href="#eb-table-content-2">O que é uma ISR no Zephyr?</a></li></ul><li><a href="#eb-table-content-3">3 – Conectando uma interrupção no Zephyr (exemplo com GPIO)</a><ul class="eb-toc__list"><li><a href="#eb-table-content-4">Passo 1 – Definição no Devicetree (conceito)</a><li><a href="#passo-2-estrutura-de-callback-de-gpio">Passo 2 – Estrutura de callback de GPIO</a><li><a href="#eb-table-content-6">Passo 3 – Implementação da ISR</a><li><a href="#eb-table-content-7">Passo 4 – Configuração do GPIO e da interrupção</a></li></ul><li><a href="#eb-table-content-8">4 – Arquitetura correta: ISR + sinalização de thread</a></ul></div></div></div></div></div>


<h3 class="wp-block-heading"><strong>1 – Introdução: o papel de Interrupções e Soft Timers em um RTOS moderno</strong></h3>



<p class="wp-block-paragraph">Em sistemas embarcados modernos, especialmente aqueles baseados em um <strong>RTOS (Real-Time Operating System)</strong> como o <strong>Zephyr OS</strong>, a forma como lidamos com eventos assíncronos define diretamente a robustez, a previsibilidade temporal e a escalabilidade do firmware. Dois mecanismos são absolutamente centrais nesse contexto: <strong>interrupções de hardware</strong> e <strong>soft timers</strong>. Embora ambos sejam usados para reagir a eventos no tempo ou no mundo físico, eles possuem naturezas, custos e implicações arquiteturais bastante distintas.</p>



<p class="wp-block-paragraph">As <strong>interrupções</strong> permitem que o hardware “interrompa” a execução normal da CPU para tratar eventos críticos e de baixa latência, como mudanças em GPIOs, chegada de dados em periféricos ou estouros de contadores. Já os <strong>soft timers</strong> do Zephyr são abstrações de alto nível baseadas no kernel, que permitem executar callbacks temporizados sem recorrer a timers de hardware dedicados ou lógica de polling. Essa separação clara entre o que é <em>tempo crítico</em> e o que é <em>tempo gerenciado pelo kernel</em> é uma das grandes virtudes do Zephyr.</p>



<p class="wp-block-paragraph">Um erro comum de quem vem de arquiteturas bare-metal ou de RTOS mais simples é tentar resolver tudo com interrupções. No Zephyr, isso é um <strong>anti-padrão arquitetural</strong>. O sistema foi projetado para que interrupções sejam <strong>curtas, determinísticas e não bloqueantes</strong>, delegando o processamento mais pesado para threads, workqueues ou timers. Entender essa filosofia é essencial para escrever firmware escalável e seguro.</p>



<p class="wp-block-paragraph">Ao longo deste artigo, vamos explorar:</p>



<ul class="wp-block-list">
<li>Como o Zephyr trata <strong>interrupções</strong> de forma portável e segura</li>



<li>Como configurar e usar <strong>ISRs (Interrupt Service Routines)</strong> corretamente</li>



<li>Como funcionam os <strong>Soft Timers (<code>k_timer</code>)</strong></li>



<li>Quando usar interrupção, timer ou thread</li>



<li>Padrões e armadilhas comuns em projetos reais</li>
</ul>



<p class="wp-block-paragraph">Sempre com exemplos em C, comentados e aplicáveis a placas reais como STM32, nRF e RP2040.</p>



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



<h3 class="wp-block-heading"><strong>2 – Modelo de Interrupções no Zephyr: conceitos fundamentais</strong></h3>



<p class="wp-block-paragraph">Antes de escrever qualquer ISR no Zephyr, é fundamental entender que o sistema adota um <strong>modelo de interrupções abstraído</strong>, desacoplado do hardware específico, mas ainda permitindo acesso direto quando necessário. O Zephyr se apoia em três pilares principais:</p>



<ol class="wp-block-list">
<li><strong>Árvore de dispositivos (Devicetree)</strong></li>



<li><strong>API genérica de IRQ do kernel</strong></li>



<li><strong>Separação rígida entre contexto de interrupção e contexto de thread</strong></li>
</ol>



<p class="wp-block-paragraph">No Zephyr, interrupções <strong>não são configuradas diretamente em registradores</strong> no código da aplicação (como em bare-metal). Em vez disso, elas são declaradas e conectadas por meio do <strong>Devicetree</strong>, que descreve o hardware de forma declarativa. Isso permite que o mesmo código rode, sem modificações, em arquiteturas distintas.</p>



<h4 class="wp-block-heading"><strong>O que é uma ISR no Zephyr?</strong></h4>



<p class="wp-block-paragraph">Uma <strong>ISR (Interrupt Service Routine)</strong> no Zephyr é uma função C comum, mas com restrições severas:</p>



<ul class="wp-block-list">
<li>Não pode bloquear</li>



<li>Não pode usar <code>k_sleep()</code></li>



<li>Não pode alocar memória dinâmica</li>



<li>Não pode chamar APIs que dependem do escalonador</li>
</ul>



<p class="wp-block-paragraph">Ela deve apenas:</p>



<ul class="wp-block-list">
<li>Reconhecer o evento</li>



<li>Capturar dados mínimos</li>



<li>Sinalizar uma thread, timer ou workqueue</li>
</ul>



<p class="wp-block-paragraph">Esse modelo força uma arquitetura mais limpa e previsível.</p>



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



<h3 class="wp-block-heading"><strong>3 – Conectando uma interrupção no Zephyr (exemplo com GPIO)</strong></h3>



<p class="wp-block-paragraph">Vamos começar com um exemplo clássico: <strong>interrupção por mudança de nível em um pino GPIO</strong>, algo extremamente comum em botões, sensores e sinais externos.</p>



<h4 class="wp-block-heading"><strong>Passo 1 – Definição no Devicetree (conceito)</strong></h4>



<p class="wp-block-paragraph">O Zephyr já fornece nós de GPIO prontos no Devicetree. Em geral, você não precisa criar nada manualmente, apenas referenciar o pino correto.</p>



<p class="wp-block-paragraph">Exemplo conceitual (simplificado):</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>button0: button_0 {
    gpios = &lt;&amp;gpioa 0 GPIO_ACTIVE_LOW>;
};
</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">button0: button_0 {</span></span>
<span class="line"><span style="color: #D8DEE9FF">    gpios = &lt;&amp;gpioa 0 GPIO_ACTIVE_LOW&gt;;</span></span>
<span class="line"><span style="color: #D8DEE9FF">};</span></span>
<span class="line"></span></code></pre></div>



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



<h4 class="wp-block-heading"><strong>Passo 2 – Estrutura de callback de GPIO</strong></h4>



<p class="wp-block-paragraph">No Zephyr, interrupções de GPIO usam a estrutura <code>gpio_callback</code>.</p>



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

/* Callback associado à interrupção */
static struct gpio_callback button_cb_data;
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">#include &lt;zephyr/kernel.h&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">#include &lt;zephyr/drivers/gpio.h&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">/* Callback associado à interrupção */</span></span>
<span class="line"><span style="color: #D8DEE9FF">static struct gpio_callback button_cb_data;</span></span>
<span class="line"></span></code></pre></div>



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



<h4 class="wp-block-heading"><strong>Passo 3 – Implementação da ISR</strong></h4>



<p class="wp-block-paragraph">A função de callback será executada <strong>em contexto de interrupção</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 button_pressed_isr(const struct device *dev,
                        struct gpio_callback *cb,
                        uint32_t pins)
{
    ARG_UNUSED(dev);
    ARG_UNUSED(cb);
    ARG_UNUSED(pins);

    /* ISR deve ser curta e não bloqueante */
    printk("Botão pressionado!\n");
}
</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">void button_pressed_isr(const struct device *dev,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                        struct gpio_callback *cb,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                        uint32_t pins)</span></span>
<span class="line"><span style="color: #D8DEE9FF">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    ARG_UNUSED(dev);</span></span>
<span class="line"><span style="color: #D8DEE9FF">    ARG_UNUSED(cb);</span></span>
<span class="line"><span style="color: #D8DEE9FF">    ARG_UNUSED(pins);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    /* ISR deve ser curta e não bloqueante */</span></span>
<span class="line"><span style="color: #D8DEE9FF">    printk(&quot;Botão pressionado!\n&quot;);</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Observação importante</strong>:<br>Mesmo o <code>printk()</code> não é ideal dentro de ISR em sistemas críticos. Ele é usado aqui apenas para fins didáticos. Em projetos reais, o correto é sinalizar uma thread.</p>



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



<h4 class="wp-block-heading"><strong>Passo 4 – Configuração do GPIO e da interrupção</strong></h4>



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

button_dev = DEVICE_DT_GET(DT_NODELABEL(gpioa));

gpio_pin_configure(button_dev, 0, GPIO_INPUT | GPIO_PULL_UP);

gpio_pin_interrupt_configure(button_dev,
                              0,
                              GPIO_INT_EDGE_FALLING);

gpio_init_callback(&amp;button_cb_data,
                   button_pressed_isr,
                   BIT(0));

gpio_add_callback(button_dev, &amp;button_cb_data);
</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">const struct device *button_dev;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">button_dev = DEVICE_DT_GET(DT_NODELABEL(gpioa));</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">gpio_pin_configure(button_dev, 0, GPIO_INPUT | GPIO_PULL_UP);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">gpio_pin_interrupt_configure(button_dev,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                              0,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                              GPIO_INT_EDGE_FALLING);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">gpio_init_callback(&amp;button_cb_data,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                   button_pressed_isr,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                   BIT(0));</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">gpio_add_callback(button_dev, &amp;button_cb_data);</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Neste ponto:</p>



<ul class="wp-block-list">
<li>O hardware gera a interrupção</li>



<li>O driver de GPIO chama a ISR</li>



<li>O kernel garante isolamento e segurança</li>
</ul>



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



<h3 class="wp-block-heading"><strong>4 – Arquitetura correta: ISR + sinalização de thread</strong></h3>



<p class="wp-block-paragraph">A forma correta de usar interrupções no Zephyr é <strong>acordar ou sinalizar uma thread</strong>, e não executar lógica pesada na ISR.</p>



<p class="wp-block-paragraph">Exemplo usando <strong>semaforos</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>K_SEM_DEFINE(button_sem, 0, 1);

void button_pressed_isr(const struct device *dev,
                        struct gpio_callback *cb,
                        uint32_t pins)
{
    k_sem_give(&amp;button_sem);
}
</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">K_SEM_DEFINE(button_sem, 0, 1);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">void button_pressed_isr(const struct device *dev,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                        struct gpio_callback *cb,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                        uint32_t pins)</span></span>
<span class="line"><span style="color: #D8DEE9FF">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    k_sem_give(&amp;button_sem);</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Thread associada:</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 button_thread(void)
{
    while (1) {
        k_sem_take(&amp;button_sem, K_FOREVER);
        printk("Evento tratado em thread\n");
    }
}
</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">void button_thread(void)</span></span>
<span class="line"><span style="color: #D8DEE9FF">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    while (1) {</span></span>
<span class="line"><span style="color: #D8DEE9FF">        k_sem_take(&amp;button_sem, K_FOREVER);</span></span>
<span class="line"><span style="color: #D8DEE9FF">        printk(&quot;Evento tratado em thread\n&quot;);</span></span>
<span class="line"><span style="color: #D8DEE9FF">    }</span></span>
<span class="line"><span style="color: #D8DEE9FF">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Essa arquitetura:</p>



<ul class="wp-block-list">
<li>Mantém ISRs determinísticas</li>



<li>Evita jitter</li>



<li>Escala melhor com múltiplos eventos</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/><p>The post <a href="https://mcu.tec.br/rtos/interrupcoes-e-soft-timers-no-zephyr-os/">Interrupções e Soft Timers no Zephyr OS</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1244</post-id>	</item>
		<item>
		<title>Criando um Projeto Zephyr RTOS no Arduino DUE – Guia Completo e Didático</title>
		<link>https://mcu.tec.br/rtos/criando-um-projeto-zephyr-rtos-no-arduino-due-guia-completo-e-didatico/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=criando-um-projeto-zephyr-rtos-no-arduino-due-guia-completo-e-didatico</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Fri, 27 Mar 2026 09:01:10 +0000</pubDate>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[RTOS]]></category>
		<category><![CDATA[Arduino DUE]]></category>
		<category><![CDATA[ARM Cortex-M3]]></category>
		<category><![CDATA[firmware profissional]]></category>
		<category><![CDATA[rtos]]></category>
		<category><![CDATA[SAM3X8E]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[Zephyr Arduino]]></category>
		<category><![CDATA[Zephyr RTOS]]></category>
		<category><![CDATA[Zephyr tutorial]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1209</guid>

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


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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



<li>SPI</li>



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



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



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



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



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



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



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



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



<li>Python 3.10+</li>



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



<li>Zephyr SDK instalada</li>



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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

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

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



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



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



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



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



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



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



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



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



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



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



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



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



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



<li>Driver de porta serial</li>



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



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



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



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



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



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

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

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

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



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



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



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



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



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



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



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



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



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



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



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



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



<li>Selecionar o SoC SAM3X8E</li>



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



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



<li>Console serial ativo</li>



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



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



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



<li>GPIO e LEDs</li>



<li>UARTs adicionais</li>



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



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



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



<p class="wp-block-paragraph"></p><p>The post <a href="https://mcu.tec.br/rtos/criando-um-projeto-zephyr-rtos-no-arduino-due-guia-completo-e-didatico/">Criando um Projeto Zephyr RTOS no Arduino DUE – Guia Completo e Didático</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1209</post-id>	</item>
		<item>
		<title>Containerização em Sistemas Embarcados com Zephyr OS</title>
		<link>https://mcu.tec.br/rtos/containerizacao-em-sistemas-embarcados-com-zephyr-os/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=containerizacao-em-sistemas-embarcados-com-zephyr-os</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Wed, 25 Feb 2026 17:20:40 +0000</pubDate>
				<category><![CDATA[RTOS]]></category>
		<category><![CDATA[arquitetura embarcada segura]]></category>
		<category><![CDATA[containerização no Zephyr OS]]></category>
		<category><![CDATA[containers embarcados]]></category>
		<category><![CDATA[domínios de memória RTOS]]></category>
		<category><![CDATA[firmware modular]]></category>
		<category><![CDATA[isolamento de aplicações em microcontroladores]]></category>
		<category><![CDATA[MPU em Cortex-M]]></category>
		<category><![CDATA[segurança em IoT]]></category>
		<category><![CDATA[userspace Zephyr]]></category>
		<category><![CDATA[Zephyr RTOS]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1386</guid>

					<description><![CDATA[<p>Entenda como funciona a containerização no Zephyr OS e como o conceito de containers foi adaptado para sistemas embarcados e dispositivos IoT. Descubra como o Zephyr implementa isolamento de aplicações utilizando MPU, separação entre kernel e user space, domínios de memória e arquitetura multi-image. Saiba quais são as diferenças em relação ao Docker tradicional, os desafios em microcontroladores sem MMU e os benefícios para segurança, modularidade e atualizações OTA. Um guia técnico detalhado para engenheiros que desejam evoluir de firmware monolítico para arquiteturas embarcadas compartimentadas e mais seguras.</p>
<p>The post <a href="https://mcu.tec.br/rtos/containerizacao-em-sistemas-embarcados-com-zephyr-os/">Containerização em Sistemas Embarcados com Zephyr OS</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<h2 class="wp-block-heading">Introdução</h2>



<p class="wp-block-paragraph">Durante muitos anos, a ideia de containerização esteve restrita ao universo de servidores e computação em nuvem. Tecnologias como Docker revolucionaram a forma como aplicações são distribuídas, implantadas e isoladas em ambientes Linux, permitindo que sistemas complexos fossem divididos em componentes independentes, seguros e facilmente atualizáveis. Entretanto, à medida que dispositivos IoT passaram a assumir funções críticas — desde gateways industriais até dispositivos médicos e infraestrutura conectada — surgiu uma necessidade semelhante no mundo dos sistemas embarcados: como isolar aplicações, garantir segurança e permitir atualizações modulares em microcontroladores com recursos limitados?</p>



<p class="wp-block-paragraph">É nesse contexto que surge a evolução do conceito de containerização aplicada ao Zephyr, um sistema operacional de tempo real (RTOS) amplamente utilizado em dispositivos IoT e aplicações embarcadas. Diferentemente do modelo tradicional baseado em kernel Linux, hypervisors e virtualização pesada, a abordagem embarcada exige um redesenho do conceito de container para se adequar a arquiteturas com pouca memória, ausência de MMU (Memory Management Unit) e requisitos rígidos de determinismo temporal.</p>



<p class="wp-block-paragraph">Este artigo explora como a containerização funciona no Zephyr OS, quais mecanismos tornam isso possível e quais são as implicações arquiteturais dessa nova abordagem para firmware moderno.</p>



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



<h2 class="wp-block-heading">O Conceito Original de Containerização</h2>



<p class="wp-block-paragraph">No ambiente Linux tradicional, containerização consiste em empacotar uma aplicação juntamente com todas as suas dependências em uma unidade isolada chamada container. Diferente de uma máquina virtual, que executa um sistema operacional completo sobre um hypervisor, o container compartilha o kernel do sistema hospedeiro, isolando apenas o espaço de usuário.</p>



<p class="wp-block-paragraph">Esse isolamento é obtido por meio de mecanismos como namespaces (isolamento de processos, rede e sistema de arquivos) e cgroups (controle de uso de CPU e memória). O resultado é um ambiente leve, eficiente e altamente portátil. Uma aplicação pode ser executada da mesma forma em diferentes máquinas, desde que o runtime de container esteja presente.</p>



<p class="wp-block-paragraph">Contudo, esse modelo depende fortemente de características típicas de sistemas Linux completos, como suporte a virtualização, gerenciamento avançado de memória e separação robusta entre kernel e espaço de usuário. Em microcontroladores, esse cenário é completamente diferente.</p>



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



<h2 class="wp-block-heading">O Desafio da Containerização em Microcontroladores</h2>



<p class="wp-block-paragraph">Em sistemas embarcados baseados em microcontroladores — como aqueles da família Cortex-M, ESP32 ou RP2040 — frequentemente não há suporte a MMU, e muitas vezes o sistema roda em modo bare-metal ou com um RTOS enxuto. A memória é limitada, e o firmware tradicionalmente é monolítico: todas as funcionalidades são compiladas juntas em uma única imagem binária.</p>



<p class="wp-block-paragraph">Nesse modelo tradicional, um erro em qualquer parte do firmware pode comprometer todo o sistema. Não há isolamento real entre módulos, nem separação de privilégios. Isso se torna particularmente problemático quando o dispositivo precisa executar múltiplas aplicações, receber atualizações OTA (Over-The-Air) ou rodar código de terceiros.</p>



<p class="wp-block-paragraph">O que o Zephyr propõe é uma adaptação do conceito de containerização para esse contexto restrito, utilizando os recursos disponíveis no hardware embarcado.</p>



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



<h2 class="wp-block-heading">Como o Zephyr Implementa Containerização</h2>



<p class="wp-block-paragraph">A containerização no Zephyr não utiliza virtualização nem hypervisor. Em vez disso, ela se apoia em três pilares fundamentais:</p>



<ol class="wp-block-list">
<li>Separação entre kernel e espaço de usuário</li>



<li>Uso de MPU (Memory Protection Unit) quando disponível</li>



<li>Definição de domínios de memória e permissões de acesso</li>
</ol>



<p class="wp-block-paragraph">O Zephyr permite que threads sejam executadas em modo usuário. Nessas condições, o acesso à memória e a periféricos é controlado pelo kernel. Cada aplicação pode ser associada a um domínio de memória específico, contendo apenas as regiões às quais ela tem permissão de acesso. Caso uma thread tente acessar uma região não autorizada, uma exceção é gerada.</p>



<p class="wp-block-paragraph">Esse mecanismo cria uma forma de sandboxing embarcado. Embora não seja um container Linux no sentido tradicional, ele oferece isolamento suficiente para impedir que falhas em um módulo comprometam o restante do sistema.</p>



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



<h2 class="wp-block-heading">Domínios de Memória e Isolamento</h2>



<p class="wp-block-paragraph">O conceito central por trás da containerização no Zephyr é o de memory domains. Um domínio de memória define um conjunto de regiões que uma aplicação pode acessar. Essas regiões podem incluir:</p>



<ul class="wp-block-list">
<li>Segmentos de código</li>



<li>Buffers de dados</li>



<li>Pilhas (stacks)</li>



<li>Heaps específicos</li>



<li>Áreas compartilhadas controladas</li>
</ul>



<p class="wp-block-paragraph">Quando a MPU está presente, o hardware impõe essas restrições fisicamente. Isso garante que uma aplicação não consiga acessar memória pertencente a outra aplicação ou ao kernel.</p>



<p class="wp-block-paragraph">Essa abordagem transforma o firmware monolítico tradicional em uma arquitetura modular compartimentada. Cada módulo passa a operar como se estivesse dentro de seu próprio container lógico.</p>



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



<h2 class="wp-block-heading">Multi-Image e Atualizações Modulares</h2>



<p class="wp-block-paragraph">Outra característica importante é a possibilidade de trabalhar com múltiplas imagens de firmware. Em arquiteturas mais avançadas, como aquelas com bootloaders seguros e suporte a atualização OTA, diferentes componentes podem ser atualizados independentemente.</p>



<p class="wp-block-paragraph">Esse modelo se aproxima ainda mais da filosofia de containerização moderna: componentes independentes, versionáveis e substituíveis sem necessidade de reconstruir todo o sistema.</p>



<p class="wp-block-paragraph">Para dispositivos IoT conectados à nuvem, essa capacidade é estratégica. Ela permite corrigir vulnerabilidades específicas sem interromper todo o sistema, além de viabilizar aplicações de terceiros com maior segurança.</p>



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



<h2 class="wp-block-heading">Diferenças Fundamentais em Relação ao Docker</h2>



<p class="wp-block-paragraph">É importante enfatizar que a containerização no Zephyr não executa Docker dentro do microcontrolador. Não há suporte a namespaces Linux nem gerenciamento de imagens no formato tradicional.</p>



<p class="wp-block-paragraph">O que existe é uma implementação conceitual do isolamento, baseada em recursos de hardware embarcado. A proteção depende da MPU e da arquitetura do microcontrolador. Em dispositivos sem suporte a proteção de memória, o nível de isolamento é limitado.</p>



<p class="wp-block-paragraph">Portanto, trata-se de uma adaptação do paradigma, e não de uma replicação direta da tecnologia de containers usada em servidores.</p>



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



<h2 class="wp-block-heading">Impacto Arquitetural</h2>



<p class="wp-block-paragraph">A introdução de containerização no contexto do Zephyr representa uma mudança significativa na forma como firmware embarcado é estruturado. Em vez de um único bloco de código com acesso irrestrito a todos os recursos, passa-se a um modelo de aplicações isoladas, com permissões explícitas e fronteiras bem definidas.</p>



<p class="wp-block-paragraph">Isso aproxima sistemas embarcados do modelo cloud-native, onde aplicações são desacopladas, independentes e resilientes. Para aplicações industriais, médicas e de infraestrutura crítica, esse nível adicional de segurança e modularidade pode ser determinante.</p>



<p class="wp-block-paragraph">Além disso, a abordagem fortalece a segurança cibernética em dispositivos IoT, mitigando riscos associados a execução de código malicioso ou falhas não tratadas.</p>



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



<h2 class="wp-block-heading">Referências</h2>



<p class="wp-block-paragraph">Electronic Design — “You Can Now Use Containers with Zephyr OS”<br><a href="https://www.electronicdesign.com/technologies/embedded/software/video/55355192/electronic-design-you-can-now-use-containers-with-zephyr-os">https://www.electronicdesign.com/technologies/embedded/software/video/55355192/electronic-design-you-can-now-use-containers-with-zephyr-os</a></p>



<p class="wp-block-paragraph">Vídeo explicativo sobre containers no Zephyr OS<br><a href="https://www.youtube.com/watch?v=qqaKtV05NqA&amp;t=120s">https://www.youtube.com/watch?v=qqaKtV05NqA&amp;t=120s</a></p>



<p class="wp-block-paragraph">Documentação oficial do Zephyr Project<br><a href="https://docs.zephyrproject.org/">https://docs.zephyrproject.org</a></p>



<p class="wp-block-paragraph">Documentação do Docker<br><a href="https://docs.docker.com/">https://docs.docker.com</a></p><p>The post <a href="https://mcu.tec.br/rtos/containerizacao-em-sistemas-embarcados-com-zephyr-os/">Containerização em Sistemas Embarcados com Zephyr OS</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1386</post-id>	</item>
		<item>
		<title>Filas, Flags, Mutexes, Notificações e Eventos no Zephyr RTOS</title>
		<link>https://mcu.tec.br/rtos/filas-flags-mutexes-notificacoes-e-eventos-no-zephyr-rtos/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=filas-flags-mutexes-notificacoes-e-eventos-no-zephyr-rtos</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Tue, 06 Jan 2026 17:05:59 +0000</pubDate>
				<category><![CDATA[RTOS]]></category>
		<category><![CDATA[comunicação entre threads]]></category>
		<category><![CDATA[eventos Zephyr]]></category>
		<category><![CDATA[k_event]]></category>
		<category><![CDATA[k_mutex]]></category>
		<category><![CDATA[k_poll]]></category>
		<category><![CDATA[k_queue]]></category>
		<category><![CDATA[k_sem]]></category>
		<category><![CDATA[mutex Zephyr]]></category>
		<category><![CDATA[queues Zephyr]]></category>
		<category><![CDATA[RTOS em C]]></category>
		<category><![CDATA[semáforo Zephyr]]></category>
		<category><![CDATA[sincronização RTOS]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[Zephyr RTOS]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1052</guid>

					<description><![CDATA[<p>Aprenda em profundidade como usar queues, flags, semáforos, mutexes, eventos e notificações no Zephyr RTOS. Um guia didático e prático com exemplos em C, comparativos arquiteturais e boas práticas para construir sistemas embarcados robustos, determinísticos e escaláveis.</p>
<p>The post <a href="https://mcu.tec.br/rtos/filas-flags-mutexes-notificacoes-e-eventos-no-zephyr-rtos/">Filas, Flags, Mutexes, Notificações e Eventos no Zephyr RTOS</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph"></p>


<div class="root-eb-toc-hud2p wp-block-essential-blocks-table-of-contents"><div class="eb-parent-wrapper eb-parent-eb-toc-hud2p "><div class="eb-toc-container eb-toc-hud2p  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;:1,&quot;content&quot;:&quot;Vis\u00e3o Geral dos Mecanismos de Sincroniza\u00e7\u00e3o e Comunica\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Vis\u00e3o Geral dos Mecanismos de Sincroniza\u00e7\u00e3o e Comunica\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-0&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;1.1 Por que o Zephyr oferece m\u00faltiplos mecanismos?&quot;,&quot;text&quot;:&quot;1.1 Por que o Zephyr oferece m\u00faltiplos mecanismos?&quot;,&quot;link&quot;:&quot;eb-table-content-1&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;1.2 Threads no Zephyr: o pano de fundo necess\u00e1rio&quot;,&quot;text&quot;:&quot;1.2 Threads no Zephyr: o pano de fundo necess\u00e1rio&quot;,&quot;link&quot;:&quot;eb-table-content-2&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;1.3 Introdu\u00e7\u00e3o \u00e0s Queues no Zephyr&quot;,&quot;text&quot;:&quot;1.3 Introdu\u00e7\u00e3o \u00e0s Queues no Zephyr&quot;,&quot;link&quot;:&quot;eb-table-content-3&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;1.4 Estrutura b\u00e1sica de uma k_queue&quot;,&quot;text&quot;:&quot;1.4 Estrutura b\u00e1sica de uma k_queue&quot;,&quot;link&quot;:&quot;eb-table-content-4&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;1.5 Enviando dados para a fila (Producer)&quot;,&quot;text&quot;:&quot;1.5 Enviando dados para a fila (Producer)&quot;,&quot;link&quot;:&quot;15-enviando-dados-para-a-fila-producer&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;1.6 Recebendo dados da fila (Consumer)&quot;,&quot;text&quot;:&quot;1.6 Recebendo dados da fila (Consumer)&quot;,&quot;link&quot;:&quot;16-recebendo-dados-da-fila-consumer&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;1.7 Quando usar k_queue (e quando n\u00e3o usar)&quot;,&quot;text&quot;:&quot;1.7 Quando usar k_queue (e quando n\u00e3o usar)&quot;,&quot;link&quot;:&quot;eb-table-content-7&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;1.8 Erros comuns no uso de Queues no Zephyr&quot;,&quot;text&quot;:&quot;1.8 Erros comuns no uso de Queues no Zephyr&quot;,&quot;link&quot;:&quot;18-erros-comuns-no-uso-de-queues-no-zephyr&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Flags, Sem\u00e1foros e Eventos no Zephyr: Sinaliza\u00e7\u00e3o e Coordena\u00e7\u00e3o de Threads&quot;,&quot;text&quot;:&quot;Flags, Sem\u00e1foros e Eventos no Zephyr: Sinaliza\u00e7\u00e3o e Coordena\u00e7\u00e3o de Threads&quot;,&quot;link&quot;:&quot;eb-table-content-9&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.1 O que s\u00e3o \u201cFlags\u201d no contexto do Zephyr?&quot;,&quot;text&quot;:&quot;2.1 O que s\u00e3o \u201cFlags\u201d no contexto do Zephyr?&quot;,&quot;link&quot;:&quot;eb-table-content-10&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.2 Sem\u00e1foros (k_sem): a forma mais simples de flag&quot;,&quot;text&quot;:&quot;2.2 Sem\u00e1foros (k_sem): a forma mais simples de flag&quot;,&quot;link&quot;:&quot;eb-table-content-11&quot;},{&quot;level&quot;:4,&quot;content&quot;:&quot;Declara\u00e7\u00e3o de um sem\u00e1foro&quot;,&quot;text&quot;:&quot;Declara\u00e7\u00e3o de um sem\u00e1foro&quot;,&quot;link&quot;:&quot;eb-table-content-12&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.3 Thread aguardando um sem\u00e1foro (consumidor do evento)&quot;,&quot;text&quot;:&quot;2.3 Thread aguardando um sem\u00e1foro (consumidor do evento)&quot;,&quot;link&quot;:&quot;eb-table-content-13&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.4 Thread ou ISR liberando o sem\u00e1foro (produtor do evento)&quot;,&quot;text&quot;:&quot;2.4 Thread ou ISR liberando o sem\u00e1foro (produtor do evento)&quot;,&quot;link&quot;:&quot;eb-table-content-14&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.5 Sem\u00e1foro bin\u00e1rio vs sem\u00e1foro contador&quot;,&quot;text&quot;:&quot;2.5 Sem\u00e1foro bin\u00e1rio vs sem\u00e1foro contador&quot;,&quot;link&quot;:&quot;eb-table-content-15&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.6 Limita\u00e7\u00f5es dos sem\u00e1foros como flags&quot;,&quot;text&quot;:&quot;2.6 Limita\u00e7\u00f5es dos sem\u00e1foros como flags&quot;,&quot;link&quot;:&quot;eb-table-content-16&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.7 Eventos (k_event): flags m\u00faltiplas em um \u00fanico objeto&quot;,&quot;text&quot;:&quot;2.7 Eventos (k_event): flags m\u00faltiplas em um \u00fanico objeto&quot;,&quot;link&quot;:&quot;eb-table-content-17&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.8 Definindo flags de evento&quot;,&quot;text&quot;:&quot;2.8 Definindo flags de evento&quot;,&quot;link&quot;:&quot;28-definindo-flags-de-evento&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.9 Sinalizando eventos&quot;,&quot;text&quot;:&quot;2.9 Sinalizando eventos&quot;,&quot;link&quot;:&quot;29-sinalizando-eventos&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.10 Aguardando eventos&quot;,&quot;text&quot;:&quot;2.10 Aguardando eventos&quot;,&quot;link&quot;:&quot;210-aguardando-eventos&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.11 Quando usar k_sem vs k_event&quot;,&quot;text&quot;:&quot;2.11 Quando usar k_sem vs k_event&quot;,&quot;link&quot;:&quot;211-quando-usar-k_sem-vs-k_event&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;2.12 Erros comuns com Flags e Eventos&quot;,&quot;text&quot;:&quot;2.12 Erros comuns com Flags e Eventos&quot;,&quot;link&quot;:&quot;212-erros-comuns-com-flags-e-eventos&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Mutex no Zephyr: Exclus\u00e3o M\u00fatua, Heran\u00e7a de Prioridade e Uso Correto&quot;,&quot;text&quot;:&quot;Mutex no Zephyr: Exclus\u00e3o M\u00fatua, Heran\u00e7a de Prioridade e Uso Correto&quot;,&quot;link&quot;:&quot;eb-table-content-23&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.1 Por que Mutex existem (e por que eles s\u00e3o perigosos)&quot;,&quot;text&quot;:&quot;3.1 Por que Mutex existem (e por que eles s\u00e3o perigosos)&quot;,&quot;link&quot;:&quot;eb-table-content-24&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.2 O que \u00e9 um recurso compartilhado de verdade?&quot;,&quot;text&quot;:&quot;3.2 O que \u00e9 um recurso compartilhado de verdade?&quot;,&quot;link&quot;:&quot;eb-table-content-25&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.3 Declara\u00e7\u00e3o e inicializa\u00e7\u00e3o de um Mutex&quot;,&quot;text&quot;:&quot;3.3 Declara\u00e7\u00e3o e inicializa\u00e7\u00e3o de um Mutex&quot;,&quot;link&quot;:&quot;eb-table-content-26&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.4 Protegendo uma regi\u00e3o cr\u00edtica com k_mutex&quot;,&quot;text&quot;:&quot;3.4 Protegendo uma regi\u00e3o cr\u00edtica com k_mutex&quot;,&quot;link&quot;:&quot;eb-table-content-27&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.5 Mutex no Zephyr n\u00e3o \u00e9 ISR-safe&quot;,&quot;text&quot;:&quot;3.5 Mutex no Zephyr n\u00e3o \u00e9 ISR-safe&quot;,&quot;link&quot;:&quot;eb-table-content-28&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.6 Invers\u00e3o de prioridade: o problema cl\u00e1ssico&quot;,&quot;text&quot;:&quot;3.6 Invers\u00e3o de prioridade: o problema cl\u00e1ssico&quot;,&quot;link&quot;:&quot;eb-table-content-29&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.7 Heran\u00e7a de prioridade no k_mutex&quot;,&quot;text&quot;:&quot;3.7 Heran\u00e7a de prioridade no k_mutex&quot;,&quot;link&quot;:&quot;eb-table-content-30&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.8 Timeout em mutex: quando faz sentido?&quot;,&quot;text&quot;:&quot;3.8 Timeout em mutex: quando faz sentido?&quot;,&quot;link&quot;:&quot;38-timeout-em-mutex-quando-faz-sentido&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.9 Deadlocks: como eles surgem&quot;,&quot;text&quot;:&quot;3.9 Deadlocks: como eles surgem&quot;,&quot;link&quot;:&quot;39-deadlocks-como-eles-surgem&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.10 Boas pr\u00e1ticas para uso de mutex no Zephyr&quot;,&quot;text&quot;:&quot;3.10 Boas pr\u00e1ticas para uso de mutex no Zephyr&quot;,&quot;link&quot;:&quot;eb-table-content-33&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;3.11 Quando n\u00e3o usar mutex&quot;,&quot;text&quot;:&quot;3.11 Quando n\u00e3o usar mutex&quot;,&quot;link&quot;:&quot;eb-table-content-34&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;Notifica\u00e7\u00f5es e k_poll: Esperando M\u00faltiplos Eventos de Forma Elegante&quot;,&quot;text&quot;:&quot;Notifica\u00e7\u00f5es e k_poll: Esperando M\u00faltiplos Eventos de Forma Elegante&quot;,&quot;link&quot;:&quot;eb-table-content-35&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.1 Por que k_poll existe?&quot;,&quot;text&quot;:&quot;4.1 Por que k_poll existe?&quot;,&quot;link&quot;:&quot;41-por-que-k_poll-existe&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.2 O que \u00e9 k_poll conceitualmente?&quot;,&quot;text&quot;:&quot;4.2 O que \u00e9 k_poll conceitualmente?&quot;,&quot;link&quot;:&quot;eb-table-content-37&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.3 Objetos suportados pelo k_poll&quot;,&quot;text&quot;:&quot;4.3 Objetos suportados pelo k_poll&quot;,&quot;link&quot;:&quot;43-objetos-suportados-pelo-k_poll&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.4 Declarando eventos de polling&quot;,&quot;text&quot;:&quot;4.4 Declarando eventos de polling&quot;,&quot;link&quot;:&quot;44-declarando-eventos-de-polling&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.5 Aguardando m\u00faltiplos eventos&quot;,&quot;text&quot;:&quot;4.5 Aguardando m\u00faltiplos eventos&quot;,&quot;link&quot;:&quot;eb-table-content-40&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.6 k_poll n\u00e3o \u00e9 uma fila nem uma flag&quot;,&quot;text&quot;:&quot;4.6 k_poll n\u00e3o \u00e9 uma fila nem uma flag&quot;,&quot;link&quot;:&quot;eb-table-content-41&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.7 k_poll_signal: notifica\u00e7\u00f5es leves e diretas&quot;,&quot;text&quot;:&quot;4.7 k_poll_signal: notifica\u00e7\u00f5es leves e diretas&quot;,&quot;link&quot;:&quot;eb-table-content-42&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.8 Arquitetura orientada a eventos com k_poll&quot;,&quot;text&quot;:&quot;4.8 Arquitetura orientada a eventos com k_poll&quot;,&quot;link&quot;:&quot;48-arquitetura-orientada-a-eventos-com-k_poll&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.9 Quando n\u00e3o usar k_poll&quot;,&quot;text&quot;:&quot;4.9 Quando n\u00e3o usar k_poll&quot;,&quot;link&quot;:&quot;eb-table-content-44&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;4.10 Erros comuns com k_poll&quot;,&quot;text&quot;:&quot;4.10 Erros comuns com k_poll&quot;,&quot;link&quot;:&quot;410-erros-comuns-com-k_poll&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot; Comparativo Pr\u00e1tico e Diretrizes Arquiteturais no Zephyr&quot;,&quot;text&quot;:&quot; Comparativo Pr\u00e1tico e Diretrizes Arquiteturais no Zephyr&quot;,&quot;link&quot;:&quot;eb-table-content-46&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.1 O problema real: escolher o mecanismo errado&quot;,&quot;text&quot;:&quot;5.1 O problema real: escolher o mecanismo errado&quot;,&quot;link&quot;:&quot;51-o-problema-real-escolher-o-mecanismo-errado&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.2 Comparativo conceitual direto&quot;,&quot;text&quot;:&quot;5.2 Comparativo conceitual direto&quot;,&quot;link&quot;:&quot;52-comparativo-conceitual-direto&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.3 Diretrizes pr\u00e1ticas de escolha (regra de engenharia)&quot;,&quot;text&quot;:&quot;5.3 Diretrizes pr\u00e1ticas de escolha (regra de engenharia)&quot;,&quot;link&quot;:&quot;eb-table-content-49&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.4 Arquitetura t\u00edpica bem projetada no Zephyr&quot;,&quot;text&quot;:&quot;5.4 Arquitetura t\u00edpica bem projetada no Zephyr&quot;,&quot;link&quot;:&quot;eb-table-content-50&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.5 Erros arquiteturais cl\u00e1ssicos a evitar&quot;,&quot;text&quot;:&quot;5.5 Erros arquiteturais cl\u00e1ssicos a evitar&quot;,&quot;link&quot;:&quot;eb-table-content-51&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;5.6 Conclus\u00e3o da s\u00e9rie (neste artigo)&quot;,&quot;text&quot;:&quot;5.6 Conclus\u00e3o da s\u00e9rie (neste artigo)&quot;,&quot;link&quot;:&quot;eb-table-content-52&quot;}]" data-visible="[true,true,true,true,true,true]" data-delete-headers="[{&quot;label&quot;:&quot;Vis\u00e3o Geral dos Mecanismos de Sincroniza\u00e7\u00e3o e Comunica\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;vis\u00e3o-geral-dos-mecanismos-de-sincroniza\u00e7\u00e3o-e-comunica\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.1 Por que o Zephyr oferece m\u00faltiplos mecanismos?&quot;,&quot;value&quot;:&quot;11-por-que-o-zephyr-oferece-m\u00faltiplos-mecanismos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.2 Threads no Zephyr: o pano de fundo necess\u00e1rio&quot;,&quot;value&quot;:&quot;12-threads-no-zephyr-o-pano-de-fundo-necess\u00e1rio&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.3 Introdu\u00e7\u00e3o \u00e0s Queues no Zephyr&quot;,&quot;value&quot;:&quot;13-introdu\u00e7\u00e3o-\u00e0s-queues-no-zephyr&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.4 Estrutura b\u00e1sica de uma k_queue&quot;,&quot;value&quot;:&quot;14-estrutura-b\u00e1sica-de-uma-k_queue&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.5 Enviando dados para a fila (Producer)&quot;,&quot;value&quot;:&quot;15-enviando-dados-para-a-fila-producer&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.6 Recebendo dados da fila (Consumer)&quot;,&quot;value&quot;:&quot;16-recebendo-dados-da-fila-consumer&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.7 Quando usar k_queue (e quando n\u00e3o usar)&quot;,&quot;value&quot;:&quot;17-quando-usar-k_queue-e-quando-n\u00e3o-usar&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;1.8 Erros comuns no uso de Queues no Zephyr&quot;,&quot;value&quot;:&quot;18-erros-comuns-no-uso-de-queues-no-zephyr&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Flags, Sem\u00e1foros e Eventos no Zephyr: Sinaliza\u00e7\u00e3o e Coordena\u00e7\u00e3o de Threads&quot;,&quot;value&quot;:&quot;flags-sem\u00e1foros-e-eventos-no-zephyr-sinaliza\u00e7\u00e3o-e-coordena\u00e7\u00e3o-de-threads&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.1 O que s\u00e3o \u201cFlags\u201d no contexto do Zephyr?&quot;,&quot;value&quot;:&quot;21-o-que-s\u00e3o-flags-no-contexto-do-zephyr&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.2 Sem\u00e1foros (k_sem): a forma mais simples de flag&quot;,&quot;value&quot;:&quot;22-sem\u00e1foros-k_sem-a-forma-mais-simples-de-flag&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Declara\u00e7\u00e3o de um sem\u00e1foro&quot;,&quot;value&quot;:&quot;declara\u00e7\u00e3o-de-um-sem\u00e1foro&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.3 Thread aguardando um sem\u00e1foro (consumidor do evento)&quot;,&quot;value&quot;:&quot;23-thread-aguardando-um-sem\u00e1foro-consumidor-do-evento&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.4 Thread ou ISR liberando o sem\u00e1foro (produtor do evento)&quot;,&quot;value&quot;:&quot;24-thread-ou-isr-liberando-o-sem\u00e1foro-produtor-do-evento&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.5 Sem\u00e1foro bin\u00e1rio vs sem\u00e1foro contador&quot;,&quot;value&quot;:&quot;25-sem\u00e1foro-bin\u00e1rio-vs-sem\u00e1foro-contador&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.6 Limita\u00e7\u00f5es dos sem\u00e1foros como flags&quot;,&quot;value&quot;:&quot;26-limita\u00e7\u00f5es-dos-sem\u00e1foros-como-flags&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.7 Eventos (k_event): flags m\u00faltiplas em um \u00fanico objeto&quot;,&quot;value&quot;:&quot;27-eventos-k_event-flags-m\u00faltiplas-em-um-\u00fanico-objeto&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.8 Definindo flags de evento&quot;,&quot;value&quot;:&quot;28-definindo-flags-de-evento&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.9 Sinalizando eventos&quot;,&quot;value&quot;:&quot;29-sinalizando-eventos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.10 Aguardando eventos&quot;,&quot;value&quot;:&quot;210-aguardando-eventos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.11 Quando usar k_sem vs k_event&quot;,&quot;value&quot;:&quot;211-quando-usar-k_sem-vs-k_event&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;2.12 Erros comuns com Flags e Eventos&quot;,&quot;value&quot;:&quot;212-erros-comuns-com-flags-e-eventos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Mutex no Zephyr: Exclus\u00e3o M\u00fatua, Heran\u00e7a de Prioridade e Uso Correto&quot;,&quot;value&quot;:&quot;mutex-no-zephyr-exclus\u00e3o-m\u00fatua-heran\u00e7a-de-prioridade-e-uso-correto&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.1 Por que Mutex existem (e por que eles s\u00e3o perigosos)&quot;,&quot;value&quot;:&quot;31-por-que-mutex-existem-e-por-que-eles-s\u00e3o-perigosos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.2 O que \u00e9 um recurso compartilhado de verdade?&quot;,&quot;value&quot;:&quot;32-o-que-\u00e9-um-recurso-compartilhado-de-verdade&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.3 Declara\u00e7\u00e3o e inicializa\u00e7\u00e3o de um Mutex&quot;,&quot;value&quot;:&quot;33-declara\u00e7\u00e3o-e-inicializa\u00e7\u00e3o-de-um-mutex&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.4 Protegendo uma regi\u00e3o cr\u00edtica com k_mutex&quot;,&quot;value&quot;:&quot;34-protegendo-uma-regi\u00e3o-cr\u00edtica-com-k_mutex&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.5 Mutex no Zephyr n\u00e3o \u00e9 ISR-safe&quot;,&quot;value&quot;:&quot;35-mutex-no-zephyr-n\u00e3o-\u00e9-isr-safe&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.6 Invers\u00e3o de prioridade: o problema cl\u00e1ssico&quot;,&quot;value&quot;:&quot;36-invers\u00e3o-de-prioridade-o-problema-cl\u00e1ssico&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.7 Heran\u00e7a de prioridade no k_mutex&quot;,&quot;value&quot;:&quot;37-heran\u00e7a-de-prioridade-no-k_mutex&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.8 Timeout em mutex: quando faz sentido?&quot;,&quot;value&quot;:&quot;38-timeout-em-mutex-quando-faz-sentido&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.9 Deadlocks: como eles surgem&quot;,&quot;value&quot;:&quot;39-deadlocks-como-eles-surgem&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.10 Boas pr\u00e1ticas para uso de mutex no Zephyr&quot;,&quot;value&quot;:&quot;310-boas-pr\u00e1ticas-para-uso-de-mutex-no-zephyr&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;3.11 Quando n\u00e3o usar mutex&quot;,&quot;value&quot;:&quot;311-quando-n\u00e3o-usar-mutex&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Notifica\u00e7\u00f5es e k_poll: Esperando M\u00faltiplos Eventos de Forma Elegante&quot;,&quot;value&quot;:&quot;notifica\u00e7\u00f5es-e-k_poll-esperando-m\u00faltiplos-eventos-de-forma-elegante&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.1 Por que k_poll existe?&quot;,&quot;value&quot;:&quot;41-por-que-k_poll-existe&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.2 O que \u00e9 k_poll conceitualmente?&quot;,&quot;value&quot;:&quot;42-o-que-\u00e9-k_poll-conceitualmente&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.3 Objetos suportados pelo k_poll&quot;,&quot;value&quot;:&quot;43-objetos-suportados-pelo-k_poll&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.4 Declarando eventos de polling&quot;,&quot;value&quot;:&quot;44-declarando-eventos-de-polling&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.5 Aguardando m\u00faltiplos eventos&quot;,&quot;value&quot;:&quot;45-aguardando-m\u00faltiplos-eventos&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.6 k_poll n\u00e3o \u00e9 uma fila nem uma flag&quot;,&quot;value&quot;:&quot;46-k_poll-n\u00e3o-\u00e9-uma-fila-nem-uma-flag&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.7 k_poll_signal: notifica\u00e7\u00f5es leves e diretas&quot;,&quot;value&quot;:&quot;47-k_poll_signal-notifica\u00e7\u00f5es-leves-e-diretas&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.8 Arquitetura orientada a eventos com k_poll&quot;,&quot;value&quot;:&quot;48-arquitetura-orientada-a-eventos-com-k_poll&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.9 Quando n\u00e3o usar k_poll&quot;,&quot;value&quot;:&quot;49-quando-n\u00e3o-usar-k_poll&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;4.10 Erros comuns com k_poll&quot;,&quot;value&quot;:&quot;410-erros-comuns-com-k_poll&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot; Comparativo Pr\u00e1tico e Diretrizes Arquiteturais no Zephyr&quot;,&quot;value&quot;:&quot;comparativo-pr\u00e1tico-e-diretrizes-arquiteturais-no-zephyr&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.1 O problema real: escolher o mecanismo errado&quot;,&quot;value&quot;:&quot;51-o-problema-real-escolher-o-mecanismo-errado&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.2 Comparativo conceitual direto&quot;,&quot;value&quot;:&quot;52-comparativo-conceitual-direto&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.3 Diretrizes pr\u00e1ticas de escolha (regra de engenharia)&quot;,&quot;value&quot;:&quot;53-diretrizes-pr\u00e1ticas-de-escolha-regra-de-engenharia&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.4 Arquitetura t\u00edpica bem projetada no Zephyr&quot;,&quot;value&quot;:&quot;54-arquitetura-t\u00edpica-bem-projetada-no-zephyr&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.5 Erros arquiteturais cl\u00e1ssicos a evitar&quot;,&quot;value&quot;:&quot;55-erros-arquiteturais-cl\u00e1ssicos-a-evitar&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;5.6 Conclus\u00e3o da s\u00e9rie (neste artigo)&quot;,&quot;value&quot;:&quot;56-conclus\u00e3o-da-s\u00e9rie-neste-artigo&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">Visão Geral dos Mecanismos de Sincronização e Comunicação</a><ul class="eb-toc__list"><li><a href="#eb-table-content-1">1.1 Por que o Zephyr oferece múltiplos mecanismos?</a><li><a href="#eb-table-content-2">1.2 Threads no Zephyr: o pano de fundo necessário</a><li><a href="#eb-table-content-3">1.3 Introdução às Queues no Zephyr</a><li><a href="#eb-table-content-4">1.4 Estrutura básica de uma k_queue</a><li><a href="#15-enviando-dados-para-a-fila-producer">1.5 Enviando dados para a fila (Producer)</a><li><a href="#16-recebendo-dados-da-fila-consumer">1.6 Recebendo dados da fila (Consumer)</a><li><a href="#eb-table-content-7">1.7 Quando usar k_queue (e quando não usar)</a><li><a href="#18-erros-comuns-no-uso-de-queues-no-zephyr">1.8 Erros comuns no uso de Queues no Zephyr</a><li><a href="#eb-table-content-9">Flags, Semáforos e Eventos no Zephyr: Sinalização e Coordenação de Threads</a><ul class="eb-toc__list"><li><a href="#eb-table-content-10">2.1 O que são “Flags” no contexto do Zephyr?</a><li><a href="#eb-table-content-11">2.2 Semáforos (k_sem): a forma mais simples de flag</a><ul class="eb-toc__list"><li><a href="#eb-table-content-12">Declaração de um semáforo</a></li></ul><li><a href="#eb-table-content-13">2.3 Thread aguardando um semáforo (consumidor do evento)</a><li><a href="#eb-table-content-14">2.4 Thread ou ISR liberando o semáforo (produtor do evento)</a><li><a href="#eb-table-content-15">2.5 Semáforo binário vs semáforo contador</a><li><a href="#eb-table-content-16">2.6 Limitações dos semáforos como flags</a><li><a href="#eb-table-content-17">2.7 Eventos (k_event): flags múltiplas em um único objeto</a><li><a href="#28-definindo-flags-de-evento">2.8 Definindo flags de evento</a><li><a href="#29-sinalizando-eventos">2.9 Sinalizando eventos</a><li><a href="#210-aguardando-eventos">2.10 Aguardando eventos</a><li><a href="#211-quando-usar-k_sem-vs-k_event">2.11 Quando usar k_sem vs k_event</a><li><a href="#212-erros-comuns-com-flags-e-eventos">2.12 Erros comuns com Flags e Eventos</a></li></ul><li><a href="#eb-table-content-23">Mutex no Zephyr: Exclusão Mútua, Herança de Prioridade e Uso Correto</a><ul class="eb-toc__list"><li><a href="#eb-table-content-24">3.1 Por que Mutex existem (e por que eles são perigosos)</a><li><a href="#eb-table-content-25">3.2 O que é um recurso compartilhado de verdade?</a><li><a href="#eb-table-content-26">3.3 Declaração e inicialização de um Mutex</a><li><a href="#eb-table-content-27">3.4 Protegendo uma região crítica com k_mutex</a><li><a href="#eb-table-content-28">3.5 Mutex no Zephyr não é ISR-safe</a><li><a href="#eb-table-content-29">3.6 Inversão de prioridade: o problema clássico</a><li><a href="#eb-table-content-30">3.7 Herança de prioridade no k_mutex</a><li><a href="#38-timeout-em-mutex-quando-faz-sentido">3.8 Timeout em mutex: quando faz sentido?</a><li><a href="#39-deadlocks-como-eles-surgem">3.9 Deadlocks: como eles surgem</a><li><a href="#eb-table-content-33">3.10 Boas práticas para uso de mutex no Zephyr</a><li><a href="#eb-table-content-34">3.11 Quando não usar mutex</a></li></ul><li><a href="#eb-table-content-35">Notificações e k_poll: Esperando Múltiplos Eventos de Forma Elegante</a><ul class="eb-toc__list"><li><a href="#41-por-que-k_poll-existe">4.1 Por que k_poll existe?</a><li><a href="#eb-table-content-37">4.2 O que é k_poll conceitualmente?</a><li><a href="#43-objetos-suportados-pelo-k_poll">4.3 Objetos suportados pelo k_poll</a><li><a href="#44-declarando-eventos-de-polling">4.4 Declarando eventos de polling</a><li><a href="#eb-table-content-40">4.5 Aguardando múltiplos eventos</a><li><a href="#eb-table-content-41">4.6 k_poll não é uma fila nem uma flag</a><li><a href="#eb-table-content-42">4.7 k_poll_signal: notificações leves e diretas</a><li><a href="#48-arquitetura-orientada-a-eventos-com-k_poll">4.8 Arquitetura orientada a eventos com k_poll</a><li><a href="#eb-table-content-44">4.9 Quando não usar k_poll</a><li><a href="#410-erros-comuns-com-k_poll">4.10 Erros comuns com k_poll</a></li></ul><li><a href="#eb-table-content-46"> Comparativo Prático e Diretrizes Arquiteturais no Zephyr</a><ul class="eb-toc__list"><li><a href="#51-o-problema-real-escolher-o-mecanismo-errado">5.1 O problema real: escolher o mecanismo errado</a><li><a href="#52-comparativo-conceitual-direto">5.2 Comparativo conceitual direto</a><li><a href="#eb-table-content-49">5.3 Diretrizes práticas de escolha (regra de engenharia)</a><li><a href="#eb-table-content-50">5.4 Arquitetura típica bem projetada no Zephyr</a><li><a href="#eb-table-content-51">5.5 Erros arquiteturais clássicos a evitar</a><li><a href="#eb-table-content-52">5.6 Conclusão da série (neste artigo)</a></li></ul></li></ul></ul></div></div></div></div></div>


<h1 class="wp-block-heading">Visão Geral dos Mecanismos de Sincronização e Comunicação</h1>



<h3 class="wp-block-heading">1.1 Por que o Zephyr oferece múltiplos mecanismos?</h3>



<p class="wp-block-paragraph">Diferente de um RTOS minimalista, o <strong>Zephyr OS</strong> foi projetado para atender desde microcontroladores simples até sistemas complexos com múltiplos <em>cores</em>, <em>drivers</em>, <em>stacks de comunicação</em> e <em>middleware</em>. Por isso, ele <strong>não impõe um único modelo de comunicação entre threads</strong>, mas oferece vários mecanismos, cada um otimizado para um tipo específico de problema.</p>



<p class="wp-block-paragraph">Em termos práticos, isso significa que <strong>não existe “o melhor mecanismo”</strong>, mas sim <strong>o mecanismo correto para cada cenário</strong>. Usar <code>k_mutex</code> onde um <code>k_queue</code> seria adequado gera latência desnecessária. Usar <code>k_poll</code> quando um <code>k_sem</code> resolveria o problema aumenta complexidade sem ganho real.</p>



<p class="wp-block-paragraph">De forma conceitual, os mecanismos do Zephyr podem ser classificados em três grandes grupos:</p>



<ul class="wp-block-list">
<li><strong>Comunicação de dados</strong>: quando informações precisam ser transferidas entre threads</li>



<li><strong>Sincronização</strong>: quando o objetivo é coordenar execução</li>



<li><strong>Exclusão mútua</strong>: quando recursos compartilhados precisam ser protegidos</li>
</ul>



<p class="wp-block-paragraph">Nas próximas seções, vamos analisar como <strong>Queues, Flags, Mutexes, Notificações e Eventos</strong> se encaixam nesses grupos.</p>



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



<h3 class="wp-block-heading">1.2 Threads no Zephyr: o pano de fundo necessário</h3>



<p class="wp-block-paragraph">Antes de falar de filas e eventos, é importante lembrar que o Zephyr adota um <strong>modelo de threads preemptivas</strong>, com prioridades explícitas. Threads de prioridade menor podem ser interrompidas por threads de prioridade maior a qualquer momento.</p>



<p class="wp-block-paragraph">Isso cria dois desafios fundamentais:</p>



<ol class="wp-block-list">
<li><strong>Compartilhamento seguro de dados</strong></li>



<li><strong>Coordenação determinística entre tarefas concorrentes</strong></li>
</ol>



<p class="wp-block-paragraph">Sem mecanismos adequados, surgem problemas clássicos:</p>



<ul class="wp-block-list">
<li><em>Race conditions</em></li>



<li><em>Deadlocks</em></li>



<li><em>Priority inversion</em></li>



<li>Leitura de dados inconsistentes</li>
</ul>



<p class="wp-block-paragraph">Os objetos do kernel (<code>k_*</code>) existem exatamente para resolver esses problemas.</p>



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



<h3 class="wp-block-heading">1.3 Introdução às Queues no Zephyr</h3>



<p class="wp-block-paragraph">As <strong>Queues</strong> no Zephyr são usadas quando <strong>dados precisam ser transferidos entre contextos</strong>, tipicamente entre threads produtoras e consumidoras. Diferente de simples variáveis globais, as queues:</p>



<ul class="wp-block-list">
<li>Garantem <strong>acesso thread-safe</strong></li>



<li>Permitem <strong>bloqueio automático</strong></li>



<li>São integradas ao <strong>escalonador do kernel</strong></li>
</ul>



<p class="wp-block-paragraph">O Zephyr oferece múltiplos tipos de fila. A mais usada conceitualmente é a <strong><code>k_queue</code></strong>, que trabalha com <strong>ponteiros genéricos (<code>void *</code>)</strong>, permitindo grande flexibilidade.</p>



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



<h3 class="wp-block-heading">1.4 Estrutura básica de uma <code>k_queue</code></h3>



<p class="wp-block-paragraph">Uma fila no Zephyr é declarada estaticamente ou dinamicamente. O caso mais comum em sistemas embarcados é a <strong>declaração estática</strong>, que evita alocação dinâmica em tempo de execução.</p>



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

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



<p class="wp-block-paragraph">Essa macro cria:</p>



<ul class="wp-block-list">
<li>A estrutura de controle da fila</li>



<li>A sincronização interna</li>



<li>A integração com o escalonador</li>
</ul>



<p class="wp-block-paragraph">Não há necessidade de inicialização manual.</p>



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



<h3 class="wp-block-heading">1.5 Enviando dados para a fila (Producer)</h3>



<p class="wp-block-paragraph">Um produtor insere elementos na fila usando <code>k_queue_append()</code> ou <code>k_queue_prepend()</code>.</p>



<p class="wp-block-paragraph">Exemplo simples: uma thread que produz mensagens.</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>struct mensagem {
    uint32_t id;
    uint32_t valor;
};

void produtor_thread(void)
{
    static struct mensagem msg;

    while (1) {
        msg.id++;
        msg.valor = k_uptime_get_32();

        k_queue_append(&amp;minha_fila, &amp;msg);

        k_sleep(K_MSEC(500));
    }
}
</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">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">mensagem</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">uint32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">id</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">uint32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">valor</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">produtor_thread</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">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">mensagem</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">msg</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">while</span><span style="color: #D8DEE9FF"> (</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">msg</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">id</span><span style="color: #81A1C1">++;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">msg</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">valor</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">k_uptime_get_32</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">k_queue_append</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">minha_fila</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">msg</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">k_sleep</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">K_MSEC</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></code></pre></div>



<p class="wp-block-paragraph"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Ponto crítico</strong>:<br>A fila armazena <strong>ponteiros</strong>, não cópias.<br>Isso significa que:</p>



<ul class="wp-block-list">
<li>O objeto precisa existir enquanto estiver na fila</li>



<li>Variáveis automáticas de pilha <strong>não devem</strong> ser usadas</li>
</ul>



<p class="wp-block-paragraph">Esse detalhe é uma das principais fontes de bugs para quem vem de FreeRTOS (onde queues normalmente copiam dados).</p>



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



<h3 class="wp-block-heading">1.6 Recebendo dados da fila (Consumer)</h3>



<p class="wp-block-paragraph">O consumidor usa <code>k_queue_get()</code>, podendo:</p>



<ul class="wp-block-list">
<li>Bloquear indefinidamente</li>



<li>Bloquear por tempo definido</li>



<li>Não bloquear</li>
</ul>



<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 consumidor_thread(void)
{
    struct mensagem *msg;

    while (1) {
        msg = k_queue_get(&amp;minha_fila, K_FOREVER);

        printk("Recebido: id=%d valor=%d\n",
               msg->id, msg->valor);
    }
}
</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">consumidor_thread</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">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">mensagem</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">msg</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">while</span><span style="color: #D8DEE9FF"> (</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">msg</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">k_queue_get</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">minha_fila</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">K_FOREVER</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">printk</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Recebido: id=%d valor=%d</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">               </span><span style="color: #D8DEE9">msg</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">id</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">msg</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">valor</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">Aqui o kernel:</p>



<ul class="wp-block-list">
<li>Coloca a thread em <strong>estado bloqueado</strong></li>



<li>Acorda automaticamente quando um item chega</li>



<li>Garante que apenas um consumidor receba cada item</li>
</ul>



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



<h3 class="wp-block-heading">1.7 Quando usar <code>k_queue</code> (e quando não usar)</h3>



<p class="wp-block-paragraph">Use <strong>Queues</strong> quando:</p>



<ul class="wp-block-list">
<li>Dados precisam ser transferidos entre threads</li>



<li>Existe um padrão produtor–consumidor</li>



<li>O volume de dados não é trivial</li>



<li>A ordem de processamento importa</li>
</ul>



<p class="wp-block-paragraph">Evite <code>k_queue</code> quando:</p>



<ul class="wp-block-list">
<li>Apenas um <em>flag</em> é necessário</li>



<li>Não há dados associados ao evento</li>



<li>Latência mínima é crítica (flags são mais rápidas)</li>
</ul>



<p class="wp-block-paragraph">Nesses casos, <strong>Flags e Eventos</strong> são mais apropriados — tema da próxima seção.</p>



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



<h3 class="wp-block-heading">1.8 Erros comuns no uso de Queues no Zephyr</h3>



<p class="wp-block-paragraph">Alguns erros aparecem com frequência em projetos reais:</p>



<ol class="wp-block-list">
<li>Inserir ponteiros para variáveis locais</li>



<li>Reutilizar a mesma estrutura sem controle</li>



<li>Usar fila quando um simples evento resolveria</li>



<li>Esquecer que múltiplos consumidores competem pelo mesmo item</li>
</ol>



<p class="wp-block-paragraph">Esses erros não geram <em>warnings</em> de compilação, mas resultam em <strong>comportamento não determinístico</strong>, especialmente sob carga.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/><p>The post <a href="https://mcu.tec.br/rtos/filas-flags-mutexes-notificacoes-e-eventos-no-zephyr-rtos/">Filas, Flags, Mutexes, Notificações e Eventos no Zephyr RTOS</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1052</post-id>	</item>
		<item>
		<title>Introdução ao Zephyr RTOS: Entendendo Threads, DeviceTree e a Ausência do main()</title>
		<link>https://mcu.tec.br/rtos/introducao-ao-zephyr-rtos-entendendo-threads-devicetree-e-a-ausencia-do-main/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=introducao-ao-zephyr-rtos-entendendo-threads-devicetree-e-a-ausencia-do-main</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Wed, 24 Dec 2025 00:20:50 +0000</pubDate>
				<category><![CDATA[RTOS]]></category>
		<category><![CDATA[DeviceTree Zephyr]]></category>
		<category><![CDATA[exemplos Zephyr]]></category>
		<category><![CDATA[FIFO Zephyr]]></category>
		<category><![CDATA[K_THREAD_DEFINE]]></category>
		<category><![CDATA[kernel Zephyr]]></category>
		<category><![CDATA[programação embarcada RTOS]]></category>
		<category><![CDATA[threads no Zephyr]]></category>
		<category><![CDATA[Zephyr main.c]]></category>
		<category><![CDATA[Zephyr RTOS]]></category>
		<category><![CDATA[Zephyr sem main]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1037</guid>

					<description><![CDATA[<p>Tutorial técnico e didático sobre o Zephyr RTOS analisando em profundidade um exemplo real de código. O artigo explica o funcionamento das threads estáticas, o uso de macros do Zephyr, a integração com DeviceTree, comunicação entre threads via FIFO e o motivo pelo qual o arquivo main.c não possui a função main tradicional. Ideal para desenvolvedores de sistemas embarcados que desejam compreender a arquitetura interna do Zephyr e seu modelo de execução orientado a kernel.</p>
<p>The post <a href="https://mcu.tec.br/rtos/introducao-ao-zephyr-rtos-entendendo-threads-devicetree-e-a-ausencia-do-main/">Introdução ao Zephyr RTOS: Entendendo Threads, DeviceTree e a Ausência do main()</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<h2 class="wp-block-heading">Visão geral do exemplo e por que <strong>não existe <code>main()</code></strong> neste <code>src/main.c</code></h2>



<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>/*
 * Copyright (c) 2017 Linaro Limited
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include &lt;zephyr/kernel.h>
#include &lt;zephyr/device.h>
#include &lt;zephyr/drivers/gpio.h>
#include &lt;zephyr/sys/printk.h>
#include &lt;zephyr/sys/__assert.h>
#include &lt;string.h>

/* size of stack area used by each thread */
#define STACKSIZE 1024

/* scheduling priority used by each thread */
#define PRIORITY 7

#define LED0_NODE DT_ALIAS(led0)
#define LED1_NODE DT_ALIAS(led1)

#if !DT_NODE_HAS_STATUS_OKAY(LED0_NODE)
#error "Unsupported board: led0 devicetree alias is not defined"
#endif

#if !DT_NODE_HAS_STATUS_OKAY(LED1_NODE)
#error "Unsupported board: led1 devicetree alias is not defined"
#endif

struct printk_data_t {
	void *fifo_reserved; /* 1st word reserved for use by fifo */
	uint32_t led;
	uint32_t cnt;
};

K_FIFO_DEFINE(printk_fifo);

struct led {
	struct gpio_dt_spec spec;
	uint8_t num;
};

static const struct led led0 = {
	.spec = GPIO_DT_SPEC_GET_OR(LED0_NODE, gpios, {0}),
	.num = 0,
};

static const struct led led1 = {
	.spec = GPIO_DT_SPEC_GET_OR(LED1_NODE, gpios, {0}),
	.num = 1,
};

void blink(const struct led *led, uint32_t sleep_ms, uint32_t id)
{
	const struct gpio_dt_spec *spec = &amp;led->spec;
	int cnt = 0;
	int ret;

	if (!device_is_ready(spec->port)) {
		printk("Error: %s device is not ready\n", spec->port->name);
		return;
	}

	ret = gpio_pin_configure_dt(spec, GPIO_OUTPUT);
	if (ret != 0) {
		printk("Error %d: failed to configure pin %d (LED '%d')\n",
			ret, spec->pin, led->num);
		return;
	}

	while (1) {
		gpio_pin_set(spec->port, spec->pin, cnt % 2);

		struct printk_data_t tx_data = { .led = id, .cnt = cnt };

		size_t size = sizeof(struct printk_data_t);
		char *mem_ptr = k_malloc(size);
		__ASSERT_NO_MSG(mem_ptr != 0);

		memcpy(mem_ptr, &amp;tx_data, size);

		k_fifo_put(&amp;printk_fifo, mem_ptr);

		k_msleep(sleep_ms);
		cnt++;
	}
}

void blink0(void)
{
	blink(&amp;led0, 100, 0);
}

void blink1(void)
{
	blink(&amp;led1, 1000, 1);
}

void uart_out(void)
{
	while (1) {
		struct printk_data_t *rx_data = k_fifo_get(&amp;printk_fifo,
							   K_FOREVER);
		printk("Toggled led%d; counter=%d\n",
		       rx_data->led, rx_data->cnt);
		k_free(rx_data);
	}
}

K_THREAD_DEFINE(blink0_id, STACKSIZE, blink0, NULL, NULL, NULL,
		PRIORITY, 0, 0);
K_THREAD_DEFINE(blink1_id, STACKSIZE, blink1, NULL, NULL, NULL,
		PRIORITY, 0, 0);
K_THREAD_DEFINE(uart_out_id, STACKSIZE, uart_out, NULL, NULL, NULL,
		PRIORITY, 0, 0);
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88">/*</span></span>
<span class="line"><span style="color: #616E88"> * Copyright (c) 2017 Linaro Limited</span></span>
<span class="line"><span style="color: #616E88"> *</span></span>
<span class="line"><span style="color: #616E88"> * SPDX-License-Identifier: Apache-2.0</span></span>
<span class="line"><span style="color: #616E88"> */</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9">zephyr</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">kernel</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">h</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9">zephyr</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">device</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">h</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9">zephyr</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">drivers</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">gpio</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">h</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9">zephyr</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">sys</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">printk</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">h</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9">zephyr</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">sys</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">__assert</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">h</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">include</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9">string</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">h</span><span style="color: #81A1C1">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">/* size of stack area used by each thread */</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">STACKSIZE</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1024</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">/* scheduling priority used by each thread */</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">PRIORITY</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">7</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">LED0_NODE</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DT_ALIAS</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">led0</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: #D8DEE9">LED1_NODE</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DT_ALIAS</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">led1</span><span style="color: #D8DEE9FF">)</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: #81A1C1">!</span><span style="color: #88C0D0">DT_NODE_HAS_STATUS_OKAY</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">LED0_NODE</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">error</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Unsupported board: led0 devicetree alias is not defined</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">endif</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">!</span><span style="color: #88C0D0">DT_NODE_HAS_STATUS_OKAY</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">LED1_NODE</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">error</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Unsupported board: led1 devicetree alias is not defined</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">endif</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">printk_data_t</span><span style="color: #D8DEE9FF"> </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: #D8DEE9">fifo_reserved</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">/* 1st word reserved for use by fifo */</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">led</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">	</span><span style="color: #D8DEE9">uint32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">cnt</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">K_FIFO_DEFINE</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">printk_fifo</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">led</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">	</span><span style="color: #D8DEE9">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">gpio_dt_spec</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">spec</span><span style="color: #81A1C1">;</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">num</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">struct</span><span style="color: #D8DEE9FF"> led led0 </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">	.</span><span style="color: #D8DEE9">spec</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">GPIO_DT_SPEC_GET_OR</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">LED0_NODE</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">gpios</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #B48EAD">0</span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">	.</span><span style="color: #D8DEE9">num</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">struct</span><span style="color: #D8DEE9FF"> led led1 </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">	.</span><span style="color: #D8DEE9">spec</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">GPIO_DT_SPEC_GET_OR</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">LED1_NODE</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">gpios</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #B48EAD">0</span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">	.</span><span style="color: #D8DEE9">num</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">blink</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">led</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">led</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">uint32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">sleep_ms</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">uint32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">id</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">	</span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">struct</span><span style="color: #D8DEE9FF"> gpio_dt_spec *spec </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">led</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">spec</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">	</span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">cnt</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">	</span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ret</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: #81A1C1">!</span><span style="color: #88C0D0">device_is_ready</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">spec</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">port</span><span style="color: #D8DEE9FF">)) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">		</span><span style="color: #88C0D0">printk</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Error: %s device is not ready</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">spec</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">port</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">name</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">		</span><span style="color: #81A1C1">return;</span></span>
<span class="line"><span style="color: #D8DEE9FF">	</span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">	</span><span style="color: #D8DEE9">ret</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">gpio_pin_configure_dt</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">spec</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">GPIO_OUTPUT</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">	</span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">ret</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">!=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">		</span><span style="color: #88C0D0">printk</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Error %d: failed to configure pin %d (LED &#39;%d&#39;)</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">			</span><span style="color: #D8DEE9">ret</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">spec</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">pin</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">led</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">num</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">		</span><span style="color: #81A1C1">return;</span></span>
<span class="line"><span style="color: #D8DEE9FF">	</span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">	</span><span style="color: #81A1C1">while</span><span style="color: #D8DEE9FF"> (</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">		</span><span style="color: #88C0D0">gpio_pin_set</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">spec</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">port</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">spec</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">pin</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">cnt</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">%</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">		</span><span style="color: #D8DEE9">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">printk_data_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">tx_data</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> .</span><span style="color: #D8DEE9">led</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">id</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> .</span><span style="color: #D8DEE9">cnt</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">cnt</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">		</span><span style="color: #D8DEE9">size_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">size</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">sizeof</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">printk_data_t</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">		</span><span style="color: #D8DEE9">char</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">mem_ptr</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">k_malloc</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">size</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">		</span><span style="color: #88C0D0">__ASSERT_NO_MSG</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">mem_ptr</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">!=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">		</span><span style="color: #88C0D0">memcpy</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">mem_ptr</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">tx_data</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">size</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">k_fifo_put</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">printk_fifo</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">mem_ptr</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">k_msleep</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">sleep_ms</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">		</span><span style="color: #D8DEE9">cnt</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">blink0</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">blink</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">led0</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">100</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">blink1</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">blink</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">led1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1000</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">uart_out</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: #81A1C1">while</span><span style="color: #D8DEE9FF"> (</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">		</span><span style="color: #D8DEE9">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">printk_data_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">rx_data</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">k_fifo_get</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">printk_fifo</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">							   </span><span style="color: #D8DEE9">K_FOREVER</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">		</span><span style="color: #88C0D0">printk</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Toggled led%d; counter=%d</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">		       </span><span style="color: #D8DEE9">rx_data</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">led</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">rx_data</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">cnt</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">		</span><span style="color: #88C0D0">k_free</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">rx_data</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: #88C0D0">K_THREAD_DEFINE</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">blink0_id</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">STACKSIZE</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">blink0</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span><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: #D8DEE9">PRIORITY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #88C0D0">K_THREAD_DEFINE</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">blink1_id</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">STACKSIZE</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">blink1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span><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: #D8DEE9">PRIORITY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #88C0D0">K_THREAD_DEFINE</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">uart_out_id</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">STACKSIZE</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">uart_out</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span><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: #D8DEE9">PRIORITY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">O arquivo <code>src/main.c</code>  do exemplo (“threads”) listado acima, foi escrito para demonstrar uma ideia central do Zephyr: <strong>o seu aplicativo pode ser composto por <em>threads</em> declaradas estaticamente</strong>, que o kernel cria e inicia automaticamente durante o boot, sem você precisar de um “superloop” com <code>main()</code> controlando tudo.</p>



<p class="wp-block-paragraph">Em muitos firmwares baremetal (ou mesmo com alguns RTOS), o padrão é:</p>



<ul class="wp-block-list">
<li>o <em>startup</em> do microcontrolador chama <code>main()</code>;</li>



<li><code>main()</code> inicializa periféricos;</li>



<li>cria tarefas/threads;</li>



<li>entra em um <code>while(1)</code>.</li>
</ul>



<p class="wp-block-paragraph">No Zephyr, isso <strong>pode</strong> existir (há muitos exemplos que têm <code>void main(void)</code>), mas <strong>não é obrigatório</strong>. Neste sample, os autores optaram por um modelo ainda mais “RTOS puro”:</p>



<ol class="wp-block-list">
<li>O Zephyr sobe (boot + init do kernel).</li>



<li>O kernel inicializa infraestrutura (scheduler, heap, drivers, etc.).</li>



<li>As threads declaradas via <code>K_THREAD_DEFINE(...)</code> já entram no sistema como “threads do aplicativo”.</li>



<li>Cada thread roda seu próprio loop e coopera via primitivas do kernel (aqui, uma FIFO).</li>
</ol>



<p class="wp-block-paragraph">Ou seja: <strong>quem faz o papel de “fluxo principal” é o próprio kernel</strong>. O aplicativo é “plugado” nele por meio de <strong>definições estáticas</strong> (macros) que geram objetos e registram tudo para o boot.</p>



<h3 class="wp-block-heading">Onde “entra” o seu código então?</h3>



<p class="wp-block-paragraph">Neste exemplo, o código entra em <strong>três pontos</strong>:</p>



<ul class="wp-block-list">
<li><code>blink0()</code> → thread que pisca o LED0 e publica mensagens na FIFO.</li>



<li><code>blink1()</code> → thread que pisca o LED1 e publica mensagens na FIFO.</li>



<li><code>uart_out()</code> → thread que consome a FIFO e imprime via <code>printk()</code>.</li>
</ul>



<p class="wp-block-paragraph">Essas três funções viram threads por causa destas três linhas no final do arquivo:</p>



<pre class="wp-block-code"><code>K_THREAD_DEFINE(blink0_id, STACKSIZE, blink0, NULL, NULL, NULL, PRIORITY, 0, 0);
K_THREAD_DEFINE(blink1_id, STACKSIZE, blink1, NULL, NULL, NULL, PRIORITY, 0, 0);
K_THREAD_DEFINE(uart_out_id, STACKSIZE, uart_out, NULL, NULL, NULL, PRIORITY, 0, 0);
</code></pre>



<p class="wp-block-paragraph">A macro <code>K_THREAD_DEFINE</code> <strong>não é “só açúcar sintático”</strong>: ela efetivamente gera (em tempo de compilação) estruturas de thread, stack, metadados e a forma de o kernel iniciar essas threads no boot. Por isso dá para ter um app “100% thread-based” sem <code>main()</code>.</p>



<h3 class="wp-block-heading">Por que isso é uma boa ideia no Zephyr?</h3>



<ul class="wp-block-list">
<li><strong>Reprodutibilidade de boot</strong>: as threads já existem na imagem final, com stacks definidos e conhecidos.</li>



<li><strong>Menos código de “cola”</strong>: não precisa de um <code>main()</code> só para “criar threads”.</li>



<li><strong>Integração com o modelo do Zephyr</strong>: o kernel tem etapas de init bem definidas; seu app pode se encaixar nelas sem reinventar o fluxo.</li>
</ul>



<p class="wp-block-paragraph">Na próxima seção, eu faço a leitura guiada do topo do arquivo (includes + <code>#define</code>s), e começo a destrinchar as macros de DeviceTree (<code>DT_ALIAS</code>, <code>DT_NODE_HAS_STATUS_OKAY</code>, <code>GPIO_DT_SPEC_GET_OR</code>) e por que elas existem no Zephyr.</p>



<h2 class="wp-block-heading">Includes, <code>#define</code>s e a filosofia de portabilidade do Zephyr</h2>



<p class="wp-block-paragraph">Vamos agora caminhar <strong>do topo do <code>src/main.c</code> para baixo</strong>, entendendo por que cada include e cada macro existem — e como isso se conecta ao modelo arquitetural do Zephyr.</p>



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



<h3 class="wp-block-heading">Includes principais</h3>



<p class="wp-block-paragraph">Logo no início do arquivo, aparecem includes semelhantes a estes:</p>



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



<p class="wp-block-paragraph">Esses headers revelam muito sobre o <strong>estilo de programação do Zephyr</strong>.</p>



<h4 class="wp-block-heading"><code>&lt;zephyr/kernel.h&gt;</code></h4>



<p class="wp-block-paragraph">É o <strong>coração do RTOS</strong>. Aqui estão:</p>



<ul class="wp-block-list">
<li>tipos básicos do kernel (<code>k_tid_t</code>, <code>k_timeout_t</code>, etc.),</li>



<li>primitivas de sincronização,</li>



<li>definição das macros de thread (<code>K_THREAD_DEFINE</code>, <code>K_FIFO_DEFINE</code>, etc.),</li>



<li>funções como <code>k_sleep()</code>, <code>k_fifo_put()</code>, <code>k_fifo_get()</code>.</li>
</ul>



<p class="wp-block-paragraph">Sem esse include, você literalmente não “fala” com o kernel.</p>



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



<h4 class="wp-block-heading"><code>&lt;zephyr/device.h&gt;</code></h4>



<p class="wp-block-paragraph">Introduz o tipo <code>struct device</code>, que representa <strong>instâncias concretas de hardware</strong> (GPIO, UART, I2C, SPI…).</p>



<p class="wp-block-paragraph">No Zephyr:</p>



<ul class="wp-block-list">
<li>você <strong>não instancia drivers manualmente</strong>,</li>



<li>os dispositivos são criados a partir do <em>DeviceTree</em>,</li>



<li>o aplicativo apenas <em>obtém uma referência</em> para eles.</li>
</ul>



<p class="wp-block-paragraph">Esse detalhe é essencial para entender por que não existe <code>GPIOA</code>, <code>GPIOB</code>, ou registradores “na mão”, como em código baremetal tradicional.</p>



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



<h4 class="wp-block-heading"><code>&lt;zephyr/devicetree.h&gt;</code></h4>



<p class="wp-block-paragraph">Aqui começa uma das maiores diferenças entre Zephyr e firmwares clássicos.</p>



<p class="wp-block-paragraph">O <em>DeviceTree</em> é um <strong>modelo declarativo de hardware</strong>, herdado do mundo Linux, mas adaptado para sistemas embarcados.</p>



<p class="wp-block-paragraph">Esse header fornece macros que:</p>



<ul class="wp-block-list">
<li>acessam nós do DeviceTree em tempo de compilação,</li>



<li>validam se um periférico existe,</li>



<li>extraem pinos, portas, flags elétricas, etc.</li>
</ul>



<p class="wp-block-paragraph">Isso permite escrever <strong>o mesmo código C para placas completamente diferentes</strong>, sem <code>#ifdef STM32</code>, <code>#ifdef NRF</code>, etc.</p>



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



<h4 class="wp-block-heading"><code>&lt;zephyr/drivers/gpio.h&gt;</code></h4>



<p class="wp-block-paragraph">Define a API genérica de GPIO do Zephyr:</p>



<ul class="wp-block-list">
<li><code>gpio_pin_configure_dt()</code></li>



<li><code>gpio_pin_toggle_dt()</code></li>



<li><code>gpio_is_ready_dt()</code></li>
</ul>



<p class="wp-block-paragraph">Repare no sufixo <code>_dt</code>: ele indica que a função trabalha <strong>diretamente com dados vindos do DeviceTree</strong>, encapsulados em estruturas como <code>gpio_dt_spec</code>.</p>



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



<h4 class="wp-block-heading"><code>&lt;zephyr/sys/printk.h&gt;</code></h4>



<p class="wp-block-paragraph">Fornece <code>printk()</code>, que é:</p>



<ul class="wp-block-list">
<li>uma saída de debug simples,</li>



<li>segura para uso em contexto de kernel,</li>



<li>muito usada em exemplos.</li>
</ul>



<p class="wp-block-paragraph">Diferente de <code>printf</code>, <code>printk</code> não depende de libc completa e é mais previsível em RTOS.</p>



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



<h2 class="wp-block-heading">Macros de configuração: <code>STACKSIZE</code> e <code>PRIORITY</code></h2>



<p class="wp-block-paragraph">Logo após os includes, aparecem definições como:</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 STACKSIZE 1024
#define PRIORITY 7
</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: #D8DEE9">STACKSIZE</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1024</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">define</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">PRIORITY</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">7</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Essas macros <strong>não são decorativas</strong>.</p>



<h3 class="wp-block-heading"><code>STACKSIZE</code></h3>



<p class="wp-block-paragraph">No Zephyr, <strong>cada thread tem sua própria pilha</strong>, explicitamente definida.</p>



<p class="wp-block-paragraph">Isso é fundamental por dois motivos:</p>



<ol class="wp-block-list">
<li><strong>Determinismo</strong><br>Em sistemas embarcados críticos, saber exatamente quanto de stack cada thread usa é parte do projeto.</li>



<li><strong>Proteção e debug</strong><br>O Zephyr pode aplicar <em>stack canaries</em> e <em>stack overflow detection</em>.</li>
</ol>



<p class="wp-block-paragraph">Aqui, cada thread criada com <code>K_THREAD_DEFINE</code> receberá uma pilha de 1024 bytes.</p>



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



<h3 class="wp-block-heading"><code>PRIORITY</code></h3>



<p class="wp-block-paragraph">No Zephyr:</p>



<ul class="wp-block-list">
<li><strong>números menores → prioridade maior</strong></li>



<li>prioridades negativas são reservadas a threads do sistema</li>



<li>prioridades positivas são para o aplicativo</li>
</ul>



<p class="wp-block-paragraph">Logo, <code>PRIORITY 7</code> significa:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">thread de aplicação, com prioridade relativamente baixa.</p>
</blockquote>



<p class="wp-block-paragraph">Isso é coerente com o exemplo:</p>



<ul class="wp-block-list">
<li>piscar LED e imprimir mensagens <strong>não são tarefas críticas</strong>.</li>
</ul>



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



<h2 class="wp-block-heading">Introdução ao DeviceTree no código</h2>



<p class="wp-block-paragraph">Agora chegamos a um trecho essencial:</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 LED0_NODE DT_ALIAS(led0)
#define LED1_NODE DT_ALIAS(led1)
</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: #D8DEE9">LED0_NODE</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DT_ALIAS</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">led0</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: #D8DEE9">LED1_NODE</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DT_ALIAS</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">led1</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Aqui entra um conceito que costuma confundir quem vem do baremetal.</p>



<h3 class="wp-block-heading">O que é <code>DT_ALIAS(led0)</code>?</h3>



<p class="wp-block-paragraph">No arquivo <code>.dts</code> da placa (ou em um overlay), existe algo como:</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>aliases {
    led0 = &led0;
    led1 = &led1;
};
</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">aliases</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">led0</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">led0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">led1</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">led1</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">O <code>DT_ALIAS(led0)</code>:</p>



<ul class="wp-block-list">
<li>resolve, <strong>em tempo de compilação</strong>, o nó correspondente,</li>



<li>gera um identificador interno usado pelas macros seguintes.</li>
</ul>



<p class="wp-block-paragraph">Isso elimina:</p>



<ul class="wp-block-list">
<li>números mágicos de pino,</li>



<li>dependência direta da placa,</li>



<li><code>#ifdef</code> por fabricante.</li>
</ul>



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



<h2 class="wp-block-heading">Validação do hardware em <em>compile time</em>: <code>DT_NODE_HAS_STATUS_OKAY</code> e <code>GPIO_DT_SPEC_GET_OR</code></h2>



<p class="wp-block-paragraph">Agora entramos em uma das partes <strong>mais importantes e menos triviais</strong> do código: o trecho que liga o <em>DeviceTree</em> ao código C de forma <strong>segura, portável e verificável em tempo de compilação</strong>.</p>



<p class="wp-block-paragraph">O código é similar a este:</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>static const struct gpio_dt_spec led0 =
    GPIO_DT_SPEC_GET_OR(LED0_NODE, gpios, {0});

static const struct gpio_dt_spec led1 =
    GPIO_DT_SPEC_GET_OR(LED1_NODE, gpios, {0});
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">struct</span><span style="color: #D8DEE9FF"> gpio_dt_spec led0 </span><span style="color: #81A1C1">=</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">GPIO_DT_SPEC_GET_OR</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">LED0_NODE</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">gpios</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #B48EAD">0</span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">struct</span><span style="color: #D8DEE9FF"> gpio_dt_spec led1 </span><span style="color: #81A1C1">=</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">GPIO_DT_SPEC_GET_OR</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">LED1_NODE</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">gpios</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #B48EAD">0</span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Mas antes disso, normalmente aparece um <code>#if</code> de proteção:</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>#if !DT_NODE_HAS_STATUS_OKAY(LED0_NODE)
#error "Unsupported board: led0 devicetree alias is not defined"
#endif
</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: #81A1C1">if</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">!</span><span style="color: #88C0D0">DT_NODE_HAS_STATUS_OKAY</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">LED0_NODE</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">error</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Unsupported board: led0 devicetree alias is not defined</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #D8DEE9">endif</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Vamos entender cada parte com profundidade.</p>



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



<h2 class="wp-block-heading"><code>DT_NODE_HAS_STATUS_OKAY(...)</code></h2>



<h3 class="wp-block-heading">O que essa macro realmente faz?</h3>



<p class="wp-block-paragraph">Essa macro pergunta ao <em>DeviceTree</em>:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">“Existe um nó com esse identificador <strong>e</strong> ele está marcado como <code>status = "okay"</code>?”</p>
</blockquote>



<p class="wp-block-paragraph">No <code>.dts</code>, um LED típico é descrito assim:</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>led0: led_0 {
    gpios = &lt;&amp;gpioa 5 GPIO_ACTIVE_LOW>;
    label = "User LED";
    status = "okay";
};
</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">led0</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">led_0</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">gpios</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;&amp;</span><span style="color: #D8DEE9">gpioa</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">5</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">GPIO_ACTIVE_LOW</span><span style="color: #81A1C1">&gt;;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">label</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">User LED</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">status</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">okay</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



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



<ul class="wp-block-list">
<li>o alias não existir, <strong>ou</strong></li>



<li>o nó existir mas estiver desativado (<code>status = "disabled"</code>),</li>
</ul>



<p class="wp-block-paragraph">então <code>DT_NODE_HAS_STATUS_OKAY(LED0_NODE)</code> será <strong>falso</strong>.</p>



<h3 class="wp-block-heading">Por que o Zephyr prefere falhar em <em>compile time</em>?</h3>



<p class="wp-block-paragraph">Este <code>#error</code> não é um capricho.</p>



<p class="wp-block-paragraph">Ele garante que:</p>



<ul class="wp-block-list">
<li>você <strong>não gera um firmware inválido</strong>,</li>



<li>o erro aparece <strong>antes</strong> de gravar no hardware,</li>



<li>o mesmo código fonte denuncia automaticamente placas incompatíveis.</li>
</ul>



<p class="wp-block-paragraph">Em código baremetal clássico, isso só seria percebido:</p>



<ul class="wp-block-list">
<li>em runtime,</li>



<li>ou pior, como um LED que “não pisca” sem explicação.</li>
</ul>



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



<h2 class="wp-block-heading"><code>struct gpio_dt_spec</code></h2>



<p class="wp-block-paragraph">Agora vamos à estrutura que tudo gira em torno:</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>struct gpio_dt_spec {
    const struct device *port;
    gpio_pin_t pin;
    gpio_flags_t dt_flags;
};
</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">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">gpio_dt_spec</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">struct</span><span style="color: #D8DEE9FF"> device *port</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">gpio_pin_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pin</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">gpio_flags_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">dt_flags</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Ela encapsula <strong>tudo que você precisa para manipular um GPIO</strong>, sem saber:</p>



<ul class="wp-block-list">
<li>qual MCU é,</li>



<li>qual registrador usar,</li>



<li>se é STM32, nRF, ESP32, etc.</li>
</ul>



<p class="wp-block-paragraph">O <em>DeviceTree</em> preenche isso para você.</p>



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



<h2 class="wp-block-heading"><code>GPIO_DT_SPEC_GET_OR(...)</code></h2>



<p class="wp-block-paragraph">Essa macro é uma obra-prima de engenharia de firmware orientada a portabilidade.</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>GPIO_DT_SPEC_GET_OR(LED0_NODE, gpios, {0})
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">GPIO_DT_SPEC_GET_OR</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">LED0_NODE</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">gpios</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #B48EAD">0</span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Vamos decompor:</p>



<h3 class="wp-block-heading">1. <code>LED0_NODE</code></h3>



<p class="wp-block-paragraph">É o nó do DeviceTree resolvido pelo alias (<code>led0</code>).</p>



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



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



<p class="wp-block-paragraph">É o nome da <strong>propriedade</strong> dentro do nó.</p>



<p class="wp-block-paragraph">No <code>.dts</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>gpios = &lt;&amp;gpioa 5 GPIO_ACTIVE_LOW>;
</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">gpios</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;&amp;</span><span style="color: #D8DEE9">gpioa</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">5</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">GPIO_ACTIVE_LOW</span><span style="color: #81A1C1">&gt;;</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Ou seja:</p>



<ul class="wp-block-list">
<li>controlador GPIO,</li>



<li>número do pino,</li>



<li>flags elétricas.</li>
</ul>



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



<h3 class="wp-block-heading">3. <code>{0}</code></h3>



<p class="wp-block-paragraph">Valor padrão caso a propriedade não exista.</p>



<p class="wp-block-paragraph">Isso evita:</p>



<ul class="wp-block-list">
<li>ponteiros inválidos,</li>



<li>acesso a hardware inexistente,</li>



<li>falhas silenciosas.</li>
</ul>



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



<h3 class="wp-block-heading">O que essa macro gera na prática?</h3>



<p class="wp-block-paragraph">Ela cria <strong>uma instância constante</strong> de <code>gpio_dt_spec</code>, preenchida em tempo de compilação, algo conceitualmente assim:</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>led0.port = DEVICE_DT_GET(DT_NODELABEL(gpioa));
led0.pin = 5;
led0.dt_flags = GPIO_ACTIVE_LOW;
</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">led0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">port</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DEVICE_DT_GET</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">DT_NODELABEL</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">gpioa</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9">led0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">pin</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">5</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9">led0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">dt_flags</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">GPIO_ACTIVE_LOW</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Mas sem você escrever nada disso manualmente — e de forma portátil.</p>



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



<h2 class="wp-block-heading">Checagem em runtime: <code>gpio_is_ready_dt()</code></h2>



<p class="wp-block-paragraph">Mais adiante, dentro da thread, aparece:</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>if (!gpio_is_ready_dt(&amp;led0)) {
    return;
}
</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">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">!</span><span style="color: #88C0D0">gpio_is_ready_dt</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">led0</span><span style="color: #D8DEE9FF">)) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Aqui há uma distinção importante:</p>



<ul class="wp-block-list">
<li><em>compile time</em>: o nó existe e está válido</li>



<li><em>runtime</em>: o driver foi inicializado corretamente</li>
</ul>



<p class="wp-block-paragraph">Essa separação é <strong>arquiteturalmente correta</strong>:</p>



<ul class="wp-block-list">
<li>DeviceTree valida o <strong>hardware declarado</strong></li>



<li><code>gpio_is_ready_dt()</code> valida o <strong>estado do driver</strong></li>
</ul>



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



<h2 class="wp-block-heading">Seção 4 — Comunicação entre threads: <code>struct msg</code> e <code>K_FIFO_DEFINE</code></h2>



<p class="wp-block-paragraph">Agora entramos no <strong>mecanismo central de comunicação entre as threads</strong> deste exemplo: a FIFO do Zephyr.<br>Aqui o código deixa claro que o objetivo do sample <strong>não é piscar LEDs</strong>, mas <strong>demonstrar concorrência e troca de dados entre threads</strong>.</p>



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



<h3 class="wp-block-heading">A estrutura <code>struct msg</code></h3>



<p class="wp-block-paragraph">O código define algo conceitualmente assim:</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>struct msg {
    void *fifo_reserved;
    uint32_t led;
    uint32_t cnt;
};
</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">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">msg</span><span style="color: #D8DEE9FF"> </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: #D8DEE9">fifo_reserved</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">uint32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">led</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">uint32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">cnt</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Essa estrutura tem um detalhe que costuma passar despercebido por quem vem de FreeRTOS ou CMSIS-RTOS:</p>



<h4 class="wp-block-heading"><code>void *fifo_reserved;</code></h4>



<p class="wp-block-paragraph">Esse campo <strong>não é opcional</strong>.</p>



<p class="wp-block-paragraph">No Zephyr, as FIFOs (<code>k_fifo</code>) funcionam de maneira diferente de queues tradicionais:</p>



<ul class="wp-block-list">
<li>o kernel <strong>não copia dados</strong> para dentro da fila,</li>



<li>ele <strong>encadeia objetos já existentes na memória</strong>,</li>



<li>para isso, o primeiro campo da estrutura deve ser reservado para o kernel.</li>
</ul>



<p class="wp-block-paragraph">Ou seja:</p>



<ul class="wp-block-list">
<li>o kernel usa esse ponteiro para formar a lista encadeada interna da FIFO,</li>



<li>você nunca deve tocar nesse campo manualmente.</li>
</ul>



<p class="wp-block-paragraph"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4cc.png" alt="📌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Regra de ouro no Zephyr</strong></p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Se um objeto vai para uma FIFO ou LIFO, o primeiro membro da struct deve ser um ponteiro reservado ao kernel.</p>
</blockquote>



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



<h3 class="wp-block-heading">Campos de dados da mensagem</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>uint32_t led;
uint32_t cnt;
</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">uint32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">led</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9">uint32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">cnt</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Aqui temos o payload real:</p>



<ul class="wp-block-list">
<li><code>led</code> → identifica qual thread/LED gerou a mensagem</li>



<li><code>cnt</code> → contador de quantas vezes aquele LED já piscou</li>
</ul>



<p class="wp-block-paragraph">Isso permite que uma thread <strong>produza dados</strong> e outra <strong>consuma</strong>, sem qualquer dependência direta entre elas.</p>



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



<h2 class="wp-block-heading">Definição da FIFO: <code>K_FIFO_DEFINE</code></h2>



<p class="wp-block-paragraph">Em seguida, aparece algo como:</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>K_FIFO_DEFINE(printk_fifo);
</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: #88C0D0">K_FIFO_DEFINE</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">printk_fifo</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Essa macro:</p>



<ul class="wp-block-list">
<li>cria uma FIFO global,</li>



<li>alocada estaticamente,</li>



<li>pronta para uso desde o boot.</li>
</ul>



<p class="wp-block-paragraph">Não há:</p>



<ul class="wp-block-list">
<li><code>malloc</code>,</li>



<li><code>init</code>,</li>



<li><code>create</code>.</li>
</ul>



<p class="wp-block-paragraph">Tudo é resolvido <strong>em tempo de compilação</strong>, o que combina perfeitamente com sistemas embarcados determinísticos.</p>



<p class="wp-block-paragraph">Internamente, essa macro cria:</p>



<ul class="wp-block-list">
<li>uma <code>struct k_fifo</code>,</li>



<li>os objetos auxiliares necessários,</li>



<li>e registra tudo para o kernel.</li>
</ul>



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



<h2 class="wp-block-heading">Produzindo mensagens: <code>k_fifo_put()</code></h2>



<p class="wp-block-paragraph">Dentro das threads <code>blink0()</code> e <code>blink1()</code>, aparece um trecho parecido com:</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>struct msg msg;

msg.led = 0;
msg.cnt = cnt++;

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



<p class="wp-block-paragraph">Aqui há um ponto <strong>extremamente importante</strong> de engenharia de firmware:</p>



<h3 class="wp-block-heading">Onde está alocada <code>msg</code>?</h3>



<p class="wp-block-paragraph">Se <code>msg</code> for:</p>



<ul class="wp-block-list">
<li>variável local na stack → <strong>ERRO GRAVE</strong></li>



<li>variável estática ou global → <strong>CORRETO</strong></li>
</ul>



<p class="wp-block-paragraph">O exemplo real do Zephyr usa <strong>variáveis estáticas</strong>, exatamente porque:</p>



<ul class="wp-block-list">
<li>a FIFO guarda apenas o <strong>ponteiro</strong>,</li>



<li>se a variável sair de escopo, o ponteiro ficará inválido,</li>



<li>isso gera comportamento indefinido.</li>
</ul>



<p class="wp-block-paragraph">Esse detalhe é intencional no sample:<br>ele força o leitor a entender o <strong>modelo de memória do kernel</strong>.</p>



<p class="wp-block-paragraph"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4cc.png" alt="📌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Comparação com FreeRTOS</strong><br>No FreeRTOS, <code>xQueueSend()</code> copia os dados.<br>No Zephyr, <code>k_fifo_put()</code> <strong>encadeia o objeto</strong>.</p>



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



<h2 class="wp-block-heading">Consumindo mensagens: <code>k_fifo_get()</code></h2>



<p class="wp-block-paragraph">Na thread <code>uart_out()</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>struct msg *msg;

msg = k_fifo_get(&amp;printk_fifo, K_FOREVER);
</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">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">msg</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">msg</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">msg</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">k_fifo_get</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">printk_fifo</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">K_FOREVER</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Aqui vemos três conceitos importantes:</p>



<ol class="wp-block-list">
<li><strong>Retorno por ponteiro</strong><br>O kernel devolve o endereço do objeto original.</li>



<li><strong>Bloqueio controlado</strong><br><code>K_FOREVER</code> indica que a thread ficará bloqueada até chegar uma mensagem.</li>



<li><strong>Eficiência extrema</strong><br>Não há cópia de dados, apenas manipulação de ponteiros.</li>
</ol>



<p class="wp-block-paragraph">Depois disso, o código faz:</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>printk("Toggled led%d; counter=%d\n", msg->led, msg->cnt);
</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: #88C0D0">printk</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Toggled led%d; counter=%d</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">msg</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">led</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">msg</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">cnt</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">A thread consumidora:</p>



<ul class="wp-block-list">
<li>não sabe quem produziu,</li>



<li>não controla LEDs,</li>



<li>apenas interpreta dados.</li>
</ul>



<p class="wp-block-paragraph">Isso é <strong>arquitetura orientada a eventos</strong>, aplicada de forma simples e elegante.</p>



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



<h2 class="wp-block-heading">As threads <code>blink0</code>, <code>blink1</code> e <code>uart_out</code>: escalonamento, <code>k_sleep()</code> e modelo de execução</h2>



<p class="wp-block-paragraph">Agora vamos analisar <strong>as funções que viram threads</strong>. Aqui está o “comportamento” real do sistema, e onde o Zephyr mostra claramente que <strong>não existe superloop</strong> — existem fluxos concorrentes cooperando sob controle do kernel.</p>



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



<h2 class="wp-block-heading">Assinatura das funções de thread</h2>



<p class="wp-block-paragraph">Todas as funções têm uma assinatura semelhante a:</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 blink0(void *a, void *b, void *c)
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">blink0</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">a</span><span style="color: #ECEFF4">,</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">b</span><span style="color: #ECEFF4">,</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">c</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Isso não é arbitrário.</p>



<p class="wp-block-paragraph">O Zephyr define que <strong>toda thread</strong> criada via <code>K_THREAD_DEFINE</code> deve aceitar <strong>três argumentos genéricos</strong> (<code>void *</code>), mesmo que você não os use.</p>



<h3 class="wp-block-heading">Por que três parâmetros?</h3>



<ul class="wp-block-list">
<li>Permite passar contexto para a thread</li>



<li>Mantém ABI estável</li>



<li>Evita múltiplas variações de protótipos</li>
</ul>



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



<ul class="wp-block-list">
<li>os parâmetros não são usados,</li>



<li>mas a assinatura precisa ser respeitada.</li>
</ul>



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



<h2 class="wp-block-heading">Thread <code>blink0</code> e <code>blink1</code>: produtoras de eventos</h2>



<p class="wp-block-paragraph">As duas threads são quase idênticas, mudando apenas:</p>



<ul class="wp-block-list">
<li>o LED controlado,</li>



<li>o período de pisca.</li>
</ul>



<p class="wp-block-paragraph">Estrutura típica:</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>static void blink0(void *a, void *b, void *c)
{
    uint32_t cnt = 0;

    while (1) {
        gpio_pin_toggle_dt(&amp;led0);

        struct msg msg0;
        msg0.led = 0;
        msg0.cnt = cnt++;

        k_fifo_put(&amp;printk_fifo, &amp;msg0);
        k_sleep(K_MSEC(1000));
    }
}
</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">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">blink0</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">a</span><span style="color: #ECEFF4">,</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">b</span><span style="color: #ECEFF4">,</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">c</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">cnt</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">while</span><span style="color: #D8DEE9FF"> (</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">gpio_pin_toggle_dt</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">led0</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">msg</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">msg0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">msg0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">led</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">msg0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">cnt</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">cnt</span><span style="color: #81A1C1">++;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">k_fifo_put</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">printk_fifo</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">msg0</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">k_sleep</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">K_MSEC</span><span style="color: #D8DEE9FF">(</span><span style="color: #B48EAD">1000</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">Vamos destrinchar isso em partes.</p>



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



<h3 class="wp-block-heading"><code>while (1)</code> não é “superloop”</h3>



<p class="wp-block-paragraph">Apesar de parecer um superloop, <strong>não é</strong>.</p>



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



<ul class="wp-block-list">
<li>cada thread tem seu próprio loop,</li>



<li>o escalonamento é feito pelo kernel,</li>



<li>a thread “some” do processador quando dorme.</li>
</ul>



<p class="wp-block-paragraph">Isso é radicalmente diferente de:</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>while (1) {
    delay_ms(1000);
}
</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">while</span><span style="color: #D8DEE9FF"> (</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">delay_ms</span><span style="color: #D8DEE9FF">(</span><span style="color: #B48EAD">1000</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">em baremetal.</p>



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



<h3 class="wp-block-heading"><code>gpio_pin_toggle_dt(&amp;led0)</code></h3>



<p class="wp-block-paragraph">Essa chamada:</p>



<ul class="wp-block-list">
<li>acessa o driver GPIO genérico,</li>



<li>usa informações vindas do DeviceTree,</li>



<li>não toca em registradores diretamente.</li>
</ul>



<p class="wp-block-paragraph">O mesmo código roda:</p>



<ul class="wp-block-list">
<li>em STM32,</li>



<li>nRF,</li>



<li>ESP32,</li>



<li>QEMU (com GPIO simulado).</li>
</ul>



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



<h3 class="wp-block-heading">Criação da mensagem</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>struct msg msg0;
msg0.led = 0;
msg0.cnt = cnt++;
</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">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">msg</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">msg0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9">msg0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">led</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9">msg0</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">cnt</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">cnt</span><span style="color: #81A1C1">++;</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">O exemplo real usa <strong>variáveis estáticas</strong>, justamente para garantir que:</p>



<ul class="wp-block-list">
<li>a memória continue válida após o <code>k_fifo_put()</code>.</li>
</ul>



<p class="wp-block-paragraph">Isso reforça a ideia de que:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">no Zephyr, <strong>memória e tempo de vida do objeto importam</strong>.</p>
</blockquote>



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



<h3 class="wp-block-heading"><code>k_fifo_put()</code></h3>



<p class="wp-block-paragraph">Quando a thread chama:</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>k_fifo_put(&amp;printk_fifo, &amp;msg0);
</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: #88C0D0">k_fifo_put</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">printk_fifo</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">msg0</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">o kernel:</p>



<ul class="wp-block-list">
<li>não copia dados,</li>



<li>apenas encadeia o objeto,</li>



<li>acorda qualquer thread bloqueada em <code>k_fifo_get()</code>.</li>
</ul>



<p class="wp-block-paragraph">Isso é uma <strong>sincronização implícita</strong>.</p>



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



<h3 class="wp-block-heading"><code>k_sleep(K_MSEC(1000))</code></h3>



<p class="wp-block-paragraph">Aqui está um ponto-chave.</p>



<p class="wp-block-paragraph"><code>k_sleep()</code>:</p>



<ul class="wp-block-list">
<li>coloca a thread em estado <strong>sleeping</strong>,</li>



<li>libera o processador imediatamente,</li>



<li>permite que outras threads rodem.</li>
</ul>



<p class="wp-block-paragraph"><code>K_MSEC(1000)</code> é uma macro que:</p>



<ul class="wp-block-list">
<li>converte milissegundos para <code>k_timeout_t</code>,</li>



<li>evita erros de unidade,</li>



<li>torna o código legível e portátil.</li>
</ul>



<p class="wp-block-paragraph"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4cc.png" alt="📌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Importante</strong><br><code>k_sleep()</code> <strong>não é busy-wait</strong>.<br>Ele coopera com o scheduler.</p>



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



<h2 class="wp-block-heading">Thread <code>uart_out</code>: consumidora de eventos</h2>



<p class="wp-block-paragraph">Agora a thread que <strong>não controla hardware crítico</strong>, apenas processa mensagens.</p>



<p class="wp-block-paragraph">Estrutura típica:</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>static void uart_out(void *a, void *b, void *c)
{
    while (1) {
        struct msg *msg;

        msg = k_fifo_get(&amp;printk_fifo, K_FOREVER);

        printk("Toggled led%d; counter=%d\n",
               msg->led, msg->cnt);
    }
}
</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">static</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">uart_out</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">a</span><span style="color: #ECEFF4">,</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">b</span><span style="color: #ECEFF4">,</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">c</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">while</span><span style="color: #D8DEE9FF"> (</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">struct</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">msg</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9">msg</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">msg</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">k_fifo_get</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">&amp;</span><span style="color: #D8DEE9">printk_fifo</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">K_FOREVER</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">printk</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Toggled led%d; counter=%d</span><span style="color: #EBCB8B">\n</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">               </span><span style="color: #D8DEE9">msg</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">led</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">msg</span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9">cnt</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



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



<h3 class="wp-block-heading"><code>k_fifo_get(..., K_FOREVER)</code></h3>



<p class="wp-block-paragraph">Esse é um exemplo clássico de <strong>thread orientada a eventos</strong>:</p>



<ul class="wp-block-list">
<li>se não há mensagem → thread dorme</li>



<li>se chega mensagem → thread acorda</li>
</ul>



<p class="wp-block-paragraph">Não existe polling, não existe <code>delay</code>.</p>



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



<h3 class="wp-block-heading"><code>printk()</code> dentro de uma thread dedicada</h3>



<p class="wp-block-paragraph">Essa decisão arquitetural é excelente:</p>



<ul class="wp-block-list">
<li>evita <code>printk()</code> em múltiplas threads concorrentes,</li>



<li>reduz risco de interleaving de mensagens,</li>



<li>centraliza I/O lento em uma única thread.</li>
</ul>



<p class="wp-block-paragraph">Isso é exatamente o tipo de padrão que se espera em sistemas RTOS bem projetados.</p>



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



<h2 class="wp-block-heading">Prioridades iguais: por quê?</h2>



<p class="wp-block-paragraph">Todas as threads usam:</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 PRIORITY 7
</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: #D8DEE9">PRIORITY</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">7</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Isso significa:</p>



<ul class="wp-block-list">
<li>escalonamento <strong>round-robin</strong> entre elas,</li>



<li>nenhuma é mais importante que a outra,</li>



<li>comportamento previsível para um exemplo didático.</li>
</ul>



<p class="wp-block-paragraph">Em um sistema real:</p>



<ul class="wp-block-list">
<li>threads de controle teriam prioridade maior,</li>



<li>logging teria prioridade menor.</li>
</ul>



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



<h2 class="wp-block-heading"><code>K_THREAD_DEFINE</code>: o que essa macro realmente cria e por que ela substitui o <code>main()</code></h2>



<p class="wp-block-paragraph">Agora chegamos ao <strong>ponto mais conceitual e arquitetural</strong> do tutorial.<br>Entender <code>K_THREAD_DEFINE</code> é entender <strong>por que o Zephyr não precisa de <code>main()</code> neste exemplo</strong>.</p>



<p class="wp-block-paragraph">Vamos partir da macro usada no código:</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>K_THREAD_DEFINE(blink0_id,
                STACKSIZE,
                blink0,
                NULL, NULL, NULL,
                PRIORITY,
                0,
                0);
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">K_THREAD_DEFINE</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">blink0_id</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #D8DEE9">STACKSIZE</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #D8DEE9">blink0</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 style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span><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: #D8DEE9">PRIORITY</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #B48EAD">0</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">À primeira vista, parece “apenas” uma forma compacta de criar threads.<br>Na prática, ela <strong>define objetos globais que o kernel conhece antes mesmo de iniciar o scheduler</strong>.</p>



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



<h2 class="wp-block-heading">Anatomia completa da macro</h2>



<p class="wp-block-paragraph">A assinatura conceitual é:</p>



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



<p class="wp-block-paragraph">Vamos destrinchar item por item.</p>



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



<h3 class="wp-block-heading"><code>name</code> — Identificador da thread</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>blink0_id
</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">blink0_id</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Esse nome:</p>



<ul class="wp-block-list">
<li>vira um símbolo global,</li>



<li>identifica a thread no linker,</li>



<li>pode ser usado para debug e tracing.</li>
</ul>



<p class="wp-block-paragraph">Internamente, o Zephyr cria:</p>



<ul class="wp-block-list">
<li>uma <code>struct k_thread</code>,</li>



<li>uma stack associada,</li>



<li>metadados de inicialização.</li>
</ul>



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



<h3 class="wp-block-heading"><code>stack_size</code> — Pilha dedicada</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>STACKSIZE
</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">STACKSIZE</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Diferente de muitos exemplos em outros RTOS, aqui:</p>



<ul class="wp-block-list">
<li><strong>a pilha é obrigatória</strong>,</li>



<li><strong>é conhecida em tempo de compilação</strong>,</li>



<li><strong>não depende de heap</strong>.</li>
</ul>



<p class="wp-block-paragraph">Isso é essencial para:</p>



<ul class="wp-block-list">
<li>sistemas determinísticos,</li>



<li>análise estática,</li>



<li>aplicações safety-critical.</li>
</ul>



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



<h3 class="wp-block-heading"><code>entry</code> — Função da thread</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>blink0
</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">blink0</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Essa função:</p>



<ul class="wp-block-list">
<li>não é chamada manualmente,</li>



<li>será invocada pelo kernel,</li>



<li>começa a rodar quando o scheduler inicia.</li>
</ul>



<p class="wp-block-paragraph">É aqui que o modelo do Zephyr diverge completamente do “<code>main()</code> cria tudo”.</p>



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



<h3 class="wp-block-heading"><code>p1, p2, p3</code> — Parâmetros genéricos</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>NULL, NULL, NULL
</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">NULL</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Esses ponteiros:</p>



<ul class="wp-block-list">
<li>permitem passar contexto para a thread,</li>



<li>evitam uso de globais,</li>



<li>mantêm ABI uniforme.</li>
</ul>



<p class="wp-block-paragraph">No exemplo, não são usados, mas em sistemas reais:</p>



<ul class="wp-block-list">
<li>podem carregar ponteiros de estruturas,</li>



<li>ou referências a drivers.</li>
</ul>



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



<h3 class="wp-block-heading"><code>priority</code> — Prioridade da thread</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>PRIORITY
</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">PRIORITY</span></span>
<span class="line"></span></code></pre></div>



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



<ul class="wp-block-list">
<li>números menores → prioridade maior</li>



<li>prioridades negativas → threads do sistema</li>
</ul>



<p class="wp-block-paragraph">Aqui todas são iguais para fins didáticos.</p>



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



<h3 class="wp-block-heading"><code>options</code> — Flags de comportamento</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>0
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #B48EAD">0</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Aqui poderiam entrar opções como:</p>



<ul class="wp-block-list">
<li><code>K_FP_REGS</code> → thread usa FPU</li>



<li><code>K_USER</code> → thread em modo usuário (se MPU estiver ativa)</li>
</ul>



<p class="wp-block-paragraph">O exemplo mantém tudo simples.</p>



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



<h3 class="wp-block-heading"><code>delay</code> — Início retardado</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>0
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #B48EAD">0</span></span>
<span class="line"></span></code></pre></div>



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



<ul class="wp-block-list">
<li>a thread inicia imediatamente no boot.</li>
</ul>



<p class="wp-block-paragraph">Em sistemas reais, você pode:</p>



<ul class="wp-block-list">
<li>atrasar threads,</li>



<li>escalonar inicializações,</li>



<li>reduzir pico de consumo no boot.</li>
</ul>



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



<h2 class="wp-block-heading">O que o Zephyr gera por trás da macro?</h2>



<p class="wp-block-paragraph">Conceitualmente, o compilador/linker acabam gerando algo equivalente a:</p>



<ul class="wp-block-list">
<li>uma stack alocada em <code>.bss</code> ou <code>.noinit</code></li>



<li>uma <code>struct k_thread</code></li>



<li>uma entrada em uma seção especial (ex: <code>.z_thread_data</code>)</li>
</ul>



<p class="wp-block-paragraph">Durante o boot:</p>



<ol class="wp-block-list">
<li>O kernel percorre essas seções.</li>



<li>Inicializa todas as threads estáticas.</li>



<li>Insere as threads prontas no scheduler.</li>



<li>Inicia a execução sem jamais chamar <code>main()</code>.</li>
</ol>



<p class="wp-block-paragraph"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4cc.png" alt="📌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Isso é fundamental</strong><br>O fluxo não é:</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>reset → main() → scheduler
</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">reset</span><span style="color: #D8DEE9FF"> → </span><span style="color: #88C0D0">main</span><span style="color: #D8DEE9FF">() → </span><span style="color: #D8DEE9">scheduler</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">É:</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>reset → kernel init → threads do sistema → threads do app
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">reset</span><span style="color: #D8DEE9FF"> → </span><span style="color: #D8DEE9">kernel</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">init</span><span style="color: #D8DEE9FF"> → </span><span style="color: #D8DEE9">threads</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">do</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">sistema</span><span style="color: #D8DEE9FF"> → </span><span style="color: #D8DEE9">threads</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">do</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">app</span></span>
<span class="line"></span></code></pre></div>



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



<h2 class="wp-block-heading">Mas o Zephyr <em>pode</em> ter <code>main()</code>?</h2>



<p class="wp-block-paragraph">Sim. E muitos exemplos têm.</p>



<p class="wp-block-paragraph">Se existir:</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 main(void)
{
    ...
}
</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">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: #81A1C1">...</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



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



<ul class="wp-block-list">
<li>cria uma thread especial chamada <code>main</code>,</li>



<li>executa essa função como uma thread normal,</li>



<li>com prioridade e stack configuráveis via Kconfig.</li>
</ul>



<p class="wp-block-paragraph">Neste sample, os autores <strong>optaram por não usar <code>main()</code></strong>, para mostrar que:</p>



<ul class="wp-block-list">
<li>o kernel é o centro da aplicação,</li>



<li>não existe mais “função principal” no sentido clássico.</li>
</ul>



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



<h2 class="wp-block-heading">Comparação direta com outros modelos</h2>



<h3 class="wp-block-heading">Baremetal</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>int main(void)
{
    init();
    while (1) { ... }
}
</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">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">main</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">init</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">while</span><span style="color: #D8DEE9FF"> (</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">...</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading">FreeRTOS clássico</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>int main(void)
{
    xTaskCreate(...);
    vTaskStartScheduler();
    while (1);
}
</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">int</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">main</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">void</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">xTaskCreate</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">...</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></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: #D8DEE9FF">    </span><span style="color: #81A1C1">while</span><span style="color: #D8DEE9FF"> (</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading">Zephyr (este exemplo)</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>K_THREAD_DEFINE(...);
K_THREAD_DEFINE(...);
K_THREAD_DEFINE(...);
</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: #88C0D0">K_THREAD_DEFINE</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">...</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #88C0D0">K_THREAD_DEFINE</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">...</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #88C0D0">K_THREAD_DEFINE</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">...</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Nenhum fluxo explícito.<br>O <strong>linker + kernel</strong> fazem o trabalho.</p>



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



<h2 class="wp-block-heading">Ciclo de vida completo do sistema, quando <strong>usar ou não</strong> <code>main()</code> e boas práticas reais</h2>



<p class="wp-block-paragraph">Para fechar o tutorial, vamos juntar todas as peças e olhar o sistema <strong>do reset até a execução contínua</strong>, e depois discutir <strong>decisões arquiteturais reais</strong>: quando esse modelo é ideal e quando o <code>main()</code> ainda faz sentido.</p>



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



<h2 class="wp-block-heading">Ciclo de vida do firmware neste exemplo</h2>



<p class="wp-block-paragraph">O fluxo real de execução do Zephyr, neste sample, é aproximadamente o seguinte:</p>



<ol class="wp-block-list">
<li><strong>Reset do microcontrolador</strong>
<ul class="wp-block-list">
<li>Código de startup (CMSIS / SoC específico)</li>



<li>Inicialização mínima de stack e memória</li>
</ul>
</li>



<li><strong>Inicialização do kernel Zephyr</strong>
<ul class="wp-block-list">
<li>Scheduler</li>



<li>Estruturas internas</li>



<li>Heap (se habilitado)</li>



<li>Infraestrutura de drivers</li>
</ul>
</li>



<li><strong>Inicialização baseada em DeviceTree</strong>
<ul class="wp-block-list">
<li>Criação dos dispositivos declarados</li>



<li>Binding de drivers (GPIO, UART, etc.)</li>



<li>Verificação de <code>status = "okay"</code></li>
</ul>
</li>



<li><strong>Criação das threads estáticas</strong>
<ul class="wp-block-list">
<li>Threads do sistema</li>



<li>Threads definidas por <code>K_THREAD_DEFINE</code></li>



<li>Pilhas já alocadas e conhecidas</li>
</ul>
</li>



<li><strong>Scheduler entra em execução</strong>
<ul class="wp-block-list">
<li>Threads <code>blink0</code>, <code>blink1</code> e <code>uart_out</code> passam a disputar CPU</li>



<li>Não existe chamada a <code>main()</code></li>



<li>Não existe “loop central”</li>
</ul>
</li>



<li><strong>Sistema em regime permanente</strong>
<ul class="wp-block-list">
<li>Threads produtoras geram eventos</li>



<li>FIFO coordena comunicação</li>



<li>Thread consumidora bloqueia e acorda conforme necessário</li>
</ul>
</li>
</ol>



<p class="wp-block-paragraph">Esse fluxo deixa claro que <strong>o kernel é o “programa principal”</strong>.<br>O seu código apenas descreve <em>o que existe</em>, não <em>quando chamar</em>.</p>



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



<h2 class="wp-block-heading">Quando esse modelo é ideal</h2>



<p class="wp-block-paragraph">Esse estilo (sem <code>main()</code>) é <strong>excelente</strong> quando:</p>



<ul class="wp-block-list">
<li>o sistema é <strong>100% orientado a eventos</strong>,</li>



<li>todas as tarefas são naturalmente threads,</li>



<li>o comportamento é reativo (sensores, mensagens, filas),</li>



<li>você quer inicialização <strong>determinística e estática</strong>,</li>



<li>o projeto cresce em complexidade e modularidade.</li>
</ul>



<p class="wp-block-paragraph">Exemplos típicos:</p>



<ul class="wp-block-list">
<li>gateways IoT,</li>



<li>sistemas de logging e monitoramento,</li>



<li>aplicações industriais com múltiplas tarefas independentes,</li>



<li>firmware educacional focado em RTOS “puro”.</li>
</ul>



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



<h2 class="wp-block-heading">Quando <code>main()</code> ainda faz sentido no Zephyr</h2>



<p class="wp-block-paragraph">Apesar do poder desse modelo, há cenários em que <strong>usar <code>main()</code> é mais adequado</strong>:</p>



<ul class="wp-block-list">
<li>inicializações sequenciais complexas;</li>



<li>criação dinâmica de threads;</li>



<li>lógica de boot dependente de estado externo;</li>



<li>migração gradual de firmware baremetal;</li>



<li>aplicações simples, onde threads estáticas seriam “overkill”.</li>
</ul>



<p class="wp-block-paragraph">Nesse caso, o Zephyr trata <code>main()</code> assim:</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 main(void)
{
    // isso roda como uma thread normal
}
</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">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: #ECEFF4">    </span><span style="color: #616E88">// isso roda como uma thread normal</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">Ou seja:</p>



<ul class="wp-block-list">
<li><code>main()</code> <strong>não quebra o modelo do Zephyr</strong>,</li>



<li>ela apenas vira uma thread especial,</li>



<li>com prioridade e stack configuráveis via Kconfig.</li>
</ul>



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



<h2 class="wp-block-heading">Boa prática arquitetural (opinião técnica)</h2>



<p class="wp-block-paragraph">Em projetos reais e bem estruturados, o padrão mais saudável costuma ser:</p>



<ul class="wp-block-list">
<li>usar <strong>threads estáticas (<code>K_THREAD_DEFINE</code>)</strong> para:
<ul class="wp-block-list">
<li>tarefas permanentes,</li>



<li>serviços do sistema,</li>



<li>pipelines de dados;</li>
</ul>
</li>



<li>usar <code>main()</code> apenas para:
<ul class="wp-block-list">
<li>orquestrar inicializações,</li>



<li>criar threads dinâmicas,</li>



<li>decidir configurações em runtime.</li>
</ul>
</li>
</ul>



<p class="wp-block-paragraph">O sample <code>threads</code> existe justamente para mostrar que:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">você <strong>não é obrigado</strong> a pensar em firmware como “um loop principal”.</p>
</blockquote>



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



<h2 class="wp-block-heading">Conclusão técnica do tutorial</h2>



<p class="wp-block-paragraph">Este exemplo simples demonstra conceitos profundos:</p>



<ul class="wp-block-list">
<li>Zephyr não é “baremetal com RTOS por cima”;</li>



<li>o kernel é o centro da aplicação;</li>



<li>DeviceTree elimina dependência de hardware no código;</li>



<li>FIFOs trabalham com objetos, não cópias;</li>



<li>threads são entidades declarativas;</li>



<li><code>main()</code> é opcional, não fundamental.</li>
</ul>



<p class="wp-block-paragraph">Quem entende esse sample entende <strong>a filosofia do Zephyr</strong>.</p><p>The post <a href="https://mcu.tec.br/rtos/introducao-ao-zephyr-rtos-entendendo-threads-devicetree-e-a-ausencia-do-main/">Introdução ao Zephyr RTOS: Entendendo Threads, DeviceTree e a Ausência do main()</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1037</post-id>	</item>
	</channel>
</rss>
