Si no está haciendo nada especial (como PIC (Código independiente de la posición), con el que no estoy familiarizado y, francamente, ni siquiera estoy seguro de si está soportado en la plataforma), el código debe estar vinculado a la el área de memoria en la que se ejecutará; por lo tanto, el código ya debería saber el banco en el que se está ejecutando. Entonces, tome la dirección de una función (o el símbolo del vinculador para el inicio del área de código) y verifique en qué banco se encuentra la dirección se cae. (Aunque probablemente también necesitará / tendrá la información disponible en otro lugar, ya que la necesitará para vincular el nuevo código con el banco adecuado)
Si el PIC es posible y lo está utilizando, deberá leer el indicador de instrucción. No he verificado exactamente cómo se debe hacer esto, pero supongo que tendrá que escribir a mano una función de ensamblaje que devuelva el contenido del registro de enlace.
Si el PIC no es posible y se acaba de dar cuenta de que tener que vincular un código con direcciones diferentes va a ser inconveniente, otra posibilidad es escribir un cargador de arranque pequeño (tampoco tiene que ser un cargador de arranque, solo una actualización de firmware por separado) blob) que maneja la actualización del firmware. De esa manera, el gestor de arranque puede permanecer igual y siempre puede escribir el código en la misma ubicación de memoria. (O primero escriba en la segunda ubicación y luego copie en la ubicación correcta, para evitar problemas si se interrumpe la transferencia)
Tenga en cuenta que incluso si utilizara el código en dos bancos diferentes, necesitaría un cargador de arranque o algo equivalente: el vector de reinicio que se encuentra al inicio de flash debería apuntar a algún código que decida si debería comenzar a ejecutar el firmware real del banco 1 o banco 2.
Sin embargo, la sugerencia del gestor de arranque es suponer que en realidad no necesita lectura mientras se borra y lectura mientras se escribe, y no los necesita solo para la actualización del firmware. Permiten que el código continúe ejecutándose mientras una parte del flash se está borrando / escribiendo, pero eso no es necesario solo para la actualización del firmware, ya que funcionará bien incluso si el código se bloquea mientras el flash se está borrando / escribiendo hasta la operación está completo, si no hay requisitos específicos para que el software principal se ejecute normalmente mientras se realiza la actualización del firmware. (Y en caso de que esté dudando de esto: anteriormente escribí un cargador de arranque que actualiza el firmware que se encuentra en el mismo banco que el cargador de arranque, y funciona bien. Así que, además de la teoría, esto también funciona en la práctica ! :)
En cuanto a mover la tabla de vectores, depende del modelo. Para el STM32F4 (y F3) que tiene, puede elegir dónde se ubica la tabla de vectores escribiendo la dirección (alineada de 512 bytes) en SCB_VTOR (Registro de compensación de la tabla de vectores). Si estaba trabajando con partes STM32F0, que no tienen el registro SCB_VTOR, podría usar los bits MEM_MODE en el registro SYSCFG_CFGR1; seleccionan lo que se asigna en la dirección 0, desde donde se lee la tabla de vectores: flash principal, flash del sistema (cargador de arranque interno) o SRAM. Como no podría cambiar la ubicación dentro de flash, desearía seleccionar SRAM en su lugar y copiar la tabla de vectores al inicio de la RAM.