<?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>firmware embarcado - MCU &amp; FPGA</title>
	<atom:link href="https://mcu.tec.br/tags/firmware-embarcado/feed/" rel="self" type="application/rss+xml" />
	<link>https://mcu.tec.br</link>
	<description>Microcontroladores &#38; FPGA</description>
	<lastBuildDate>Tue, 10 Feb 2026 11:01:00 +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>firmware embarcado - MCU &amp; FPGA</title>
	<link>https://mcu.tec.br</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Comparativo Técnico de Microcontroladores: ESP32, STM32, Arduino, RP2040 e nRF52</title>
		<link>https://mcu.tec.br/microcontroladores/comparativo-tecnico-de-microcontroladores-esp32-stm32-arduino-rp2040-e-nrf52/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=comparativo-tecnico-de-microcontroladores-esp32-stm32-arduino-rp2040-e-nrf52</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Tue, 10 Feb 2026 10:59:31 +0000</pubDate>
				<category><![CDATA[microcontroladores]]></category>
		<category><![CDATA[Arduino AVR]]></category>
		<category><![CDATA[baixo consumo]]></category>
		<category><![CDATA[bluetooth low energy]]></category>
		<category><![CDATA[controle industrial]]></category>
		<category><![CDATA[engenharia eletrônica]]></category>
		<category><![CDATA[esp32]]></category>
		<category><![CDATA[firmware embarcado]]></category>
		<category><![CDATA[IoT]]></category>
		<category><![CDATA[nRF52]]></category>
		<category><![CDATA[RP2040]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[stm32]]></category>
		<category><![CDATA[wi-fi embarcado]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1291</guid>

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


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



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



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



<hr class="wp-block-separator has-alpha-channel-opacity"/><p>The post <a href="https://mcu.tec.br/microcontroladores/comparativo-tecnico-de-microcontroladores-esp32-stm32-arduino-rp2040-e-nrf52/">Comparativo Técnico de Microcontroladores: ESP32, STM32, Arduino, RP2040 e nRF52</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1291</post-id>	</item>
		<item>
		<title>Protocolos para Redes de Sensores e IoT: LEACH, PEGASIS, TDMA, 6TiSCH e WirelessHART</title>
		<link>https://mcu.tec.br/protoclos/protocolos-para-redes-de-sensores-e-iot-leach-pegasis-tdma-6tisch-e-wirelesshart/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=protocolos-para-redes-de-sensores-e-iot-leach-pegasis-tdma-6tisch-e-wirelesshart</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Sat, 07 Feb 2026 18:13:47 +0000</pubDate>
				<category><![CDATA[IoT]]></category>
		<category><![CDATA[protocolos]]></category>
		<category><![CDATA[6TiSCH]]></category>
		<category><![CDATA[comunicação sem fio industrial]]></category>
		<category><![CDATA[eficiência energética]]></category>
		<category><![CDATA[firmware embarcado]]></category>
		<category><![CDATA[IEEE 802.15.4e]]></category>
		<category><![CDATA[IIoT]]></category>
		<category><![CDATA[iot industrial]]></category>
		<category><![CDATA[LEACH]]></category>
		<category><![CDATA[PEGASIS]]></category>
		<category><![CDATA[protocolos de comunicação]]></category>
		<category><![CDATA[redes de sensores sem fio]]></category>
		<category><![CDATA[redes determinísticas]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[TDMA]]></category>
		<category><![CDATA[TSCH]]></category>
		<category><![CDATA[WirelessHART]]></category>
		<category><![CDATA[WSN]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=1269</guid>

					<description><![CDATA[<p>Este artigo apresenta uma análise técnica e didática dos principais protocolos utilizados em Redes de Sensores Sem Fio (Wireless Sensor Networks – WSNs) e sua evolução até o IoT industrial moderno. São explorados em profundidade os protocolos LEACH (Low-Energy Adaptive Clustering Hierarchy) e PEGASIS (Power-Efficient Gathering in Sensor Information Systems), amplamente estudados no meio acadêmico por sua eficiência energética e estratégias de organização da rede, bem como o papel fundamental do TDMA (Time Division Multiple Access) na construção de sistemas determinísticos e previsíveis. O texto avança para protocolos industriais consolidados, como 6TiSCH (IPv6 over TSCH IEEE 802.15.4e) e WirelessHART, destacando seus mecanismos de sincronização temporal, salto de frequência, confiabilidade, interoperabilidade e adequação a sistemas embarcados de baixo consumo. Ao longo do artigo, são discutidos os conceitos de clusterização, roteamento em cadeia, agendamento temporal e comunicação determinística, sempre conectando teoria, firmware embarcado e contexto de uso real em aplicações industriais, ambientais e de infraestrutura crítica. O conteúdo é direcionado a engenheiros, estudantes e profissionais que desejam compreender as bases conceituais que sustentam o IoT moderno e o Industrial IoT, indo além de protocolos de aplicação e explorando a camada estrutural das redes distribuídas de sensores.</p>
<p>The post <a href="https://mcu.tec.br/protoclos/protocolos-para-redes-de-sensores-e-iot-leach-pegasis-tdma-6tisch-e-wirelesshart/">Protocolos para Redes de Sensores e IoT: LEACH, PEGASIS, TDMA, 6TiSCH e WirelessHART</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<div class="root-eb-toc-sssef wp-block-essential-blocks-table-of-contents"><div class="eb-parent-wrapper eb-parent-eb-toc-sssef "><div class="eb-toc-container eb-toc-sssef  eb-toc-is-not-sticky eb-toc-not-collapsible eb-toc-initially-not-collapsed eb-toc-scrollToTop style-1 list-style-none" data-scroll-top="false" data-scroll-top-icon="fas fa-angle-up" data-collapsible="false" data-sticky-hide-mobile="false" data-sticky="false" data-scroll-target="scroll_to_toc" data-copy-link="false" data-editor-type="" data-hide-desktop="false" data-hide-tab="false" data-hide-mobile="false" data-itemcollapsed="false" data-highlight-scroll="false"><div class="eb-toc-header"><h2 class="eb-toc-title">Table of Contents</h2></div><div class="eb-toc-wrapper " data-headers="[{&quot;level&quot;:3,&quot;content&quot;:&quot;Introdu\u00e7\u00e3o&quot;,&quot;text&quot;:&quot;Introdu\u00e7\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-0&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;LEACH \u2013 Low-Energy Adaptive Clustering Hierarchy&quot;,&quot;text&quot;:&quot;LEACH \u2013 Low-Energy Adaptive Clustering Hierarchy&quot;,&quot;link&quot;:&quot;leach-low-energy-adaptive-clustering-hierarchy&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;PEGASIS \u2013 Power-Efficient Gathering in Sensor Information Systems&quot;,&quot;text&quot;:&quot;PEGASIS \u2013 Power-Efficient Gathering in Sensor Information Systems&quot;,&quot;link&quot;:&quot;pegasis-power-efficient-gathering-in-sensor-information-systems&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;TDMA \u2013 Time Division Multiple Access&quot;,&quot;text&quot;:&quot;TDMA \u2013 Time Division Multiple Access&quot;,&quot;link&quot;:&quot;tdma-time-division-multiple-access&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;6TiSCH \u2013 IPv6 over the TSCH mode of IEEE 802.15.4e&quot;,&quot;text&quot;:&quot;6TiSCH \u2013 IPv6 over the TSCH mode of IEEE 802.15.4e&quot;,&quot;link&quot;:&quot;6tisch-ipv6-over-the-tsch-mode-of-ieee-802154e&quot;},{&quot;level&quot;:2,&quot;content&quot;:&quot;WirelessHART \u2013 Highway Addressable Remote Transducer (Wireless)&quot;,&quot;text&quot;:&quot;WirelessHART \u2013 Highway Addressable Remote Transducer (Wireless)&quot;,&quot;link&quot;:&quot;wirelesshart-highway-addressable-remote-transducer-wireless&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Tabela comparativa entre os protocolos analisados&quot;,&quot;text&quot;:&quot;Tabela comparativa entre os protocolos analisados&quot;,&quot;link&quot;:&quot;tabela-comparativa-entre-os-protocolos-analisados&quot;},{&quot;level&quot;:3,&quot;content&quot;:&quot;Conclus\u00e3o&quot;,&quot;text&quot;:&quot;Conclus\u00e3o&quot;,&quot;link&quot;:&quot;eb-table-content-7&quot;}]" data-visible="[true,true,true,true,true,true]" data-delete-headers="[{&quot;label&quot;:&quot;Introdu\u00e7\u00e3o&quot;,&quot;value&quot;:&quot;introdu\u00e7\u00e3o&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;LEACH \u2013 Low-Energy Adaptive Clustering Hierarchy&quot;,&quot;value&quot;:&quot;leach-low-energy-adaptive-clustering-hierarchy&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;PEGASIS \u2013 Power-Efficient Gathering in Sensor Information Systems&quot;,&quot;value&quot;:&quot;pegasis-power-efficient-gathering-in-sensor-information-systems&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;TDMA \u2013 Time Division Multiple Access&quot;,&quot;value&quot;:&quot;tdma-time-division-multiple-access&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;6TiSCH \u2013 IPv6 over the TSCH mode of IEEE 802.15.4e&quot;,&quot;value&quot;:&quot;6tisch-ipv6-over-the-tsch-mode-of-ieee-802154e&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;WirelessHART \u2013 Highway Addressable Remote Transducer (Wireless)&quot;,&quot;value&quot;:&quot;wirelesshart-highway-addressable-remote-transducer-wireless&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Tabela comparativa entre os protocolos analisados&quot;,&quot;value&quot;:&quot;tabela-comparativa-entre-os-protocolos-analisados&quot;,&quot;isDelete&quot;:false},{&quot;label&quot;:&quot;Conclus\u00e3o&quot;,&quot;value&quot;:&quot;conclus\u00e3o&quot;,&quot;isDelete&quot;:false}]" data-smooth="true" data-top-offset=""><div class="eb-toc__list-wrap"><ul class="eb-toc__list"><li><a href="#eb-table-content-0">Introdução</a><li><a href="#leach-low-energy-adaptive-clustering-hierarchy">LEACH – Low-Energy Adaptive Clustering Hierarchy</a><li><a href="#pegasis-power-efficient-gathering-in-sensor-information-systems">PEGASIS – Power-Efficient Gathering in Sensor Information Systems</a><li><a href="#tdma-time-division-multiple-access">TDMA – Time Division Multiple Access</a><li><a href="#6tisch-ipv6-over-the-tsch-mode-of-ieee-802154e">6TiSCH – IPv6 over the TSCH mode of IEEE 802.15.4e</a><li><a href="#wirelesshart-highway-addressable-remote-transducer-wireless">WirelessHART – Highway Addressable Remote Transducer (Wireless)</a><ul class="eb-toc__list"><li><a href="#tabela-comparativa-entre-os-protocolos-analisados">Tabela comparativa entre os protocolos analisados</a><li><a href="#eb-table-content-7">Conclusão</a></li></ul></ul></div></div></div></div></div>


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



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



<p class="wp-block-paragraph">Redes de sensores sem fio e sistemas embarcados de baixo consumo formam a espinha dorsal de grande parte das aplicações modernas de Internet das Coisas (IoT), especialmente nos domínios industrial, ambiental e de infraestrutura crítica. Nesses cenários, os desafios não se restringem à aquisição de dados, mas envolvem de forma central <strong>como os nós se organizam, como compartilham o meio de comunicação e como preservam energia ao longo de anos de operação</strong>. É nesse contexto que surgem protocolos voltados à eficiência energética, à previsibilidade temporal e à confiabilidade da comunicação.</p>



<p class="wp-block-paragraph">Protocolos como <strong>LEACH</strong> e <strong>PEGASIS</strong> emergem inicialmente no meio acadêmico como respostas diretas às limitações físicas dos nós sensores, propondo novas formas de organização da rede para reduzir o custo energético das transmissões. Esses trabalhos estabelecem fundamentos conceituais importantes, como agregação de dados, hierarquização e comunicação cooperativa, que influenciaram profundamente a evolução das Wireless Sensor Networks e, posteriormente, do IoT.</p>



<p class="wp-block-paragraph">À medida que as aplicações avançam para ambientes industriais e de missão crítica, a necessidade de <strong>determinismo, robustez e interoperabilidade</strong> torna-se dominante. Técnicas como <strong>TDMA</strong> passam a ser adotadas como base estrutural, permitindo controle preciso do tempo, do consumo e da latência. Sobre esse alicerce, surgem protocolos industriais como <strong>6TiSCH</strong> e <strong>WirelessHART</strong>, que consolidam esses princípios em padrões amplamente utilizados no Industrial IoT.</p>



<p class="wp-block-paragraph">Este artigo apresenta uma análise progressiva desses protocolos, explorando seus conceitos fundamentais, modos de funcionamento e contextos de uso, com foco especial na relação direta entre <strong>arquitetura de rede, firmware embarcado e eficiência energética</strong>. Ao compreender essa trajetória, torna-se possível enxergar o IoT não como um conjunto de tecnologias isoladas, mas como o resultado de décadas de refinamento conceitual no campo das redes de sensores e sistemas embarcados distribuídos.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/><p>The post <a href="https://mcu.tec.br/protoclos/protocolos-para-redes-de-sensores-e-iot-leach-pegasis-tdma-6tisch-e-wirelesshart/">Protocolos para Redes de Sensores e IoT: LEACH, PEGASIS, TDMA, 6TiSCH e WirelessHART</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1269</post-id>	</item>
		<item>
		<title>Como Estruturar um Projeto Profissional com CMake para o RP2040: Guia Didático Passo a Passo</title>
		<link>https://mcu.tec.br/linguagem/builds/como-estruturar-um-projeto-profissional-com-cmake-para-o-rp2040-guia-didatico-passo-a-passo/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=como-estruturar-um-projeto-profissional-com-cmake-para-o-rp2040-guia-didatico-passo-a-passo</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Fri, 01 Aug 2025 01:06:42 +0000</pubDate>
				<category><![CDATA[Builds]]></category>
		<category><![CDATA[build system CMake]]></category>
		<category><![CDATA[CMake]]></category>
		<category><![CDATA[CMakeLists.txt]]></category>
		<category><![CDATA[compile_commands.json]]></category>
		<category><![CDATA[env.cmake]]></category>
		<category><![CDATA[firmware embarcado]]></category>
		<category><![CDATA[lwIP MQTT]]></category>
		<category><![CDATA[microcontrolador com Wi-Fi]]></category>
		<category><![CDATA[MQTT embedded]]></category>
		<category><![CDATA[projeto embarcado]]></category>
		<category><![CDATA[projeto RP2040]]></category>
		<category><![CDATA[Raspberry Pi Pico]]></category>
		<category><![CDATA[RP2040]]></category>
		<category><![CDATA[SDK Pico]]></category>
		<category><![CDATA[stdio UART]]></category>
		<category><![CDATA[stdio USB]]></category>
		<category><![CDATA[toolchain para RP2040]]></category>
		<category><![CDATA[variável de ambiente]]></category>
		<category><![CDATA[Wi-Fi no RP2040]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=635</guid>

					<description><![CDATA[<p>Aprenda a estruturar corretamente um projeto para o microcontrolador RP2040 utilizando CMake. Este guia didático passo a passo explica cada linha do CMakeLists.txt, desde variáveis de ambiente até a geração do firmware .uf2, com foco em boas práticas e clareza para iniciantes.</p>
<p>The post <a href="https://mcu.tec.br/linguagem/builds/como-estruturar-um-projeto-profissional-com-cmake-para-o-rp2040-guia-didatico-passo-a-passo/">Como Estruturar um Projeto Profissional com CMake para o RP2040: Guia Didático Passo a Passo</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">No universo do desenvolvimento embarcado, a jornada do iniciante pode parecer repleta de barreiras invisíveis. Uma das mais frequentes – e subestimadas – está na <strong>estruturação correta do projeto</strong>, especialmente quando se trata de plataformas modernas como o <strong>RP2040</strong>, o microcontrolador da Raspberry Pi Foundation. Antes mesmo de escrever a primeira linha de código C, é essencial compreender como preparar o ambiente de compilação, como organizar os arquivos e como garantir que tudo esteja pronto para transformar ideias em firmware funcional.</p>



<p class="wp-block-paragraph">Neste contexto, o sistema de build <strong>CMake</strong> se torna uma ferramenta central. Apesar de sua aparência intimidadora para quem está começando, o CMake é uma ponte poderosa entre o código-fonte e o binário que rodará no seu dispositivo. Ele permite organizar dependências, configurar variáveis, compilar múltiplos arquivos e até mesmo lidar com diferentes toolchains de forma automatizada. E quando combinamos o CMake com o ecossistema do RP2040, especialmente com o <strong>Pico SDK</strong>, temos um ambiente robusto, escalável e flexível — desde projetos educacionais até aplicações industriais.</p>



<p class="wp-block-paragraph">Por isso, este artigo tem como objetivo guiar o leitor iniciante <strong>passo a passo</strong> pela análise de um projeto real baseado no RP2040, explicando detalhadamente cada trecho do arquivo <code>CMakeLists.txt</code> e os scripts auxiliares que compõem a infraestrutura de build. Vamos abordar o papel de cada linha, o porquê das decisões adotadas, e quais boas práticas estão sendo aplicadas — além de sugerir melhorias e comparações com abordagens de outras plataformas.</p>



<p class="wp-block-paragraph">Este não é apenas um guia técnico: é também um convite à compreensão. Ao final desta leitura, você não apenas será capaz de compilar um projeto com confiança, mas também entenderá <strong>por que cada etapa é importante</strong>. Assim, poderá adaptar seus projetos futuros com segurança e domínio técnico, explorando todo o potencial do RP2040.</p>



<p class="wp-block-paragraph">Prepare seu editor de texto e acompanhe cada seção com atenção — pois cada linha que vamos explorar é um pequeno degrau em direção à maestria no desenvolvimento embarcado moderno.</p>



<p class="wp-block-paragraph">Para este artigo foi usado os seguintes arquivos CMakeLists.txt:</p>



<ul class="wp-block-list">
<li><a href="https://github.com/carlosdelfino/embarcatech_etapa_2_cap_2_Tarefa-Pr-tica-IOT-3/blob/main/rp2040_mqtt_server_example/CMakeLists.txt">https://github.com/carlosdelfino/embarcatech_etapa_2_cap_2_Tarefa-Pr-tica-IOT-3/blob/main/rp2040_mqtt_server_example/CMakeLists.txt</a> </li>



<li><a href="https://github.com/carlosdelfino/embarcatech_etapa_2_cap_2_Tarefa-Pr-tica-IOT-3/blob/main/rp2040_mqtt_client_example/CMakeLists.txt ">https://github.com/carlosdelfino/embarcatech_etapa_2_cap_2_Tarefa-Pr-tica-IOT-3/blob/main/rp2040_mqtt_client_example/CMakeLists.txt </a></li>
</ul>



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



<h2 class="wp-block-heading"><strong>1. Configuração Inicial do CMake: Definindo Versão e Padrões do Projeto</strong></h2>



<p class="wp-block-paragraph">Logo no início do arquivo <code>CMakeLists.txt</code>, temos um trecho essencial para garantir a compatibilidade e padronização do ambiente de compilação. Veja abaixo:</p>



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

set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">cmake_minimum_required</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">VERSION</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">3.13</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">set</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">CMAKE_C_STANDARD</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">11</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #88C0D0">set</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">CMAKE_CXX_STANDARD</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">17</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #88C0D0">set</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">CMAKE_EXPORT_COMPILE_COMMANDS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ON</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading"><strong>Explicação Didática</strong></h3>



<ol class="wp-block-list">
<li><strong><code>cmake_minimum_required(VERSION 3.13)</code></strong><br>Esta linha define a <strong>versão mínima do CMake</strong> exigida para processar corretamente este projeto. O valor <code>3.13</code> é uma escolha segura para projetos com RP2040, pois é compatível com as versões mais estáveis do SDK da Raspberry Pi e da extensão para VSCode. Se o desenvolvedor tentar compilar o projeto com uma versão mais antiga do CMake, ele receberá uma mensagem de erro clara, evitando comportamento indefinido ou suporte incompleto a recursos.</li>



<li><strong><code>set(CMAKE_C_STANDARD 11)</code></strong><br>Define que o código C será compilado segundo o <strong>padrão C11</strong>, uma versão estável e moderna da linguagem C, que inclui melhorias importantes como <em>atomics</em>, <em>static assertions</em> e melhor suporte a multithreading.</li>



<li><strong><code>set(CMAKE_CXX_STANDARD 17)</code></strong><br>Determina que, caso o projeto inclua arquivos em C++, eles devem seguir o padrão <strong>C++17</strong>. Este padrão oferece recursos como <em>structured bindings</em>, <em>if constexpr</em>, e <em>std::optional</em>, que podem ser úteis em aplicações mais complexas.</li>



<li><strong><code>set(CMAKE_EXPORT_COMPILE_COMMANDS ON)</code></strong><br>Esta opção gera o arquivo <code>compile_commands.json</code>, que descreve os comandos de compilação de cada fonte no projeto. Ele é extremamente útil para ferramentas externas como <strong>servidores de linguagem (LSPs)</strong>, <strong>linters</strong> e <strong>analisadores estáticos</strong>, como o <code>clangd</code>.</li>
</ol>



<h3 class="wp-block-heading"><strong>Análise Crítica</strong></h3>



<ul class="wp-block-list">
<li>A escolha de <strong>C11 e C++17</strong> é apropriada: garante modernidade sem sacrificar a compatibilidade com a maioria dos toolchains usados no mundo embarcado.</li>



<li>A inclusão de <code>CMAKE_EXPORT_COMPILE_COMMANDS</code> mostra preocupação com a <strong>qualidade do desenvolvimento</strong>, pois favorece a integração com IDEs modernas e ferramentas de verificação de código.</li>



<li>Poderia ser interessante tornar os padrões configuráveis via variável de cache (<code>CACHE STRING</code>), permitindo ao usuário customizar sem alterar diretamente o CMakeLists.txt.</li>
</ul>



<h3 class="wp-block-heading"><strong>Observações Didáticas</strong></h3>



<ul class="wp-block-list">
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f530.png" alt="🔰" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Para iniciantes:</strong> Pense nesta seção como o &#8220;acordo inicial&#8221; entre você e o compilador. Aqui você diz: “vamos trabalhar com a linguagem C moderna, C++ moderno e quero um ambiente que me ajude a detectar erros logo no começo”.</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f6e0.png" alt="🛠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Boas práticas:</strong> Sempre explicite o padrão da linguagem em projetos embarcados. Evita surpresas e garante consistência entre diferentes ambientes de build.</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f9e0.png" alt="🧠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Dica extra:</strong> O <code>compile_commands.json</code> pode ser usado por ferramentas como o <strong>clang-tidy</strong> ou <strong>cppcheck</strong> para inspeções profundas do seu código.</li>
</ul>



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



<h2 class="wp-block-heading"><strong>2. Configuração da Extensão VSCode e Inclusão do SDK</strong></h2>



<p class="wp-block-paragraph">Após definir os padrões iniciais de compilação, o projeto introduz uma etapa importante para integração com o ambiente de desenvolvimento e o SDK do RP2040. Veja o trecho a seguir:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="# == DO NOT EDIT THE FOLLOWING LINES for the Raspberry Pi Pico VS Code Extension to work ==
if(WIN32)
    set(USERHOME $ENV{USERPROFILE})
else()
    set(USERHOME $ENV{HOME})
endif()
set(sdkVersion 2.1.1)
set(toolchainVersion 14_2_Rel1)
set(picotoolVersion 2.1.1)
set(picoVscode ${USERHOME}/.pico-sdk/cmake/pico-vscode.cmake)
if (EXISTS ${picoVscode})
    include(${picoVscode})
endif()
# ====================================================================================
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #81A1C1">==</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">DO</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NOT</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">EDIT</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THE</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">FOLLOWING</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">LINES</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">the</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Raspberry</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Pi</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Pico</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">VS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Code</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Extension</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">to</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">work</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">==</span></span>
<span class="line"><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">WIN32</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">set</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">USERHOME</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">$ENV</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9">USERPROFILE</span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #81A1C1">else</span><span style="color: #D8DEE9FF">()</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">set</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">USERHOME</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">$ENV</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9">HOME</span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #88C0D0">endif</span><span style="color: #D8DEE9FF">()</span></span>
<span class="line"><span style="color: #88C0D0">set</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">sdkVersion</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2.1</span><span style="color: #ECEFF4">.</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #88C0D0">set</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">toolchainVersion</span><span style="color: #D8DEE9FF"> 14</span><span style="color: #D8DEE9">_2_Rel1</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #88C0D0">set</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">picotoolVersion</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2.1</span><span style="color: #ECEFF4">.</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #88C0D0">set</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">picoVscode</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">$</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9">USERHOME</span><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">/</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">pico</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">sdk</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">cmake</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9">pico</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">vscode</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">cmake</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">EXISTS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">$</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9">picoVscode</span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">include</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">$</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9">picoVscode</span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #88C0D0">endif</span><span style="color: #D8DEE9FF">()</span></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #81A1C1">====================================================================================</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading"><strong>Explicação Didática</strong></h3>



<ol class="wp-block-list">
<li><strong>Bloco condicional <code>if(WIN32)</code>&#8230;</strong><br>Aqui é verificado se o sistema operacional é Windows (<code>WIN32</code>). Se for, define a variável <code>USERHOME</code> como o caminho da variável de ambiente <code>USERPROFILE</code>. Caso contrário (Linux/macOS), usa <code>HOME</code>.<br>Isso garante <strong>portabilidade do projeto entre sistemas operacionais</strong>, o que é essencial para ambientes colaborativos e didáticos.</li>



<li><strong><code>set(sdkVersion ...)</code>, <code>toolchainVersion ...</code>, <code>picotoolVersion ...)</code></strong><br>Essas linhas servem como <strong>metadados informativos</strong> que descrevem as versões usadas no ambiente de desenvolvimento. Embora não sejam diretamente utilizadas pelo CMake nesta etapa, são úteis para documentação, scripts externos ou para controle de consistência do ambiente de build.</li>



<li><strong><code>set(picoVscode ...)</code> e <code>include(...)</code></strong><br>Essa etapa tenta localizar o arquivo <code>pico-vscode.cmake</code>, que é utilizado pela extensão oficial da Raspberry Pi no VSCode para configurar corretamente o ambiente.<br>Se o arquivo existir, ele é incluído, permitindo que recursos como <strong>auto-complete</strong>, <strong>debug remoto</strong>, e <strong>templates automáticos</strong> funcionem adequadamente.</li>
</ol>



<h3 class="wp-block-heading"><strong>Análise Crítica</strong></h3>



<ul class="wp-block-list">
<li>O uso de <code>EXISTS</code> para checar a presença do arquivo evita erros e torna o projeto mais robusto.</li>



<li>Esta seção é essencial para <strong>ambientes com suporte a IDEs modernas</strong>, mas pode ser <strong>omitida com segurança</strong> se o projeto for construído apenas via terminal.</li>



<li>A presença dos comentários <code>DO NOT EDIT</code> é uma prática comum para marcar blocos sensíveis que são exigidos por ferramentas externas.</li>
</ul>



<h3 class="wp-block-heading"><strong>Observações Didáticas</strong></h3>



<ul class="wp-block-list">
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f9f0.png" alt="🧰" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Para iniciantes:</strong> Essa parte pode parecer obscura à primeira vista, mas pense nela como a “ponte” entre o CMake e o seu editor (VSCode). Se ela estiver funcionando, você terá suporte a <strong>atalhos, intellisense e debug facilitado</strong>.</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f30d.png" alt="🌍" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Dica de compatibilidade:</strong> Quando você compartilha seu projeto com colegas usando Windows e você usa Linux (ou vice-versa), esse bloco ajuda a manter tudo funcionando sem dor de cabeça.</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4e6.png" alt="📦" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Importante saber:</strong> Se o arquivo <code>pico-vscode.cmake</code> não estiver instalado, o build ainda funcionará — mas <strong>você perderá integração com o VSCode</strong>.</li>
</ul>



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



<h2 class="wp-block-heading"><strong>3. Parametrização por Ambiente: Importando o <code>env.cmake</code></strong></h2>



<p class="wp-block-paragraph">Este bloco mostra como carregar configurações externas e definir valores padrão para variáveis críticas de conexão, como Wi-Fi e MQTT. Veja o trecho abaixo:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="if(EXISTS &quot;${CMAKE_SOURCE_DIR}/env.cmake&quot;)
    include(&quot;${CMAKE_SOURCE_DIR}/env.cmake&quot;)
    message(STATUS &quot;Arquivo env.cmake carregado com sucesso.&quot;)
else()
    message(FATAL_ERROR &quot;Arquivo env.cmake não encontrado!&quot;)
endif()
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">EXISTS</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">${CMAKE_SOURCE_DIR}/env.cmake</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">include</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">${CMAKE_SOURCE_DIR}/env.cmake</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">message</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">STATUS</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Arquivo env.cmake carregado com sucesso.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #81A1C1">else</span><span style="color: #D8DEE9FF">()</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">message</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">FATAL_ERROR</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Arquivo env.cmake não encontrado!</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #88C0D0">endif</span><span style="color: #D8DEE9FF">()</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading"><strong>Explicação Didática</strong></h3>



<ol class="wp-block-list">
<li><strong><code>if(EXISTS "${CMAKE_SOURCE_DIR}/env.cmake")</code></strong><br>Verifica se o arquivo <code>env.cmake</code> existe no diretório raiz do projeto. Essa verificação é crucial para não interromper o processo de configuração se o arquivo estiver ausente ou mal posicionado.</li>



<li><strong><code>include(...)</code></strong><br>Se o arquivo existir, ele é carregado e suas variáveis passam a ser conhecidas no escopo do CMake. Isso permite separar a <strong>configuração sensível ou personalizada</strong> (como senhas e tópicos MQTT) do corpo principal do projeto.</li>



<li><strong><code>message(STATUS "...")</code> e <code>message(FATAL_ERROR "...")</code></strong><br>Usadas para informar claramente ao usuário o sucesso ou falha dessa etapa. Um erro fatal é gerado se o <code>env.cmake</code> estiver ausente, forçando o desenvolvedor a corrigi-lo antes de prosseguir — uma forma de evitar builds incompletos ou configurações erradas.</li>
</ol>



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



<p class="wp-block-paragraph">A seguir, são aplicadas validações adicionais:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="if(NOT DEFINED ENV{WIFI_SSID})
    message(WARNING &quot;Variável WIFI_SSID não definida no .env.&quot;)
    set(ENV{WIFI_SSID} &quot;ArvoreDosSaberes&quot;)
endif()
# ... outros blocos semelhantes para WIFI_PASSWORD, MQTT_BROKER, etc.
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">NOT</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">DEFINED</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ENV</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9">WIFI_SSID</span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">message</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">WARNING</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Variável WIFI_SSID não definida no .env.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">set</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">ENV</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9">WIFI_SSID</span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">ArvoreDosSaberes</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #88C0D0">endif</span><span style="color: #D8DEE9FF">()</span></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #81A1C1">...</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">outros</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">blocos</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">semelhantes</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">para</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">WIFI_PASSWORD</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MQTT_BROKER</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">etc</span><span style="color: #ECEFF4">.</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading"><strong>Explicação Didática</strong></h3>



<p class="wp-block-paragraph">Cada bloco verifica se uma variável de ambiente essencial está definida (<code>ENV{VARIAVEL}</code>). Se não estiver, ele:</p>



<ul class="wp-block-list">
<li>Emite um <strong>aviso não fatal</strong>, alertando o usuário;</li>



<li>Define um valor <strong>padrão razoável</strong> para que o build continue.</li>
</ul>



<p class="wp-block-paragraph">Ao final, todas as variáveis são capturadas explicitamente para o escopo interno do CMake:</p>



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



<h3 class="wp-block-heading"><strong>Análise Crítica</strong></h3>



<ul class="wp-block-list">
<li>O uso do <code>env.cmake</code> permite separar configuração de ambiente do código — uma excelente prática que segue os princípios da engenharia de software moderna.</li>



<li>Fornecer valores padrão facilita testes e uso didático, mas o ideal seria mover os valores <strong>sensíveis (como senhas)</strong> para fora do controle de versão (usando, por exemplo, <code>.gitignore</code>).</li>



<li>Poderia haver uma variável global ou opção no CMake para <strong>desativar temporariamente os erros fatais</strong>, facilitando builds rápidos durante o desenvolvimento.</li>
</ul>



<h3 class="wp-block-heading"><strong>Observações Didáticas</strong></h3>



<ul class="wp-block-list">
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f9ea.png" alt="🧪" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Analogia simples:</strong> Pense no <code>env.cmake</code> como um “cartão de visita” que você entrega ao projeto, dizendo quem você é (SSID, senha, broker). Assim, ele sabe com quem falar e como se comportar.</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4c1.png" alt="📁" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Organização é tudo:</strong> Ao manter essas variáveis fora do <code>CMakeLists.txt</code>, você pode trocar de rede ou broker sem reconfigurar o projeto inteiro — basta editar ou substituir o <code>env.cmake</code>.</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f6ab.png" alt="🚫" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Cuidado comum:</strong> Não deixar o <code>env.cmake</code> com credenciais sensíveis visíveis em repositórios públicos. Para isso, use <code>.gitignore</code>.</li>
</ul>



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



<h2 class="wp-block-heading"><strong>4. Inicialização do SDK e Definição do Executável</strong></h2>



<p class="wp-block-paragraph">Com todas as variáveis e configurações preparadas, o próximo passo é estruturar o projeto de forma que o SDK da Raspberry Pi Pico possa ser utilizado corretamente, e o firmware final seja construído como um <strong>executável nomeado</strong>. O trecho em destaque é o seguinte:</p>



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

project(firmware_client_mqtt C CXX ASM)

# Initialise the Raspberry Pi Pico SDK
pico_sdk_init()
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #D8DEE9">Pull</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">in</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Raspberry</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Pi</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Pico</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">SDK</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">must</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">be</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">before</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">project</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #88C0D0">include</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">pico_sdk_import</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">cmake</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">project</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">firmware_client_mqtt</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">C</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">CXX</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ASM</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #D8DEE9">Initialise</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">the</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Raspberry</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Pi</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Pico</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">SDK</span></span>
<span class="line"><span style="color: #88C0D0">pico_sdk_init</span><span style="color: #D8DEE9FF">()</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading"><strong>Explicação Didática</strong></h3>



<ol class="wp-block-list">
<li><strong><code>include(pico_sdk_import.cmake)</code></strong><br>Este comando inclui o script <code>pico_sdk_import.cmake</code>, normalmente localizado na raiz do SDK da Raspberry Pi. Ele é responsável por <strong>carregar as bibliotecas, drivers e configurações internas</strong> que fazem parte do Pico SDK.<br>É essencial que esta linha venha <strong>antes do comando <code>project(...)</code></strong>, pois o SDK precisa estar carregado para que o CMake reconheça suas funções auxiliares como <code>pico_sdk_init()</code> ou <code>pico_enable_stdio_usb()</code>.</li>



<li><strong><code>project(firmware_client_mqtt C CXX ASM)</code></strong><br>Define oficialmente o nome do projeto, bem como os tipos de código que ele conterá:
<ul class="wp-block-list">
<li><code>C</code>: código C (linguagem base do projeto);</li>



<li><code>CXX</code>: suporte a C++, mesmo que opcional;</li>



<li><code>ASM</code>: suporte à linguagem Assembly, caso você deseje manipular diretamente registradores ou realizar otimizações de baixo nível.</li>
</ul>
</li>



<li><strong><code>pico_sdk_init()</code></strong><br>Esta função é uma <strong>macro do Pico SDK</strong> que realiza a configuração padrão do ambiente, ativando funcionalidades como drivers de hardware (<code>hardware_gpio</code>, <code>hardware_adc</code>, etc.), bibliotecas utilitárias e integração com o sistema de build.</li>
</ol>



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



<p class="wp-block-paragraph">Em seguida, o projeto define o binário principal:</p>



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



<p class="wp-block-paragraph">E depois configura nome e versão para fins de organizaçã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" data-code="pico_set_program_name(firmware_client_mqtt &quot;firmware_client_mqtt&quot;)
pico_set_program_version(firmware_client_mqtt &quot;0.1&quot;)
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">pico_set_program_name</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">firmware_client_mqtt</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">firmware_client_mqtt</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #88C0D0">pico_set_program_version</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">firmware_client_mqtt</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">0.1</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading"><strong>Explicação Didática</strong></h3>



<ol start="4" class="wp-block-list">
<li><strong><code>add_executable(...)</code></strong><br>Esta linha define o <strong>arquivo principal a ser compilado</strong>, neste caso, <code>firmware_client_mqtt.c</code>. O nome dado ao executável será usado como base para gerar o binário <code>.uf2</code> (formato de firmware usado pelo RP2040).<br>Também é possível incluir múltiplos arquivos <code>.c</code>, <code>.cpp</code> ou <code>.s</code> (Assembly) se o projeto for modularizado.</li>



<li><strong><code>pico_set_program_name</code> e <code>pico_set_program_version</code></strong><br>Estes comandos definem metadados do projeto, como nome e versão, que podem ser usados por ferramentas de depuração ou sistemas de versionamento. Embora opcionais, são úteis em ambientes colaborativos ou industriais.</li>
</ol>



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



<h3 class="wp-block-heading"><strong>Análise Crítica</strong></h3>



<ul class="wp-block-list">
<li>Esta seção está <strong>tecnicamente correta</strong> e bem estruturada, seguindo as recomendações do Pico SDK.</li>



<li>O uso explícito de <code>C</code>, <code>CXX</code> e <code>ASM</code> torna o projeto mais <strong>versátil</strong> e pronto para escalar em complexidade.</li>



<li>O nome do projeto (<code>firmware_client_mqtt</code>) é repetido em vários pontos. Poderia ser definido via uma variável (<code>set(PROJECT_NAME firmware_client_mqtt)</code>) para facilitar manutenção futura.</li>
</ul>



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



<h3 class="wp-block-heading"><strong>Observações Didáticas</strong></h3>



<ul class="wp-block-list">
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f680.png" alt="🚀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Analogia prática:</strong> Essa parte é como “ligar a tomada” do seu projeto. Você diz ao sistema: “meu projeto se chama X, usa essas linguagens, e quero usar as bibliotecas do SDK da Raspberry Pi”.</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4e6.png" alt="📦" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Dica extra:</strong> Ao compilar, o CMake vai gerar automaticamente arquivos <code>.elf</code>, <code>.bin</code> e <code>.uf2</code>, prontos para serem gravados na flash do RP2040.</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f5c3.png" alt="🗃" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Boas práticas:</strong> Sempre modularize seu código desde o começo. Mesmo que só tenha um arquivo <code>.c</code>, mantenha espaço para crescer (ex: <code>src/</code>, <code>include/</code>).</li>
</ul>



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



<h2 class="wp-block-heading"><strong>5. Ativando Entradas/Saídas e Ligando Bibliotecas Essenciais</strong></h2>



<p class="wp-block-paragraph">Depois de declarar o executável e configurar seu nome e versão, o projeto define como o firmware irá se comunicar com o mundo externo — por portas seriais ou USB — e quais bibliotecas devem ser incluídas na hora da linkagem. Veja o trecho:</p>



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



<h3 class="wp-block-heading"><strong>Explicação Didática</strong></h3>



<ol class="wp-block-list">
<li><strong><code>pico_enable_stdio_uart(&lt;target> &lt;boolean>)</code></strong><br>Define se a <strong>UART (porta serial física)</strong> será usada como saída padrão (<code>stdout</code>) do programa. No exemplo acima, o valor <code>0</code> desativa a UART. Isso pode ser útil se o projeto não utilizar os pinos GPIO dedicados à UART, ou se estiver usando USB para comunicação com o PC.</li>



<li><strong><code>pico_enable_stdio_usb(&lt;target> &lt;boolean>)</code></strong><br>Ativa a comunicação serial via <strong>USB virtual (CDC)</strong>. Com <code>1</code>, o firmware pode imprimir mensagens no terminal conectado via cabo USB — muito útil para debug com ferramentas como <code>minicom</code>, <code>PuTTY</code>, <code>Thonny</code> ou o console do VSCode.</li>
</ol>



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



<p class="wp-block-paragraph">Em seguida, são declaradas as bibliotecas necessárias à aplicaçã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" data-code="target_link_libraries(firmware_client_mqtt
    pico_stdlib
    pico_cyw43_arch_lwip_threadsafe_background
    pico_lwip_mqtt
)
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">target_link_libraries</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">firmware_client_mqtt</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">pico_stdlib</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">pico_cyw43_arch_lwip_threadsafe_background</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">pico_lwip_mqtt</span></span>
<span class="line"><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading"><strong>Explicação Didática</strong></h3>



<ol start="3" class="wp-block-list">
<li><strong><code>target_link_libraries(...)</code></strong><br>Essa linha especifica quais bibliotecas serão <strong>ligadas (linkadas)</strong> ao firmware durante a compilação.
<ul class="wp-block-list">
<li><code>pico_stdlib</code>: a <strong>biblioteca padrão</strong> do SDK, que fornece funções básicas como <code>printf</code>, controle de pinos, delays, etc.</li>



<li><code>pico_cyw43_arch_lwip_threadsafe_background</code>: fornece <strong>acesso ao chip Wi-Fi CYW43</strong> (usado no RP2040 W) em modo cooperativo com a pilha TCP/IP lwIP.</li>



<li><code>pico_lwip_mqtt</code>: adiciona suporte ao <strong>protocolo MQTT</strong> com base na biblioteca lwIP, permitindo que o firmware se comunique com brokers MQTT como o Mosquitto, HiveMQ, etc.</li>
</ul>
</li>
</ol>



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



<h3 class="wp-block-heading"><strong>Análise Crítica</strong></h3>



<ul class="wp-block-list">
<li>Desativar UART e ativar apenas USB (como neste projeto) é uma escolha moderna e prática, já que a maioria dos computadores não possui porta serial física.</li>



<li>O uso de <code>pico_lwip_mqtt</code> demonstra um foco em <strong>conectividade IoT</strong>. Esta biblioteca ainda é pouco documentada fora dos exemplos oficiais, então usar os exemplos do SDK como base é uma boa prática.</li>



<li>Poderia ser interessante encapsular as bibliotecas adicionais em uma função auxiliar (<code>add_custom_dependencies()</code>), principalmente em projetos maiores.</li>
</ul>



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



<h3 class="wp-block-heading"><strong>Observações Didáticas</strong></h3>



<ul class="wp-block-list">
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f50c.png" alt="🔌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Para iniciantes:</strong> Pense na UART e na USB como “canais de conversa” entre o RP2040 e o mundo externo. Você pode escolher usar um, ambos, ou nenhum.</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f9f0.png" alt="🧰" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Boas práticas:</strong> Se for usar UART, lembre-se de configurar os pinos no firmware (<code>gpio_set_function(...)</code>). Se usar USB, não esqueça que a comunicação começa <strong>após a USB ser enumerada pelo host</strong> — o que leva alguns milissegundos após reset.</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f310.png" alt="🌐" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Importante saber:</strong> A biblioteca <code>pico_cyw43_arch_lwip_threadsafe_background</code> executa tarefas de rede em segundo plano, sem precisar de um RTOS. Ideal para projetos simples mas que precisam de conectividade Wi-Fi confiável.</li>
</ul>



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



<h2 class="wp-block-heading"><strong>6. Inclusão de Diretórios e Definição de Macros de Conexão</strong></h2>



<p class="wp-block-paragraph">Com a estrutura principal pronta e as bibliotecas já ligadas, o projeto agora configura o acesso aos diretórios de cabeçalhos e exporta as variáveis de ambiente para uso direto no código C:</p>



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



<h3 class="wp-block-heading"><strong>Explicação Didática</strong></h3>



<ol class="wp-block-list">
<li><strong><code>target_include_directories(...)</code></strong><br>Especifica para o compilador onde ele deve procurar os arquivos <code>.h</code> durante a compilação.
<ul class="wp-block-list">
<li><code>firmware_client_mqtt</code>: é o alvo (o executável).</li>



<li><code>PRIVATE</code>: significa que esses diretórios são usados <strong>apenas internamente</strong> para este alvo (e não propagados a outras dependências).</li>



<li><code>${CMAKE_CURRENT_LIST_DIR}</code>: refere-se ao diretório atual onde está o <code>CMakeLists.txt</code>. Isso permite que o <code>main.c</code> e outros arquivos no mesmo diretório acessem os headers locais diretamente.</li>
</ul>
</li>
</ol>



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



<p class="wp-block-paragraph">Agora, as variáveis de ambiente definidas anteriormente são “injetadas” no código-fonte como macros com <code>#define</code>, utilizando o comando:</p>



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



<h3 class="wp-block-heading"><strong>Explicação Didática</strong></h3>



<ol start="2" class="wp-block-list">
<li><strong><code>target_compile_definitions(...)</code></strong><br>Insere <strong>macros de pré-processador</strong> no projeto. Na prática, é como se o CMake escrevesse automaticamente estas linhas no seu código: <code>#define WIFI_SSID "ArvoreDosSaberes" #define WIFI_PASSWORD "Arduino2022" #define MQTT_BROKER "mqtt.rapport.tec.br" #define MQTT_BASE_TOPIC "rack_inteligente" #define MQTT_RACK_NUMBER "3"</code> Isso permite que o código-fonte seja <strong>genérico e portátil</strong>, pegando os dados do ambiente e não de strings fixas.</li>
</ol>



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



<h3 class="wp-block-heading"><strong>Análise Crítica</strong></h3>



<ul class="wp-block-list">
<li>O uso de <code>target_compile_definitions</code> é <strong>altamente recomendável</strong>, pois centraliza a configuração no CMake em vez de espalhar definições pelo código-fonte.</li>



<li>A sintaxe de escape com <code>\"...\"</code> garante que as strings sejam corretamente interpretadas como literais no código C. Uma falha comum de iniciantes é esquecer essas aspas.</li>



<li>Em projetos maiores, pode-se usar arquivos <code>.h</code> autogerados a partir do CMake para organizar essas definições (ex: <code>config.h.in</code> com <code>configure_file()</code>).</li>
</ul>



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



<h3 class="wp-block-heading"><strong>Observações Didáticas</strong></h3>



<ul class="wp-block-list">
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f9e0.png" alt="🧠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Para iniciantes:</strong> Pense que você está mandando um bilhete do CMake para o seu código C. Esse bilhete diz: “ei, aqui está o nome da sua rede Wi-Fi e os dados do MQTT”.</li>



<li><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>Erros comuns:</strong> Se você esquecer de escapar as aspas (<code>\"</code>), o compilador vai entender errado a definição e gerar erros como “expected identifier”.</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f6e1.png" alt="🛡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Boas práticas:</strong> Nunca inclua senhas reais ou dados sensíveis diretamente no <code>main.c</code>. Use sempre esse método de parametrização, ou proteja via arquivos ignorados no Git.</li>
</ul>



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



<h2 class="wp-block-heading"><strong>7. Geração dos Arquivos de Saída: <code>pico_add_extra_outputs</code></strong></h2>



<p class="wp-block-paragraph">No final do arquivo, encontramos a seguinte linha:</p>



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



<h3 class="wp-block-heading"><strong>Explicação Didática</strong></h3>



<p class="wp-block-paragraph">Este comando é uma <strong>macro fornecida pelo Pico SDK</strong> que automatiza a criação de diferentes formatos de saída do firmware. A partir do executável gerado (<code>firmware_client_mqtt.elf</code>), ela cuida de produzir também:</p>



<ul class="wp-block-list">
<li><code>firmware_client_mqtt.bin</code>: imagem binária “crua”, usada em alguns programadores.</li>



<li><code>firmware_client_mqtt.uf2</code>: formato específico do RP2040, utilizado para arrastar e soltar o firmware diretamente na unidade USB visível quando o RP2040 está em modo de bootloader.</li>



<li>Arquivos <code>.map</code>, <code>.hex</code>, <code>.dis</code> ou <code>.lst</code> também podem ser gerados, dependendo das opções do CMake.</li>
</ul>



<p class="wp-block-paragraph">Tudo isso acontece de forma automática, dispensando a escrita manual de comandos extras.</p>



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



<h3 class="wp-block-heading"><strong>Análise Crítica</strong></h3>



<ul class="wp-block-list">
<li>O uso de <code>pico_add_extra_outputs</code> é <strong>obrigatório</strong> em projetos com RP2040 se você quiser gerar arquivos <code>.uf2</code>, que são os mais práticos para upload via USB.</li>



<li>Essa macro também <strong>facilita o debug</strong>, já que o <code>.elf</code> gerado pode ser carregado diretamente por ferramentas como GDB, OpenOCD ou o depurador do VSCode.</li>



<li>Poderia ser complementada com scripts de pós-build para, por exemplo, copiar o <code>.uf2</code> para um diretório específico ou ativar gravação automática via <code>picotool</code>.</li>
</ul>



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



<h3 class="wp-block-heading"><strong>Observações Didáticas</strong></h3>



<ul class="wp-block-list">
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f9fe.png" alt="🧾" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Para iniciantes:</strong> Essa etapa é como pedir ao compilador: “não me dê só o resultado final, me dê também outras versões do programa — uma para o bootloader, outra para depurar, outra para backup”.</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4be.png" alt="💾" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Boas práticas:</strong> Após cada build, confira a pasta <code>build/</code> — os arquivos <code>.uf2</code>, <code>.elf</code> e <code>.bin</code> estarão lá. O <code>.uf2</code> é o que você deve <strong>arrastar e soltar</strong> no RP2040 quando ele estiver em modo boot (pressionando o botão BOOTSEL).</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f6a6.png" alt="🚦" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Dica de produtividade:</strong> Se você estiver usando VSCode com a extensão oficial, essa macro garante que o botão “Build” funcione corretamente e gere o <code>.uf2</code> automaticamente.</li>
</ul>



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



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Finalização da Análise Técnica</h3>



<p class="wp-block-paragraph">Com essa última linha, fechamos a análise completa e detalhada do arquivo <code>CMakeLists.txt</code>. Todas as etapas — desde configuração básica, carregamento do SDK, definição do executável, inclusão de bibliotecas, parâmetros de ambiente até a geração dos arquivos finais — foram explicadas com clareza e espírito didático.</p>



<p class="wp-block-paragraph">Perfeito! Vamos então à conclusão geral do artigo, amarrando todo o conteúdo de forma coesa e didática.</p>



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



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



<p class="wp-block-paragraph">Ao longo deste artigo, percorremos — linha por linha — a estrutura de um <code>CMakeLists.txt</code> real utilizado em um projeto baseado no microcontrolador <strong>RP2040</strong>, com foco em conectividade Wi-Fi e MQTT. O objetivo foi mais do que explicar comandos: buscamos desenvolver no leitor a compreensão do <strong>porquê</strong> de cada configuração, tornando-o capaz de <strong>analisar, adaptar e evoluir seus próprios projetos</strong>.</p>



<p class="wp-block-paragraph">Iniciamos com a definição dos padrões de compilação e seguimos pela configuração do ambiente de desenvolvimento, mostrando como tornar o projeto compatível com ferramentas modernas como o VSCode. Depois, vimos como separar parâmetros de configuração em arquivos auxiliares (<code>env.cmake</code>) e como capturar variáveis de ambiente de forma segura e elegante. Em seguida, exploramos a inicialização do SDK, a declaração do executável, a ativação dos canais de comunicação via USB e UART, a ligação com bibliotecas críticas como <code>pico_lwip_mqtt</code>, e, por fim, a geração dos arquivos <code>.uf2</code> e <code>.elf</code> prontos para gravação.</p>



<p class="wp-block-paragraph">Além do conteúdo técnico, discutimos <strong>boas práticas</strong> como:</p>



<ul class="wp-block-list">
<li>Separar configuração do código-fonte com <code>env.cmake</code>;</li>



<li>Utilizar <code>target_compile_definitions</code> para injetar parâmetros no pré-processador;</li>



<li>Escapar corretamente strings definidas no CMake;</li>



<li>Manter o projeto modular e escalável com <code>target_include_directories</code> e <code>target_link_libraries</code>;</li>



<li>Evitar hardcoding de dados sensíveis e trabalhar com variáveis de ambiente.</li>
</ul>



<p class="wp-block-paragraph">Esse conhecimento é <strong>fundamental para qualquer desenvolvedor embarcado que deseje usar o RP2040 de forma profissional e segura</strong>. A compreensão profunda da infraestrutura de build é o que separa um programador iniciante de um desenvolvedor capaz de integrar sistemas complexos, automatizar tarefas, e resolver problemas de forma elegante.</p>



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



<h2 class="wp-block-heading"><strong>Próximos Passos</strong></h2>



<p class="wp-block-paragraph">Se você chegou até aqui, parabéns! Seu próximo passo pode ser:</p>



<ul class="wp-block-list">
<li>Explorar o conteúdo do arquivo <code>env.cmake</code> em detalhes;</li>



<li>Modularizar seu projeto criando subdiretórios como <code>src/</code> e <code>include/</code>;</li>



<li>Automatizar tarefas de pós-build, como upload via <code>picotool</code>;</li>



<li>Adicionar testes unitários usando CMocka ou Unity em conjunto com CMake;</li>



<li>Criar templates de projetos reutilizáveis com base nessa estrutura.</li>
</ul>



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



<h2 class="wp-block-heading"><strong>Indicações de Leitura Complementar</strong></h2>



<ul class="wp-block-list">
<li><a href="https://datasheets.raspberrypi.com/pico/raspberry-pi-pico-c-sdk.pdf">Documentação oficial do Pico SDK</a></li>



<li><a href="https://www.jetbrains.com/help/clion/quick-cmake-tutorial.html">Tutorial CMake da JetBrains</a></li>



<li><a href="https://interrupt.memfault.com/blog/firmware-build-systems">CMake para Embedded (platformIO-style)</a></li>
</ul>



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



<p class="wp-block-paragraph"></p><p>The post <a href="https://mcu.tec.br/linguagem/builds/como-estruturar-um-projeto-profissional-com-cmake-para-o-rp2040-guia-didatico-passo-a-passo/">Como Estruturar um Projeto Profissional com CMake para o RP2040: Guia Didático Passo a Passo</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">635</post-id>	</item>
		<item>
		<title>Como Firmwares Conscientes de Energia Podem Prevenir Falhas de Hardware</title>
		<link>https://mcu.tec.br/algoritimos/como-firmwares-conscientes-de-energia-podem-prevenir-falhas-de-hardware/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=como-firmwares-conscientes-de-energia-podem-prevenir-falhas-de-hardware</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Mon, 30 Jun 2025 20:10:17 +0000</pubDate>
				<category><![CDATA[Algoritimos]]></category>
		<category><![CDATA[Basis Peak recall]]></category>
		<category><![CDATA[consumo de energia em firmware]]></category>
		<category><![CDATA[DVFS]]></category>
		<category><![CDATA[falhas de hardware]]></category>
		<category><![CDATA[falhas por LED]]></category>
		<category><![CDATA[firmware embarcado]]></category>
		<category><![CDATA[firmware power-aware]]></category>
		<category><![CDATA[gerenciamento de energia]]></category>
		<category><![CDATA[microcontroladores e energia]]></category>
		<category><![CDATA[modos de baixo consumo]]></category>
		<category><![CDATA[prevenção de falhas em eletrônicos]]></category>
		<category><![CDATA[proteção térmica]]></category>
		<category><![CDATA[STM32 consumo]]></category>
		<category><![CDATA[superaquecimento eletrônico]]></category>
		<category><![CDATA[sustentabilidade em sistemas embarcados]]></category>
		<category><![CDATA[técnicas de economia de energia]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=535</guid>

					<description><![CDATA[<p>Descubra como firmwares inteligentes podem proteger seu hardware, reduzir falhas e aumentar a durabilidade com técnicas de gerenciamento energético.</p>
<p>The post <a href="https://mcu.tec.br/algoritimos/como-firmwares-conscientes-de-energia-podem-prevenir-falhas-de-hardware/">Como Firmwares Conscientes de Energia Podem Prevenir Falhas de Hardware</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">A crescente complexidade dos sistemas embarcados e o aumento da demanda por dispositivos eletrônicos mais eficientes e confiáveis tornam o consumo de energia uma preocupação crítica, não apenas para a autonomia dos equipamentos, mas também para a integridade do hardware. A execução de firmware desatento ao gerenciamento de energia pode levar a sobreaquecimento, degradação prematura de componentes e, em casos mais extremos, falhas catastróficas do sistema.</p>



<p class="wp-block-paragraph">Neste contexto, o conceito de <em>firmware power-aware</em> — firmware consciente e adaptativo ao consumo energético — emerge como uma abordagem estratégica essencial para a prevenção de falhas físicas. Ao ajustar dinamicamente a frequência de operação, controlar o modo de atividade dos periféricos e otimizar algoritmos com base nos perfis de carga e uso, um firmware inteligente pode reduzir significativamente o estresse térmico e elétrico sobre os componentes, prolongando a vida útil do hardware.</p>



<p class="wp-block-paragraph">Este artigo explora os fundamentos do firmware power-aware, destacando os impactos do gerenciamento de energia no desempenho e na confiabilidade dos sistemas embarcados. Abordaremos as principais técnicas utilizadas, os padrões de projeto associados e estudos de caso práticos onde o firmware energeticamente consciente se mostrou determinante para evitar falhas de hardware. Ao final, será possível entender por que projetar com consciência energética não é apenas uma questão de eficiência, mas de durabilidade e segurança.</p>



<h2 class="wp-block-heading">Problemas de Hardware Causados por Firmware Negligente</h2>



<p class="wp-block-paragraph">Embora o hardware seja projetado para operar dentro de faixas específicas de tensão, corrente e temperatura, o firmware é responsável por manter o sistema dentro desses limites em tempo real. Quando o firmware ignora práticas de controle de energia, diversos problemas críticos podem surgir, mesmo em hardware robusto.</p>



<p class="wp-block-paragraph">Um dos problemas mais comuns é o sobreaquecimento. Sem um gerenciamento adequado dos ciclos de atividade da CPU e dos periféricos, o sistema pode operar em alta carga contínua, gerando calor excessivo que afeta diretamente a integridade dos semicondutores. Em microcontroladores e SoCs (System on Chip), esse calor pode causar degradação de transistores, alteração de características elétricas e até falhas permanentes em regiões sensíveis da matriz.</p>



<p class="wp-block-paragraph">Outro risco é a degradação eletromigratória, causada pelo fluxo contínuo de corrente elevada através de trilhas metálicas internas. Essa degradação acelera quando o firmware não implementa modos de baixo consumo durante ociosidade ou não limita a atividade de interfaces de comunicação e periféricos de alto consumo como ADCs e controladores de rádio.</p>



<p class="wp-block-paragraph">Além disso, o firmware negligente pode provocar ciclos de energia desnecessários, resultando em <em>inrush currents</em> (correntes de partida) que sobrecarregam reguladores de tensão, indutores e capacitores, diminuindo sua vida útil. Sistemas mal projetados podem também ativar dispositivos simultaneamente de forma descoordenada, criando <em>power surges</em> que danificam linhas de alimentação internas ou externos conectados via barramentos.</p>



<p class="wp-block-paragraph">Em sistemas alimentados por bateria, a falta de inteligência no consumo energético pode causar quedas abruptas de tensão, o que compromete não apenas a estabilidade do sistema, mas também a própria bateria — levando a ciclos de descarga profunda que a degradam de forma irreversível.</p>



<p class="wp-block-paragraph">Esses problemas mostram que o firmware não deve ser tratado apenas como “software embarcado”, mas como parte essencial do projeto físico do equipamento. Ignorar o gerenciamento energético no firmware equivale a negligenciar a saúde do hardware.</p>



<h2 class="wp-block-heading">Conceito e Fundamentos de Firmware Power-Aware</h2>



<p class="wp-block-paragraph">O termo <em>power-aware firmware</em> refere-se a um conjunto de práticas e técnicas aplicadas no desenvolvimento de firmware com o objetivo de otimizar o uso de energia elétrica sem comprometer a funcionalidade do sistema. Mais do que simplesmente economizar energia, o firmware power-aware tem como missão proteger o hardware de estresses elétricos e térmicos, atuando de forma proativa na preservação da integridade física do sistema.</p>



<p class="wp-block-paragraph">O núcleo desse conceito está no monitoramento e controle inteligente do consumo de energia em tempo real. Isso inclui o uso de modos de baixo consumo (como <em>sleep</em>, <em>stop</em> e <em>standby</em>) disponíveis em muitos microcontroladores modernos, além de estratégias como <em>Dynamic Voltage and Frequency Scaling (DVFS)</em>, que permitem ajustar a frequência e a tensão de operação do processador de acordo com a carga de trabalho.</p>



<p class="wp-block-paragraph">Outro aspecto fundamental é o controle seletivo de periféricos. Um firmware power-aware liga e desliga módulos como ADCs, interfaces SPI/I2C/UART, controladores de rádio e timers apenas quando necessário. Esse controle pode ser baseado em eventos, temporizações ou estados do sistema, reduzindo assim o consumo ocioso e prevenindo o desgaste precoce de componentes.</p>



<p class="wp-block-paragraph">Além disso, o firmware pode utilizar sensores internos, como termômetros integrados e monitores de tensão e corrente, para tomar decisões contextuais sobre o funcionamento do sistema. Com esses dados, é possível implementar algoritmos que evitem, por exemplo, operar o processador em alta carga quando a temperatura ambiente estiver elevada.</p>



<p class="wp-block-paragraph">Essas práticas não apenas melhoram a eficiência energética do dispositivo, mas também estendem sua durabilidade, reduzem os custos de manutenção e aumentam a confiabilidade geral do produto, especialmente em ambientes críticos ou aplicações industriais.</p>



<h2 class="wp-block-heading">Técnicas de Implementação de Firmware Power-Aware</h2>



<p class="wp-block-paragraph">A implementação de um firmware energeticamente consciente exige mais do que boas intenções — envolve o domínio de técnicas específicas, ferramentas de apoio ao desenvolvimento e o uso criterioso dos recursos oferecidos pelo microcontrolador. A seguir, exploramos algumas das abordagens mais eficazes para tornar o firmware power-aware.</p>



<p class="wp-block-paragraph">Uma das principais técnicas é a utilização eficiente dos modos de economia de energia oferecidos pelo microcontrolador. A maioria das plataformas modernas, como os STM32, nRF, MSP430 e ESP32, oferecem múltiplos níveis de suspensão do sistema. O firmware deve ser capaz de entrar e sair desses modos dinamicamente, mantendo apenas os blocos essenciais ativos e desligando o restante. Essa técnica exige um projeto de firmware orientado a eventos, onde tarefas são ativadas sob demanda.</p>



<p class="wp-block-paragraph">O controle fino de clock e alimentação dos periféricos é outra estratégia essencial. Por meio de registros de controle (como RCC em STM32), é possível ativar somente os módulos necessários, economizando energia e reduzindo o ruído elétrico no sistema. Além disso, com o uso de técnicas como <em>clock gating</em> e <em>peripheral clock management</em>, é possível reduzir drasticamente o consumo em tempo real.</p>



<p class="wp-block-paragraph">A adaptação dinâmica da frequência e da tensão de operação — conhecida como DVFS (Dynamic Voltage and Frequency Scaling) — também contribui para a preservação do hardware. Essa técnica permite que o processador opere em uma frequência mais baixa durante tarefas leves e apenas aumente o desempenho quando estritamente necessário. Isso reduz o consumo energético exponencialmente e minimiza o aquecimento.</p>



<p class="wp-block-paragraph">Ferramentas de medição e simulação de consumo energético, como os <em>Energy Trace</em> da Texas Instruments, <em>Power Profiler Kit</em> da Nordic ou simuladores embarcados nos IDEs, são essenciais durante o desenvolvimento. Elas permitem identificar gargalos de consumo e verificar em tempo real o impacto de cada decisão de projeto, possibilitando ajustes finos.</p>



<p class="wp-block-paragraph">Além das técnicas clássicas, a adoção de padrões de projeto como o <em>State Machine</em>, <em>Command Pattern</em> e <em>Observer Pattern</em> facilita a organização do firmware em torno de estados e eventos, promovendo um modelo de execução assíncrona e com consumo otimizado.</p>



<p class="wp-block-paragraph">A verdadeira implementação de um firmware power-aware, portanto, é um esforço multidisciplinar: exige conhecimento de hardware, domínio do microcontrolador, estruturação do código em padrões eficientes e uso de ferramentas de análise energética. Quando bem aplicada, essa abordagem transforma o firmware em uma camada de proteção ativa contra falhas físicas.</p>



<h2 class="wp-block-heading">Estudo de Caso: Falhas Evitadas (ou não) por Firmware Power-Aware</h2>



<p class="wp-block-paragraph">Para ilustrar na prática os impactos do gerenciamento energético no firmware, apresentamos dois estudos de caso contrastantes: um onde a aplicação bem-sucedida de técnicas power-aware evitou falhas físicas, e outro onde a negligência nesse aspecto levou ao recall global de um produto de alto perfil.</p>



<h3 class="wp-block-heading">Caso 1: Sistema de Monitoramento Ambiental em Áreas Remotas</h3>



<p class="wp-block-paragraph">Um sistema de monitoramento ambiental alimentado por bateria foi implantado em áreas remotas para medir temperatura, umidade e qualidade do ar. Baseado em um microcontrolador STM32L4 e equipado com interface LoRa, o sistema enfrentava falhas recorrentes: reinicializações inesperadas, perda de dados e degradação prematura do circuito de rádio.</p>



<p class="wp-block-paragraph">A investigação apontou para a ausência de gerenciamento energético no firmware: a CPU permanecia ativa por longos períodos, sensores funcionavam continuamente e o rádio era reativado em sequência, sem levar em conta a temperatura ambiente. O resultado foi um aumento do estresse térmico e elétrico, reduzindo a vida útil do hardware.</p>



<p class="wp-block-paragraph">Na segunda versão, o firmware foi reestruturado com foco em consumo consciente: uso de modos de baixo consumo, timers para desligamento automático dos sensores, e controle térmico sobre o rádio. Com isso, a autonomia da bateria aumentou em 80% e as falhas em campo desapareceram.</p>



<h3 class="wp-block-heading">Caso 2: O Recall do Smartwatch Intel Basis Peak</h3>



<p class="wp-block-paragraph">Em um exemplo emblemático de negligência com o gerenciamento térmico, a Intel enfrentou um sério problema com seu smartwatch <em>Basis Peak</em>. O dispositivo, lançado como um relógio fitness premium com sensores de batimentos cardíacos baseados em LEDs, foi recolhido do mercado em 2016 após relatos de superaquecimento que causavam queimaduras na pele dos usuários.</p>



<p class="wp-block-paragraph">A fonte do problema estava no LED infravermelho utilizado para medição contínua da frequência cardíaca. O firmware do dispositivo não implementava uma lógica eficaz de monitoramento e controle térmico, permitindo que o LED permanecesse ativo por longos períodos sem levar em conta a dissipação de calor acumulada, principalmente em condições de uso intenso ou ambientes quentes.</p>



<p class="wp-block-paragraph">Apesar das tentativas de correção via atualizações de firmware, a falha de projeto foi tão crítica que a empresa optou por um recall completo dos dispositivos, oferecendo reembolso total aos clientes. Esse caso mostrou de forma clara que ignorar o gerenciamento de energia e temperatura no firmware pode resultar não apenas em falhas técnicas, mas também em danos à reputação, à segurança do usuário e ao negócio como um todo【Fonte: Wired, 2016 → <a>https://www.wired.com/2016/08/basis-peak-recall/】</a>.</p>



<p class="wp-block-paragraph">Esses dois casos revelam como o firmware pode atuar tanto como protetor quanto como vilão. Em um cenário, ele prolonga a vida útil do hardware; no outro, contribui para sua destruição. O fator decisivo é o grau de consciência energética embutido no projeto de software embarcado.</p>



<h2 class="wp-block-heading">Conclusão e Recomendações para Projetistas</h2>



<p class="wp-block-paragraph">O desenvolvimento de firmware power-aware deixou de ser uma escolha opcional para se tornar uma exigência de qualidade, confiabilidade e até segurança. Em sistemas embarcados modernos, onde os limites térmicos e energéticos são cada vez mais estreitos, o firmware é a linha de frente na proteção do hardware contra falhas físicas.</p>



<p class="wp-block-paragraph">Conforme demonstrado nos estudos de caso, a negligência no controle de consumo e temperatura pode levar a consequências sérias: desde falhas intermitentes até recalls em larga escala. Por outro lado, a adoção de práticas inteligentes, como uso eficiente de modos de baixo consumo, controle seletivo de periféricos e supervisão de condições ambientais, pode estender significativamente a vida útil dos componentes, aumentar a autonomia do sistema e reduzir os custos com manutenção e substituições.</p>



<p class="wp-block-paragraph">Para projetistas e desenvolvedores de firmware, seguem algumas recomendações práticas:</p>



<ol class="wp-block-list">
<li><strong>Entenda profundamente o hardware</strong>: conheça os limites térmicos, elétricos e funcionais dos componentes utilizados. Estude os modos de economia de energia do microcontrolador escolhido.</li>



<li><strong>Projete com foco em eventos</strong>: evite firmware baseado em polling. Prefira arquiteturas orientadas a eventos e interrupções, que naturalmente consomem menos energia.</li>



<li><strong>Implemente monitoramento ativo</strong>: utilize sensores internos e externos para ajustar dinamicamente o comportamento do sistema com base em temperatura, tensão e carga de trabalho.</li>



<li><strong>Teste em cenários reais e extremos</strong>: simulações laboratoriais nem sempre expõem os piores casos. Teste seu sistema em campo, sob carga real e variações ambientais.</li>



<li><strong>Use ferramentas de medição energética</strong>: trace o consumo em tempo real para identificar gargalos e oportunidades de otimização.</li>



<li><strong>Atualize continuamente o firmware</strong>: esteja preparado para adaptar o comportamento do sistema com base em novos dados de campo, falhas observadas ou melhorias de eficiência.</li>
</ol>



<p class="wp-block-paragraph">Projetar firmware power-aware é mais do que uma boa prática: é um compromisso com a durabilidade, a responsabilidade técnica e a confiança do usuário. Em um mundo onde a eficiência energética é cada vez mais valorizada, essa abordagem se traduz não apenas em sistemas mais robustos, mas também em negócios mais sustentáveis.</p><p>The post <a href="https://mcu.tec.br/algoritimos/como-firmwares-conscientes-de-energia-podem-prevenir-falhas-de-hardware/">Como Firmwares Conscientes de Energia Podem Prevenir Falhas de Hardware</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">535</post-id>	</item>
		<item>
		<title>Introdução ao Linker em Sistemas Embarcados</title>
		<link>https://mcu.tec.br/geral/introducao-ao-linker-em-sistemas-embarcados/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=introducao-ao-linker-em-sistemas-embarcados</link>
		
		<dc:creator><![CDATA[Carlos Delfino]]></dc:creator>
		<pubDate>Mon, 31 Mar 2025 18:12:23 +0000</pubDate>
				<category><![CDATA[geral]]></category>
		<category><![CDATA[arquivo ld]]></category>
		<category><![CDATA[esp-idf]]></category>
		<category><![CDATA[esp32]]></category>
		<category><![CDATA[firmware embarcado]]></category>
		<category><![CDATA[ld file]]></category>
		<category><![CDATA[linker]]></category>
		<category><![CDATA[linker ESP32]]></category>
		<category><![CDATA[linker map]]></category>
		<category><![CDATA[linker script]]></category>
		<category><![CDATA[linker STM32]]></category>
		<category><![CDATA[mapeamento de memória]]></category>
		<category><![CDATA[memória flash]]></category>
		<category><![CDATA[memória RAM]]></category>
		<category><![CDATA[memória ROM]]></category>
		<category><![CDATA[partitions.csv]]></category>
		<category><![CDATA[script de linker]]></category>
		<category><![CDATA[sistemas embarcados]]></category>
		<category><![CDATA[stm32]]></category>
		<category><![CDATA[stm32cubeide]]></category>
		<guid isPermaLink="false">https://mcu.tec.br/?p=295</guid>

					<description><![CDATA[<p>Entenda como funciona o linker e os arquivos .ld em sistemas embarcados como STM32 e ESP32. Veja exemplos práticos, o uso do arquivo partitions.csv e aprenda a customizar o mapeamento de memória do seu firmware.</p>
<p>The post <a href="https://mcu.tec.br/geral/introducao-ao-linker-em-sistemas-embarcados/">Introdução ao Linker em Sistemas Embarcados</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">O Linker é uma das etapas mais críticas no processo de construção de um firmware para sistemas embarcados. Sua função é consolidar diversos arquivos de código objeto em um único arquivo executável, organizando como os dados e instruções serão posicionados na memória do microcontrolador. Em arquiteturas como a do <strong>STM32</strong> (baseada em ARM Cortex-M) e do <strong>ESP32</strong> (baseada em Tensilica Xtensa), o controle de onde e como os segmentos de código e dados são alocados é fundamental para o correto funcionamento do sistema. Esse controle é feito por meio de <strong>scripts de Linker (.ld)</strong> e, no caso do ESP32, também com o <strong>arquivo <code>partitions.csv</code></strong>, que define o particionamento da memória Flash.</p>



<h3 class="wp-block-heading"><strong>Objetivo da Seção</strong></h3>



<p class="wp-block-paragraph">Apresentar uma visão geral do papel do Linker no processo de construção de firmware, destacando:</p>



<ul class="wp-block-list">
<li>O que é o Linker e qual sua função;</li>



<li>Como ele é usado para posicionar variáveis e trechos de código em regiões específicas da memória;</li>



<li>A diferença entre seu uso em plataformas STM32 e ESP32;</li>



<li>A importância dos arquivos <code>.ld</code> e <code>partitions.csv</code> no projeto embarcado.</li>
</ul>



<h3 class="wp-block-heading"><strong>Conceito Básico</strong></h3>



<p class="wp-block-paragraph">Durante a compilação, o código-fonte (em C ou C++) é transformado em arquivos objeto <code>.o</code>. O Linker pega esses arquivos e os combina, resolvendo endereços de funções, referências cruzadas entre variáveis globais e posicionando tudo de acordo com o layout de memória definido pelo script <code>.ld</code>. Esse script age como um <strong>mapa da memória</strong>, especificando as regiões onde devem ser colocados:</p>



<ul class="wp-block-list">
<li>Código (<code>.text</code>);</li>



<li>Dados inicializados (<code>.data</code>);</li>



<li>Dados não inicializados (<code>.bss</code>);</li>



<li>Pilha e heap;</li>



<li>Tabelas de vetores de interrupção e memória de inicialização.</li>
</ul>



<h3 class="wp-block-heading"><strong>Plataformas em Destaque</strong></h3>



<ul class="wp-block-list">
<li><strong>STM32</strong>: Usa arquivos <code>.ld</code> customizados que refletem a memória RAM e Flash, com seções bem definidas para bootloaders, vetores de interrupção, código principal, etc.</li>



<li><strong>ESP32</strong>: Usa também arquivos <code>.ld</code>, mas sua complexidade aumenta com a presença de múltiplas CPUs, caches e particionamento de memória Flash definido pelo <code>partitions.csv</code>.</li>
</ul>



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



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



<h2 class="wp-block-heading"><strong>Estrutura de um Arquivo LD: seções e símbolos</strong></h2>



<p class="wp-block-paragraph">O script do Linker, geralmente com extensão <code>.ld</code>, descreve como o firmware será disposto na memória do dispositivo. Ele segue a sintaxe da linguagem de scripts do GNU Linker (<code>ld</code>) e define <strong>regiões de memória física</strong> e a <strong>atribuição de seções do programa</strong> nessas regiões. Essa estrutura garante que o código e os dados sejam colocados em áreas apropriadas da RAM e Flash.</p>



<h3 class="wp-block-heading"><strong>Definindo a Memória</strong></h3>



<p class="wp-block-paragraph">No início do arquivo <code>.ld</code>, define-se o <strong>layout físico da memória</strong> com a diretiva <code>MEMORY</code>. Essa seção especifica os nomes, tamanhos e endereços base da RAM, Flash e outras regiões, como SRAM2 ou CCM no STM32, ou RTC_SLOW na RAM do ESP32.</p>



<p class="wp-block-paragraph"><strong>Exemplo – STM32:</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" data-code="MEMORY
{
  FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
  RAM (xrw)  : ORIGIN = 0x20000000, LENGTH = 128K
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">MEMORY</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">FLASH</span><span style="color: #D8DEE9FF"> (rx) </span><span style="color: #88C0D0">:</span><span style="color: #D8DEE9FF"> ORIGIN = 0x08000000, LENGTH = 512K</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">RAM</span><span style="color: #D8DEE9FF"> (xrw)  </span><span style="color: #88C0D0">:</span><span style="color: #D8DEE9FF"> ORIGIN = 0x20000000, LENGTH = 128K</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph"><strong>Exemplo – ESP32:</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" data-code="MEMORY
{
  iram0_0_seg (RX) : org = 0x40080000, len = 0x20000
  dram0_0_seg (RW) : org = 0x3FFAE000, len = 0x20000
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">MEMORY</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">iram0_0_seg</span><span style="color: #D8DEE9FF"> (RX) </span><span style="color: #88C0D0">:</span><span style="color: #D8DEE9FF"> org = 0x40080000, len = 0x20000</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">dram0_0_seg</span><span style="color: #D8DEE9FF"> (RW) </span><span style="color: #88C0D0">:</span><span style="color: #D8DEE9FF"> org = 0x3FFAE000, len = 0x20000</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading"><strong>Seções Padrão</strong></h3>



<p class="wp-block-paragraph">A diretiva <code>SECTIONS</code> define como as seções do código objeto (geradas pelo compilador) são mapeadas nas regiões de memória definidas anteriormente.</p>



<h4 class="wp-block-heading">Principais seções:</h4>



<ul class="wp-block-list">
<li><code>.isr_vector</code>: Vetor de interrupções (normalmente colocado no início da Flash).</li>



<li><code>.text</code>: Código do programa.</li>



<li><code>.rodata</code>: Dados somente leitura (constantes).</li>



<li><code>.data</code>: Dados inicializados na RAM.</li>



<li><code>.bss</code>: Variáveis globais não inicializadas (zeradas na inicialização).</li>



<li><code>.heap</code> / <code>.stack</code>: Reservas para alocação dinâmica e pilha de execução.</li>
</ul>



<p class="wp-block-paragraph"><strong>Trecho típico:</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" data-code="SECTIONS
{
  .text :
  {
    KEEP(*(.isr_vector))
    *(.text*)
    *(.rodata*)
  } &gt; FLASH

  .data : AT (ADDR(.text) + SIZEOF(.text))
  {
    *(.data*)
  } &gt; RAM

  .bss :
  {
    *(.bss*)
    *(COMMON)
  } &gt; RAM
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">SECTIONS</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">.text</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">KEEP(*(.isr_vector</span><span style="color: #D8DEE9FF">))</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">*(.text*</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">*(.rodata*</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> FLASH</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">.data</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">AT</span><span style="color: #D8DEE9FF"> (ADDR(.text) + SIZEOF</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">.text</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">*(.data*</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> RAM</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">.bss</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">*(.bss*</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">*(COMMON</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> RAM</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading"><strong>Símbolos Especiais</strong></h3>



<p class="wp-block-paragraph">Os scripts <code>.ld</code> frequentemente definem símbolos que serão usados no código C para indicar, por exemplo, o início e fim da RAM, do stack, ou a posição de carga de dados:</p>



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



<p class="wp-block-paragraph">No código C, podem ser declarados 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" data-code="extern uint32_t _estack;
extern uint32_t _end;
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">extern</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">uint32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">_estack</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #88C0D0">extern</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">uint32_t</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">_end</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading"><strong>Observações Importantes</strong></h3>



<ul class="wp-block-list">
<li>A ordem das seções é essencial: o que estiver listado primeiro será posicionado primeiro na memória.</li>



<li>A diretiva <code>KEEP()</code> impede que o Linker remova seções não referenciadas, comum em vetores de interrupção.</li>



<li>A diretiva <code>AT()</code> é usada para indicar onde os dados residem na Flash antes de serem copiados para a RAM.</li>
</ul>



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



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



<h2 class="wp-block-heading"><strong>Diferenças entre os arquivos LD no STM32 e no ESP32</strong></h2>



<p class="wp-block-paragraph">Embora tanto o STM32 quanto o ESP32 utilizem scripts <code>.ld</code> para definir o mapeamento de memória, existem diferenças estruturais e conceituais importantes entre essas plataformas. Essas diferenças são motivadas pelas arquiteturas distintas de hardware, modelos de inicialização e tipos de memória disponíveis.</p>



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



<h3 class="wp-block-heading"><strong>STM32 – Arquitetura Simples e Direta</strong></h3>



<p class="wp-block-paragraph">O STM32, baseado na arquitetura ARM Cortex-M, segue uma abordagem linear e previsível no mapeamento de memória. A memória Flash normalmente começa em <code>0x08000000</code>, e a RAM em <code>0x20000000</code>. A posição do vetor de interrupções (reset vector) é crucial, pois a CPU começa a executar a partir desse ponto após o reset.</p>



<p class="wp-block-paragraph"><strong>Características:</strong></p>



<ul class="wp-block-list">
<li>O arquivo <code>.ld</code> do STM32 é quase sempre dividido em <strong>FLASH</strong> e <strong>RAM</strong>;</li>



<li>Contém o vetor de interrupções na primeira posição (<code>.isr_vector</code>);</li>



<li>Define símbolos como <code>_estack</code> para controle da pilha;</li>



<li>Permite personalizações simples para bootloaders ou seções específicas de RAM (como DTCM, SRAM2, CCMRAM, etc.);</li>



<li>Ferramentas como STM32CubeIDE geram <code>.ld</code> automaticamente com base no modelo selecionado.</li>
</ul>



<p class="wp-block-paragraph"><strong>Exemplo típico de layout:</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" data-code="MEMORY
{
  FLASH (rx)  : ORIGIN = 0x08000000, LENGTH = 512K
  RAM   (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">MEMORY</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">FLASH</span><span style="color: #D8DEE9FF"> (rx)  </span><span style="color: #88C0D0">:</span><span style="color: #D8DEE9FF"> ORIGIN = 0x08000000, LENGTH = 512K</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">RAM</span><span style="color: #D8DEE9FF">   (xrw) </span><span style="color: #88C0D0">:</span><span style="color: #D8DEE9FF"> ORIGIN = 0x20000000, LENGTH = 128K</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"><strong>ESP32 – Arquitetura Multinível e Particionada</strong></h3>



<p class="wp-block-paragraph">O ESP32 é mais complexo: possui múltiplos tipos de RAM (DRAM, IRAM, RTC RAM), cache externa e bootloader configurável. A memória Flash é externa e <strong>compartilhada entre o bootloader, partições de aplicativo, sistema de arquivos (SPIFFS/FFat) e NVS</strong> (armazenamento não-volátil).</p>



<p class="wp-block-paragraph"><strong>Características:</strong></p>



<ul class="wp-block-list">
<li>Utiliza <strong>vários arquivos <code>.ld</code></strong> para diferentes segmentos (<code>esp32.ld</code>, <code>memory.ld</code>, <code>sections.ld</code>, etc.);</li>



<li>Define múltiplas regiões: <code>iram0</code>, <code>dram0</code>, <code>rtc_slow</code>, <code>rtc_fast</code>, etc.;</li>



<li>Utiliza a diretiva <code>INCLUDE</code> para modularizar o layout;</li>



<li>Integra o conceito de <strong>partições</strong>, definidas no arquivo <code>partitions.csv</code>;</li>



<li>O bootloader da Espressif localiza a partição de aplicação na Flash e carrega o código para a IRAM ou executa diretamente da Flash (via cache).</li>
</ul>



<p class="wp-block-paragraph"><strong>Trecho exemplo de <code>esp32.ld</code>:</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" data-code="MEMORY
{
  iram0_0_seg : org = 0x40080000, len = 0x20000
  dram0_0_seg : org = 0x3FFAE000, len = 0x20000
  rtc_slow_seg : org = 0x50000000, len = 0x2000
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">MEMORY</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">iram0_0_seg</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">org</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0x40080000</span><span style="color: #A3BE8C">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">len</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0x20000</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">dram0_0_seg</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">org</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0x3FFAE000</span><span style="color: #A3BE8C">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">len</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0x20000</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">rtc_slow_seg</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">org</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0x50000000</span><span style="color: #A3BE8C">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">len</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0x2000</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"><strong>Principais Diferenças Resumidas</strong></h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Aspecto</th><th>STM32</th><th>ESP32</th></tr></thead><tbody><tr><td>Arquitetura</td><td>Cortex-M (monocore ou dual core)</td><td>Tensilica Xtensa (dual core + co-processador)</td></tr><tr><td>Memória Flash</td><td>Interna</td><td>Externa via SPI</td></tr><tr><td>RAM</td><td>Linear e simples</td><td>Vários tipos: DRAM, IRAM, RTC RAM</td></tr><tr><td>Arquivo <code>.ld</code></td><td>Simples, único</td><td>Fragmentado, com includes</td></tr><tr><td>Particionamento</td><td>Manual (caso de bootloaders)</td><td>Definido via <code>partitions.csv</code></td></tr><tr><td>Bootloader</td><td>Opcional ou fixo</td><td>Obrigatório e configurável</td></tr></tbody></table></figure>



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



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



<h2 class="wp-block-heading"><strong>Entendendo o partitions.csv no ESP32</strong></h2>



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



<p class="wp-block-paragraph">O arquivo <code>partitions.csv</code> é um componente essencial nos projetos com ESP32. Ele define como a memória Flash externa será <strong>particionada</strong> para armazenar diferentes partes do firmware, como o bootloader, a aplicação principal, o sistema de arquivos (SPIFFS, FATFS, LittleFS), armazenamento de chaves criptográficas, dados de calibragem de RF, entre outros. É o que garante que o firmware saiba onde cada bloco de dados deve ser gravado e lido na memória externa.</p>



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



<h3 class="wp-block-heading"><strong>O que é o <code>partitions.csv</code>?</strong></h3>



<p class="wp-block-paragraph">É um arquivo de texto, em formato <strong>CSV (Comma-Separated Values)</strong>, que define as partições da Flash para uso pelo bootloader e sistema operacional (no caso do ESP-IDF). Ele é convertido em um binário de tabela de partições que o bootloader carrega durante a inicialização.</p>



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



<h3 class="wp-block-heading"><strong>Formato do Arquivo</strong></h3>



<p class="wp-block-paragraph">Cada linha do <code>partitions.csv</code> define uma partição com os seguintes campos:</p>



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



<p class="wp-block-paragraph"><strong>Exemplo comum:</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" data-code="# Nome      Tipo     Subtipo  Endereço   Tamanho    Flags
nvs         data     nvs      0x9000     0x5000
otadata     data     ota      0xe000     0x2000
app0        app      ota_0    0x10000    1M
app1        app      ota_1    0x110000   1M
spiffs      data     spiffs   0x210000   0xF0000
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88"># Nome      Tipo     Subtipo  Endereço   Tamanho    Flags</span></span>
<span class="line"><span style="color: #88C0D0">nvs</span><span style="color: #D8DEE9FF">         </span><span style="color: #A3BE8C">data</span><span style="color: #D8DEE9FF">     </span><span style="color: #A3BE8C">nvs</span><span style="color: #D8DEE9FF">      </span><span style="color: #B48EAD">0x9000</span><span style="color: #D8DEE9FF">     </span><span style="color: #B48EAD">0x5000</span></span>
<span class="line"><span style="color: #88C0D0">otadata</span><span style="color: #D8DEE9FF">     </span><span style="color: #A3BE8C">data</span><span style="color: #D8DEE9FF">     </span><span style="color: #A3BE8C">ota</span><span style="color: #D8DEE9FF">      </span><span style="color: #B48EAD">0xe000</span><span style="color: #D8DEE9FF">     </span><span style="color: #B48EAD">0x2000</span></span>
<span class="line"><span style="color: #88C0D0">app0</span><span style="color: #D8DEE9FF">        </span><span style="color: #A3BE8C">app</span><span style="color: #D8DEE9FF">      </span><span style="color: #A3BE8C">ota_0</span><span style="color: #D8DEE9FF">    </span><span style="color: #B48EAD">0x10000</span><span style="color: #D8DEE9FF">    </span><span style="color: #B48EAD">1</span><span style="color: #A3BE8C">M</span></span>
<span class="line"><span style="color: #88C0D0">app1</span><span style="color: #D8DEE9FF">        </span><span style="color: #A3BE8C">app</span><span style="color: #D8DEE9FF">      </span><span style="color: #A3BE8C">ota_1</span><span style="color: #D8DEE9FF">    </span><span style="color: #B48EAD">0x110000</span><span style="color: #D8DEE9FF">   </span><span style="color: #B48EAD">1</span><span style="color: #A3BE8C">M</span></span>
<span class="line"><span style="color: #88C0D0">spiffs</span><span style="color: #D8DEE9FF">      </span><span style="color: #A3BE8C">data</span><span style="color: #D8DEE9FF">     </span><span style="color: #A3BE8C">spiffs</span><span style="color: #D8DEE9FF">   </span><span style="color: #B48EAD">0x210000</span><span style="color: #D8DEE9FF">   </span><span style="color: #B48EAD">0xF0000</span></span>
<span class="line"></span></code></pre></div>



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



<h3 class="wp-block-heading"><strong>Campos Explicados</strong></h3>



<ul class="wp-block-list">
<li><strong>nome</strong>: Identificador da partição (pode ser usado no código C, por exemplo para montar SPIFFS).</li>



<li><strong>tipo</strong>:
<ul class="wp-block-list">
<li><code>app</code>: usado para partições de firmware.</li>



<li><code>data</code>: para armazenamento persistente (ex: NVS, SPIFFS).</li>
</ul>
</li>



<li><strong>subtipo</strong>:
<ul class="wp-block-list">
<li><code>factory</code>, <code>ota_0</code>, <code>ota_1</code>: partições de aplicação.</li>



<li><code>nvs</code>, <code>spiffs</code>, <code>fat</code>, <code>ota</code>, etc.: tipos específicos de dados.</li>
</ul>
</li>



<li><strong>endereço</strong>: onde na memória Flash essa partição começa (em hexadecimal).</li>



<li><strong>tamanho</strong>: em bytes ou usando sufixos (<code>K</code>, <code>M</code>).</li>



<li><strong>flags</strong>: parâmetros opcionais (ex: <code>encrypted</code> para criptografia).</li>
</ul>



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



<h3 class="wp-block-heading"><strong>Como o partitions.csv é usado</strong></h3>



<ol class="wp-block-list">
<li>Durante a <strong>compilação</strong>, o arquivo é processado e gera um binário chamado <code>partition_table.bin</code>.</li>



<li>Durante a <strong>gravação (flash)</strong>, esse binário é gravado em um endereço fixo (tipicamente <code>0x8000</code>).</li>



<li>Durante o <strong>boot</strong>, o bootloader do ESP32 lê essa tabela para saber onde está cada partição.</li>



<li>No <strong>código</strong>, você pode montar sistemas de arquivos ou acessar partições diretamente com base nos nomes definidos no CSV.</li>
</ol>



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



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



<p class="wp-block-paragraph">Você pode modificar o <code>partitions.csv</code> para incluir, por exemplo:</p>



<ul class="wp-block-list">
<li>Mais partições OTA para atualizações em lote;</li>



<li>Uma partição para armazenamento FAT montado via <code>esp_vfs_fat_mount</code>;</li>



<li>Uma partição para arquivos estáticos com LittleFS;</li>



<li>Tamanhos reduzidos para aplicações mínimas.</li>
</ul>



<p class="wp-block-paragraph"><strong>Exemplo com FAT:</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" data-code="storage     data     fat      0x300000   512K
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">storage</span><span style="color: #D8DEE9FF">     </span><span style="color: #A3BE8C">data</span><span style="color: #D8DEE9FF">     </span><span style="color: #A3BE8C">fat</span><span style="color: #D8DEE9FF">      </span><span style="color: #B48EAD">0x300000</span><span style="color: #D8DEE9FF">   </span><span style="color: #B48EAD">512</span><span style="color: #A3BE8C">K</span></span>
<span class="line"></span></code></pre></div>



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



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



<h2 class="wp-block-heading"><strong>Estratégias de Construção de Arquivos LD: práticas e ferramentas</strong></h2>



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



<p class="wp-block-paragraph">A criação e manutenção de arquivos <code>.ld</code> pode ser feita manualmente ou gerenciada por ferramentas automáticas. Em sistemas embarcados, a escolha da estratégia depende da complexidade da aplicação, do ambiente de desenvolvimento e da necessidade de controle sobre o uso da memória. Nesta seção, exploramos como construir e adaptar arquivos de Linker para STM32 e ESP32, além das ferramentas que auxiliam no processo.</p>



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



<h3 class="wp-block-heading"><strong>Construção Manual de Arquivos <code>.ld</code></strong></h3>



<p class="wp-block-paragraph">A escrita manual é útil em projetos onde se deseja controle total sobre a organização de memória — especialmente para bootloaders, realocação de código crítico em RAM, ou para usar áreas especiais como DTCM, CCM ou RTC.</p>



<p class="wp-block-paragraph"><strong>Dicas práticas:</strong></p>



<ul class="wp-block-list">
<li>Sempre comece definindo corretamente as regiões com <code>MEMORY</code>.</li>



<li>Use <code>SECTIONS</code> para mapear precisamente o conteúdo dos binários.</li>



<li>Defina símbolos auxiliares (<code>_end</code>, <code>_stack_start</code>) para controle no código C.</li>



<li>Use <code>KEEP()</code> para evitar que o Linker remova trechos importantes como vetores de interrupção.</li>



<li>Comente abundantemente o arquivo <code>.ld</code> — erros silenciosos podem causar falhas difíceis de depurar.</li>
</ul>



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



<h3 class="wp-block-heading"><strong>Uso de Ferramentas:</strong></h3>



<h4 class="wp-block-heading"><strong>Para STM32:</strong></h4>



<ul class="wp-block-list">
<li><strong>STM32CubeIDE / STM32CubeMX</strong>:
<ul class="wp-block-list">
<li>Gera automaticamente arquivos <code>.ld</code> com base no modelo do microcontrolador selecionado.</li>



<li>Permite configuração de áreas específicas de memória (ex: RAM2, CCMRAM).</li>



<li>Reorganiza o linker script ao incluir bibliotecas HAL ou FreeRTOS.</li>
</ul>
</li>



<li><strong>GNU Arm Toolchain (<code>arm-none-eabi-ld</code>)</strong>:
<ul class="wp-block-list">
<li>O script <code>.ld</code> é passado na linha de comando usando <code>-T</code>.</li>



<li>Pode ser usado em Makefiles ou CMake para projetos personalizados.</li>
</ul>
</li>
</ul>



<h4 class="wp-block-heading"><strong>Para ESP32:</strong></h4>



<ul class="wp-block-list">
<li><strong>ESP-IDF</strong>:
<ul class="wp-block-list">
<li>Utiliza um conjunto modular de scripts <code>.ld</code> organizados em:
<ul class="wp-block-list">
<li><code>memory.ld</code>: define as regiões de memória disponíveis.</li>



<li><code>sections.ld</code>: organiza onde o código e dados são colocados.</li>



<li><code>esp32.ld</code>: script de entrada que inclui os anteriores.</li>
</ul>
</li>



<li>Permite criar <strong>fragmentos de linker (<code>ld</code> fragments)</strong> no diretório do componente para colocar variáveis em regiões específicas, como IRAM.</li>
</ul>
</li>
</ul>



<p class="wp-block-paragraph"><strong>Exemplo de fragmento:</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" data-code="myvar (noinit) : ALIGN(4)
{
  _myvar_start = .;
  KEEP(*(.myvar_section))
  _myvar_end = .;
} &gt; DRAM
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">myvar</span><span style="color: #D8DEE9FF"> (noinit) </span><span style="color: #88C0D0">:</span><span style="color: #D8DEE9FF"> ALIGN</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">4</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">_myvar_start</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">.</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">KEEP(*(.myvar_section</span><span style="color: #D8DEE9FF">))</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">_myvar_end</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">.</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> DRAM</span></span>
<span class="line"></span></code></pre></div>



<ul class="wp-block-list">
<li><strong>idf.py linkmap</strong>:
<ul class="wp-block-list">
<li>Gera o mapa de ligação (<code>.map</code>) detalhado, útil para depuração de problemas de alocação de memória.</li>
</ul>
</li>
</ul>



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



<h3 class="wp-block-heading"><strong>Boas Práticas</strong></h3>



<ul class="wp-block-list">
<li>Sempre gere e revise o <strong>mapa de ligação (<code>.map</code>)</strong> após compilar. Ele mostra o endereço final de cada seção.</li>



<li>Valide o tamanho das regiões para evitar sobreposição.</li>



<li>Em projetos com <strong>OTA</strong>, certifique-se de que as partições app0/app1 não ultrapassem o tamanho máximo.</li>



<li>Use <code>ASSERT()</code> no script <code>.ld</code> para verificar restrições em tempo de link:</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" data-code="ASSERT(SIZEOF(.data) < 0x2000, &quot;Data section too big!&quot;)
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">ASSERT(SIZEOF(.data</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> 0x2000, </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Data section too big!</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span></code></pre></div>



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



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



<h2 class="wp-block-heading"><strong>Casos Práticos: Customizando o Linker para necessidades reais</strong></h2>



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



<p class="wp-block-paragraph">Customizar o script de Linker permite criar soluções otimizadas para aplicações embarcadas que demandam desempenho, economia de energia ou acesso rápido à memória. A seguir, são apresentados exemplos reais de customizações em projetos com STM32 e ESP32, incluindo alocação de variáveis em regiões específicas, execução de código diretamente na RAM, buffers persistentes e uso de seções noinit.</p>



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



<h3 class="wp-block-heading"><strong>Executar código diretamente na RAM (STM32)</strong></h3>



<p class="wp-block-paragraph">Para funções críticas em tempo real — como interrupções com baixa latência — pode ser necessário colocá-las na RAM, onde a execução é mais rápida que na Flash.</p>



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



<ol class="wp-block-list">
<li>Criar uma seção <code>.ramfunc</code> no script:</li>
</ol>



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



<ol start="2" class="wp-block-list">
<li>Declarar a função no código com atributo:</li>
</ol>



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



<ol start="3" class="wp-block-list">
<li>(Opcional) Garantir cópia da Flash para RAM durante a inicialização usando <code>AT()</code> e símbolos auxiliares para copiar os dados.</li>
</ol>



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



<h3 class="wp-block-heading"><strong>2Criar buffers fixos em local específico da RAM (ESP32 e STM32)</strong></h3>



<p class="wp-block-paragraph">Se você precisa garantir que um buffer de DMA fique em uma região não cacheada da memória (ou alinhada), é possível forçar sua posição.</p>



<p class="wp-block-paragraph"><strong>ESP32 – usando fragmento de linker:</strong></p>



<ol class="wp-block-list">
<li>Crie um arquivo <code>linker_fragment.ld</code> no componente:</li>
</ol>



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



<ol start="2" class="wp-block-list">
<li>No código:</li>
</ol>



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



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



<h3 class="wp-block-heading"><strong>3. Buffer persistente entre resets (seção <code>.noinit</code>)</strong></h3>



<p class="wp-block-paragraph">A seção <code>.noinit</code> impede que variáveis sejam zeradas na inicialização. Isso é útil para armazenar dados temporários entre resets, watchdogs ou soft reboots.</p>



<p class="wp-block-paragraph"><strong>Script LD:</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" data-code=".noinit (NOLOAD):
{
  *(.noinit*)
} &gt; RAM
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">.noinit</span><span style="color: #D8DEE9FF"> (NOLOAD):</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">*(.noinit*</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> RAM</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph"><strong>Código C:</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" data-code="__attribute__((section(&quot;.noinit&quot;))) uint32_t retained_counter;
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">__attribute__((section(</span><span style="color: #88C0D0">&quot;.noinit&quot;</span><span style="color: #D8DEE9FF">))) uint32_t retained_counter</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<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;" /> Importante: você é responsável por inicializar essa variável, pois o C startup não o fará.</p>
</blockquote>



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



<h3 class="wp-block-heading"><strong>4. Espaço reservado para bootloader ou firmware OTA</strong></h3>



<p class="wp-block-paragraph">Em projetos com bootloaders, você pode reservar o início da Flash para ele e mover o início da aplicaçã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" data-code="MEMORY
{
  BOOTLOADER (rx) : ORIGIN = 0x08000000, LENGTH = 16K
  APP_FLASH  (rx) : ORIGIN = 0x08004000, LENGTH = 496K
}
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">MEMORY</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">BOOTLOADER</span><span style="color: #D8DEE9FF"> (rx) </span><span style="color: #88C0D0">:</span><span style="color: #D8DEE9FF"> ORIGIN = 0x08000000, LENGTH = 16K</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">APP_FLASH</span><span style="color: #D8DEE9FF">  (rx) </span><span style="color: #88C0D0">:</span><span style="color: #D8DEE9FF"> ORIGIN = 0x08004000, LENGTH = 496K</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph">E ajustar o início da seção <code>.text</code> para a nova região <code>APP_FLASH</code>.</p>



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



<h3 class="wp-block-heading"><strong>5. Dividindo a RAM em blocos com finalidades distintas</strong></h3>



<p class="wp-block-paragraph">No STM32 com RAMs separadas (SRAM1, SRAM2), você pode mover buffers grandes para a RAM auxiliar:</p>



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

.bigbuffers (NOLOAD):
{
  *(.bigbuffer*)
} &gt; RAM2
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">MEMORY</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">RAM1</span><span style="color: #D8DEE9FF"> (xrw): ORIGIN = 0x20000000, LENGTH = 96K</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">RAM2</span><span style="color: #D8DEE9FF"> (xrw): ORIGIN = 0x20018000, LENGTH = 32K</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">.bigbuffers</span><span style="color: #D8DEE9FF"> (NOLOAD):</span></span>
<span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">*(.bigbuffer*</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> RAM2</span></span>
<span class="line"></span></code></pre></div>



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



<p class="wp-block-paragraph">Esses exemplos ilustram o poder e a flexibilidade dos scripts de Linker quando bem utilizados. Customizá-los pode ser a chave para alcançar desempenho, estabilidade e segurança em sistemas embarcados críticos.</p>



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



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



<h2 class="wp-block-heading"><strong>Considerações Finais e Dicas de Diagnóstico</strong></h2>



<p class="wp-block-paragraph">A compreensão e personalização de scripts de Linker são habilidades essenciais para engenheiros de sistemas embarcados. Erros nesse estágio podem resultar em falhas silenciosas, corrupção de dados, mau uso de memória e comportamento imprevisível do firmware. Esta seção final destaca boas práticas, armadilhas comuns e ferramentas úteis para diagnóstico e validação do layout de memória.</p>



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



<h3 class="wp-block-heading"><strong>Boas Práticas ao Trabalhar com <code>.ld</code></strong></h3>



<ul class="wp-block-list">
<li><strong>Comente extensivamente</strong> cada bloco do script para documentar a intenção de uso de cada região.</li>



<li><strong>Use símbolos nomeados</strong> (_start, _end, <em>stack_top</em>) para facilitar o acesso no código C.</li>



<li><strong>Divida responsabilidades</strong> em arquivos menores com <code>INCLUDE</code> (usado amplamente no ESP-IDF).</li>



<li><strong>Crie seções específicas</strong> para dados críticos, buffers, código de interrupção ou dados de boot.</li>



<li><strong>Teste variações de layout</strong> com segurança em projetos de bootloader + aplicação OTA.</li>
</ul>



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



<h3 class="wp-block-heading"><strong>Validação com o Arquivo <code>.map</code></strong></h3>



<p class="wp-block-paragraph">Após a compilação, o GCC gera um arquivo de <strong>mapa de ligação (<code>.map</code>)</strong>, contendo o endereço real de cada símbolo, função e variável alocada.</p>



<p class="wp-block-paragraph"><strong>Dicas para leitura do <code>.map</code>:</strong></p>



<ul class="wp-block-list">
<li>Verifique se há sobreposição entre seções;</li>



<li>Confirme se buffers grandes foram realmente colocados em RAM auxiliar;</li>



<li>Localize variáveis em <code>.bss</code> que estão ocupando muito espaço;</li>



<li>Confirme se a tabela de interrupções foi posicionada corretamente (ex: início da Flash).</li>
</ul>



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



<h3 class="wp-block-heading"><strong>Uso de ASSERTs no Linker</strong></h3>



<p class="wp-block-paragraph">Para evitar erros silenciosos, você pode usar <code>ASSERT()</code> no script <code>.ld</code> para impor limites:</p>



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



<p class="wp-block-paragraph">Isso impede que a compilação gere um firmware que vá ultrapassar o espaço físico disponível.</p>



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



<h3 class="wp-block-heading"><strong>Ferramentas de Apoio</strong></h3>



<ul class="wp-block-list">
<li><strong>objdump (<code>arm-none-eabi-objdump -h</code>)</strong>: mostra as seções e onde foram colocadas.</li>



<li><strong>nm (<code>arm-none-eabi-nm</code>)</strong>: lista símbolos com endereços — útil para variáveis específicas.</li>



<li><strong>size (<code>arm-none-eabi-size</code>)</strong>: resume o tamanho das seções <code>.text</code>, <code>.data</code> e <code>.bss</code>.</li>



<li><strong>idf.py size-components</strong> (ESP32): mostra quanto cada componente ocupa na Flash/RAM.</li>



<li><strong>STM32CubeIDE</strong>: gera visualizações gráficas do uso de memória, além de adaptar o linker automaticamente.</li>
</ul>



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



<h3 class="wp-block-heading"><strong>Armadilhas Comuns</strong></h3>



<ul class="wp-block-list">
<li>Esquecer de alinhar buffers de DMA (pode causar falha silenciosa).</li>



<li>Colocar código na IRAM sem definir corretamente as seções no ESP32.</li>



<li>Deixar variáveis grandes na <code>.data</code> (copiadas da Flash para a RAM, consumindo tempo e espaço).</li>



<li>Não usar <code>NOLOAD</code> em seções como <code>.noinit</code>, resultando em perda de dados após o reset.</li>
</ul>



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



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



<p class="wp-block-paragraph">Scripts de Linker não são apenas “detalhes técnicos”, mas componentes essenciais que controlam como o firmware funciona na prática. Dominar sua estrutura, lógica e sintaxe permite que você construa sistemas mais rápidos, estáveis e confiáveis — explorando ao máximo o hardware disponível, seja no robusto STM32 ou no versátil ESP32.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/><p>The post <a href="https://mcu.tec.br/geral/introducao-ao-linker-em-sistemas-embarcados/">Introdução ao Linker em Sistemas Embarcados</a> first appeared on <a href="https://mcu.tec.br">MCU & FPGA</a>.</p>]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">295</post-id>	</item>
	</channel>
</rss>
