Este es el código complementario del libro CM Kormanyos, C++ en tiempo real: programación eficiente de microcontroladores de plantilla y orientada a objetos, cuarta edición (Springer, Heidelberg, 2021) ISBN 9783662629956.
Este repositorio tiene varias partes principales.
ref_app
ubicada en ref_app. Esto también incluye los puntos de referencia. Los compiladores cruzados GNU/GCC y varias herramientas adicionales que se ejecutan en Win*
, opcionalmente necesarias para ciertas compilaciones como se describe a continuación, se pueden encontrar en el repositorio relacionado ckormanyos/real-time-cpp-toolchains.
La aplicación de referencia arranca con un pequeño código de inicio y posteriormente inicializa una delgada capa de abstracción de microcontrolador (MCAL). Luego, el control se pasa a un programador multitarea simple que administra la aplicación LED, llama a una tarea de referencia cíclica y da servicio al organismo de vigilancia.
La aplicación LED alterna un LED de usuario con una frecuencia de
La aplicación de referencia es compatible con C++ 14, 17, 20, 23 y posteriores.
El software de la aplicación se implementa una vez y se usa de manera uniforme en cada objetivo admitido en ref_app. Las diferencias entre los objetivos individuales surgen solo en las capas inferiores de software relacionadas con los detalles de inicio/MCAL específicos del chip y de la placa.
De esta manera, el proyecto exhibe un alto nivel de portabilidad.
La aplicación de referencia admite los siguientes objetivos:
Nombre del objetivo (como se usa en el comando de compilación) | Descripción del objetivo | *(tablero de circuitos) |
---|---|---|
avr | MICROCHIP(R) [antiguo ATMEL(R)] AVR(R) ATmega328P | incógnita |
atmega2560 | MICROCHIP(R) [antiguo ATMEL(R)] AVR(R) ATmega2560 | |
atmega4809 | MICROCHIP(R) [antiguo ATMEL(R)] AVR(R) ATmegax4809 | incógnita |
am335x | BeagleBone con Texas Instruments(R) AM335x ARM(R) A8 | |
bcm2835_raspi_b | RaspberryPi(R) Zero con ARM1176-JZFS(TM) | |
Debug / Release | PC en Win* a través del compilador MSVC x64 Debug / Release | |
host | PC/estación de trabajo en Win* / mingw64 / *nix a través del compilador host | |
lpc11c24 | Placa NXP(R) OM13093 LPC11C24 ARM(R) Cortex(R)-M0+ | |
nxp_imxrt1062 | Placa Teensy 4.0 / NXP(R) iMXRT1062 ARM(R) Cortex(R)-M7 | incógnita |
riscvfe310 | SoC SiFive RISC-V FE310 | |
rl78 | Renesas(R) RL78/G13 | |
rpi_pico_rp2040 | RaspberryPi(R) Pico RP2040 con doble ARM(R) Cortex(R)-M0+ | incógnita |
rpi_pico2_rp2350 | RaspberryPi(R) Pico2 RP2350 con doble ARM(R) Cortex(R)-M33 | incógnita |
rx63n | Renesas(R) RX630/RX631 | |
stm32f100 | STMicroelectronics(R) STM32F100 ARM(R) Cortex(R)-M3 | incógnita |
stm32f407 | STMicroelectronics(R) STM32F407 ARM(R) Cortex(R)-M4F | |
stm32f429 | STMicroelectronics(R) STM32F429 ARM(R) Cortex(R)-M4F | |
stm32f446 | STMicroelectronics(R) STM32F446 ARM(R) Cortex(R)-M4F | |
stm32h7a3 | STMicroelectronics(R) STM32H7A3 ARM(R) Cortex(R)-M7 | |
stm32l100c | STMicroelectronics(R) STM32L100 ARM(R) Cortex(R)-M3 | incógnita |
stm32l152 | STMicroelectronics(R) STM32L152 ARM(R) Cortex(R)-M3 | |
stm32l432 | STMicroelectronics(R) STM32L432 ARM(R) Cortex(R)-M4F | incógnita |
v850es_fx2 | Renesas(R) Electrónica V850es/Fx2 actualización703231 | |
wch_ch32v307 | Placa WCH CH32v307 RISC-V | |
wch_ch32v307_llvm | Placa WCH CH32v307 RISC-V (pero usando una cadena de herramientas LLVM) | |
x86_64-w64-mingw32 | PC en Win* / mingw64 mediante el compilador GNU/GCC x86_x64 | |
xtensa32 | Espressif (XTENSA) NodeMCU ESP32 | incógnita |
En esta tabla, *(placa de pruebas) significa que la placa (o ciertas versiones de ella) se puede utilizar fácilmente con una placa de pruebas común. Es posible que esto requiera una soldadura/montaje manual muy sencillo de los pines del cabezal.
Es más fácil comenzar con la aplicación de referencia utilizando una de las placas compatibles, como avr
(ARDUINO) o bcm2835_raspi_b
(RaspberryPi ZERO) o am335x
(BeagleBoneBlack), etc. La aplicación de referencia se puede encontrar en el directorio ref_app y sus subdirectorios. .
La aplicación de referencia utiliza desarrollo cruzado y sistemas de compilación compatibles con:
*nix
make herramientas en combinación con Bash/GNUmake (script bash) en LINUX/MacOS,*nix
-like make tools en Win*
en combinación con secuencias de comandos por lotes o Microsoft(R) Visual Studio(R) a través de un Makefile externo ,Win*
, Una vez completada con éxito la compilación, los artefactos resultantes, incluidos archivos HEX (como ref_app.hex
), archivos de mapas, informes de tamaño, etc., están disponibles en el directorio bin
.
Para comenzar con la aplicación de referencia en *nix
target avr
) le gustaría crear.build.sh
con el comando: ./target/build/build.sh avr rebuild
.avr rebuild
que posteriormente reconstruye toda la solución para target avr
.*nix
, ejecute sudo apt install gcc-avr avr-libc
.*nix
para target avr
Ahora ejemplificaremos cómo construir la aplicación de referencia en un shell de comandos en *nix
para target avr
. Este sistema de destino incluye esencialmente cualquier placa compatible con ARDUINO(R). Esta es también la compatibilidad de placas realmente utilizada con las placas caseras del libro.
Instale gcc-avr
si es necesario.
sudo apt install gcc-avr avr-libc
Clona u obtén el repositorio ckormanyos/real-time-cpp. Luego construye con:
cd real-time-cpp
cd ref_app
./target/build/build.sh avr rebuild
*nix
para target stm32f446
Ahora ejemplificaremos cómo construir la aplicación de referencia en un shell de comandos en *nix
para un objetivo ARM(R). Considere, por ejemplo, la variante de compilación target stm32f446
. Para ello se puede utilizar cómodamente la placa NUCLEO-F446RE de STMicroelectronics(R).
Instale gcc-arm-none-eabi
si es necesario.
sudo apt install gcc-arm-none-eabi
Clona u obtén el repositorio ckormanyos/real-time-cpp. Luego construye con:
cd real-time-cpp
cd ref_app
./target/build/build.sh stm32f446 rebuild
target stm32f446
Ahora ejemplificaremos cómo construir la aplicación de referencia en un shell de comandos en MacOS para un objetivo ARM(R). Considere, por ejemplo, la variante de compilación target stm32f446
. Para ello se puede utilizar cómodamente la placa NUCLEO-F446RE de STMicroelectronics(R).
Clona u obtén el repositorio ckormanyos/real-time-cpp.
(Ahora) se puede utilizar la versión predeterminada 3.81 de GNUmake en MacOS. Los archivos make utilizados en este repositorio se han hecho compatibles con él. Para obtener información general, consulte también el número 273.
Construya el objetivo con una llamada manual directa para make
.
cd real-time-cpp
cd ref_app
make -f target/app/make/app_make.gmk rebuild TGT=stm32f446
Si se necesita la cadena de herramientas, se debe instalar o recuperar antes de crear el destino de la aplicación de referencia.
Puede obtener a través de wget
(u opcionalmente instalar) la cadena de herramientas gcc-arm-none-eabi
si es necesario. En este caso, me ha parecido conveniente utilizar un gcc-arm-none-eabi
moderno para MacOS que se puede encontrar en Descargas de Arm GNU Toolchain.
La cadena de herramientas arm-non-eabi
se puede recuperar a través de wget
y utilizar con éxito localmente en el shell. Si esto es lo que desea, siga el procedimiento paso a paso a continuación.
Paso 1: cree un directorio local (como macos-gnu-arm-toolchain
) y cd
en él.
cd real-time-cpp
mkdir -p macos-gnu-arm-toolchain
cd macos-gnu-arm-toolchain
Paso 2: obtenga el tarball de la cadena de herramientas con wget
, descomprímalo y agregue el directorio bin
del compilador a la ruta ejecutable del shell.
wget --no-check-certificate https://developer.arm.com/-/media/Files/downloads/gnu/12.2.rel1/binrel/arm-gnu-toolchain-12.2.rel1-darwin-x86_64-arm-none-eabi.tar.xz
tar -xvf arm-gnu-toolchain-12.2.rel1-darwin-x86_64-arm-none-eabi.tar.xz
PATH= $( pwd ) /arm-gnu-toolchain-12.2.rel1-darwin-x86_64-arm-none-eabi/bin: $PATH
Paso 3: Opcionalmente echo
de la PATH
para una verificación rápida de la ruta. También puede resultar útil consultar la versión de arm-non-eabi-g++
. Se espera que esto verifique que la cadena de herramientas se agregue correctamente a PATH
local de este shell.
echo $PATH
arm-none-eabi-g++ -v
Ahora simplemente use los comandos para construir el objetivo con una llamada directa a make
(que es lo mismo que se muestra arriba para el caso *nix
).
cd real-time-cpp
cd ref_app
make -f target/app/make/app_make.gmk rebuild TGT=stm32f446
Para comenzar con la aplicación de referencia en Win*
Win*
, como se describe en detalle unos pocos párrafos a continuación.ref_app.sln
en el directorio ref_app. La compilación ref_app
en Microsoft(R) VisualStudio(R) hace un uso intensivo del desarrollo cruzado utilizando un espacio de trabajo de proyecto de tipo Makefile externo . GNUmake se invoca mediante un archivo por lotes en el proceso de compilación. Posteriormente se ejecuta en combinación con varios Makefiles.
Para crear cualquier objetivo ref_app
que no sea Debug
o Release
para Win32, se requiere un compilador cruzado (compilador cruzado GNU/GCC). Consulte el texto a continuación para obtener detalles adicionales.
Los compiladores cruzados GNU/GCC que se ejecutan en Win*
destinados a la aplicación de referencia en VisualStudio(R) se pueden encontrar en el repositorio de cadenas de herramientas , ckormanyos/real-time-cpp-toolchains. El repositorio de cadenas de herramientas contiene instrucciones detalladas sobre cómo instalar, mover y usar estos compiladores GNU/GCC adaptados.
Nota sobre GNUmake para Win*
: Se puede encontrar un GNUmake capaz de usarse en Win*
en el repositorio ckormanyos/make-4.2.1-msvc-build. Si lo desea, clone u obtenga el código de este repositorio. Compile make-4.2.1
en su configuración Release
x64
con MSVC (es decir, VC 14.2 o posterior, Community Edition está bien).
CMake entre entornos puede crear la aplicación de referencia. Para ello, también se han creado archivos CMake para cada objetivo compatible.
Considere, por ejemplo, crear la aplicación de referencia para el objetivo avr
con CMake. El patrón se muestra a continuación.
cd real-time-cpp
mkdir build
cd build
cmake ../ref_app -DTRIPLE=avr -DTARGET=avr -DCMAKE_TOOLCHAIN_FILE=../ref_app/cmake/gcc-toolchain.cmake
make -j ref_app
Ahora consideraremos, por ejemplo, crear la aplicación de referencia para uno de los objetivos ARM(R) compatibles con CMake. El patrón se muestra a continuación. En este caso, necesitamos identificar las siguientes opciones de marca:
-DTRIPLE=avr -DTARGET=avr
Cambie estas opciones a las destinadas al objetivo basado en stm32f446
ARM(R) que se está construyendo.
-DTRIPLE=arm-none-eabi -DTARGET=stm32f446
Aclaremos los comandos en su totalidad para ejecutar una compilación de CMake para stm32f446
(es decir, ST Microelectronics(R) STM32F446 ARM(R) con Cortex(R)-M4F.
cd real-time-cpp
mkdir build
cd build
cmake ../ref_app -DTRIPLE=arm-none-eabi -DTARGET=stm32f446 -DCMAKE_TOOLCHAIN_FILE=../ref_app/cmake/gcc-toolchain.cmake
make -j ref_app
Al compilar con CMake para otros objetivos, siga el patrón estándar *nix
para compilar. También debería funcionar compilar con CMake para x86_64-w64-mingw32
o host
de MSYS, Cygwin o cualquier shell o consola similar a *nix
.
La siguiente secuencia de comandos se compilará para el host
nativo en un shell o consola tipo *nix
.
cd real-time-cpp
mkdir build
cd build
cmake ../ref_app -DTARGET=host -DCMAKE_TOOLCHAIN_FILE=../ref_app/cmake/gcc-toolchain.cmake
make -j ref_app
También existe una solución de espacio de trabajo para ATMEL(R) AtmelStudio(R) 7. Se llama ref_app.atsln
y también se encuentra en el directorio ref_app. Existen proyectos de ATMEL Studio tanto para la aplicación de referencia como para cada uno de los ejemplos. Los proyectos ATMEL Studio en este repositorio solo admiten el objetivo AVR.
Si decide utilizar ATMEL Studio, no necesita utilizar ni incluir bibliotecas adicionales para estos proyectos (aparte de las que normalmente se instalan durante la instalación estándar de ATMEL Studio).
Los detalles del destino, incluido el código de inicio y los archivos de definición del vinculador, se pueden encontrar en el directorio ref_app/target y sus subdirectorios. Hay subdirectorios individuales para cada sistema de microcontrolador de destino compatible.
La configuración AVR(R) de MICROCHIP(R) [antiguo ATMEL(R)] llamada target avr
se ejecuta en una placa compatible con ARDUINO(R) clásica. El programa alterna el LED amarillo en portb.5
.
La configuración del MICROCHIP(R) [antiguo ATMEL(R)] ATmega4809 llamada target atmega4809
se ejecuta en un ARDUINO(R) TODAS las placas compatibles sincronizadas con el resonador interno en porte.2
(es decir, D5
).
La implementación de Espressif (XTENSA) NodeMCU ESP32 utiliza un subconjunto del SDK de Espressif para ejecutar la aplicación de referencia con una única tarea del sistema operativo exclusivamente en 1 de sus núcleos.
La configuración ARM(R) Cortex(R)-M0+ de la placa NXP(R) OM13093 LPC11C24 denominada "objetivo lpc11c24" alterna el LED en port0.8
.
La configuración ARM(R) Cortex(R)-M3 (llamada target stm32f100
) se ejecuta en la placa STM32VL-DISCOVERY disponible comercialmente en ST Microelectronics(R). El programa alterna el LED azul en portc.8
.
La segunda configuración ARM(R) Cortex(R)-M3 (llamada target stm32l100c
) se ejecuta en la placa STM32L100-DISCOVERY disponible comercialmente en ST Microelectronics(R). El programa alterna el LED azul en portc.8
.
La tercera configuración ARM(R) Cortex(R)-M3 (llamada target stm32l152
) se ejecuta en la placa STM32L152C-DISCOVERY disponible comercialmente en ST Microelectronics(R). El programa alterna el LED azul en portb.6
.
La primera configuración ARM(R) Cortex(R)-M4F (llamada target stm32f407
) se ejecuta en la placa STM32F4-DISCOVERY disponible comercialmente en ST Microelectronics(R). El programa alterna el LED azul en portd.15
.
Otra configuración ARM(R) Cortex(R)-M4F (llamada target stm32f446
) se ejecuta en la placa STM32F446-NUCLEO-64 disponible comercialmente en ST Microelectronics(R). El programa alterna el LED verde en porta.5
. Se proporciona un archivo de depuración de Ozone para este sistema para aquellos interesados.
La primera configuración ARM(R) Cortex(R)-M7 (llamada target stm32h7a3
) se ejecuta en la placa STM32H7A3-NUCLEO-144 disponible comercialmente en ST Microelectronics(R). El programa alterna el LED verde en portb.0
.
La configuración ARM(R) A8 (llamada target am335x
) se ejecuta en la placa BeagleBone (edición negra). Para la edición blanca, el reloj de la CPU debe reducirse de *nix
en la placa. Nuestro programa está diseñado para iniciar BeagleBone desde un archivo binario sin formato llamado MLO almacenado en una microtarjeta FAT32 SDHC. El archivo binario incluye un encabezado de arranque especial compuesto por dos enteros de 32 bits. El programa se carga desde la tarjeta SD a la memoria RAM y posteriormente se ejecuta. Al encender el BeagleBone black, se debe presionar el botón de arranque (S2) mientras se enciende la placa. El programa alterna el primer LED de usuario (LED1 en port1.21
).
La configuración ARM(R) 1176-JZF-S (llamada target bcm2835_raspi_b
) se ejecuta en el controlador de un solo núcleo RaspberryPi(R) Zero (PiZero). Este proyecto crea un programa básico para PiZero. Este programa se ejecuta independientemente de cualquier tipo de distribución *nix
en la placa. Nuestro programa está diseñado para iniciar PiZero desde un archivo binario sin formato. El archivo binario sin formato se llama kernel.img y se almacena en una microtarjeta FAT32 SDHC. El programa objcopy se puede utilizar para extraer archivos binarios sin formato de un archivo ELF utilizando los indicadores de salida -O binary
. El archivo kernel.img se almacena en la tarjeta SD junto con otros tres archivos: bootcode.bin, start.elf y (opcional) config.txt, todos descritos en Internet. En este repositorio se incluye un conjunto completo de contenidos de arranque de PiZero para una tarjeta SD que ejecuta la aplicación de referencia básica. El programa alterna el LED de estado GPIO en el índice GPIO 0x47
.
La configuración de destino rpi_pico_rp2040
emplea el RaspberryPi(R) Pico RP2040 con ARM(R) Cortex(R)-M0+ de doble núcleo sincronizado a Blinky_Pico_dual_core_nosdk
.
La configuración de destino rpi_pico2_rp2350
emplea el RaspberryPi(R) Pico2 RP2350 con ARM(R) Cortex(R)-M33 de doble núcleo sincronizado a 2040
. De manera similar, la startup de doble núcleo fue pionera en los esfuerzos revelados en el repositorio modernizado Blinky_Pico2_dual_core_nosdk
.
Target v850es_fx2
utiliza un núcleo clásico Renesas(R) V850es/Fx2. Se utiliza el derivado del microcontrolador upd703231 en un kit de inicio F-Line Drive It .
El objetivo riscvfe310
utiliza el SoC SiFive RISC-V FE310 en la placa Red Thing Plus disponible comercialmente de Spark Fun. El LED azul en el puerto GPIO0.5
está encendido.
La adaptación para wch_ch32v307
se ejecuta en la placa WCH CH32v307. Utiliza el microcontrolador RISC-V CH32v307 de Nanjing Qinheng Microelectronics Co., Ltd. El LED1 azul conectado manualmente al puerto GPIOC.0
mediante una conexión de cable proporciona el interruptor parpadeante. La adaptación similar wch_ch32v307_llvm
es esencialmente la misma excepto que utiliza una cadena de herramientas LLVM RISC-V en lugar de GCC RISC-V.
Target nxp_imxrt1062
se ejecuta en la placa Teensy 4.0 de Spark Fun. El LED de usuario naranja está activado.
Para otras placas compatibles, no dude en contactarme directamente o enviar un problema solicitando soporte para el sistema de destino que desee.
Los puntos de referencia proporcionan medios portátiles y escalables para identificar el rendimiento y la clase de rendimiento del microcontrolador. Para obtener más información, consulte la información detallada en las páginas de pruebas comparativas.
Los proyectos de este repositorio se programan sin sistema operativo en modo básico y sin sistema operativo utilizando código de inicio escrito por uno mismo. No se utilizan bibliotecas externas distintas de C++ nativo y sus propias bibliotecas estándar.
Considere, por ejemplo, BeagleBone Black Edition (BBB, también conocido como target am335x
), que es uno de varios sistemas de destino populares compatibles con este repositorio. Los proyectos en esta placa arrancan desde el archivo de imagen binaria MLO en la tarjeta SD. Como todos los demás proyectos en este repositorio, los proyectos BBB realizan su propia inicialización estática e inicialización de chip (es decir, en este caso particular, inicialización de chip del procesador ARM(R) 8 AM335x). Los proyectos BBB, después de la inicialización, saltan posteriormente a main()
que inicializa el MCAL am335x
e inicia nuestro programador multitarea escrito por nosotros mismos.
La siguiente imagen muestra el BeagleBone Black Edition de metal desnudo en acción. En este modo de operación básica, no hay ningún sistema operativo *nix
en ejecución en BBB, ni teclado, ni mouse, ni monitor, ni interfaz de depuración ni emulador.
El microcontrolador de la placa realiza cíclicamente uno de los puntos de referencia mencionados anteriormente. El primer LED de usuario se enciende en port1.21
en operación multitarea y el osciloscopio captura una medición en tiempo real de la señal de tiempo del punto de referencia en el puerto de E/S digital port1.15
, pin de encabezado P8.15
del BBB.
Las insignias de estado de compilación representan el estado de las compilaciones y pruebas de CI nocturnas.
avr-gcc
moderna El repositorio ckormanyos/avr-gcc-build crea cadenas de herramientas avr-gcc
actualizadas para x86_64-linux-gnu
y x86_64-w64-mingw32
. Los scripts de Shell y YAML crean avr-gcc
directamente desde el código fuente en los ejecutores de GHA. Además, las versiones ocasionales de GitHub proporcionan cadenas de herramientas avr-gcc
prediseñadas para x86_64-linux-gnu
y x86_64-w64-mingw32
.
Este repositorio es un excelente lugar para aprender a crear su propia cadena de herramientas avr-gcc
desde el código fuente. Los scripts YAML y Shell, sencillos y bien descritos, son fáciles de entender, usar o adaptar.
Como se mencionó anteriormente, en ckormanyos/real-time-cpp-toolchains se describe un alcance mucho más detallado y más amplio de las cadenas de herramientas integradas. Estos incluyen la cadena de herramientas avr-gcc
mencionada anteriormente, así como otras (algunas difíciles de encontrar en otros lugares).
La aplicación de referencia y los ejemplos (también los fragmentos de código) se pueden compilar con compiladores GNU/GCC y GNUmake en *nix
. Se supone que los compiladores cruzados GNU/GCC y GNUmake en *nix
están disponibles en la ruta ejecutable estándar, como después de las prácticas estándar de instalación.
Algunos compiladores cruzados GNU/GCC adaptados para Win*
están disponibles en el repositorio de cadenas de herramientas , real-time-cpp-toolchains. Estos se pueden utilizar con las configuraciones de la solución de microcontrolador en la aplicación de referencia al desarrollar/construir dentro de Microsoft(R) VisualStudio(R). Se han adaptado varias otras herramientas GNU, como GNUmake, SED, etc., y se pueden encontrar allí. Estos se utilizan en los Makefiles al crear proyectos integrados cruzados como ref_app
en Win*
.
En la aplicación de referencia en Win*
, los Makefiles utilizan una ubicación predeterminada autodefinida para las respectivas herramientas y cadenas de herramientas GNU/GCC. La ubicación predeterminada de la cadena de herramientas en Win*
es ./ref_app/tools/Util/msys64/usr/local
. Esta ubicación particular de la cadena de herramientas está inspirada en el sistema msys2
/ mingw64
.
Las cadenas de herramientas destinadas a compilaciones cruzadas de MSVC/GCC en Win*
deben ubicarse allí. Estas cadenas de herramientas no forman parte de este repositorio y es necesario obtenerlas por separado cuando se utilizan las compilaciones Win*
compatibles cuando se utilizan opcionalmente proyectos VisualStudio(R) con CMD Batch.
Las instrucciones detalladas sobre cómo obtener y usar las cadenas de herramientas para compilaciones cruzadas de MSVC/GCC en Win*
están disponibles en el repositorio de cpp-toolchains en tiempo real. Estas instrucciones proporcionan orientación sobre el uso de estas cadenas de herramientas al seleccionar el proyecto Microsoft(R) VisualStudio(R) (a través de la forma habitual MSVC/ Win*
descrita anteriormente) para crear la aplicación de referencia.
Se requiere un puerto GNU/GCC (u otro compilador) con un alto nivel de conocimiento y adherencia a C++14 (o superior), como GCC 5 a 13 (por lo general, es más ventajoso) o MSVC 14.2 o superior para crear la referencia. aplicación (y los ejemplos y fragmentos de código).
Algunos de los fragmentos de código demuestran elementos del lenguaje no solo de C++14, sino también de C++17, 20, 23 y posteriores. Por lo tanto, un compilador compatible con C++ 17 o incluso con C++ 20, 23 (como GCC 13, clang 15, MSVC 14.3 o superior) puede ser beneficioso para lograr el éxito con todos los fragmentos de código.
<chrono>
, <ratio>
y algunos encabezados de rasgos internos, tienen la licencia GNU General Public License Versión 3 o superior.