Firmware ARM Cortex M3

Primero algunos antecedentes.

Hay un producto (un sensor) comprado a un fabricante del Lejano Oriente, benditos sean sus calcetines blancos de algodón, que utiliza el microcontrolador STM32F103V. El firmware que se suministró originalmente, junto con las actualizaciones, tiene algunos errores desagradables que convierten el producto en un ladrillo a intervalos aleatorios (y se espera que el producto funcione sin ningún tiempo de inactividad durante meses).

Al principio se mostraron receptivos y deseosos de brindar apoyo; después de la compra no dan respuesta a ninguno de los e-mails enviados.

Entonces, la solución es reescribir el firmware yo mismo.

En el problema ahora.

El microcontrolador ya tiene un cargador de arranque y no hay un puerto JTAG disponible en las placas. ¿Hay alguna forma de encontrar, a partir de los archivos bin que tengo, cuál es la dirección de inicio del firmware? Debido al gestor de arranque, no es 0x00000000. Además, ¿hay alguna otra cosa que deba tener en cuenta al escribir el firmware (es decir, ciertas configuraciones para registros, etc.)?

¿Puede proporcionar información sobre el gestor de arranque? Estás hablando de uno personalizado, no el de STMicro que ya está en la ROM de la MCU, ¿verdad? ¿Quién lo desarrolló? esta misma empresa?
No tengo información sobre el cargador de arranque y los dispositivos se suministraron con una aplicación de Windows que maneja la carga de firmware. No hay referencia al desarrollador de la aplicación de carga de firmware (aunque tiene algunos caracteres chinos) y se entrega con una DLL que puede provenir de ST (STUARTBLLIB.dll).
@Iulian: "errores desagradables que convierten el producto en un ladrillo a intervalos aleatorios [...] la solución es reescribir el firmware yo mismo". Recomiendo mantener una mente abierta sobre la posible causa y solución. Suponiendo que los bloqueos se produzcan en varios dispositivos, además del firmware, los bloqueos también podrían deberse a (a) errores de diseño de hardware en el dispositivo y/o (b) algo específico de su uso de los dispositivos, incluidos, entre otros , , problemas relacionados con la fuente de alimentación. ¡Sería una pena si reescribes el firmware y sigues teniendo el mismo problema! ¿Puedes compartir un enlace web para el dispositivo?
@SamGibson: Gracias por la pista. Llegué a esta conclusión probando el producto también en una fuente de alimentación filtrada, en el banco y obteniendo como resultado diferentes ladrillos, dependiendo de la versión de firmware (uno de ellos se quejará del montón, mientras que otro no dirá nada). Aún así, no descarto el hardware por completo, ya que también estoy agregando algunos cables adicionales para hacer algunas comprobaciones más. Buscará el producto en línea y proporcionará un enlace.
¿Cómo se conecta la placa a la PC para cargar? El cargador de arranque de fábrica en el STM32F103 admite una conexión UART, pero no una conexión USB. La DLL que menciona sugiere que el cargador de arranque UART puede estar en uso, pero si se conecta a través de USB, el cargador de arranque sería algo personalizado. También debería poder saberlo determinando el flejado de los pines del modo de arranque. Para hacer el desarrollo, querrá una placa en la que recoja los dos pines SWD, a menos que usen la versión BGA que debería ser posible con cuidado y ampliación.

Respuestas (2)

Le recomiendo que obtenga una pieza equivalente y una placa de conexión. solo deberias necesitar corriente y tierra y vdda. obtenga el paquete más pequeño si lo prefiere (desglose más barato). otra opción es una placa nucleo, y es posible que desee el final de depuración de todos modos, querrá desconectar el swd/debugger para que pueda obtener lo que busco...

las partes vienen preprogramadas desde ST con un cargador de arranque en ellas. ata boot0 de la manera correcta y luego puede programar a través de uart. en cualquier momento debería poder usar la interfaz swd (jtag-ish). Utilizo el extremo superior de estas placas para programar otros chips, sin embargo, quieren usar la cosa mbed y montar como una memoria USB y arrastras y sueltas el archivo. no es la experiencia que está buscando en una experiencia de entorno controlado usando openocd o algo así sobre swd para tratar con una de estas partes. por lo tanto, la idea de obtener un tablero de descubrimiento, o una ruptura u otra. No debería costarte más de $20 en total, tal vez $10 dependiendo del camino que tomes.

una vez que lo experimenta con una placa que no tiene nada más, puede adaptar ese conocimiento a su placa en el circuito. los pines uart pueden reutilizarse, por ejemplo, por lo que es posible que no pueda acceder al primer gestor de arranque. No puedo imaginar que los pines swd se reutilicen, querrían tener una forma de hacer una actualización de firmware en el circuito. es posible que hayan programado previamente las piezas para la producción, pero también es posible que las hayan programado en el circuito. También es posible que sean programables una sola vez, pero no analizó detenidamente su número de pieza.

Como Chris Stratton mencionó, la tabla de vectores será una lista de direcciones, comience con un número de tipo 0x2000x000 y luego números impares, desde un puñado hasta docenas, posiblemente muchos de ellos apuntando al mismo controlador. 0x00000051 0x00000071, 0x00000103, etc. no necesariamente aumentando en valor. la tabla de vectores, etc. están todos en los documentos st y arm en cuanto a lo que hacen.

Creo que el flash del usuario está basado en 0x08000000, por lo que en el código puede haber direcciones basadas en eso. en realidad, la tabla de vectores puede/debe contener vectores en ese espacio

08000000 <_start>:
 8000000:   20001000    andcs   r1, r0, r0
 8000004:   08000041    stmdaeq r0, {r0, r6}
 8000008:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 800000c:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000010:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000014:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000018:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 800001c:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000020:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000024:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000028:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 800002c:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000030:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000034:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 8000038:   08000047    stmdaeq r0, {r0, r1, r2, r6}
 800003c:   08000047    stmdaeq r0, {r0, r1, r2, r6}

a menos que se hayan hecho cargo del gestor de arranque incorporado (si es posible).

mire el pinout del paquete y descubra dónde están los pines swd, y tírelos en el tablero, no me sorprendería si hay algunas almohadillas. ir con una placa nucleo de $ 10 es más barato que un stlink de $ 15, aunque ambos son relativamente baratos, prefiero la ruta nucleo o una placa de descubrimiento y uso el extremo frontal para programar partes en el circuito. bastante fácil de conectar con openocd.

¿Está seguro de que no puede acceder a los pines SWD en el dispositivo? Parece poco probable que el fabricante tenga una parte que no pueda depurar por sí mismo. No es que hayan mostrado ninguna preocupación por proteger su propiedad intelectual hasta la fecha. Compruebe que el gestor de arranque ST tampoco responde. Tal vez el fabricante escribió herramientas personalizadas para interactuar con este gestor de arranque.

Has desmontado el archivo bin, supongo. ¿Viste algo que se parece a una tabla de vectores? A diferencia de los núcleos de clase A que tienen un bloque de direcciones LDR PC,[PC#0x20]repetidas (o algo similar), seguido de una cadena de direcciones, en la clase M, la tabla de vectores siempre es una lista de direcciones con el bit 0 establecido (igual que para cualquier rama a Pulgar). Antes de las direcciones de vector está el valor del puntero de pila inicial. En realidad, cualquier carga relativa de PC debería darte algunas pistas, nuevamente, estas harán referencia a un valor de número impar.

Sí, la MCU solo tiene TCK y TDI disponibles como puntos de prueba y no hay ningún otro conector en la PCB. Gracias por la idea de verificar con el cargador de arranque ST, también lo intentaré. Sí, desarmé el archivo bin y no hay nada que parezca una tabla de vectores, como mencionaste.
SWD solo usa tck y tdi, ¿no es así? Si no tiene una sonda SWD, obtenga una placa de desarrollo de £ 10 que tenga una a bordo.
La razón por la que no vio una tabla vectorial es porque esta publicación describe una incorrectamente. No consta de instrucciones de bifurcación, sino de direcciones absolutas sin procesar. Busque un valor little endian de 16 bits de 0x0800 (es decir, 0x00 0x08) que se intercalará con las compensaciones del firmware dentro de la región flash.
Todas las direcciones de instrucciones en la tabla de vectores tienen el LSB establecido (este es el bit T para el controlador). Disculpe el error, lo arreglaré más tarde.
En realidad, SWD usa TCK como reloj, pero TMS en lugar de TDI para datos bidireccionales. Por supuesto, es posible que el cartel esté mezclando lo que realmente está roto.