Este é o código complementar do livro CM Kormanyos, Real-Time C++: Efficient Object-Oriented and Template Microcontroller Programming, Fourth Edition (Springer, Heidelberg, 2021) ISBN 9783662629956.
Este repositório possui várias partes principais.
ref_app
localizado em ref_app. Isso também inclui os benchmarks. Compiladores cruzados GNU/GCC e várias ferramentas adicionais em execução no Win*
, opcionalmente necessárias para certas compilações conforme descrito abaixo, podem ser encontradas no repositório ckormanyos/real-time-cpp-toolchains relacionado.
O aplicativo de referência é inicializado com um pequeno código de inicialização e, posteriormente, inicializa uma fina camada de abstração de microcontrolador (MCAL). O controle é então passado para um agendador multitarefa simples que gerencia o aplicativo LED, chama uma tarefa de benchmark cíclica e atende o watchdog.
O aplicativo LED alterna um LED do usuário com uma frequência de
O aplicativo de referência é compatível com C++ 14, 17, 20, 23 e posteriores.
O software aplicativo é implementado uma vez e usado uniformemente em cada destino suportado no ref_app. As diferenças entre os alvos individuais surgem apenas nas camadas inferiores de software relativas aos detalhes de inicialização/MCAL específicos do chip e da placa.
Desta forma, o projeto apresenta um alto nível de portabilidade.
O aplicativo de referência oferece suporte aos seguintes destinos:
Nome de destino (conforme usado no comando build) | Descrição do alvo | *(placa de ensaio) |
---|---|---|
avr | MICROCHIP(R) [antigo ATMEL(R)] AVR(R) ATmega328P | X |
atmega2560 | MICROCHIP(R) [antigo ATMEL(R)] AVR(R) ATmega2560 | |
atmega4809 | MICROCHIP(R) [antigo ATMEL(R)] AVR(R) ATmegax4809 | X |
am335x | BeagleBone com Texas Instruments(R) AM335x ARM(R) A8 | |
bcm2835_raspi_b | RaspberryPi(R) Zero com ARM1176-JZFS(TM) | |
Debug / Release | PC no Win* via Debug / Release do compilador MSVC x64 | |
host | PC/estação de trabalho em Win* / mingw64 / *nix via 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 | X |
riscvfe310 | SoC SiFive RISC-V FE310 | |
rl78 | Renesas(R) RL78/G13 | |
rpi_pico_rp2040 | RaspberryPi(R) Pico RP2040 com ARM(R) Cortex(R)-M0+ duplo | X |
rpi_pico2_rp2350 | RaspberryPi(R) Pico2 RP2350 com ARM(R) Cortex(R)-M33 duplo | X |
rx63n | Renesas(R) RX630/RX631 | |
stm32f100 | STMicroelectronics(R) STM32F100 ARM(R) Cortex(R)-M3 | X |
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 | X |
stm32l152 | STMicroelectronics(R) STM32L152 ARM(R) Cortex(R)-M3 | |
stm32l432 | STMicroelectronics(R) STM32L432 ARM(R) Cortex(R)-M4F | X |
v850es_fx2 | Renesas(R) Electronics V850es/Fx2 upd703231 | |
wch_ch32v307 | Placa WCH CH32v307 RISC-V | |
wch_ch32v307_llvm | Placa WCH CH32v307 RISC-V (mas usando um conjunto de ferramentas LLVM) | |
x86_64-w64-mingw32 | PC no Win* / mingw64 via compilador GNU/GCC x86_x64 | |
xtensa32 | Espressif (XTENSA) NodeMCU ESP32 | X |
Nesta tabela, *(placa de ensaio) significa que a placa (ou certas versões dela) pode ser facilmente usada com uma placa de ensaio comum. Isso pode precisar de uma soldagem/montagem manual muito simples de pinos de cabeçalho.
É mais fácil começar com o aplicativo de referência usando uma das placas suportadas, como avr
(ARDUINO) ou bcm2835_raspi_b
(RaspberryPi ZERO) ou am335x
(BeagleBoneBlack), etc. O aplicativo de referência pode ser encontrado no diretório ref_app e seus subdiretórios .
O aplicativo de referência usa desenvolvimento cruzado e sistemas de construção com suporte em:
*nix
make em combinação com Bash/GNUmake (script bash) no LINUX/MacOS,*nix
no Win*
em combinação com script em lote ou Microsoft(R) Visual Studio(R) via Makefile externo ,Win*
, Após a conclusão bem-sucedida da construção, os artefatos resultantes, incluindo arquivos HEX (como ref_app.hex
), arquivos de mapa, relatórios de tamanho, etc., estão disponíveis no diretório bin
.
Para começar com o aplicativo de referência no *nix
target avr
) você gostaria de construir.build.sh
com o comando: ./target/build/build.sh avr rebuild
.avr rebuild
que posteriormente reconstrói toda a solução para target avr
.*nix
, execute sudo apt install gcc-avr avr-libc
.*nix
para target avr
Agora exemplificaremos como construir o aplicativo de referência em um shell de comando em *nix
para target avr
. Este sistema alvo inclui essencialmente qualquer placa compatível com ARDUINO(R). Esta também é a compatibilidade da placa realmente usada com as placas caseiras do livro.
Instale gcc-avr
se necessário.
sudo apt install gcc-avr avr-libc
Clone ou obtenha o repositório ckormanyos/real-time-cpp. Então construa com:
cd real-time-cpp
cd ref_app
./target/build/build.sh avr rebuild
*nix
para target stm32f446
Agora exemplificaremos como construir o aplicativo de referência em um shell de comando em *nix
para um alvo ARM(R). Considere, por exemplo, o target stm32f446
. A placa NUCLEO-F446RE da STMicroelectronics(R) pode ser usada convenientemente para isso.
Instale gcc-arm-none-eabi
se necessário.
sudo apt install gcc-arm-none-eabi
Clone ou obtenha o repositório ckormanyos/real-time-cpp. Então construa com:
cd real-time-cpp
cd ref_app
./target/build/build.sh stm32f446 rebuild
target stm32f446
Iremos agora exemplificar como construir o aplicativo de referência em um shell de comando no MacOS para um alvo ARM(R). Considere, por exemplo, o target stm32f446
. A placa NUCLEO-F446RE da STMicroelectronics(R) pode ser usada convenientemente para isso.
Clone ou obtenha o repositório ckormanyos/real-time-cpp.
A versão padrão 3.81 do GNUmake no MacOS pode (agora) ser usada. Os arquivos make usados neste repositório foram tornados compatíveis com ele. Para informações básicas, consulte também a edição 273.
Construa o alvo com uma chamada manual direta para make
.
cd real-time-cpp
cd ref_app
make -f target/app/make/app_make.gmk rebuild TGT=stm32f446
Se a cadeia de ferramentas for necessária, ela deverá ser instalada ou recuperada antes da construção do destino do aplicativo de referência.
Você pode obter via wget
(ou opcionalmente instalar) o conjunto de ferramentas gcc-arm-none-eabi
se necessário. Neste caso, achei conveniente usar um gcc-arm-none-eabi
moderno para MacOS, que pode ser encontrado em Arm GNU Toolchain Downloads.
O conjunto de ferramentas arm-non-eabi
pode ser obtido via wget
e usado localmente no shell. Se desejar, siga o procedimento passo a passo abaixo.
Passo 1: Crie um diretório local (como macos-gnu-arm-toolchain
) e cd
nele.
cd real-time-cpp
mkdir -p macos-gnu-arm-toolchain
cd macos-gnu-arm-toolchain
Etapa 2: busque o tarball do conjunto de ferramentas com wget
, descompacte-o e adicione o diretório bin
do compilador ao caminho executável do 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
Etapa 3: opcionalmente, echo
do PATH
para uma verificação rápida do caminho. Também pode ser útil consultar a versão de arm-non-eabi-g++
. Espera-se que isso verifique se o conjunto de ferramentas foi adicionado corretamente ao PATH
local deste shell.
echo $PATH
arm-none-eabi-g++ -v
Agora basta usar os comandos para construir o alvo com uma chamada direta para make
(que é a mesma mostrada acima para o caso *nix
).
cd real-time-cpp
cd ref_app
make -f target/app/make/app_make.gmk rebuild TGT=stm32f446
Para começar a usar o aplicativo de referência no Win*
Win*
, conforme descrito em detalhes alguns parágrafos abaixo.ref_app.sln
no diretório ref_app. A compilação ref_app
no Microsoft(R) VisualStudio(R) faz uso intenso de desenvolvimento cruzado usando um espaço de trabalho de projeto do tipo External Makefile . GNUmake é invocado via arquivo em lote no processo de construção. Posteriormente, ele é executado em combinação com vários Makefiles.
Para construir qualquer destino ref_app
diferente de Debug
ou Release
para Win32, é necessário um compilador cruzado (compilador cruzado GNU/GCC). Veja o texto abaixo para detalhes adicionais.
Compiladores cruzados GNU/GCC em execução no Win*
destinados ao aplicativo de referência no VisualStudio(R) podem ser encontrados no repositório de cadeias de ferramentas , ckormanyos/real-time-cpp-toolchains. O repositório de toolchains contém instruções detalhadas sobre instalação, movimentação e uso desses compiladores GNU/GCC portados.
Nota sobre o GNUmake para Win*
: Um GNUmake capaz de ser usado no Win*
pode ser encontrado no repositório ckormanyos/make-4.2.1-msvc-build. Se desejar, clone ou obtenha o código deste repositório. Construa make-4.2.1
em sua configuração Release
x64
com MSVC (ou seja, VC 14.2 ou posterior, Community Edition está OK).
O Cross-Environment CMake pode criar o aplicativo de referência. Para este propósito, arquivos CMake também foram criados para cada destino suportado.
Considere, por exemplo, construir o aplicativo de referência para o destino avr
com CMake. O padrão é mostrado abaixo.
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
Consideraremos agora, por exemplo, construir o aplicativo de referência para um dos alvos ARM(R) suportados com CMake. O padrão é mostrado abaixo. Neste caso, precisamos identificar as seguintes opções de make:
-DTRIPLE=avr -DTARGET=avr
Mude essas opções para aquelas destinadas ao destino baseado em ARM(R) stm32f446
que está sendo construído.
-DTRIPLE=arm-none-eabi -DTARGET=stm32f446
Vamos esclarecer os comandos em sua totalidade para executar uma compilação do CMake para stm32f446
(ou seja, ST Microelectronics(R) STM32F446 ARM(R) com 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
Ao construir com CMake para outros destinos, siga o padrão *nix
para construir. Também construir com CMake para x86_64-w64-mingw32
ou host
de MSYS, Cygwin ou qualquer shell ou console semelhante *nix
deve funcionar também.
A sequência de comandos a seguir será construída para o host
nativo em um shell ou console semelhante *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
Há também uma solução de espaço de trabalho para ATMEL(R) AtmelStudio(R) 7. Ela é chamada ref_app.atsln
e também está localizada no diretório ref_app. Existem projetos ATMEL Studio tanto para a aplicação de referência quanto para cada um dos exemplos. Os projetos ATMEL Studio neste repositório suportam apenas o alvo AVR.
Se você decidir usar o ATMEL Studio, não será necessário usar ou incluir nenhuma biblioteca adicional para esses projetos (além daquelas que normalmente são instaladas durante a instalação padrão do ATMEL Studio).
Detalhes do destino, incluindo código de inicialização e arquivos de definição do vinculador, podem ser encontrados no diretório ref_app/target e seus subdiretórios. Existem subdiretórios individuais para cada sistema microcontrolador de destino suportado.
A configuração do MICROCHIP(R) [antigo ATMEL(R)] AVR(R) chamada target avr
é executada em uma placa clássica compatível com ARDUINO(R). O programa alterna o LED amarelo na portb.5
.
A configuração do MICROCHIP(R) [antigo ATMEL(R)] ATmega4809 chamada target atmega4809
é executada em uma placa compatível com ARDUINO(R) EVERY com clock do ressonador interno em porte.2
(ou seja, D5
).
A implementação do NodeMCU ESP32 do Espressif (XTENSA) usa um subconjunto do SDK do Espressif para executar o aplicativo de referência com uma única tarefa de sistema operacional exclusivamente em um de seus núcleos.
A configuração ARM(R) Cortex(R)-M0+ da placa NXP(R) OM13093 LPC11C24 chamada "target lpc11c24" alterna o LED na port0.8
.
A configuração ARM(R) Cortex(R)-M3 (chamada target stm32f100
) é executada na placa STM32VL-DISCOVERY disponível comercialmente na ST Microelectronics(R). O programa alterna o LED azul em portc.8
.
A segunda configuração ARM(R) Cortex(R)-M3 (chamada target stm32l100c
) é executada na placa STM32L100-DISCOVERY disponível comercialmente na ST Microelectronics(R). O programa alterna o LED azul em portc.8
.
A terceira configuração ARM(R) Cortex(R)-M3 (chamada target stm32l152
) é executada na placa STM32L152C-DISCOVERY disponível comercialmente na ST Microelectronics(R). O programa alterna o LED azul em portb.6
.
A primeira configuração ARM(R) Cortex(R)-M4F (chamada target stm32f407
) é executada na placa STM32F4-DISCOVERY disponível comercialmente na ST Microelectronics(R). O programa alterna o LED azul em portd.15
.
Outra configuração ARM(R) Cortex(R)-M4F (chamada target stm32f446
) é executada na placa STM32F446-NUCLEO-64 disponível comercialmente na ST Microelectronics(R). O programa alterna o LED verde em porta.5
. Um arquivo de depuração do Ozone é fornecido para este sistema para os interessados.
A primeira configuração ARM(R) Cortex(R)-M7 (chamada target stm32h7a3
) é executada na placa STM32H7A3-NUCLEO-144 disponível comercialmente na ST Microelectronics(R). O programa alterna o LED verde em portb.0
.
A configuração ARM(R) A8 (chamada target am335x
) roda na placa BeagleBone (edição preta). Para a edição branca, o clock da CPU precisa ser reduzido de *nix
na placa. Nosso programa foi projetado para inicializar o BeagleBone a partir de um arquivo binário bruto chamado MLO armazenado em um microcartão SDHC FAT32. O arquivo binário inclui um cabeçalho de inicialização especial composto por dois números inteiros de 32 bits. O programa é carregado do cartão SD na memória RAM e posteriormente executado. Ao ligar a BeagleBone black, o botão boot (S2) deve ser pressionado enquanto a placa é ligada. O programa alterna o primeiro LED do usuário (LED1 na port1.21
).
A configuração ARM(R) 1176-JZF-S (chamada target bcm2835_raspi_b
) é executada no controlador de núcleo único RaspberryPi(R) Zero (PiZero). Este projeto cria um programa bare metal para o PiZero. Este programa é executado independentemente de qualquer tipo de distribuição *nix
na placa. Nosso programa foi projetado para inicializar o PiZero a partir de um arquivo binário bruto. O arquivo binário bruto é chamado kernel.img e é armazenado em um microcartão FAT32 SDHC. O programa objcopy pode ser usado para extrair binário bruto de um arquivo ELF usando os sinalizadores de saída -O binary
. O arquivo kernel.img é armazenado no cartão SD junto com outros três arquivos: bootcode.bin, start.elf e (opcional) config.txt, todos descritos na internet. Um conjunto completo de conteúdo de inicialização do PiZero para um cartão SD executando o aplicativo de referência bare-metal está incluído neste repositório. O programa alterna o LED de status GPIO no índice GPIO 0x47
.
A configuração de destino rpi_pico_rp2040
emprega o RaspberryPi(R) Pico RP2040 com ARM(R) Cortex(R)-M0+ dual-core com clock de Blinky_Pico_dual_core_nosdk
.
A configuração de destino rpi_pico2_rp2350
emprega o RaspberryPi(R) Pico2 RP2350 com ARM(R) Cortex(R)-M33 dual-core com clock de 2040
. Da mesma forma, a startup dual-core foi pioneira nos esforços revelados no repositório modernizado Blinky_Pico2_dual_core_nosdk
.
O Target v850es_fx2
usa um núcleo Renesas(R) V850es/Fx2 clássico. O microcontrolador upd703231 derivado em um kit inicial F-Line Drive It é usado.
O alvo riscvfe310
utiliza o SoC SiFive RISC-V FE310 na placa Red Thing Plus disponível comercialmente da Spark Fun. O LED azul na porta GPIO0.5
está alternado.
A adaptação para wch_ch32v307
é executada na placa WCH CH32v307. Ele usa o microcontrolador RISC-V CH32v307 da Nanjing Qinheng Microelectronics Co., Ltd. O LED1 azul conectado manualmente à porta GPIOC.0
por meio de conexão com fio fornece a alternância piscante. A adaptação semelhante wch_ch32v307_llvm
é essencialmente a mesma, exceto que usa um conjunto de ferramentas LLVM RISC-V em vez de GCC RISC-V.
O alvo nxp_imxrt1062
é executado na placa Teensy 4.0 da Spark Fun. O LED do usuário laranja está alternado.
Para outras placas compatíveis, não hesite em contactar-me diretamente ou envie um problema solicitando suporte para o sistema alvo desejado.
Os benchmarks fornecem meios escaláveis e portáteis para identificar o desempenho e a classe de desempenho do microcontrolador. Para obter mais informações, consulte as informações detalhadas nas páginas de benchmarks.
Os projetos neste repositório são programados sem sistema operacional no modo bare-metal, fazendo uso de código de inicialização escrito por você mesmo. Nenhuma biblioteca externa além do C++ nativo e suas próprias bibliotecas padrão são usadas.
Considere, por exemplo, o BeagleBone Black Edition (BBB, também conhecido como target am335x
), que é um dos vários sistemas de destino populares suportados neste repositório. Os projetos nesta placa são inicializados a partir do arquivo de imagem binária MLO no cartão SD. Como todos os outros projetos neste repositório, os projetos BBB realizam sua própria inicialização estática e inicialização de chip (ou seja, neste caso específico, inicialização de chip do processador ARM(R) 8 AM335x). Os projetos BBB, após a inicialização, saltam posteriormente para main()
que inicializa o am335x
MCAL e inicia nosso agendador multitarefa auto-escrito.
A imagem abaixo mostra o BeagleBone Black Edition bare-metal em ação. Neste modo de operação bare-metal, não há sistema operacional *nix
em execução no BBB, nem teclado, nem mouse, nem monitor, nem interface de depuração e nem emulador.
O microcontrolador na placa executa ciclicamente um dos benchmarks mencionados acima. O primeiro LED do usuário é alternado na port1.21
em operação multitarefa e o osciloscópio captura uma medição em tempo real do sinal de tempo do benchmark na porta de E/S digital port1.15
, pino de cabeçalho P8.15
do BBB.
Os emblemas de status de build representam o estado dos builds e testes noturnos de CI.
avr-gcc
moderno O repositório ckormanyos/avr-gcc-build cria conjuntos de ferramentas avr-gcc
atualizados para x86_64-linux-gnu
e x86_64-w64-mingw32
. Os scripts Shell e YAML constroem avr-gcc
diretamente da fonte no(s) executor(es) GHA. Além disso, lançamentos ocasionais do GitHub fornecem conjuntos de ferramentas avr-gcc
pré-construídos para x86_64-linux-gnu
e x86_64-w64-mingw32
.
Este repositório é um ótimo lugar para aprender como construir seu próprio conjunto de ferramentas avr-gcc
a partir do código-fonte. Os scripts shell e YAML simples e bem descritos são fáceis de entender, usar ou adaptar.
Como mencionado acima, um escopo muito mais detalhado e mais amplo de cadeias de ferramentas incorporadas é descrito em ckormanyos/real-time-cpp-toolchains. Isso inclui o conjunto de ferramentas avr-gcc
mencionado acima, bem como outros (alguns difíceis de encontrar em outros lugares).
O aplicativo de referência e os exemplos (também os trechos de código) podem ser construídos com compiladores GNU/GCC e GNUmake em *nix
. Supõe-se que os compiladores cruzados GNU/GCC e GNUmake em *nix
estejam disponíveis no caminho executável padrão, como após as práticas padrão de instalação.
Alguns compiladores cruzados GNU/GCC portados para Win*
estão disponíveis no repositório de conjuntos de ferramentas , real-time-cpp-toolchains. Eles podem ser usados com as configurações da solução do microcontrolador no aplicativo de referência ao desenvolver/construir no Microsoft(R) VisualStudio(R). Várias outras ferramentas GNU como GNUmake, SED, etc. foram portadas e podem ser encontradas lá. Eles são usados nos Makefiles ao construir projetos integrados cruzados, como ref_app
no Win*
.
No aplicativo de referência no Win*
, os Makefiles usam um local padrão autodefinido para as respectivas ferramentas e conjuntos de ferramentas GNU/GCC. O local padrão do conjunto de ferramentas no Win*
é ./ref_app/tools/Util/msys64/usr/local
. Esta localização específica do conjunto de ferramentas é inspirada no sistema msys2
/ mingw64
.
As cadeias de ferramentas destinadas a compilações cruzadas de MSVC/GCC no Win*
devem estar localizadas lá. Essas cadeias de ferramentas não fazem parte deste repositório e é necessário obtê-las separadamente ao usar as compilações Win*
suportadas ao usar opcionalmente Projetos VisualStudio(R) com CMD Batch.
Instruções detalhadas sobre como obter e usar os conjuntos de ferramentas para compilações cruzadas de MSVC/GCC no Win*
estão disponíveis no repositório real-time-cpp-toolchains. Estas instruções fornecem orientação sobre como usar essas cadeias de ferramentas ao selecionar o projeto Microsoft(R) VisualStudio(R) (por meio do método usual MSVC/ Win*
descrito acima) para construir o aplicativo de referência.
Uma porta GNU/GCC (ou outro compilador) com um alto nível de conhecimento e adesão ao C++ 14 (ou superior), como GCC 5 a 13 (maior geralmente sendo mais vantajoso) ou MSVC 14.2 ou superior é necessária para construir a referência aplicativo (e os exemplos e trechos de código).
Alguns dos trechos de código demonstram elementos de linguagem não apenas do C++ 14, mas também do C++ 17, 20, 23 e posteriores. Um compilador com suporte a C++ 17 ou mesmo suporte a C++ 20, 23 (como GCC 13, clang 15, MSVC 14.3 ou superior) pode, portanto, ser benéfico para o sucesso com todos os trechos de código.
<chrono>
, <ratio>
e alguns cabeçalhos de características internos são licenciados sob a Licença Pública Geral GNU Versão 3 ou superior.