Desarrollo de Firmware: Introducción

Hola Habr! Les presento la traducción de los artículos de Chris Svec, el original está aquí . Publicado con permiso del autor bajo licencia CC-A-NC-ND .

Ingeniería de software integrada 101: introducción


Estoy lanzando una serie de tutoriales sobre desarrollo de firmware. Comenzaremos describiendo un microcontrolador simple, y después de que comprenda cómo funciona, lo desarrollaremos para comprender cómo funciona con respecto a sistemas complejos como Fitbit o Nest.
Llamé a esta serie Embedded Software Engineering 101, y comienza esta semana aquí mismo en este blog.

Siga leyendo para obtener más explicaciones y detalles.


Algunos bloques de construcción en otros bloques de construcción.

He estado trabajando con sistemas embebidos y desarrollando microchips durante más de 14 años. Me gustan los sistemas integrados: hardware, software y las limitaciones que los unen.
La electrónica y las ideas de aficionados, como Arduino , Adafruit y Sparkfun , permitieron lanzar fácilmente algo de hardware y software durante el fin de semana (o un mes o un semestre), creando algo nuevo, interesante e incluso puede ser útil.

¡Es genial! Darle a la gente la oportunidad de crear es algo increíble; si quisiera expresarme con dureza, lo llamaría aspiracionalmente "tecnología democratizadora".

La mayoría de los proyectos de aficionados son de una sola vez. Recoges algo, lo haces tan bueno como tienes suficiente tiempo o energía, y sigues adelante.
Pasé mi carrera en el extremo opuesto del espectro, creando productos que son cientos de miles o millones o más copias, y esto requiere una forma de pensar completamente diferente y un enfoque sistemático.

Quiero enseñar a la gente cómo escribir firmware para este tipo de sistemas. Durante mucho tiempo he nutrido esta idea para el curso / guía / libro / blog de Embedded Software Engineering 101, y gracias al blog Embedded.fm, estoy comenzando a implementarlo ahora.

Soy una persona de un tipo fundamental, por lo que mi plan es comenzar con lo básico, con una descripción simple de un microprocesador simple, y desarrollar esta base hasta que comprenda cómo funciona un sistema embebido relativamente complejo.

Mi objetivo es que al final de este ciclo puedas descubrir cómo funciona Fitbit, un termostato Nest o un sistema embebido similar. Puede comenzar a trabajar con sistemas de software integrados utilizando la experiencia profesional.

Embedded Software Engineering 101 está diseñado para:

  1. Graduados universitarios en el campo de la informática, ingeniería informática o electrónica, interesados ​​en sistemas embebidos.
  2. Entusiastas aficionados de la electrónica que desean comprender más profundamente cómo funciona su sistema en Arduino y descubrir cómo se mueven (¡y si es necesario!).
  3. , , .
  4. , , -.

¿Qué quiero decir con decir que soy una "persona de tipo fundamental"? Richard Feynman , físico ganador del Premio Nobel y excelente narrador de historias, lo expresó de la mejor manera: "Lo que no puedo recrear, no lo entiendo".

Entonces, no soy Feynman, pero estoy seguro de que la mejor manera de entender el sistema es comenzar con lo básico. Armado con esta comprensión, puede crear sistemas integrados simples con software simple. Y habiendo entendido al principio un programa muy simple, puede desarrollarlo creando un software más complejo a medida que crece la experiencia.

Lo básico en primer lugar: esto es, por supuesto, solo mi convicción personal. Muchas personas hicieron cosas útiles con Arduino sin comprender ninguno de los conceptos básicos. Esta serie de artículos es para aquellos que aún quieren entender los conceptos básicos y todo lo que se basa en ellos.

Por supuesto, debemos preguntarnos: ¿dónde está el nivel correcto para comenzar con estos mismos "conceptos básicos"? Transistores y puertas lógicas? No, esto es demasiado bajo para comenzar con el firmware. ¿Conectar a sensores comunes? No, este es un nivel demasiado alto, se necesita demasiado conocimiento para comenzar con esto.

Creo que el nivel correcto de conceptos básicos es el microprocesador incorporado. No es necesario comprender la física o la electrónica para usar el microprocesador incorporado; tampoco es necesario ser un experto en programación.

Así que aquí es donde comenzaremos en el próximo artículo.

Advertencia de prejuicios: en una vida pasada, fui arquitecto / desarrollador de procesadores. Comenzar este ciclo entendiendo cómo funciona la CPU puede no ser la mejor manera de comprender los sistemas integrados, pero así es como funciona mi cerebro. Asegúrese de probar otros cursos / manuales, etc., si no comprende esto después de varios artículos.

Ingeniería de software integrada 101: conceptos básicos del microcontrolador


Comenzaremos nuestro viaje de Embedded Software Egineering 101 con un microcontrolador modesto. Un microcontrolador (o microprocesador) es el principal componente de todos los sistemas informáticos, integrados y otros.

MK parece bastante complicado, pero consta de tres cosas simples: instrucciones, registros y memoria. Las instrucciones son aquellas cosas que el microcontrolador sabe cómo realizar. Un MK simple puede realizar no tanto, puede tener, por ejemplo, 20 o 30 instrucciones. Más adelante en este ciclo usaré el microcontrolador MSP430 de Texas Instruments, que tiene solo 27 instrucciones.


Solo una foto de MK (TI MSP430F5529)

Estas 27 instrucciones son las únicas cosas que puede hacer el MSP430. Puede sumar dos números, restar otro de un número, mover números de un lugar a otro o realizar otras 24 operaciones simples. Es posible que 27 operaciones no parezcan suficientes para hacer algo útil, pero en realidad serán suficientes para llevar a cabo cualquier programa concebible.

Bueno, eso significa que el microcontrolador tiene instrucciones que hacen algo con los números. ¿Pero dónde están estos números? Registros y memoria! Las instrucciones funcionan con números almacenados en registros y memoria.

Los registros son un repositorio muy rápido que contiene números que funcionan según las instrucciones. Puede pensar en ellos como un bloc de notas utilizado por las instrucciones. MK contiene pocos registros, generalmente 8-32. Por ejemplo, el MSP430 tiene 16 registros.

La memoria también es almacenamiento para números, pero es mucho más grande y más lenta que los registros. El microcontrolador puede tener 64 kB, 256 kB o incluso más de 1 MB de memoria. MSP430F5529 tiene aproximadamente 128 kB de memoria; ¡esto es más de 8,000 veces el número de sus registros!

Antes de comenzar a ver ejemplos, le insto a que obtenga un trozo de papel y un bolígrafo o lápiz y estudie estos ejemplos mientras lee. Es más difícil estudiarlos en papel que simplemente leer lo que escribí. Por lo tanto, se acercará cuidadosamente al proceso y las posibilidades de memorizar lo aprendido serán mayores.

Veamos un ejemplo ficticio pero característico de un microcontrolador.

Digamos que nuestro MK tiene 4 registros y 8 celdas de memoria. Los registros generalmente se llaman creativamente, por ejemplo, "R0", "R1", etc., y haremos lo mismo. Por lo general, las células de memoria son referenciadas por sus números, también llamados direcciones de memoria, comenzando en la numeración 0. Así es como se verán nuestros registros y memoria:



y ahora pondré algunos valores en ellos:



ahora nuestro microcontrolador ficticio necesita algunas instrucciones.
El conjunto de instrucciones que MK conoce se llama conjunto de instrucciones. Digamos que en el conjunto habrá tres instrucciones: AGREGAR (agregar), SUB (abreviatura de "restar" - restar) y MOVER (mover). Las instrucciones deben obtener los números de los que operan en algún lugar y también poner sus resultados en algún lugar, por lo que algunos de ellos contienen información sobre dónde están los datos de entrada y salida.

Por ejemplo, deje que nuestra instrucción ADD tenga dos fuentes y un receptor de datos, y todos deben ser registros. El manual puede describir esta instrucción así:
ADD regist, regPrm
La instrucción ADD agrega el valor del registro reg reg al valor del registro reg reg y almacena el resultado en el registro reg reg
Resumen: regPrm = regIST + regPrm
Ejemplo: ADD R1, R2 realiza la operación R2 = R1 + R2
En general, se acepta en las instrucciones usar una de las fuentes también como receptor, como lo hace la instrucción ADD, usando regPrm como fuente y receptor de datos.

"ADD R1, R2" es un lenguaje ensamblador para un microcontrolador, es un lenguaje de programación nativo MK.

Definamos SUB en el mismo estilo:
Registro SUB, regrpm
La instrucción SUB resta el valor del registro de registro del valor del registro de registro y almacena el resultado en el registro de registro
Resumen: regPrm = regPrm - registro
Ejemplo: SUB R3, R0 realiza la operación R0 = R0 - R3
Finalmente, deje que la instrucción MOVE tenga una fuente y un receptor, y:

  • ambos argumentos son registros, ya sea
  • uno es un registro y uno es una ubicación de memoria.

La guía del conjunto de instrucciones leerá:
1. MOVE registro, registro
2. MOVE registro, reg
3. MOVE registro, rem
La instrucción MOVE copia los datos del argumento Este en el argumento Prm.
Resumen: Hay tres tipos de instrucciones MOVE
1. regPrm = regist
2.regPm = memist
3. memPm = reg
Ejemplo: más adelante en esta publicación mostraré ejemplos de la instrucción MOVE.
Una nota sobre la palabra "mover" utilizada para esta instrucción: la mayoría de los conjuntos de instrucciones la usan, aunque en realidad los datos se copian, no se mueven.

El nombre "mover" puede dar la impresión de que la fuente del operando de la instrucción se destruye o borra, pero de hecho permanece sola, solo se modifica el receptor.
Veamos algunos ejemplos usando nuestro microcontrolador ficticio.
Al principio, nuestros registros y memoria se ven así:



Ahora ejecutamos las siguientes instrucciones en el MK:

ADD R1, R2

Toma el valor de R1, lo agrega al valor de R2 y almacena el resultado en R2. El procesador ejecuta la mayoría de las instrucciones en una sola operación, pero dividiré la ejecución de cada instrucción ADD, SUB y MOVE en varios pasos con la flecha "=>" a través de reemplazos (registro / memoria => valor):

R2 = R1 + R2 =>
R2 = 37 + 100 =>
R2 = 137

Después de ejecutar esta instrucción, la memoria no cambia, pero los registros ahora se ven de la siguiente manera, con el valor modificado escrito en rojo:



Tenga en cuenta que R1 no cambia; solo el registro del receptor R2 ha cambiado.
A continuación, intentemos la declaración SUB:

SUB R3, R0

Ella toma el valor de R3, lo resta del valor de R0 y almacena el resultado en R0:

R0 = R0 - R3 =>
R0 = 42 - 2 =>
R0 = 40

Después de ejecutar esta instrucción, la memoria no cambia, pero los registros ahora se ven así:



Finalmente, intentemos un par de versiones de la instrucción MOVE:

MOVE R2, R0

Esta instrucción MOVE copia el valor de R2 a R0:

R0 = R2 =>
R0 = 137

Y ahora los registros se ven así: a



continuación, copiamos el registro en la memoria:

MOVE R3, [3]

Esta instrucción MOVE copia R3 en la ubicación de memoria 3. Los corchetes en nuestro conjunto de instrucciones son las celdas de memoria.

[3] = R3 =>
[3] = 2

Los registros no cambian, pero la memoria cambia:



y para nuestro último ejemplo, copiamos el valor de la memoria para registrar:

MOVE [6], R0

Aquí, el valor de la celda de memoria 6 se copia en el registro R0:

R0 = [6] =>
R0 = 1

La memoria es inmutable y los registros ahora se ven así: lo



creas o no, pero si entiendes la mayoría de lo que acabamos de discutir sobre instrucciones, registros y memoria, entonces entiendes los conceptos básicos de los microcontroladores y el lenguaje ensamblador.

Por supuesto, he omitido muchos detalles. Por ejemplo, ¿cómo obtiene MK instrucciones para ejecutar?

¿Hay más instrucciones interesantes que simples instrucciones matemáticas y de copia? ¿La memoria es igual a RAM o flash, o no?

Responderemos estas preguntas en el próximo artículo.

All Articles