Revisão de Conceitos Fundamentais para Sistemas Embarcados

  1. Polimorfismo em C++

O polimorfismo permite que um mesmo contrato de interface se comporte de formas distintas conforme o tipo concreto do objeto. Em C++, ele se manifesta de duas maneiras principais:

1.1 Polimorfismo em Tempo de Compilação

Resolvido durante a compilação, geralmente por meio de sobrecarga de funções e operadores.

class Calculadora {
public:
    int soma(int x, int y) { return x + y; }
    double soma(double x, double y) { return x + y; }
};

1.2 Polimorfismo em Tempo de Execução

Implementado com funções virtuais e ponteiros/referências para a classe base.

class Forma {
public:
    virtual void desenhar() const {
        std::cout << "Desenhando forma genérica" << std::endl;
    }
    virtual ~Forma() = default;
};

class Circulo : public Forma {
public:
    void desenhar() const override {
        std::cout << "Desenhando círculo" << std::endl;
    }
};

void renderizar(const Forma& figura) {
    figura.desenhar();
}

Vantagens: reutilização de código, extensibilidade, vinculação dinâmica e maior clareza em sistemas com famílias de objetos.

  1. Busca de Texto no Vim

Para localizar palavras dentro do editor Vim:

  • Busca para frente: /termo e pressione Enter.
  • Busca para trás: ?termo e pressione Enter.
  • Próxima ocorrência: n.
  • Ocorrência anterior: N.
  1. Diferença entre struct e union

Aspecto struct union
Memória Soma dos membros + alinhamento Tamanho do maior membro
Armazenamento Todos os membros simultaneamente Apenas um membro por vez
Inicialização Lista completa de valores Apenas o primeiro membro
struct Pessoa {
    char nome[20];
    int idade;
};

union Valor {
    int inteiro;
    float decimal;
    char caractere;
};

struct Pessoa p = {"Ana", 25};
union Valor v = {100}; // inicializa o membro int
  1. Enumerações em C

O tipo enum define constantes inteiras nomeadas, melhorando a legibilidade e a manutenção.

typedef enum {
    DESLIGADO = 0,
    LIGADO,
    STANDBY
} Estado;

Estado motor = LIGADO;

Quando combinado com typedef, simplifica a declaração de variáveis e restringe o escopo quando usado em C99 ou superior.

  1. Fluxo de Uso de Interrupções no STM32

Configuração típica de uma interrupção externa (EXTI) usando a Standard Peripheral Library:

void inicializar_gpio(void) {
    GPIO_InitTypeDef cfg;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
    cfg.GPIO_Pin = GPIO_Pin_0;
    cfg.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOA, &cfg);
}

void inicializar_nvic(void) {
    NVIC_InitTypeDef nvic;
    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
    nvic.NVIC_IRQChannel = EXTI0_IRQn;
    nvic.NVIC_IRQChannelPreemptionPriority = 1;
    nvic.NVIC_IRQChannelSubPriority = 0;
    nvic.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&nvic);
}

void inicializar_exti(void) {
    EXTI_InitTypeDef exti;
    
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
    EXTI_ClearITPendingBit(EXTI_Line0);
    
    exti.EXTI_Line = EXTI_Line0;
    exti.EXTI_Mode = EXTI_Mode_Interrupt;
    exti.EXTI_Trigger = EXTI_Trigger_Falling;
    exti.EXTI_LineCmd = ENABLE;
    EXTI_Init(&exti);
}

void EXTI0_IRQHandler(void) {
    if (EXTI_GetITStatus(EXTI_Line0) != RESET) {
        EXTI_ClearITPendingBit(EXTI_Line0);
        GPIOA->ODR ^= GPIO_Pin_5;
    }
}
  1. Sinais Comuns no Linux

Alguns sinais importantes para aplicações embarcadas e controle de processos:

  • SIGINT (2): interrompe um processo via Ctrl+C.
  • SIGKILL (9): encerramento forçado, não pode ser capturado.
  • SIGTERM (15): solicita encerramento ordenado.
  • SIGSEGV (11): violação de acesso à memória.
  • SIGALRM (14): alarme de temporização.
  1. Funções Comuns da string.h

Função Descrição
strlen Retorna o comprimento de uma string, sem contar o '\0'.
strcpy Copia uma string para outra.
strncpy Copia até n caracteres, preenchendo com nulos se necessário.
strcat Concatena duas strings.
strncat Concatena até n caracteres.
strcmp Compara duas strings lexicograficamente.
strncmp Compara até n caracteres.
  1. Detecção de Endianness

Endiannesss define a ordem de armazenamento dos bytes de um valor multi-byte na memória. O código a seguir identifica se a arquitetura é little-endian ou big-endian:

#include <stdio.h>

int main(void) {
    unsigned int valor = 1;
    unsigned char *ptr = (unsigned char *)&valor;

    if (ptr[0] == 1) {
        printf("Little-endian\n");
    } else {
        printf("Big-endian\n");
    }
    return 0;
}
  1. Ponteiros Inteligentes em C++

Introduzidos para gerenciar automaticamente a vida útil da memória dinâmica, reduzindo vazamentos:

  • std::unique_ptr<T>: ownership exclusivo.
  • std::shared_ptr<T>: ownership compartilhado com contagem de referências.
  • std::weak_ptr<T>: observa um recurso sem aumentar sua contagem de referências.
  1. Benefícios do Alinhamento de Memória em Estruturas

O alinhamento otimiza o acesso do processador a variáveis, respeitando limites de endereço. Ele evita leituras múltiplas e exceções de hardware, mesmo que aumente ligeiramente o consumo de memória por causa do preenchimento.

struct Exemplo {
    char a;
    int b;
    char c;
};

Em uma arquitetura de 32 bits, a estrutura acima pode ocupar 12 bytes devido ao preenchimento, em vez de 6.

  1. std::vector vs Arrays em C++

Característica Array std::vector
Tamanho Fixo em tempo de compilação Dinâmico em tempo de execução
Memória Pode estar na stack ou heap Sempre na heap, gerenciada automaticamente
Funcionalidades Acesso por índice push_back, size, empty, erase, etc.
Segurança Menor Maior, com iteradores e RAII
  1. Formas do Operador new em C++

// Alocação simples
int *p1 = new int;

// Alocação com inicialização
int *p2 = new int(42);

// Alocação de array
int *p3 = new int[10];

// Alocação com construtor default explícito
std::string *p4 = new std::string();

// Sobrecarga customizada
void* operator new(size_t size) {
    return std::malloc(size);
}
  1. Funções inline em C++

Uma função marcada com inline sugere ao compilador que substitua o corpo da função diretamente no ponto de chamada, eliminando o overhead da chamada. É indicada para funções pequenas e frequentemente executadas, mas a decisão final de expansão permanece com o compilador.

inline int quadrado(int x) {
    return x * x;
}

Tags: C++ STM32 vim Linux string.h

Publicado em 7-29 21:16