STM32F411VE Problema de eliminación de inicio de USB del cargador de arranque personalizado que provoca un error en el salto a la aplicación

Estoy desarrollando un cargador de arranque personalizado en la MCU STM32F411VE que debe descargar un archivo .bin de la llave USB y actualizarlo en los sectores de aplicación de la memoria flash. Siguiendo los ejemplos proporcionados con las bibliotecas de cubos, logré abrir correctamente el archivo con el sistema FAT FS, pero me cuesta entender cómo salir del gestor de arranque y saltar a mi aplicación.

Estos son los escenarios: 1) Encienda la placa sin una llave USB insertada; el código no tiene usb stop/deinit/disconnect call -->boot finaliza su función y salta correctamente a la aplicación. Si conecto la llave USB durante la vida útil de la aplicación, el sistema se reinicia. Tenga en cuenta que en mi aplicación no tengo ningún controlador USB en ejecución 2) Encienda con la llave USB insertada; el código no tiene usb stop/deinit/disconnect call --> el arranque falla al configurar el MSP de la aplicación:

__set_MSP((uint32_t)*APPLICATION_START_ADDRESS); 

3) Encienda sin una llave USB insertada y llame a USBH_Stop antes de saltar a la aplicación --> el arranque falla al configurar el MSP de la aplicación

Esta es mi implementación de Jump to app. Funcionó de manera óptima antes de insertar el controlador USB Host

static void JumpToApplication(void)
{
 void (*pmain_app)(void);
 /* First, disable all IRQs */
 __disable_irq();

 SCB->VTOR = (uint32_t)APPLICATION_START_ADDRESS;
__set_MSP((uint32_t)*APPLICATION_START_ADDRESS);

pmain_app = (void (*)(void))*(APPLICATION_START_ADDRESS + 1);

pmain_app();
}

muchas gracias por apoyarme

¿Cómo sabes que falla al configurar el MSP? ¿Puede recorrer la declaración en modo de depuración de instrucciones (en la ventana de desmontaje)? ¿Cuál es el valor del spregistro antes y después? ¿Puedes mostrar la función desmontada? ¿Qué configuración de optimización usas?
Puedo decir que estoy usando una optimización media, aunque lo siento, pero no puedo darle las otras respuestas. Serias tan amable de guiarme de alguna manera? Me gustaría entender mejor los inconvenientes y peligros relacionados con la optimización del código.

Respuestas (1)

Su problema general es tratar de bifurcarse a una aplicación después de que un cargador de arranque haya operado mucho el sistema. Esto no se recomienda encarecidamente en el STM32, ya que para que funcione, debe hacer que todos los aspectos del chip vuelvan al estado que asume el código de la aplicación. Las fallas probablemente más obvias incluyen cosas como tener el reloj PLL encendido y seleccionado (como se requiere para USB) y luego el código de aplicación esperado, el PLL no está seleccionado cuando comienza a configurarlo. Pero perseguir todo será extremadamente frustrante, y puede quedar con un 90% de funcionalidad pero un 10% de rarezas aparentemente inexplicables en algún periférico.

En su lugar, la recomendación habitual es establecer un indicador en la memoria o en los registros de copia de seguridad de RCC, reiniciar el sistema y luego detectar el indicador y la bifurcación al inicio antes de realizar cualquier configuración. Cuando necesité implementar esto, lo hice en ensamblador incluso antes de que se ejecutara el inicio de C; Sin embargo, eso probablemente no era necesario si elige usar un indicador de memoria, tenga cuidado con la probabilidad de que el código de inicio inicialice la RAM. Si ingresar al cargador de arranque requiere una acción explícita, ni siquiera necesitaría el indicador, sino solo para verificar que el GPIO "permanecer en el cargador de arranque" o cualquier condición no se cumpla, y que haya una aplicación presente que coincida con cualquier verificación de validez que use.

el arranque falla al configurar el MSP de la aplicación

Esto se explica más fácilmente. Su código intenta utilizar una variable de pila local que se asignó antes de cambiar el puntero de pila, que es esencialmente una receta para el desastre. Si va a hacer eso, no querrá hacer ningún uso de la pila después de cambiarla.

usar un indicador en la memoria para detectar la necesidad de iniciar periféricos en el cargador de arranque sería sin duda una excelente técnica para evitar mi problema. Por otro lado, es posible que deba implementar un cargador de arranque que pueda detectar si se inserta una llave USB y, eventualmente, comenzar con la actualización de FW por sí mismo. Tenga en cuenta que antes de inicializar el USB utilicé algunos temporizadores y relojes y PLL en mi cargador de arranque sin tener ningún problema. Más en detalle, probé que la función que rompe todo es "USBH_Start". Si no inicio el USB, solo lo inicio, no ocurre ningún problema
Su actualización automática no es incompatible con hacer un reinicio automático para borrar el estado. Le invitamos a intentar identificar y solucionar el problema específico, pero la mejor práctica en esta plataforma es restablecer; es donde terminaron todas las demás versiones de esta pregunta que se ha hecho.