¿Cómo hacer la transición de los microcontroladores “básicos” a ARM Cortex?

21

Tengo muchos años de experiencia con núcleos de 8 bits de varios fabricantes, concretamente 8051, PIC y AVR, y ahora tengo un Cortex M0 para resolverlo. Específicamente éste , pero espero que podamos ser más generales que eso.

Está resultando ser un poco más de lo que esperaba, con varios documentos que describen diferentes partes del sistema en diferentes niveles de detalle y ninguno que haya visto para conectarlo todo. Esto comparado con tener una hoja de datos que explica todo. Entiendo que tengo muchas más cosas que documentar en primer lugar, pero el cambio de formato me está lanzando para un bucle.

El sitio web anterior tiene un documento que ofrece una buena visión general de cada subsistema y periférico de forma aislada, y otro que describe cada registro en detalle, y tengo todo el código fuente de su SDK, incluidos los archivos de encabezado y algunos ejemplos complejos, pero Todavía no veo nada que describa cómo todo se conecta entre sí.

¿Existe un tutorial conciso de la arquitectura de Cortex que explica la función de las cosas que los controladores más pequeños simplemente no tienen, como varias capas de buses desde la CPU a los periféricos, cada uno con su propio temporizador de vigilancia, y cómo se conectan entre sí? ?

    
pregunta AaronD

6 respuestas

39

He trabajado en AVR y en MCU basadas en ARM Cortex-M3 / M4 / R4. Creo que puedo ofrecer algunos consejos generales. Esto asumirá que estás programando en C, no en ensamblaje.

La CPU es realmente la parte fácil. Los tipos de datos C básicos serán de diferentes tamaños, pero de todos modos estás usando uint8 / 16 / 32_t, ¿verdad? :-) Y ahora todos los tipos de enteros deben ser razonablemente rápidos, con 32 bits (int) siendo los más rápidos. Es probable que no tenga una FPU, así que continúe evitando las flotaciones y los dobles.

Primero, trabaje en su comprensión de la arquitectura a nivel del sistema. Esto significa IOs, temporización, memoria, reinicios e interrupciones. Además, debe acostumbrarse a la idea de los periféricos asignados en memoria. En AVR puede evitar pensar en eso porque los registros tienen nombres únicos con variables globales únicas definidas para ellos. En sistemas más complejos, es común referirse a registros por una dirección base y un desplazamiento. Todo se reduce a la aritmética de punteros. Si no te sientes cómodo con los punteros, comienza a aprender ahora.

Para IOs, descubra cómo se maneja el muxing periférico. ¿Hay un control central de mux para seleccionar qué pines son señales periféricas y cuáles son GPIO? ¿O establece pines en modo periférico utilizando los registros periféricos? Y, por supuesto, deberá saber cómo configurar los GPIO como entradas y salidas, y habilitar el modo de drenaje abierto y las funciones de pull-ups / downs. Las interrupciones externas usualmente caen en esta categoría también. Los GPIO son bastante genéricos, por lo que su experiencia debería servirle bien aquí.

La sincronización se reduce a algunas cosas. Comienzas con una fuente de reloj, típicamente un cristal o un oscilador RC interno. Esto se utiliza para crear uno o más dominios de reloj de nivel de sistema. Los chips de mayor velocidad utilizarán un PLL, que se puede considerar como un multiplicador de frecuencia. También habrá divisores de reloj en varios puntos. Los puntos clave a considerar son la frecuencia de reloj de su CPU y las velocidades de bits que necesita para sus periféricos de comunicación. Por lo general, esto es bastante flexible. Cuando te vuelves más avanzado, puedes aprender cosas como los modos de bajo consumo, que generalmente se basan en la sincronización del reloj.

Memoria significa flash y RAM. Si tiene suficiente RAM, a menudo es más rápido mantener su programa allí durante el desarrollo temprano para que no tenga que programar el flash una y otra vez. El gran problema aquí es la gestión de la memoria. Su proveedor debe proporcionar secuencias de comandos de vinculador de ejemplo, pero es posible que deba asignar más memoria a código, constantes, variables globales o la pila según la naturaleza de su programa. Los temas más avanzados incluyen la seguridad del código y la programación flash en tiempo de ejecución.

Los reinicios son bastante sencillos. Por lo general, solo debe mirar hacia fuera el temporizador de vigilancia, que puede estar habilitado de forma predeterminada. Los reinicios son más importantes durante la depuración cuando ejecutas el mismo código una y otra vez. Es fácil pasar por alto un error debido a problemas de secuencia de esa manera.

Hay dos cosas que debe saber acerca de las interrupciones: cómo las habilita y deshabilita, y cómo configura los vectores de interrupción. AVR-GCC hace esto último por usted con las macros ISR (), pero en otras arquitecturas puede que tenga que escribir una dirección de función en un registro manualmente.

Los periféricos del microcontrolador suelen ser independientes entre sí, por lo que puede aprenderlos uno por uno. Podría ayudar elegir un periférico y usarlo para aprender parte de las cosas a nivel del sistema. Los periféricos y PWM de Comm son buenos para la temporización y los IO, y los temporizadores son buenos para las interrupciones.

No te dejes intimidar por el nivel de complejidad. Esos microcontroladores "básicos" ya te han enseñado mucho de lo que necesitas saber. Por favor, avíseme si necesita que aclare algo.

    
respondido por el Adam Haun
8

Es útil recordar que ARM posee la propiedad intelectual del microprocesador, pero en realidad no hace partes. En su lugar, los fabricantes obtienen licencias para las distintas versiones de procesadores ARM y producen sus propias piezas únicas con combinaciones individuales de funciones y periféricos.

Dicho esto, si eres nuevo en la arquitectura, probablemente tenga sentido comenzar con la documentación de ARM, que es, esencialmente, la documentación de referencia para todos estos microprocesadores.

Por ejemplo, el Cortex-M0 se describe en el sitio web de ARM .

También hay una lista de libros relacionados con ARM que se adaptan a una amplia variedad de necesidades e intereses.

Finalmente, están las hojas de datos del fabricante específico. Para M0, Cypress, NXP y STMicroelectronics son solo tres de los muchos fabricantes de piezas reales basadas en el Cortex-M0.

(Y no, no trabajo para ARM y nunca lo he hecho).

    
respondido por el Edward
8

Una gran diferencia es el uso de bibliotecas suministradas por el proveedor. Para los PIC, Atmels, etc., las bibliotecas básicas (para gpio, temporizadores, adc, etc.) no fueron utilizadas mucho por la mayoría de los desarrolladores. En mi experiencia, la gente los usaría (a lo sumo) como guías al escribir su propio código.

Sin embargo, con ARM, las bibliotecas casi siempre se usan. Hay una norma, "CMSIS", que los fabricantes recomiendan seguir. Debe hacerse. Ayuda en la portabilidad del código (entre diferentes ARM y entre fabricantes) y proporciona un método "estandarizado" para estructurar su código. La gente se acostumbra a ver y comprender las funciones de la biblioteca.

Seguro que hay algunos desarrolladores que acceden directamente a los registros, pero son los valores atípicos :)

Para responder a su pregunta, me resultó muy útil leer la documentación de la Biblioteca. ST tiene un código bien desarrollado, con un gran archivo de ayuda creado por Doxygen. Puede ver cuáles son todas las opciones para cada módulo de hardware.

Para usar GPIO como ejemplo, la función de inicialización se maneja:

  • Dirección (entrada o salida)
  • pullups / pulldowns
  • colector abierto / push-pull
  • velocidad de desplazamiento
  • etc.

Al mirar las opciones, puedes ver lo que es posible. Y, por supuesto, ¡aprenderá cómo pasar estas opciones a la función Init!

Bien, ahora que lo he dicho, veo que su ARM específica no tiene bibliotecas compatibles con CMSIS. En su lugar, tienen su SDK propietario disponible para descargar. Empezaría a buscar en sus documentos del SDK.

Si no está casado con este producto específico, es posible que le recomiende que busque un proveedor diferente con bibliotecas más compatibles. De todos modos, va a escalar una curva de aprendizaje, por lo que también podría hacer que su inversión sea más portátil ...

¡Las ARM son divertidas! No he mirado atrás.

    
respondido por el bitsmack
5

Buen momento para estar en movimiento; los 8 bits están muriendo rápidamente; cuando puede comprar una tarjeta de $ 5 con (por ejemplo) un STM32F103 que es un microcontrolador ARM de 32 bits bastante capaz (incluso con USB), no hay duda de que los tiempos han cambiado.

Ya ha recibido algunas respuestas excelentes, pero principalmente diría "olvídese del ensamblaje" y casi "olvide preocuparse por cómo funciona la CPU en un nivel bajo". Un día habrá un caso de esquina en el que necesita profundice en él (una optimización específica o para la depuración) pero los núcleos ARM ejecutan el código C excepcionalmente bien (por diseño) y rara vez es necesario aventurarse dentro de las entrañas.

Esto significa que pasará una cierta cantidad de tiempo golpeando su cabeza contra problemas con los compiladores (y especialmente con los enlazadores y los makefiles) que le arrojan errores oscuros, pero todos son superables.

Las agallas de cómo funcionan las ARM (es decir, los libros de CPU de ARM) son densas y no muy interesantes hasta el día en que realmente necesita optimizarlas (y se sorprenderá de la poca frecuencia con la que tenga registros de 32 bits). su reloj de CPU PLL'd está en la región de 100 mhz).

El conjunto de instrucciones ARM "skool antiguo" es mucho más fácil de leer y desensamblar que el "Thumb2" mucho más nuevo, que es lo que se encuentra en la mayoría de las ARM a nivel de microcontrolador (Cortex), pero de nuevo las entrañas del ensamblaje -las instrucciones de lenguaje en su mayoría se desvanecen en el fondo; si tiene el conjunto de herramientas adecuado (especialmente un depurador de nivel de fuente decente con puntos de interrupción / paso único, etc.) simplemente no le importa que sea ARM.

Una vez que esté en el mundo de los registros de 32 bits y los anchos de bus de datos de 32 bits y todo lo que siempre quiso tener disponible en el chip, nunca más querrá volver a una CPU de 8 bits; Básicamente, a menudo no hay penalización por "tomárselo con calma" y escribir un código para que sea legible más que eficiente.

Sin embargo ... periféricos ... sí, y ahí está el problema.

Seguro que obtienes un montón de cosas para jugar en las MCU modernas, y muchas de ellas son cosas bastante extravagantes; a menudo encuentra un mundo de sofisticación mucho más allá de los periféricos en chip AVR, PIC y 8051.

¿Un temporizador programable? ¡No, ten ocho! DMA? ¿Qué tal 12 canales con prioridad programable y modo de ráfaga y modo encadenado y auto-recarga y .. y .. y ...

I2C? I2S? ¿Docenas de opciones de muxing pin? ¿Quince formas diferentes de reprogramar el flash en chip? ¡Claro!

A menudo se siente como si hubieras pasado del hambre al banquete con los periféricos y es común que hay fragmentos enteros de un chip que admirarás pero que apenas usarás (por lo tanto, la sincronización del reloj).

La cantidad de hardware en el chip (y las variaciones en eso en la línea de chips de un solo proveedor) hoy en día es bastante alucinante. Un proveedor de chips, por supuesto, tenderá a reutilizar los bloques de IP, por lo que una vez que te familiarices con una determinada marca, se vuelve más fácil, pero "la mierda ya se hizo realidad hoy en día".

En todo caso, los periféricos y sus interacciones (y DMA y las interrupciones y la asignación de bus y y y ...) son TAN complejos (y, en ocasiones, no exactamente como se describe en las hojas de datos) que los ingenieros con frecuencia tienen una gama favorita de MCU ARM y tienden a querer quedarse con ella simplemente porque están familiarizados con los periféricos y las herramientas de desarrollo.

Buenas bibliotecas y herramientas de desarrollo (es decir, compilación rápida + ciclo de depuración con un depurador adecuado) y un gran conjunto de proyectos de código de ejemplo en funcionamiento son absolutamente cruciales para su elección de ARM MCU en la actualidad. Parece que la mayoría de los vendedores ahora tienen tableros de evaluación extremadamente baratos (

Como estoy seguro de que lo ha notado, una vez que haya superado el nivel del microcontrolador con ARM y al nivel SOC (por ejemplo, SOC de estilo Raspberry Pi / etc), las reglas cambian por completo y se trata de qué tipo de Linux vamos a correr porque, con unas pocas excepciones, estarías ladrando para intentar cualquier otra cosa.

Básicamente; independientemente de la CPU que (puede) haber sido preseleccionada para usted en este concierto, compre un puñado de tableros de evaluación súper baratos basados en Cortex de diferentes proveedores (TI, STM, Freescale y más vienen a la mente) y tener un hack alrededor con el código de ejemplo proporcionado.

Consejo final; Una vez que encuentre la página o la página tres en la hoja de datos que describe las opciones de combinación de pines para el chip de número de parte exacto con el que está trabajando, es posible que desee imprimirlo y pegarlo en la pared. Descubrir al final de un proyecto que una combinación determinada de periféricos es imposible debido a la manipulación de pines no es divertido, y a veces esa información está tan oculta que juraría que están tratando de ocultarla :-)

    
respondido por el Richard Aplin
3

No he trabajado mucho en 8051, AVR o PIC. Pero recientemente comencé a buscar en la línea de procesadores ARM Cortex MX. Por lo tanto, no puedo decirle mucho sobre la transición de 8051, AVR o PIC, pero sobre todo desde el punto de vista de un principiante.

El procesador ARM®Cortex ™ -M4 se basa en la arquitectura de Harvard, por lo que tiene buses de datos e instrucciones separados. A continuación se muestra una imagen de alto nivel.

EstasemanalosrepresentantesdeNXPvisitaránnuestrasinstalaciones.ConsultaréconellossihayrecursosdeNXPARM-CortexMxylospublicaréaquí.Freescaletiene Microcontrolador (MCU) de 32 bits de bajo consumo de Kinetis basado en ARM® Cortex®-M Cores , entiendo que también tienen guías similares para aprender procesadores ARM. Lamentablemente no los he investigado.

Referencias:

respondido por el Mahendra Gunawardena
3

También vengo de AVR y ahora usualmente me quedo con STM32 (Cortex-M). Esto es lo que recomiendo para empezar, y refleja mis propias dificultades cuando comencé:

  1. Obtenga una placa con un depurador, o al menos un conector JTAG (y luego compre un depurador JTAG). Hay muchos baratos y ahorrará mucho tiempo al usarlo.

  2. Consigue un buen IDE con todo incluido. Solía recomendar el CooCox CoIDE hace mucho tiempo. Desde entonces, ha detenido y reiniciado el desarrollo, así que no estoy seguro de cómo es ahora. "Un buen IDE" le permite hacer que el LED básico de Hello World parpadee rápidamente.

  3. "Un buen IDE" debe configurar los encabezados CMSIS del fabricante. Básicamente, se trata de los mapas de registro que permiten la escritura más fácil de los programas C / C ++, con nombres de variables en lugar de números simples y punteros.

  4. Intente usar las bibliotecas periféricas del fabricante, si no necesita el mejor rendimiento absoluto. En realidad no lo haces por ahora, ya que estás aprendiendo. Si luego descubre que necesita apretar más, mire el código de la biblioteca para ver cómo hace qué. Lo bueno de las bibliotecas es que, por lo general, le permiten usar muchos chips diferentes del mismo fabricante con el mismo código.

  5. A diferencia del AVR, los chips ARM comienzan con los periféricos desactivados. Necesitas habilitarlos primero. Una buena biblioteca de periféricos tendrá ejemplos sobre cómo usar los periféricos correctamente, y puede obtener más información de la hoja de datos del dispositivo. Por lo tanto, recuerde habilitar los relojes y periféricos antes de usarlos. Sí, incluso los puertos de E / S se consideran periféricos.

  6. Codifica a medida que aprendes. No intente asimilar todo de una vez, ya que es bastante complejo. Comenzaría por aprender el árbol del reloj (APB, AHB, etc. autobuses) y cómo interactúan los relojes y los divisores del reloj. Luego, buscaría en el IDE que almacena los scripts del enlazador y el código de inicio para su dispositivo. El script del enlazador es bastante parecido a cómo se organiza la memoria (donde se encuentra la memoria RAM, flash, tabla de vectores ISR, etc.). El script de inicio configura su programa (cosas como copiar inicializadores de variables globales de flash a RAM). Algunos IDE tienen scripts de inicio en ASM y otros en C. A veces puedes buscar otro en Google, en el idioma que prefieras.

  7. Haz que el depurador vaya lo antes posible. Es muy común cometer un error al principio, al hacer algunas cosas (normalmente la inicialización del hardware) en un orden diferente al que debería. Esto a veces activa una excepción de ISR que lo pone en while(1); infinite loop (implementación predeterminada para ese ISR) que detiene su programa y es difícil rastrearlo incluso con un depurador. Imagínese sin un depurador.

  8. Hablando de un depurador, intente poner en marcha el UART también, luego use un adaptador USB serie para leerlo. La eliminación de printf() siempre es útil :-)

respondido por el Ronan Paixão

Lea otras preguntas en las etiquetas