Optimización de Portabilidad RTOS en STM32: Verificación a Nivel de Registros para Cortex-M

Fundamentos de Portabilidad RTOS en Microcontroladores STM32

La adaptación de sistemas RTOS (FreeRTOS, RT-Thread, Zephyr) a plataformas STM32 requiere un entendimiento profundo de la capa de abstracción de hardware, mecanismos de interrupción y gestión de contexto. Este proceso implica una transición de programación bare-metal a modelos de concurrencia determinísticos.

Vector de Interrupciones y Gestión de Contexto

Los núcleos Cortex-M utilizan tablas de vectores para manejar excepciones, donde el planificador RTOS depende de SysTick y PendSV para cambios de contexto. PendSV debe ejecutarse con prioridad mínima para evitar interrupciones de usuario:

// Configuración de prioridad en stm32f4xx_it.c
void PendSV_Handler(void) {
    // Gestión interna del RTOS
    NVIC_SetPriority(PendSV_IRQn, PRIORIDAD_MIN); // 0xFF
}

Reconfiguración del Proceso de Inicio

El manejador Reset_Handler debe inicializar el RTOS:

  • Deshabilitar interrupciones globales
  • Configurar reloj principal y periféricos críticos
  • Invocar inicializador del núcleo RTOS
  • Convertir main() en función de tarea inicial

Modelo de Memoría y Pilas

Tipo Modo Bare-Metal Modo RTOS
Pila Principal (MSP) Única para todo el sistema Solo para ISR y llamadas al sistema
Pila de Proceso (PSP) Inactiva Asignada por tarea mediante xTaskCreate()

Sistema de Verificación de Registros Cortex-M

Consistencia de SCB, NVIC y SysTick

SCB->VTOR debe apuntar a la tabla de vectores con alineación de 256 bytes:

ldr r0, =VTOR_ADDR
ldr r1, [r0]
ldr r2, =__TablaVectores
cmp r1, r2
bne error_vtor

Configuración MPU

Reglas esenciales para regiones MPU:

  • Alineación de dirección base según tamaño de región
  • Tamaño de región potencia de 2 (32B–4GB)
  • Prohibición de solapamiento de regiones
uint8_t idx = MPU_ObtenerRegion();
uint32_t rbar = MPU->RBAR;
uint32_t rasr = MPU->RASR;
if ((rbar & 0x1F) != (rasr & 0x1E)) {
    // Error de alineación
}

Calibración de SysTick

Los errores acumulados en la cadena de reloj afectan la precisión:

uint32_t freq = HAL_RCC_GetHCLKFreq();
uint32_t reload = (freq / 8) / TICK_RATE - 1;
Fuente de Error Desvaición Típica
HSI ±1% ±47.6 ns/tic
Envejecimiento cristal ±20 ppm

Verificación de Tareas y Aislamiento de Memoria

Comparación dinámica de punteros de pila:

uint32_t nivel_agua = pxTareaObtenerMaxUsoStack(NULL);
uint32_t *sp_actual;
__asm("MRS %0, psp" : "=r"(sp_actual));

Adaptación de Componentes RTOS

Mecanismo PendSV

Secuencia crítica en manejadores:

PendSV_Handler:
    CPSID I
    MRS R0, PSP
    STMDB R0!, {R4-R11}
    CPSIE I
    BX LR

Configuración MPU Dinámica

uint32_t rasr = MPU->RASR;
configASSERT(rasr & HABILITADO); 
configASSERT((rasr & TAMANO) == TAMANO_ESPERADO);

Diagnóstico de Fallos

Análisis de HardFault

void HardFault_Handler() {
  __asm(
    "tst lr, #4\n\t"
    "ite eq\n\t"
    "mrseq r0, msp\n\t"
    "mrsne r0, psp\n\t"
    "ldr r1, =BFAR_ADDR\n\t"
    "ldr r2, [r1]\n\t"
    "bkpt #0\n\t"
  );
}

Detección de Pérdida de Ticks

uint32_t t0, t1;
void SysTick_Handler() {
    t0 = DWT->CYCCNT;
    xManejadorSysTick();
    t1 = DWT->CYCCNT;
}
Retardo (ciclos) Severidad
< 500 Baja
1200–3500 Media-Alta

Etiquetas: STM32 RTOS Cortex-M FreeRTOS MPU

Publicado el 7-17 01:18