---
title: "Rust Embarcados: Carreira IoT e ARM Cortex-M | Rust Brasil"
url: "https://rustlang.com.br/carreira/nicho-embedded/"
markdown_url: "https://rustlang.com.br/carreira/nicho-embedded.MD"
description: "Carreira em sistemas embarcados com Rust: microcontroladores, IoT, embedded-hal, ARM Cortex-M e RISC-V. Salários e roadmap."
date: ""
author: ""
---

# Rust Embarcados: Carreira IoT e ARM Cortex-M | Rust Brasil

Carreira em sistemas embarcados com Rust: microcontroladores, IoT, embedded-hal, ARM Cortex-M e RISC-V. Salários e roadmap.


## Introdução

Sistemas embarcados representam uma das fronteiras mais empolgantes para Rust. Historicamente dominado por C e Assembly, o mundo embedded está passando por uma transformação silenciosa: Rust oferece as mesmas garantias de acesso direto a hardware e controle de memória que C, mas com segurança de memória em tempo de compilação, um sistema de tipos expressivo e ferramentas modernas de desenvolvimento.

De microcontroladores ARM Cortex-M a processadores RISC-V, de dispositivos IoT a sistemas automotivos, Rust está conquistando seu espaço na programação embedded. O ecossistema `embedded-hal` criou uma camada de abstração padronizada que permite escrever drivers portáveis entre diferentes famílias de chips, algo que nunca foi alcançado de forma satisfatória com C.

Para desenvolvedores brasileiros, o mercado de embedded com Rust é especialmente interessante: o Brasil possui uma indústria significativa de eletrônica e IoT, e a demanda global por profissionais que dominem Rust embedded está crescendo rapidamente, com salários atrativos tanto em posições nacionais quanto internacionais remotas.

## Por Que Rust Para Embedded?

### Segurança Sem Overhead

Em sistemas embarcados, bugs podem ter consequências físicas graves — desde dispositivos médicos que falham até sistemas automotivos que se comportam de forma imprevisível. Rust elimina classes inteiras de bugs comuns em C embedded:

- **Buffer overflows**: Verificações em tempo de compilação
- **Use-after-free**: Sistema de ownership
- **Data races**: Garantias de concorrência do tipo system
- **Null pointer dereference**: `Option<T>` em vez de ponteiros nulos
- **Integer overflow**: Checked arithmetic disponível sem custo em debug

### Zero-Cost Abstractions

Traits, generics e iterators em Rust geram código de máquina tão eficiente quanto C escrito à mão:

```rust
// Esta abstração de alto nível...
let soma: u32 = dados.iter()
    .filter(|x| **x > 10)
    .map(|x| x * 2)
    .sum();

// ...gera código de máquina equivalente a um loop C manual
```

### `no_std`: Rust Sem a Standard Library

Rust pode ser compilado sem a standard library, eliminando qualquer dependência de sistema operacional ou alocação dinâmica de memória:

```rust
#![no_std]
#![no_main]

use core::panic::PanicInfo;

#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
    loop {}
}

// Seu código bare-metal aqui
```

### Ecossistema `embedded-hal`

O trait `embedded-hal` padroniza interfaces de hardware, permitindo escrever drivers que funcionam em qualquer microcontrolador:

```rust
use embedded_hal::digital::OutputPin;
use embedded_hal::delay::DelayNs;

/// Driver genérico para LED que funciona em qualquer plataforma
struct Led<P: OutputPin> {
    pin: P,
}

impl<P: OutputPin> Led<P> {
    fn new(pin: P) -> Self {
        Led { pin }
    }

    fn ligar(&mut self) {
        self.pin.set_high().ok();
    }

    fn desligar(&mut self) {
        self.pin.set_low().ok();
    }

    fn piscar<D: DelayNs>(&mut self, delay: &mut D, ms: u32) {
        self.ligar();
        delay.delay_ms(ms);
        self.desligar();
        delay.delay_ms(ms);
    }
}
```

## Exemplo Prático: LED Blink no STM32

O "Hello World" do mundo embedded -- piscar um LED:

```rust
//! Pisca LED no STM32F4 (ARM Cortex-M4)
#![no_std]
#![no_main]

use cortex_m_rt::entry;
use panic_halt as _;
use stm32f4xx_hal::{
    pac,
    prelude::*,
};

#[entry]
fn main() -> ! {
    // Obter acesso aos periféricos do microcontrolador
    let dp = pac::Peripherals::take().unwrap();
    let cp = cortex_m::Peripherals::take().unwrap();

    // Configurar o clock do sistema
    let rcc = dp.RCC.constrain();
    let clocks = rcc.cfgr
        .sysclk(84.MHz())
        .freeze();

    // Configurar o GPIO para o LED (pino PA5 no STM32F4 Discovery)
    let gpioa = dp.GPIOA.split();
    let mut led = gpioa.pa5.into_push_pull_output();

    // Configurar o delay usando o SysTick timer
    let mut delay = cp.SYST.delay(&clocks);

    // Loop principal: pisca o LED a cada 500ms
    loop {
        led.set_high();
        delay.delay_ms(500u32);
        led.set_low();
        delay.delay_ms(500u32);
    }
}
```

## Exemplo: Leitura de Sensor de Temperatura (I2C)

Lendo um sensor de temperatura via barramento I2C:

```rust
#![no_std]
#![no_main]

use cortex_m_rt::entry;
use panic_halt as _;
use stm32f4xx_hal::{
    pac,
    prelude::*,
    i2c::I2c,
};
use core::fmt::Write;

/// Driver para sensor de temperatura LM75
struct Lm75<I2C> {
    i2c: I2C,
    endereco: u8,
}

impl<I2C, E> Lm75<I2C>
where
    I2C: embedded_hal::i2c::I2c<Error = E>,
{
    const REG_TEMPERATURA: u8 = 0x00;

    fn new(i2c: I2C, endereco: u8) -> Self {
        Lm75 { i2c, endereco }
    }

    fn ler_temperatura(&mut self) -> Result<f32, E> {
        let mut buf = [0u8; 2];
        self.i2c.write_read(
            self.endereco,
            &[Self::REG_TEMPERATURA],
            &mut buf,
        )?;

        // Converter os 2 bytes para temperatura em Celsius
        let raw = ((buf[0] as i16) << 8 | buf[1] as i16) >> 5;
        Ok(raw as f32 * 0.125)
    }
}

#[entry]
fn main() -> ! {
    let dp = pac::Peripherals::take().unwrap();
    let cp = cortex_m::Peripherals::take().unwrap();

    let rcc = dp.RCC.constrain();
    let clocks = rcc.cfgr.sysclk(84.MHz()).freeze();

    // Configurar I2C
    let gpiob = dp.GPIOB.split();
    let scl = gpiob.pb6.into_alternate_open_drain();
    let sda = gpiob.pb7.into_alternate_open_drain();

    let i2c = I2c::new(dp.I2C1, (scl, sda), 100.kHz(), &clocks);

    // Criar driver do sensor
    let mut sensor = Lm75::new(i2c, 0x48);

    // Configurar UART para output
    let gpioa = dp.GPIOA.split();
    let tx = gpioa.pa2.into_alternate();
    let mut serial = dp.USART2.tx(tx, 115_200.bps(), &clocks).unwrap();

    let mut delay = cp.SYST.delay(&clocks);

    loop {
        match sensor.ler_temperatura() {
            Ok(temp) => {
                writeln!(serial, "Temperatura: {:.1}°C", temp).ok();
            }
            Err(_) => {
                writeln!(serial, "Erro ao ler sensor").ok();
            }
        }
        delay.delay_ms(1000u32);
    }
}
```

## Exemplo: Controle de Motor PWM

Controlando um servo motor com PWM:

```rust
#![no_std]
#![no_main]

use cortex_m_rt::entry;
use panic_halt as _;
use stm32f4xx_hal::{
    pac,
    prelude::*,
    timer::Channel,
};

/// Controle de servo motor via PWM
struct ServoMotor<PWM> {
    pwm: PWM,
    min_pulso_us: u32,
    max_pulso_us: u32,
}

impl<PWM> ServoMotor<PWM>
where
    PWM: embedded_hal::pwm::SetDutyCycle,
{
    fn new(pwm: PWM, min_us: u32, max_us: u32) -> Self {
        ServoMotor {
            pwm,
            min_pulso_us: min_us,
            max_pulso_us: max_us,
        }
    }

    /// Define o ângulo do servo (0-180 graus)
    fn set_angulo(&mut self, angulo: u8) {
        let angulo = angulo.min(180) as u32;
        let faixa = self.max_pulso_us - self.min_pulso_us;
        let pulso = self.min_pulso_us + (faixa * angulo / 180);

        // Converter microsegundos para duty cycle
        // Período PWM = 20ms (50Hz), duty = pulso / período
        let duty = (pulso * 100) / 20_000;
        let max_duty = self.pwm.max_duty_cycle();
        let duty_valor = (max_duty as u32 * duty / 100) as u16;

        self.pwm.set_duty_cycle(duty_valor).ok();
    }
}

#[entry]
fn main() -> ! {
    let dp = pac::Peripherals::take().unwrap();
    let cp = cortex_m::Peripherals::take().unwrap();

    let rcc = dp.RCC.constrain();
    let clocks = rcc.cfgr.sysclk(84.MHz()).freeze();

    let gpioa = dp.GPIOA.split();
    let canal_pwm = gpioa.pa0.into_alternate();

    // Configurar Timer para PWM a 50Hz (período de 20ms)
    let mut pwm = dp.TIM2.pwm_hz(canal_pwm, 50.Hz(), &clocks);
    pwm.enable(Channel::C1);

    let mut servo = ServoMotor::new(pwm, 500, 2500);
    let mut delay = cp.SYST.delay(&clocks);

    loop {
        // Varrer de 0 a 180 graus
        for angulo in (0..=180).step_by(10) {
            servo.set_angulo(angulo);
            delay.delay_ms(100u32);
        }

        // Varrer de 180 a 0 graus
        for angulo in (0..=180).rev().step_by(10) {
            servo.set_angulo(angulo);
            delay.delay_ms(100u32);
        }

        delay.delay_ms(1000u32);
    }
}
```

## Alvos e Plataformas Suportadas

### ARM Cortex-M (Mais Popular)

| Alvo | Descrição | Chips Comuns |
|------|-----------|--------------|
| `thumbv6m-none-eabi` | Cortex-M0/M0+ | STM32F0, nRF51, RP2040 |
| `thumbv7m-none-eabi` | Cortex-M3 | STM32F1, LPC1768 |
| `thumbv7em-none-eabi` | Cortex-M4/M7 (sem FPU) | STM32F4 (soft float) |
| `thumbv7em-none-eabihf` | Cortex-M4/M7 (com FPU) | STM32F4, STM32H7 |
| `thumbv8m.main-none-eabihf` | Cortex-M33 | STM32L5, nRF9160 |

### RISC-V

| Alvo | Descrição | Chips Comuns |
|------|-----------|--------------|
| `riscv32imac-unknown-none-elf` | RISC-V 32-bit | ESP32-C3, GD32VF103 |
| `riscv32imc-unknown-none-elf` | RISC-V 32-bit (sem atomic) | ESP32-C2 |
| `riscv64gc-unknown-none-elf` | RISC-V 64-bit | K210, BL808 |

### Outros Alvos

| Alvo | Descrição |
|------|-----------|
| `xtensa-esp32-none-elf` | ESP32 (Xtensa) |
| `xtensa-esp32s2-none-elf` | ESP32-S2 |
| `xtensa-esp32s3-none-elf` | ESP32-S3 |
| `aarch64-unknown-none` | ARM 64-bit bare-metal |

## Crates Essenciais para Embedded

### Camada de Abstração de Hardware

| Crate | Descrição |
|-------|-----------|
| `embedded-hal` | Traits padrão para periféricos |
| `embedded-hal-async` | Versão async do embedded-hal |
| `embedded-io` | Traits para I/O |
| `cortex-m` | Acesso ao processador ARM Cortex-M |
| `cortex-m-rt` | Runtime para Cortex-M |

### HALs Específicas

| Crate | Descrição |
|-------|-----------|
| `stm32f4xx-hal` | HAL para STM32F4 |
| `stm32h7xx-hal` | HAL para STM32H7 |
| `nrf-hal` | HAL para nRF (Nordic Semiconductor) |
| `rp2040-hal` | HAL para Raspberry Pi Pico (RP2040) |
| `esp-hal` | HAL para ESP32 (Espressif) |
| `atsamd-hal` | HAL para Atmel SAMD |

### Comunicação e Protocolos

| Crate | Descrição |
|-------|-----------|
| `smoltcp` | Stack TCP/IP para `no_std` |
| `embassy-net` | Networking async para embedded |
| `defmt` | Logging eficiente para embedded |
| `postcard` | Serialização compacta para `no_std` |
| `heapless` | Estruturas de dados sem heap |
| `bbqueue` | Buffer circular lock-free para `no_std` |

### Frameworks Async

| Crate | Descrição |
|-------|-----------|
| `embassy` | Framework async completo para embedded |
| `rtic` | Real-Time Interrupt-driven Concurrency |
| `embassy-executor` | Executor async para microcontroladores |
| `embassy-time` | Timers e delays async |

## Embassy: O Futuro do Embedded Rust

Embassy é um framework async para embedded que está transformando como escrevemos firmware em Rust:

```rust
#![no_std]
#![no_main]

use embassy_executor::Spawner;
use embassy_stm32::gpio::{Level, Output, Speed};
use embassy_time::Timer;
use defmt::info;
use {defmt_rtt as _, panic_probe as _};

#[embassy_executor::main]
async fn main(spawner: Spawner) {
    let p = embassy_stm32::init(Default::default());

    // Spawn de tarefas independentes
    spawner.spawn(tarefa_led(p.PA5)).unwrap();
    spawner.spawn(tarefa_sensor()).unwrap();
    spawner.spawn(tarefa_comunicacao()).unwrap();

    info!("Sistema inicializado!");
}

#[embassy_executor::task]
async fn tarefa_led(pin: embassy_stm32::peripherals::PA5) {
    let mut led = Output::new(pin, Level::Low, Speed::Low);

    loop {
        led.set_high();
        Timer::after_millis(500).await;
        led.set_low();
        Timer::after_millis(500).await;
    }
}

#[embassy_executor::task]
async fn tarefa_sensor() {
    loop {
        // Simular leitura de sensor
        info!("Lendo sensor de temperatura...");
        Timer::after_secs(2).await;
    }
}

#[embassy_executor::task]
async fn tarefa_comunicacao() {
    loop {
        // Simular envio de dados via rede
        info!("Enviando dados via MQTT...");
        Timer::after_secs(5).await;
    }
}
```

## Empresas que Contratam

### Semicondutores e Hardware

- **Espressif Systems**: Fabricante do ESP32, investindo pesado em Rust
- **Nordic Semiconductor**: Suporte Rust para chips nRF
- **STMicroelectronics**: Ecossistema crescente em Rust
- **Raspberry Pi Foundation**: RP2040 com excelente suporte Rust

### Automotivo

- **Volvo**: Usando Rust para software de veículos
- **Volkswagen**: Explorando Rust para sistemas embarcados
- **Rivian**: Veículos elétricos com componentes em Rust
- **Woven by Toyota**: Plataforma de mobilidade

### IoT e Dispositivos

- **Oxide Computer**: Firmware de servidor em Rust
- **Ferrous Systems**: Consultoria especializada em Rust embedded
- **Tweede Golf**: Consultoria Rust na Holanda
- **Espressif**: ESP-IDF com suporte Rust

### Aeroespacial e Defesa

- **Lynx Software Technologies**: RTOS com componentes Rust
- **Krtkl**: Hardware com firmware Rust
- **Empresas de defesa**: Sistemas críticos migrando para Rust

### No Brasil

- **Indústria automotiva**: Fornecedores de autopeças com eletrônica embarcada
- **IoT e agritech**: Dispositivos de monitoramento agrícola
- **Telecomunicações**: Firmware de equipamentos de rede
- **Startups de hardware**: Dispositivos IoT e wearables
- **Consultorias**: Projetos embedded para clientes nacionais e internacionais

## Roadmap de Habilidades

### Nível Júnior (0-12 meses)

1. **Fundamentos Rust**: Ownership, lifetimes, traits, generics, `no_std`
2. **Eletrônica básica**: Circuitos digitais, LEDs, botões, resistores, multímetro
3. **Microcontrolador**: Começar com RP2040 (Raspberry Pi Pico) ou STM32F4
4. **GPIO e periféricos**: Entrada/saída digital, PWM, ADC
5. **Comunicação**: UART, SPI, I2C
6. **Ferramentas**: probe-rs, defmt, cargo-embed, openocd

### Nível Pleno (1-3 anos)

1. **Protocolos avançados**: USB, CAN, Ethernet, BLE
2. **RTOS**: Embassy ou RTIC para multitasking
3. **DMA**: Direct Memory Access para transfers eficientes
4. **Drivers**: Escrever drivers para sensores e atuadores
5. **Múltiplos targets**: ARM, RISC-V, ESP32
6. **Segurança**: Secure boot, criptografia em hardware, TrustZone

### Nível Sênior (3+ anos)

1. **Design de sistemas**: Arquitetura de firmware complexo
2. **BSP (Board Support Package)**: Criar suporte para novas placas
3. **Certificações**: Safety-critical (IEC 61508, ISO 26262)
4. **HAL contributions**: Contribuir para HALs e embedded-hal
5. **Performance**: Otimização de código para targets específicos
6. **Liderança**: Decisões de arquitetura, escolha de componentes

## Expectativas Salariais

### Brasil (CLT)

| Nível | Faixa Salarial (R$/mês) | Observações |
|-------|--------------------------|-------------|
| Júnior | R$ 5.000 - R$ 9.000 | Firmware básico |
| Pleno | R$ 10.000 - R$ 18.000 | Drivers, protocolos, IoT |
| Sênior | R$ 18.000 - R$ 30.000 | Arquitetura de firmware |
| Staff | R$ 30.000 - R$ 45.000+ | Safety-critical, liderança |

### Remoto Internacional (USD)

| Nível | Faixa Salarial (USD/ano) | Observações |
|-------|---------------------------|-------------|
| Júnior | $55.000 - $85.000 | Startups IoT |
| Pleno | $85.000 - $130.000 | Empresas de hardware |
| Sênior | $130.000 - $200.000 | Automotivo, aeroespacial |
| Staff | $200.000 - $280.000+ | Safety-critical, liderança |

### Diferencial Salarial

Desenvolvedores embedded com Rust costumam ganhar 15-30% a mais que equivalentes puramente C, refletindo a raridade da combinação de habilidades e a crescente demanda por firmware seguro.

## Hardware Para Começar

### Kit Iniciante Recomendado

| Item | Preço Aproximado | Por Quê |
|------|-------------------|---------|
| Raspberry Pi Pico (RP2040) | R$ 30-50 | Melhor suporte Rust para iniciantes |
| STM32F4 Discovery | R$ 100-150 | ARM Cortex-M4 com vários periféricos |
| ESP32-C3 DevKit | R$ 40-60 | RISC-V com Wi-Fi e Bluetooth |
| Breadboard + jumpers | R$ 20-30 | Para prototipagem |
| LEDs, resistores, sensores | R$ 30-50 | Componentes básicos |
| Debugger ST-Link V2 | R$ 30-50 | Para STM32 |

### Investimento Total Inicial

Com aproximadamente R$ 200-400, você pode montar um laboratório de desenvolvimento embedded com Rust capaz de explorar ARM, RISC-V e Wi-Fi.

## Projetos Práticos para o Portfólio

1. **LED blink com timer**: O clássico hello world embedded
2. **Estação meteorológica**: Sensor de temperatura/umidade com display OLED
3. **Controle de servo**: PWM para controlar servo motores
4. **Logger de dados**: Registrar dados de sensores em cartão SD
5. **Monitor de qualidade do ar**: Sensor de CO2/PM2.5 com display
6. **Semáforo inteligente**: Máquina de estados com botões e LEDs
7. **Relógio digital**: RTC com display de 7 segmentos
8. **Comunicação BLE**: Enviar dados de sensor via Bluetooth Low Energy

## Recursos de Aprendizado

### Livros e Documentação

- **"The Embedded Rust Book"**: Documentação oficial do Embedded WG
- **"Discovery Book"**: Tutorial hands-on com placa micro:bit
- **"Real-Time Interrupt-driven Concurrency"**: Documentação do RTIC
- **"Embassy Book"**: Documentação do framework Embassy

### Comunidades

- **Rust Embedded Working Group**: Grupo oficial de embedded Rust
- **Matrix #rust-embedded**: Chat oficial
- **Rust Brasil**: Comunidade brasileira
- **Embassy Discord**: Comunidade do framework Embassy

### Hardware Playgrounds

- **Wokwi**: Simulador online de microcontroladores com suporte Rust
- **QEMU**: Emulador para ARM e RISC-V
- **Renode**: Framework de simulação de sistemas embarcados

## Conclusão

Sistemas embarcados com Rust representam uma convergência perfeita de demanda do mercado e capacidade técnica. A segurança de memória de Rust é particularmente valiosa em dispositivos que operam em ambientes críticos -- de carros autônomos a dispositivos médicos, de infraestrutura industrial a satélites.

### Próximos Passos Concretos

1. **Compre um kit**: Raspberry Pi Pico ou ESP32-C3 para começar
2. **Configure o ambiente**: Instale Rust com targets `thumbv6m-none-eabi` e `riscv32imc-unknown-none-elf`
3. **Faça o LED piscar**: Complete o tutorial do Embedded Rust Book
4. **Explore periféricos**: I2C, SPI, UART, PWM, ADC
5. **Aprenda Embassy**: Framework async moderno para embedded
6. **Construa projetos**: Estação meteorológica, logger de dados
7. **Contribua**: embedded-hal, HALs específicas, drivers
8. **Publique no GitHub**: Documente seus projetos com fotos e diagramas
9. **Participe da comunidade**: Rust Embedded WG, Rust Brasil
10. **Busque vagas**: Embedded Rust jobs em empresas de IoT, automotivo e hardware

O mundo embedded está em plena transição de C para Rust. Ser um dos primeiros profissionais a dominar essa combinação coloca você em uma posição privilegiada no mercado. Comece hoje -- seu próximo projeto pode ser o firmware que roda em milhões de dispositivos.
