STM32MP1 - kernels + Linux = microcontrolador perfeito

Pela natureza da minha atividade, estou envolvido no desenvolvimento de vários dispositivos: medição, controle, controle etc. A grande maioria do dispositivo é dividida em 2 partes:

  1. Microcontrolador de alto recurso e que não requer interface gráfica do usuário (GUI) em tempo real.
  2. Consumindo poucos recursos e trabalhando em hardware rígido em tempo real do dispositivo.

Como regra, a transição para uma nova série de microcontroladores foi determinada pelo aprimoramento da GUI: mais cores, maior resolução, elementos de design mais complexos. Ao mesmo tempo, a idéia era usar algum tipo de placa Raspberry como interface gráfica.

Mas com o advento da nova linha de microcontroladores STM32MP1 da STM, meu tormento terminou e foi o que aconteceu até agora.

Controlador perfeito


Um controlador ideal para mim deve ter as seguintes características:

  • possui recursos gráficos decentes, como suporte simples para vários formatos gráficos, suporte para fontes vetoriais
  • grande quantidade de memória para gráficos
  • Suporte a teclado e mouse USB
  • Suporte Ethernet
  • um grande número de temporizadores de hardware
  • Geração PWM
  • um grande número de GPIO
  • ADC de 16 bits

São esses requisitos que são necessários para construir vários dispositivos com uma interface gráfica de usuário decente.

Então fiquei muito feliz em ver uma nova série da STM: STM32MP1.

Primeiro encontro


Para se familiarizar com o novo chip, a placa STM32MP157C-DK2 foi adquirida. Aqui está uma (foto de uma Internet): A



placa de demonstração é construída em um chip STM32MP157CAC, que inclui:

  • 2 núcleos A7, 650 MHz cada
  • 1 núcleo M4, 208 MHz

Memória


A primeira diferença que chama sua atenção é a falta de memória flash no chip. Para o núcleo A7, que é essencialmente um microprocessador, essa é uma situação normal e o código é sempre executado a partir da DRAM. Microcontroladores baseados em M4 geralmente incluem memória flash na qual o código executável é armazenado.

Neste cristal, o kernel M4 possui apenas RAM e o código é executado a partir dele (da folha de dados):

708 Kbytes de SRAM interna: 256 Kbytes de
AXI SYSRAM + 384 Kbytes de AHB SRAM +
64 Kbytes de AHB SRAM no domínio de Backup
e 4 Kbytes de SRAM no domínio de Backup

O núcleo A7 possui um controlador DDR embutido (de uma folha de dados):
Os dispositivos STM32MP157C / F incorporam um controlador para SDRAM externa que suporta os
seguintes dispositivos:

  • Dados LPDDR2 ou LPDDR3, 16 ou 32 bits, até 1 Gbyte, até 533 MHz.
  • Dados DDR3 ou DDR3L, 16 ou 32 bits, até 1 Gbyte, até 533 MHz.

Por um lado, a memória do kernel M4 parece ser menor que a da versão na memória flash, mas, por outro lado, a memória RAM é executada na frequência principal. A memória flash não pode fazer isso e é necessário usar um divisor de frequência.

Organização do local de trabalho


Como o Linux é necessário para trabalhar com a placa, eu tive que instalar um disco rígido adicional no meu computador e implantar o Ubuntu 16.04 nele. Este sistema operacional é recomendado pelo STM.

Modo de Engenharia e Produção


A placa pode iniciar em um dos dois modos (determinados pelo interruptor DIP). No modo de engenharia, o núcleo M4 funciona separadamente. No modo de produção, o núcleo M4 é executado sob o controle do núcleo A7. Não usei o modo Engenharia, trabalhei apenas no modo Produção. Nesse modo, você não precisa se preocupar em ajustar o relógio principal. O tempo é configurado durante o processo de inicialização com os valores máximos. Eu verifiquei vários registros no depurador, deduzi algumas das frequências no MCO e olhei para o osciloscópio. A7 opera na frequência de 650 MHz, M4 na frequência de 208 MHz.

Kernel M4. Baixe e execute programas


Como o núcleo M4 está executando o A7, isso significa executar o OpenSTLinux. A estrutura remoteproc do Linux (RPROC) é usada para controlar o núcleo M4. Essa estrutura permite ativar e desativar o kernel, o download e o software de depuração (arquivos ELF).

Para carregar o programa no kernel M4, use o seguinte comando:

echo -n <firmware_name.elf >> / sys / class / remoteproc / remoteproc0 / firmware

Para iniciar o programa:

echo start> / sys / class / remoteproc / remoteproc0 / state

Para parar:

echo stop> / sys / class / remoteproc / remoteprocX / state

Kernel M4. SW4STM32


Os comandos acima mencionados foram tentados, tudo funciona :) Mas, para funcionar, você precisa de algum tipo de IDE normal. O STM recomenda o uso do software AC6 SW4STM32 para isso. Ao mesmo tempo, o site do OpenSTM32 tem um título muito interessante:
Com o System Workbench para Linux, o Embedded Linux na família de MPUs STM32MP1 da ST nunca foi tão simples de construir e manter, mesmo para iniciantes no mundo Linux.
E, se você instalar o System Workbench para Linux no System Workbench for STM32, poderá desenvolver e depurar perfeitamente aplicativos assimétricos em execução parcialmente no Linux, parcialmente no Cortex-M4.
Ou seja, você pode escrever um código para o núcleo m4 e o A7. Mas esta é uma versão paga. E o gratuito, disponível para download, permite escrever e depurar código apenas para o núcleo M4.

O IDE SW4STM32 foi baixado, instalado e testado. Tudo funciona, o processo de escrever e compilar não é diferente da versão no Windows.
A única diferença é o carregamento e depuração do código, porque a conexão Ethenet e SSH é usada para escrever software. Para depuração e parada por pontos, a placa ST LINK embutida é usada.

Kernel A7. Compilador cruzado


Para compilar programas em um PC, o STM oferece um compilador cruzado. O processo de carregamento e execução do script do compilador cruzado é descrito em detalhes no wiki do STM32MP1, link abaixo. Tudo foi feito de acordo com as instruções, tudo funciona como deveria. :)

Executando o compilador cruzado para o ecossistema v1.1.0:

SDK de origem / configuração do ambiente-cortexa7t2hf-neon-vfpv4-openstlinux_weston-linux-gnueabi
, o
comando make
e o código-fonte, de acordo com o makefile, são compilados nos códigos ARM :)

Kernel A7. Baixe e execute programas


Para carregar o programa na placa demo, use o comando:

scp gtk_hello_world root@192.168.1.18: / usr / local

Este comando carrega o arquivo gtk_hello_world na seção / usr / local, localizada na placa com endereço IP: 192.168.1.18. Raiz - a senha que está no quadro por padrão.

Intercâmbio de dados entre núcleos


Passava a maior parte do tempo entendendo o mecanismo de troca de dados entre os núcleos. Nos exemplos fornecidos pelo STM, existem várias opções para implementar essa troca. Você pode trabalhar diretamente com o driver do OpenSTLinux ou usar o mecanismo UART virtual. Decidi simplificar o compartilhamento via portas virtuais.

No lado do Linux, fica assim:

Abra o dispositivo:

fd = open ("/ dev / ttyRPMSG0", O_RDWR);

Em seguida, escrevemos para ele ou lemos:

write (fd, "LED_Toggle \ r \ 0", 10);
len = leitura (fd, buf, sizeof (buf));

Tudo é bastante simples, mas há uma pequena nuance. Para que o dispositivo ttyRPMSG0 apareça, você precisa do núcleo M4 para acessar o núcleo A7 desta forma:

estas são as linhas de código do núcleo M4:

VIRT_UART_Init(&huart0); //  
VIRT_UART_RegisterCallback(&huart0, VIRT_UART_RXCPLT_CB_ID, VIRT_UART0_RxCpltCallback) //      .

Recepção de dados de uma porta virtual pelo núcleo M4:

if (VirtUart0RxMsg)
{
      //     VirtUart0ChannelBuffRx
     
      VirtUart0RxMsg = 0;
}

Gravando dados na porta virtual:

VIRT_UART_Transmit(&huart0, TxArray, TXCounter);

Tudo funciona, mas há uma pequena nuance que ainda não consigo entender. A recepção de dados pelo núcleo A7, transmitida pelo núcleo M4, não é iniciada, a menos que o núcleo A7 grave anteriormente quaisquer dados na porta.

Todo esse mecanismo é implementado por um conjunto de bibliotecas OpenAMP de terceiros. Essa biblioteca deve ser incluída no projeto do kernel M4 e inicializada de acordo.

Planos futuros


Instale e configure o Eclipse para escrever e depurar código para A7.
Escreva uma demonstração gráfica normal, como um osciloscópio de um M4 ADC.
E, finalmente, faça sua placa controladora com base nesse chip. :)

Links úteis da

Wiki
STM32MP1
Comunidade OpenSTM32 ST
AC6

All Articles