Programación de microcontroladores modernos: clase 1

Resumen de la primera conferencia sobre programación de microcontroladores modernos utilizando el ejemplo de STM32 y el sistema operativo RIOT. Las conferencias se imparten en el Instituto de Tecnología de la Información MIREA los sábados, desde las 12:50 en el auditorio en el 4to piso del Edificio D. Las clases dan 1.5 horas a la conferencia en sí y 3 horas a clases prácticas en el laboratorio de IoT de la Academia Samsung sobre el tema de la conferencia.

Hola giktayms Como prometimos, estamos comenzando a publicar notas de conferencias que se entregan en el Instituto de TI MIREA. Según los resultados de la primera clase introductoria, decidimos cambiar ligeramente la estructura del curso; en lugar de las dos secuencias planificadas de 5 lecciones, habrá una secuencia para 7 lecciones. Esto permitirá resolver una serie de preguntas de apoyo a un ritmo más relajado, así como artículos abstractos aparecerán en el GT todas las semanas durante marzo y abril, y no en una semana, como se planificó previamente.

Sin embargo, es imposible cubrir por completo un tema tan extenso en siete conferencias, por lo que la presentación será una tesis en algunos lugares, aunque para compensar esto, trataremos de indicar en qué dirección mirarán aquellos que quieran examinar más a fondo este o aquel tema.

El curso está diseñado para estudiantes de segundo y tercer año que están familiarizados con el lenguaje C y los conceptos básicos de electrónica e ingeniería eléctrica. No se requiere conocimiento previo de microcontroladores.

El objetivo del curso es el desarrollo de habilidades que le permitan trabajar libremente con microcontroladores en el núcleo ARM Cortex-M a nivel moderno y, si existe tal deseo, avanzar para profundizar aún más sus conocimientos.



La conferencia de hoy es la primera, por lo que comprenderá conceptos generales: qué es un microcontrolador en general y por qué se necesita, qué es el firmware y cómo se obtiene, por qué necesitamos un sistema operativo y, finalmente, cómo trabajar con git. El resultado de esta lección es su propio repositorio de GitHub con códigos fuente del sistema operativo, así como un entorno de compilación configurado con éxito en la computadora local.

Microcontrolador


En resumen, el microcontrolador es un ejemplo clásico de un "sistema en un chip", que incluye tanto el núcleo del procesador como un conjunto de dispositivos auxiliares y periféricos, lo que permite que el microcontrolador en muchos casos sea completamente autosuficiente.



En un microprocesador típico, similar al de cualquier PC o teléfono inteligente, casi todos los módulos que pueden atribuirse a los auxiliares (alimentación, sincronización, incluso dispositivos periféricos básicos) se mueven fuera del chip, a pesar de que el microprocesador funciona sin ellos. no puedo

En el microcontrolador, por el contrario, en el mismo chip con el núcleo, no solo se implementan los subsistemas necesarios para su funcionamiento, sino también la masa de dispositivos periféricos que pueden requerirse en diversas tareas prácticas. Además, muchos fabricantes de microcontroladores compiten entre sí no en el rendimiento central o la capacidad de memoria, sino en la abundancia y las funciones de los dispositivos periféricos.

Los microcontroladores se han desarrollado en paralelo con los microprocesadores durante bastante tiempo; por ejemplo, la arquitectura Intel 8051 que todavía se encuentra en productos industriales se desarrolló en 1980. En algunos puntos, las líneas de su desarrollo comienzan a cruzarse con los microprocesadores; por ejemplo, los modelos más antiguos de microcontroladores tienen interfaces para RAM externa, y los fabricantes de microprocesadores integran más y más dispositivos periféricos en el chip (es suficiente recordar que en los albores de las "computadoras personales" se marcó incluso el caché externo microcircuitos), pero en cualquier caso, siguen siendo dos ramas de desarrollo significativamente diferentes.

En realidad, el objetivo de crear microcontroladores era reducir el costo y la miniaturización de varios dispositivos que requieren una pequeña potencia informática: el uso de un solo chip, para el que es fácil suministrar energía para su funcionamiento, simplifica enormemente el diseño y la fabricación de una placa de circuito impreso en comparación con un conjunto de 4-5 chips separados .

Por supuesto, el microcontrolador tiene sus propias limitaciones: es técnicamente imposible empacar en un chip lo que en una PC grande ocupa la mitad de una placa bastante grande.

  • Las frecuencias de funcionamiento rara vez superan los 200 MHz, y con mayor frecuencia se encuentran en la región de decenas de megahercios.
  • La cantidad de RAM está dentro de megabytes, y más a menudo en la región de decenas de kilobytes.
  • La cantidad de memoria del programa está dentro de megabytes, y más a menudo en el área de decenas a cientos de kilobytes.

Como parte del curso, trabajaremos con microcontroladores STM32L151CC que tienen 32 KB de RAM, 256 KB de ROM y una frecuencia operativa máxima de 32 MHz (hay chips un poco más serios en las placas Nucleo-L152RE: 80 KB de RAM y 512 KB de ROM).

El recuerdo


En general, puede haber cuatro tipos de memoria dentro de un microcontrolador:

  1. La memoria permanente ( memoria flash) se utiliza para almacenar programas de usuario y, a veces, algunas configuraciones del microcontrolador. Si, al especificar las características del microcontrolador, escriben la cantidad de memoria sin especificar cuál, por regla general, se trata de flash. El contenido del flash no se restablece cuando falla la alimentación, el período de almacenamiento de la información en condiciones normales suele ser de al menos 10 años.
  2. RAM se utiliza para ejecutar un programa de usuario y almacenar datos "momentáneos". La RAM siempre se restablece cuando reinicia o apaga, y también puede no guardarse cuando ingresa a algunos modos de suspensión. En los microcontroladores, a menudo no existe una separación clara entre la memoria del programa y la memoria de datos; como resultado, se puede encontrar el término "ejecución desde RAM", lo que significa que en la RAM no solo hay datos, sino también el programa en sí; Sin embargo, estos son casos bastante exóticos.
  3. EEPROM . También se refiere a la memoria de solo lectura, pero difiere significativamente de la memoria flash en sus características. El flash tiene dos grandes inconvenientes que hacen que sea muy incómodo guardar algunos datos actuales del programa: en primer lugar, el flash tiene un número limitado de sobrescrituras de la misma celda y, en segundo lugar, a menudo es posible trabajar con el flash solo en páginas enteras, que son cientos de bytes de tamaño, incluso si necesita sobrescribir solo un byte. La EEPROM no tiene estos inconvenientes: su vida útil suele ser diez veces más larga (de 100 mil a 1 millón de sobrescrituras) y es posible trabajar en ella con cada byte individualmente. Por esta razón, EEPROM se utiliza para el almacenamiento permanente de datos generados por el propio programa (archivos de medición, configuraciones del programa, etc.), su volumen típico es unidades de kilobytes, pero no está en todos los controladores.
  4. Memoria del sistema Áreas de memoria de solo lectura, inaccesibles para el usuario para la grabación, pero registradas en la producción del microcontrolador. Por lo general, contienen el código ejecutable del gestor de arranque (más abajo), pero también se pueden almacenar algunas constantes de calibración, números de serie o incluso bibliotecas auxiliares para trabajar con dispositivos periféricos.

Puede ver la organización de la memoria de un controlador específico en su hoja de datos. Aquí, por ejemplo, hay una hoja de datos sobre el STM32L151CC , en la página 51 de la cual se presenta una tarjeta de memoria de esta familia.

Es fácil notar que los cuatro tipos de memoria, de los que hablamos, ocupan una parte muy pequeña de la tarjeta, y en la mayoría de las imágenes hay una lista de todos los dispositivos periféricos disponibles en el controlador.

Registros


El hecho es que todo, en general todo, la comunicación con todos los dispositivos periféricos del microcontrolador y todos sus ajustes se llevan a cabo utilizando solo dos operaciones:

  • lee el valor en la dirección dada
  • escribe el valor en la dirección dada

Todo lo que está dentro del microcontrolador está necesariamente asignado a alguna dirección. Estas direcciones se denominan registros (no confunda con los registros del procesador: los registros de los procesadores contienen datos en los que el procesador realiza operaciones; los registros de los que estamos hablando contienen algunos datos especiales que se asignan específicamente al estado de varias unidades de hardware del microcontrolador).

Entonces, por ejemplo, si queremos que aparezca "1" en el tercer tramo del Puerto A del microcontrolador (PA2, la numeración es desde cero), debemos escribir "1" en el tercer bit del registro ubicado en 0x4002014. Y si este tramo está configurado como una entrada y, por el contrario, queremos saber qué valor tiene, debemos leer el tercer bit del registro en la dirección 0x40020010.

Sí, para indicarle al controlador que este tramo es la entrada o la salida; debe escribir los valores correspondientes en los bits correspondientes en la dirección 0x40020000.

Este es un punto importante para comprender el funcionamiento del microcontrolador: absolutamente todo lo que no son operaciones computacionales, de las cuales es responsable el núcleo del procesador, se realiza escribiendo o leyendo este o aquel registro. Cualesquiera que sean las bibliotecas engañadas en su programa desde arriba, al final, todo se reduce a registros.

Por supuesto, trabajar con direcciones numéricas es bastante incómodo, por lo tanto, para cada microcontrolador en el núcleo Cortex-M hay una biblioteca CMSIS (Cortex Microcontroller Software Interface Standard), cuyo componente más importante para nosotros es el archivo de encabezado que describe los registros disponibles en un controlador en particular y les da una lectura relativamente humana nombres

Con CMSIS, las operaciones descritas anteriormente con el pie PA se verán así:

int pin_num = 2; /* PA2*/
GPIOA->MODER &= ~(0b11 << (pin_num*2)); /*     PA2    */
GPIOA->MODER |= 0b01 << (pin_num*2); /*     PA2  01 —  */
GPIOA->ODR |= 1 << pin_num; /*   PA2  1 */

GPIOA->MODER &= ~(0b11 << (pin_num*2)); /*     PA2,    */
uint32_t pa2_value = GPIOA->IDR & (1 << pin_num); /*    PA2 */

, — Reference Manual (, , , RM0038, STM32L1). , 900 RM0038 —  , 1500-2000 . -, , —  .

, — . , , «» .

, , — , - ( 1 , , , 1 , , ), .

STM32 Standard Peripherals Library, StdPeriphLib, SPL. , ST LL, — , LibOpenCM3. , STM32 .

, SPL , , , GPIO_Init GPIO_Write.

, , SPL — .

, SPL «» , , STM32 CubeMX. (, , ) STM32.

, , « , - » — « , ». SPL, , , , SPL , —  SPL , . , .

, , , - , , , STM32L1 ATSAMD21 , SPL, .

SPL — , , , SPL.

, SPL —  «» . , :

  • . , (RTC), — - , ( ) (, ), . -, .
  • . , . Arduino loop() , . loop() , , . ( , ).
  • . , , — , : -, , , . - —  , , , , . , API.

—  —  .

, ( 5-20 ), , 70 % .



, , SPL. RIOT OS, STM32 —  SPL .

: , , , , SPL . , SPL , , STM32, , .


, :



  • — , ;
  • — , , : , , ;
  • —  .

, RIOT OS - (IDE) — , , IDE, (, , Arduino IDE —  ; , , ).

, , , , « , , ».

, , Arduino IDE, IDE, — .



, RIOT OS , : HAL cpu ( , , AVR PIC32), — boards, — drivers, — core, — sys, — examples.

, — , ( ) , , , , . — , , .


https://github.com/unwireddevices/RIOT/tree/mirea — RIOT OS, Unwired Devices STM32L1, , , , .

Github, «Clone/Download» «Download ZIP», . GitHub, «Fork» — , .

GitHub Git —  , .


, , - , «Hello world» :

#include <stdio.h>
int main(void)
{
    puts("Hello World!");
    printf("You are running RIOT on a(n) %s board.\n", RIOT_BOARD);
    printf("This board features a(n) %s MCU.\n", RIOT_MCU);
    return 0;
}

example/hello-world main.c ( ).

, , , . - .

1. Windows 8 . , MinGW, . . , Git/GitHub Git for Windows, MinGW. MinGW, MinGW .

, Windows 7 Windows 8, , .

2. Windows 10. Microsoft Store, Ubuntu . Ubuntu Windows, « Windows», « Windows Linux» .

Ubuntu, , MinGW.

(: 64- Linux!), Ubuntu, :

cd /opt
sudo tar xf /mnt/c/Users/vasya/Downloads/gcc-arm-none-eabi-7-2017-q4-major-linux.tar.bz2
export PATH=/opt/gcc-arm-none-eabi-7-2017-q4-major/bin/:$PATH
export PATH=/opt/gcc-arm-none-eabi-7-2017-q4-major/arm-none-eabi/bin/:$PATH
echo "export PATH=/opt/gcc-arm-none-eabi-7-2017-q4-major/bin/:\$PATH" >> ~/.bashrc
echo "export PATH=/opt/gcc-arm-none-eabi-7-2017-q4-major/arm-none-eabi/bin/:\$PATH" >> ~/.bashrc

.bashrc, Ubuntu. $ >> —  , ( ) .bashrc.

arm-none-eabi-gcc --version , , — 7.2.1 ( ).

Git ssh-keygen, ( Ubuntu Windows cat ~/.ssh/id_rsa.pub, Enter — ) GitHub. GitHub git.

NB: Linux, : , Tab ( cd /opt/gcc- cd /opt/gcc-arm-none-eabi-7-2017-q4-major). , — , . , Tab .

NB: Windows , , Windows, Documents/git/RIOT. - MinGW /c/Users/vasya/Documents/git/RIOT, - Ubuntu — /mnt/c/Users/vasya/Documents/git/RIOT. , , , Windows, Notepad++.

3. Linux. Windows 10, , Microsoft Store . gcc-arm-none-eabi — .

, RIOT examples/hello-world, make.

, , unzip ( Windows 10 ), make . Windows 10 ( ):

sudo apt-get install unzip make

make — , «make clean && make»: , . , - , —  , .

NB: RIOT hello-world native, , , x86. unwd-range-l1-r3, stm32,

Building application "mirea" for "unwd-range-l1-r3" with MCU "stm32l1".

- , make — . mirea.elf ( - ).

- :



, , , , , .

, GPIO, — , , — , .

P.S. — 360- ( : « » , , - ):



Source: https://habr.com/ru/post/es411143/


All Articles