Resumo da primeira aula sobre programação de microcontroladores modernos usando o exemplo do STM32 e do sistema operacional RIOT. As palestras são ministradas no Instituto MIREA de Tecnologia da Informação aos sábados, a partir das 12:50 no auditório no 4º andar do Edifício D. As aulas dão 1,5 horas para a palestra em si e 3 horas para aulas práticas no laboratório de IoT da Samsung Academy sobre o tema da palestra.Olá Giktayms! Como prometemos, estamos começando a publicar anotações de palestras que estão sendo entregues no MIREA IT Institute. De acordo com os resultados da primeira aula introdutória, decidimos mudar um pouco a estrutura do curso - em vez das duas sequências planejadas de 5 lições, haverá uma sequência para 7 lições. Isso tornará possível resolver uma série de perguntas de suporte em um ritmo mais relaxado, além de artigos abstratos aparecerão no GT todas as semanas, durante os meses de março e abril, e não em uma semana, conforme planejado anteriormente.
No entanto, é impossível encobrir completamente um tópico tão extenso em sete palestras; portanto, a apresentação será uma tese em alguns lugares - embora, para compensar isso, tentaremos indicar em que direção aqueles que desejam examinar independentemente mais profundamente esse ou aquele problema procurarão.
O curso foi desenvolvido para alunos do segundo e terceiro ano que estejam familiarizados com a linguagem C e com os conceitos básicos de eletrônica e engenharia elétrica. O conhecimento prévio de microcontroladores não é necessário.
O objetivo do curso é o desenvolvimento de habilidades que permitem que você trabalhe livremente com microcontroladores no núcleo do ARM Cortex-M no nível moderno e, se houver esse desejo, avance para aprofundar ainda mais seu conhecimento.

A palestra de hoje é a primeira, para entender conceitos gerais: o que é um microcontrolador em geral e por que é necessário, o que é firmware e como é obtido, por que precisamos de um sistema operacional e, finalmente, como trabalhar com o git. O resultado desta lição é o seu próprio repositório GitHub com códigos-fonte do SO, bem como um ambiente de construção configurado com sucesso no computador local.
Microcontrolador
Em resumo, o microcontrolador é um exemplo clássico de um "sistema em um chip", que inclui o núcleo do processador e um conjunto de dispositivos auxiliares e periféricos, o que permite que o microcontrolador em muitos casos seja completamente auto-suficiente.

Em um microprocessador típico, semelhante ao de qualquer PC ou smartphone, quase todos os módulos que podem ser atribuídos aos auxiliares (energia, relógio, até dispositivos periféricos básicos) são movidos para fora do próprio chip, apesar do microprocessador funcionar sem eles. não posso.
No microcontrolador, pelo contrário, no mesmo chip com o núcleo, não apenas os subsistemas necessários para sua operação são implementados, mas também uma série de dispositivos periféricos que podem ser necessários em várias tarefas práticas. Além disso, muitos fabricantes de microcontroladores competem entre si não no desempenho principal ou na capacidade de memória, mas na abundância e nas funções dos dispositivos periféricos.
Os microcontroladores vêm desenvolvendo-se em paralelo com os microprocessadores há algum tempo - por exemplo, a arquitetura Intel 8051 ainda encontrada em produtos industriais foi desenvolvida em 1980. Em alguns pontos, as linhas de seu desenvolvimento começam a se cruzar com os microprocessadores - por exemplo, modelos mais antigos de microcontroladores têm interfaces para RAM externa, e os fabricantes de microprocessadores integram cada vez mais dispositivos periféricos ao chip (basta lembrar que, no início dos "computadores pessoais", até o cache externo era discado microcircuitos) - mas, de qualquer forma, eles permanecem dois ramos de desenvolvimento significativamente diferentes.
Na verdade, o objetivo de criar microcontroladores era reduzir o custo e a miniaturização de vários dispositivos que requerem um pequeno poder de computação: o uso de um único chip, para o qual é suficiente para fornecer energia para sua operação, simplifica significativamente o design e a fabricação de uma placa de circuito impresso em comparação com um conjunto de 4-5 chips separados .
Obviamente, o microcontrolador tem suas próprias limitações - é tecnicamente impossível empacotar em um chip o que em um PC grande ocupa metade de uma placa bastante grande.
- As frequências de operação raramente excedem os 200 MHz e mais frequentemente estão na região de dezenas de megahertz.
- A quantidade de RAM está em megabytes e mais frequentemente na região de dezenas de kilobytes.
- A quantidade de memória do programa está em megabytes e mais frequentemente na região de dezenas a centenas de kilobytes.
Como parte do curso, trabalharemos com microcontroladores STM32L151CC que possuem 32 KB de RAM, 256 KB de ROM e uma freqüência operacional máxima de 32 MHz (chips um pouco mais sérios estão nas placas Nucleo-L152RE - 80 KB de RAM e 512 KB de ROM).
A memória
Em geral, pode haver quatro tipos de memória dentro de um microcontrolador:
- A memória permanente ( memória flash) é usada para armazenar programas do usuário e, algumas vezes, algumas configurações do próprio microcontrolador. Se, ao especificar as características do microcontrolador, eles escrevem a quantidade de memória sem especificar qual - como regra geral, trata-se de flash. O conteúdo do flash não é redefinido quando a energia falha, o período de armazenamento de informações nele em condições normais é geralmente de pelo menos 10 anos.
- A RAM é usada para executar um programa do usuário e armazenar dados "momentâneos". A RAM sempre é redefinida quando você reinicia ou desliga e também pode não ser salva quando você entra em alguns modos de suspensão. Nos microcontroladores, geralmente não existe uma separação clara entre a memória do programa e a memória de dados - como resultado, o termo "execução da RAM" pode ser encontrado, significando que na RAM não existem apenas dados, mas o próprio programa; no entanto, esses são casos bastante exóticos.
- EEPROM . Também se refere à memória somente leitura, mas difere significativamente da memória flash em suas características. O flash tem duas grandes desvantagens que tornam muito inconveniente salvar alguns dados atuais do programa - em primeiro lugar, o flash possui um número limitado de substituições da mesma célula e, em segundo lugar, geralmente é possível trabalhar com o flash apenas em páginas inteiras, o que têm centenas de bytes de tamanho, mesmo que você precise substituir apenas um byte. A EEPROM não possui essas desvantagens - sua vida útil geralmente é dez vezes maior (de 100 mil a 1 milhão de substituições) e você pode trabalhar individualmente com cada byte. Por esse motivo, a EEPROM é usada para armazenamento permanente de dados gerados pelo próprio programa (arquivos de medição, configurações do programa etc.), seu volume típico é de unidades de kilobytes, mas não está em todos os controladores.
- Memória do sistema Áreas de memória somente leitura, inacessíveis ao usuário para gravação, mas gravadas na produção do microcontrolador. Geralmente eles contêm o código executável do gerenciador de inicialização (abaixo), mas algumas constantes de calibração, números de série ou mesmo bibliotecas auxiliares para trabalhar com dispositivos periféricos também podem ser armazenadas
Você pode observar a organização da memória de um controlador específico em sua folha de dados. Aqui, por exemplo, há uma
folha de dados no STM32L151CC , na página 51, da qual é apresentado um cartão de memória dessa família.
É fácil notar que todos os quatro tipos de memória, sobre os quais falamos, ocupam um pedaço muito pequeno do cartão - e na maioria das fotos há uma lista de todos os dispositivos periféricos disponíveis no controlador.
Registros
O fato é que tudo - em geral tudo - a comunicação com todos os dispositivos periféricos do microcontrolador e todas as suas configurações é realizada usando apenas duas operações:
- leia o valor no endereço fornecido
- escreva o valor no endereço fornecido
Tudo o que está dentro do microcontrolador é necessariamente mapeado para algum endereço. Esses endereços são chamados de
registradores (não confunda com os registradores do processador - os registradores dos processadores contêm dados nos quais o processador executa operações; os registradores de que falamos contêm alguns dados especiais que mapeiam especificamente o estado de várias unidades de hardware do microcontrolador).
Assim, por exemplo, se queremos que “1” apareça na terceira parte da porta A do microcontrolador (PA2, a numeração é do zero), precisamos escrever “1” no terceiro bit do registro localizado em 0x4002014. E se esse trecho estiver configurado como uma entrada e, pelo contrário, quisermos descobrir qual o valor, precisamos ler o terceiro bit do registrador no endereço 0x40020010.
Sim, para indicar ao controlador esse trecho é a entrada ou saída - você precisa escrever os valores correspondentes nos bits correspondentes no endereço 0x40020000.
Este é um ponto importante para entender a operação do microcontrolador: absolutamente tudo o que não são operações computacionais, pelas quais o núcleo do processador é responsável, é feito escrevendo ou lendo este ou aquele registro. Quaisquer que sejam as bibliotecas que são enganadas no seu programa a partir de cima - no final, tudo se resume a registros.
Obviamente, trabalhar com endereços numéricos é bastante inconveniente, portanto, para cada microcontrolador no núcleo do Cortex-M, existe uma biblioteca CMSIS (Cortex Microcontroller Software Interface Standard), cujo componente mais importante para nós é um arquivo de cabeçalho que descreve os registros disponíveis em um controlador em particular e os fornece relativamente legíveis por humanos nomes.
Usando o CMSIS, as operações descritas acima com o pé PA terão a seguinte aparência:
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- ( : « » , , - ):
