He estado trabajando con un STM32F2 (específicamente, el STM32F217IGH6 en una placa de desarrollo) durante aproximadamente dos meses. Con mucho, mi mayor problema tenía que ver con la "configuración", que incluye el archivo MAKE, el script de enlace y el archivo de inicio.
En particular, no he podido configurar correctamente mi tabla de vectores de interrupciones y he llamado a los manejadores de interrupciones. ST proporciona ejemplos adaptados a IDEs comerciales. En cambio, estoy usando la compilación gratuita de Yagarto de la cadena de herramientas GCC (y OpenOCD para cargar la imagen a través de JTAG).
¿Hay proyectos de ejemplo para mi tablero (o un primo cercano) que contengan el archivo MAKE apropiado, la secuencia de comandos del enlazador y la combinación de archivos de inicio para IDE no comerciales que están configurados para que se llamen los manejadores de interrupciones?
Respuestas:
http://github.com/dwelch67
stm32f4 y stm32vld en particular, pero los otros también pueden serle útiles. mbed y el directorio mzero debajo de mbed (cortex-m0).
Me gusta el enfoque estúpido simple, guiones de enlace mínimos, código de inicio mínimo, etc. El trabajo lo realiza el código, no ninguna cadena de herramientas en particular.
La mayoría de las formas de gcc y binutils (capaces de pulgar) funcionarán de alguna manera con estos ejemplos, ya que uso el compilador para compilar no como un recurso para las llamadas a la biblioteca, no uso los scripts del enlazador de acciones, etc. las partes más nuevas del thumb2 por lo que pueden ser necesarios algunos cambios
Construyo mi propio gcc, binutils y llvm / clang, así como también uso el código fuente (por ejemplo, ahora mentores gráficos, pero aún puede obtener la versión gratuita / lite).
Esp al comenzar a armar un proyecto para un nuevo objetivo, necesita hacer un poco de desmontaje. En particular para asegurarse de que los elementos estén donde los desea, por ejemplo, la tabla de vectores.
Mire stm32f4d / blinker02 por ejemplo. Comienza con vectors.s la tabla de excepción / vector más algunas rutinas de soporte de asm:
No hay interrupciones en este ejemplo, pero las otras cosas que necesita están aquí.
blinker02.c contiene el cuerpo principal del código C con el punto de entrada C que llamo notmain () para evitar llamarlo main (algunos compiladores agregan basura a su binario cuando tiene un main ()).
te ahorrará cortar y pegar. El archivo MAKE cuenta la historia sobre compilación y vinculación. Tenga en cuenta que varios de mis ejemplos compilan dos o más archivos binarios del mismo código. compilador gcc, compilador clang de llvm, solo thumb y thumb2, diferentes optimizaciones, etc.
Comience haciendo archivos de objetos a partir de los archivos de origen.
el enlazador, ld, usa un script enlazador que llamo memmap, estos pueden ser extremadamente dolorosos, a veces por una buena razón, a veces no. Prefiero cuanto menos se acerque más a la talla única, todo menos el enfoque del fregadero de la cocina.
Normalmente no uso .data (bueno, casi nunca) y este ejemplo no necesita .bss, así que aquí está el script de enlace, solo lo suficiente para colocar el programa (.text) donde debe estar para este procesador como estoy. usándolo
Tengo una región de memoria para definir eso, no hay nada especial sobre el nombre ram que puede llamar foo o bar o bob o ted, no importa, solo vincula los elementos de memoria a las secciones. Las secciones definen cosas como .text, .data, .bss, .rodata y dónde van en el mapa de memoria.
cuando construyes esto, ves que desmonto todo (objdump -D) ves esto
La clave a tener en cuenta es que la dirección a la izquierda es donde la queríamos, el código vectors.s es el primero en el binario (porque es el primero en la línea de comando ld, a menos que haga algo en el script del enlazador, los elementos mostrarán arriba en el binario en el orden en que están en la línea de comando ld). Para arrancar correctamente, debe asegurarse de que su tabla de vectores esté en el lugar correcto. El primer elemento es mi dirección de pila, eso está bien. El segundo elemento es la dirección para iniciar y debe ser un número impar. el uso de .thumb_func antes de una etiqueta hace que esto suceda, por lo que no tiene que hacer otras cosas feas.
entonces 0x08000051 y 0x08000057 son las entradas de vector apropiadas para _start y hang. iniciar llamadas notmain ()
Eso se ve bien (no muestran la dirección impar en el desmontaje).
Todo está bien.
Pase al ejemplo blinker05, este admite interrupciones. y necesita algo de ram, por lo que se define .bss.
recuerda que ram y rom son nombres arbitrarios, bob y ted, foo y bar funcionan bien.
No se mostrarán los vectores completos porque el cortex-m3 tiene un billón de entradas en la tabla de vectores si realiza uno completo (varía de núcleo a núcleo y tal vez dentro del mismo núcleo dependiendo de las opciones elegidas por el proveedor del chip) Las porciones relevantes están aquí después del desmontaje:
requiere un poco de prueba y error para colocar ese controlador exactamente en el lugar correcto, verifique con su chip dónde debe estar, no necesariamente en el mismo lugar que este, y con tantas interrupciones puede estar buscando una interrupción diferente de todos modos. Los procesadores Cortex-M, a diferencia de los brazos normales, hacen que no NECESITES código de trampolín para las interrupciones, conservan un cierto número de registros y gestionan el cambio de modos de procesador a través del contenido del registro de enlace. siempre y cuando el hardware y el abi para el compilador estén lo suficientemente cerca, todo funciona. En este caso, hice el controlador en C, a diferencia de otras plataformas y el pasado, no necesita hacer nada especial con el compilador / sintaxis, solo haga una función (pero no haga cosas estúpidas en la función / controlador)
El archivo MAKE para blinker05 debe parecerse al ejemplo de blinker02, principalmente cortar y pegar para la mayoría de estos. convertir los archivos de origen individuales en objetos y luego vincularlos. Construyo para thumb, thumb2 usando gcc y clang. puede cambiar la línea all: en ese momento para incluir solo los elementos gcc si no tiene / quiere un sonido metálico (llvm) involucrado. Utilizo binutils para ensamblar y vincular la salida de sonido por cierto.
Todos estos proyectos utilizan herramientas gratuitas, de código abierto, de código abierto. sin IDE, solo línea de comando. Sí, solo me meto con Linux y no con Windows, pero estas herramientas también están disponibles para los usuarios de Windows, cambian cosas como rm -f algo a algo en el archivo MAKE, cosas así al construir en Windows. Eso o ejecutar Linux en vmware o virtualbox o qemu. No usar un IDE significa que también eliges tu editor de texto, no voy a entrar en eso, tengo mis favoritos. Tenga en cuenta que una característica extremadamente molesta del programa gnu make es que requiere pestañas reales en el archivo MAKE, odio las pestañas invisibles con pasión. Entonces, un editor de texto para makefiles que deja pestañas, el otro para el código fuente que crea espacios. No sé sobre ventanas
Espero que esto ayude, no es el chip / placa exacto sino un cortex-m4 y m4 no m3, lo suficientemente cerca para esta discusión. vea el directorio mbed o stm32vld para un cortex-m3 real (no hay suficientes diferencias con respecto al m4 para los archivos MAKE y el código de arranque, etc.), pero no está hecho por st. Los núcleos de cortex-m3 deben ser los mismos en todos los proveedores, el cortex-m3 y el cortex-m4 son ARMv7m y están más cerca que son diferentes. El cortex-m0 es un ARMv6m, apenas tiene instrucciones suficientes para el pulgar2, los compiladores no lo han alcanzado, así que solo use el pulgar (pretenda que está construyendo un ARMv4T (solo el pulgar) si es necesario). Mi simulador de thumbulator es solo thumb, no thumb2, también podría ser útil para usted, creo que lo hice realizar interrupciones de alguna forma o forma.
fuente
Puede echar un vistazo a este sitio donde intenta explicar los conceptos básicos del vinculador y low_level_init en el código.
Tenga en cuenta que la página se centra en describir el problema, por lo que el vector nvic es un poco mínimo.
Luego tiene ejemplos más completos en la "biblioteca de periféricos estándar STM32F2xx", solo mire las secciones de gcc (ya que Yagarto está basado en gcc). Y hay un código de ejemplo que lo ayudará con una configuración correcta de nvic (tabla de vectores de interrupción).
Entonces, incluso si esta no es una respuesta completa, espero que sea de alguna manera útil.
fuente