sistemas operativos niveles manejo interrupciones enmascaramiento enmascarables ejemplos control computadoras arquitectura c gdb embedded breakpoints stm32

operativos - niveles de control de interrupciones



SIGTRAP a pesar de que no hay puntos de interrupciĆ³n establecidos; punto de interrupciĆ³n de hardware oculto? (5)

De acuerdo. Respuesta larga: los puntos de interrupción del hardware generalmente se establecen al escribir en algunos registros especiales de la CPU. Esto se hace por gdb. Si gdb muere, puede dejar los instalados en la CPU. Supongo que su implementación (de gdb) no las borra ni las examina cuando se conecta a su objetivo. Para localizarlos, deberá enumerar el contenido de los registros de puntos de interrupción de hardware en su CPU (no sabe cómo hacerlo en STM32). La solución alternativa sería (supongo que es una suposición informada): establezca pocos puntos de interrupción de HW (normalmente solo hay unos pocos, rara vez más de 8) con gdb, luego elimínelos todos. Esto debería sobrescribir y luego limpiar esos registros hw. Una vez que establezca esos puntos de interrupción (antes de eliminarlos), haga "continuar" (por si acaso, ya que gdb establece los puntos de interrupción solo en ese momento).

Estoy depurando esta pieza de software para un sistema embebido STM32. En una de las funciones, mis programas siguen llegando a algún tipo de punto de interrupción:

SIGTRAP, traza / trampa de punto de ruptura

Sin embargo, en GDB, cuando hago info breakpoints no obtengo No breakpoints or watchpoints . El punto de interrupción en realidad corresponde a un punto de interrupción que había establecido hace bastante tiempo, en otra versión del ejecutable. Cuando configuré ese punto de interrupción, GDB me dijo automatically using a hardware breakpoint on read-only memory (o un mensaje similar).

Creo que el punto de interrupción del hardware permanece en mi chip, a pesar de haber cargado una nueva versión del software. Si hay un punto de interrupción falso, ¿cómo puedo ubicarlo y eliminarlo?


El código que está ejecutando puede contener

int $0x03 ; talking about x86, don''t know STM32 mnemo

que invoca un SIGTRAP.


Los siguientes me ayudaron:

# Ones I hit the SIGTRAP: (gdb) f 0 # Show the current stack frame of the current thread. #0 0x4003ed70 in pthread_create@@GLIBC_2.4 () from /opt/CodeSourcery/arm-2011.09/arm-none-linux-gnueabi/libc/lib/libpthread.so.0 # The fragment of interest is the current address: 0x4003ed70. # Set the hardware assisted breakpoint at the current address: (gdb) hbreak *0x4003ed70 # Continue execution (without hitting SIGTRAP): (gdb) c # Continuing.


SIGTRAP debería ser una instrucción de punto de interrupción que se está ejecutando.

Depure esto al inspeccionar el indicador de instrucción, lo más probable es que apunte a una dirección que contenga la instrucción BKPT (tendrá que buscar cuál es el código real).

A partir de ahí, tendrás que trabajar hacia atrás en función de la pila y el indicador de instrucción y ver si estás donde esperas estar. Podría haber varias cosas que causan esto, desde que GDB inserta una instrucción de punto de interrupción que no pudo eliminar, hasta la corrupción de memoria.


Si agregar y eliminar puntos de interrupción de hardware no ayuda, verifique el vector de interrupción.

En los microcontroladores Cortex-M, todas las entradas del controlador deben tener una dirección impar ( Preguntas frecuentes de ARM Cortex-M ). Si no lo hacen, entonces se activa un UsageFault de tipo INVSTATE y se detiene la MCU. GDB interpreta esto como un SIGABRT.

Si una de las entradas tiene una dirección par, entonces verifique si la función del controlador tiene las directivas .thumb_func y .type ( NXP Evite hardfault , HardFault y .thumb_func ).

Ejemplo para un HardFault_Handler:

.thumb_func .type HardFault_Handler, %function HardFault_Handler: TST LR, #4 ITE EQ MRSEQ R0, MSP MRSNE R0, PSP B hard_fault_handler_c