es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

STM32 Hardfault cuando se intenta acceder a la memoria

Estoy analizando código escrito para el microcontrolador STM32H730. Encuentro el siguiente fragmento de código que produce un hardfault cuando se llama a BootHoldRequest(&fnBoot).

#define BOOTBLOCK_ADD        0x08000000L
#define BootHoldRequest        (*((BOOTLOAD_PROCEED_TYPE *) (BOOTBLOCK_ADD + 0x200)))

typedef void (* CALLBACK_PTR)(void);
typedef uint16_t BOOTLOAD_PROCEED_TYPE(CALLBACK_PTR *);

typedef void (* VOID_FUN_TYPE)(void);
static VOID_FUN_TYPE fnBoot;

if (BootHoldRequest(&fnBoot)) //<--------- HARDFAULT
{

}
Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El código anterior define dos macros y tres typedefs. Estas macros se utilizan para establecer la dirección de memoria en BOOTBLOCK_ADD y para llamar a la función BootHoldRequest. El tipo de puntero a función BOOTLOAD_PROCEED_TYPE toma un CALLBACK_PTR como argumento y devuelve un uint16_t. El tipo de puntero a función VOID_FUN_TYPE se define como un puntero a una función void. La variable fnBoot es una variable estática de tipo VOID_FUN_TYPE.

    La función BootHoldRequest se llama con la dirección de fnBoot. Sin embargo, el prototipo de función BOOTLOAD_PROCEED_TYPE espera un puntero a un puntero a función. Esta discrepancia en los tipos provoca un fallo duro.

    Para solucionar este problema, es necesario modificar el código para pasar un puntero a fnBoot en lugar de la dirección de fnBoot. El siguiente código modificado debería funcionar:

    #define BOOTBLOCK_ADD        0x08000000L
    #define BootHoldRequest        (*((BOOTLOAD_PROCEED_TYPE *) (BOOTBLOCK_ADD + 0x200)))
    
    typedef void (* CALLBACK_PTR)(void);
    typedef uint16_t (*BOOTLOAD_PROCEED_TYPE)(CALLBACK_PTR *);
    
    typedef void (* VOID_FUN_TYPE)(void);
    static VOID_FUN_TYPE fnBoot;
    
    if (BootHoldRequest(&fnBoot)) // Sin fallo duro
    {
        // Código para una llamada a la función exitosa
    }
    

    Aquí, se ha modificado el prototipo del puntero a función BOOTLOAD_PROCEED_TYPE para aceptar un puntero a CALLBACK_PTR. Ahora se puede llamar a la función BootHoldRequest con un puntero a fnBoot, y el fallo duro ya no debería ocurrir.

Comments are closed.