Além de ter uma boa placa, é sempre bom ter uma boa ferramenta para desenvolver projetos para ela, não concorda? Então. Recentemente apresentei a STM32F429I-Disco, um excelente kit de desenvolvimento da STMicro. Dentre as várias opções que existem atualmente, optei por usar a System Workbench com STM32F429I, por ser uma IDE que recebe suporte oficial da STMicro, possui suporte a ferramentas de geração de código automático tais como STM32CubeMX (ferramenta apresentada pelo Eder Tadeu neste artigo do Embarcados), e conta com uma série de facilitadores que agilizam o processo de desenvolvimento de código e depuração nos microcontroladores e kits compatíveis com STM32.
Também chamado de SW4STM32, o System Workbench é uma IDE gratuita compatível com Windows e Linux (beta), sendo baseada em Eclipse com suporte à toda gama de microcontroladores STM32 e demais placas e kits didáticos associados.
O System Workbench e sua toolchain são desenvolvidos pela Ac6, uma companhia de serviços francesa que fornece treinamentos e consultorias em sistemas embarcados. Todas as ferramentas podem ser obtidas no site openSTM32, que inclui fóruns, blogs e treinamento para suporte técnico. Uma vez registrados, os usuários poderão obter as instruções de instalação na parte Documentation -> System Workbench for STM32, assim como também poderão proceder com o download da solução completa, composta pelo System Workbench e o toolchain. Seguem suas características:
- Amplo suporte aos microcontroladores STM32, Placas STM32 Nucleo, Kits da linha Discovery e placa de avaliação, assim como também a firmware STM32 (bibliotecas Cube HAL ou Standard Peripheral);
- Compilador GCC C/C++;
- Depurador baseado em GDB;
- IDE Eclipse com gerenciamento de equipe;
- Compatível com plugins do Eclipse;
- Suporte ao gravador ST-LinkV2;
- Sem limite de código;
- Multiple OS support: Windows, Linux (Q2’2015), OSX (Q2’2015).
Para baixar, instalar e assim ter acesso à ferramenta, é preciso ir ao site openSTM32, realizar um cadastro (também gratuito) para ter um login de acesso. Com o processo de cadastro concluído, e devidamente logado no openSTM32, vá ao link de download e procure pela opção mais adequada para baixar a aplicação. No meu caso, tomei por base o instalador para Windows 7 ou superior 64 bits, como pode ser mostrado na Figura 1.
Terminado o download do executável instalador, inicie o programa para dar então início ao processo de instalação do System Workbench for STM32. A primeira janela do processo de instalação é basicamente um termo de contrato do uso do programa, como pode ser visto na Figura 2. Marque a opção I accept e clique no botão Next.
Na próxima janela, mostrada na Figura 3, você deverá escolher um local de instalação para o System Workbench. Por padrão, ele ficará no C:\Ac6\SystemWorkbench. Caso tenha preferência por outro local, altere por meio de Browse, selecionando o diretório desejado na janela que irá aparecer. De todo jeito, clique no botão Next para continuar.
Após isso, aparecerá uma janela de aviso informando que o diretório escolhido será criado, tal como mostrado na Figura 4. Clique em OK para continuar.
A próxima janela do processo de instalação é relacionada aos pacotes que serão instalados. Um ponto positivo do processo de instalação do System Workbench é a possibilidade de também instalar o driver ST-Link/V2, necessário para o processo de gravação e depuração das placas Discovery da STMicro. Deixe marcada a opção para o ST-Link/V2 driver, assim como mostrado na Figura 5, e clique no botão Next para continuar.
A próxima janela do processo, mostrada na Figura 6, é basicamente para escolher se o usuário deseja criar atalhos do programa no Menu Inicial e no Desktop para todos os usuários ou apenas para o usuário corrente. Marque a seu critério, e clique em Next para continuar.
Por fim, será apresentado um sumário das opções selecionadas para instalação, tal qual mostrado na Figura 7, apenas a título de informar o usuário do que será feito. Clique no botão Next para dar início à instalação.
Com o início do processo de instalação, será mostrado ao usuário o progresso da atividade, como pode ser visto na Figura 8. Numa primeira etapa, o programa irá instalar o System Workbench, propriamente, copiando os arquivos para o diretório selecionado. Numa segunda parte, irá instalar o ST-Link/V2, conforme marcado anteriormente.
Finalizada a parte de instalação do System Workbench, é iniciada então a instalação do driver ST-Link/V2, como mostrado na janela do processo de instalação presente na Figura 9.
No processo de instalação do ST-Link/V2, o programa irá carregar o guia de instalação do driver. Este não tem muito segredo, é o processo clicando em Next, Next, Next, de sempre. Veja a janela do guia de instalação do driver na Figura 10.
Quando a instalação do driver estiver já em andamento, o Windows irá lhe notificar pedindo autorização para instalar o driver em questão, assim como mostrado na Figura 11. Clique no botão Install para instalar e prosseguir com a instalação.
Se tudo correr bem e os drivers necessários forem apropriadamente instalados, o guia de instalação do driver irá encerrar assim como mostrado na Figura 12, destacando com um sinal de “Conferido” (marcação em cor verde) nos itens instalados. Clique em Finish
Finalizada a instalação do System Workbench e finalizada também a instalação dos drivers ST-Link/V2, o programa de instalação irá então por fim notificar que a instalação foi completada com sucesso, como mostrado na Figura 13. Clique em Done para encerrar o programa de instalação.
Finalizada a instalação com sucesso, inicie o programa System Workbench, seja clicando no atalho criado no Desktop (área de trabalho), seja pelo atalho do Menu Iniciar. Assim que o programa é carregado, é exibida uma tela de Splash, já destacando que a ferramenta é baseada no Eclipse, como mostrado na Figura 14.
Como padrão no Eclipse, é questionado qual o Workspace a ser utilizado na ferramenta. Para quem não está familiarizado, um workspace é um diretório gerido pela ferramenta para armazenar os projetos desenvolvidos. Você pode selecionar um Workspace diferente a cada vez que inicia a IDE, ou caso vá sempre usar um mesmo Workspace, deixe marcada a caixa Use this as the default and do not ask again, ou seja, usará sempre o diretório que você informou como padrão. As minhas opções para workspace são mostradas na Figura 15. Clique em OK para continuar.
Após carregadas as configurações de Workspace, a IDE finalmente irá aparecer, a princípio vazia, sem nenhum projeto, tal como na Figura 16. Como mostrado também na Figura 16, na parte esquerda da IDE temos o Project Explorer, que é a aba que destaca os projetos carregados na IDE. A parte central é destacada para edição dos arquivos de código. A aba da lateral direita é voltada para o acompanhamento de rotinas e variávies, dentre outras coisas. E na parte inferior da IDE temos um conjunto de abas que executam funções específicas, tais como o Console que mostra o resultado das operações (compilação, depuração), tarefas, erros, dentre outros.
Falei, falei, falei. Hora de colocar a mão em código, né? Então, vamos começar agora o processo para criação de projeto com a ferramenta. Neste exemplo, tomarei por base um projeto para código C, o qual é criado por meio da sequência de itens de menu File -> New -> C Project, assim como pode ser visto na Figura 17.
Ao clicar em C Project, irá então aparecer uma janela para você definir o nome do projeto, no campo Project name, além de selecionar opções tais como Project Type e Toolchains. Coloque como nome de projeto blinkLed, e deixe marcada a opção “Empty Project” para Project Type, de modo a criar um projeto vazio, e selecione a opção “Ac6 STM32 MCU GCC” para Toolchains, para fazer uso da toolchain da Ac6. Veja como ficam as opções marcadas na Figura 18. Clique em Next para continuar a criação do projeto.
Na próxima janela são marcadas as opções de configuração para o projeto. Normalmente, ambas as opções Debug e Release estarão marcadas, como visto na Figura 19. Deixe como está e clique em Next para continuar a instalação.
Agora a coisa fica um tanto quanto bem interessante. Na janela de MCU Configuration é fornecida toda uma gama de opções que facilitam a seleção de um microcontrolador/estrutura voltada para uma placa específica, seja NUCLEO, Discovery, EVAL ou até mesmo uma placa customizada. Para o meu caso, deixei todas as caixas de seleção marcadas, e selecionei a opção STM32F4 em Series e STM32F429I-DISCO em Board, destacando assim o microcontrolador empregado na placa utilizada como base para o projeto a ser desenvolvido. Vejam as opções que marquei na Figura 20. Clique em Next para continuar o processo de criação do projeto.
A próxima janela compreende o Project Firmware configuration, que é o ponto onde você irá escolher uma base de código para o seu projeto, podendo ser o Standard Peripheral Library, que se fundamenta no CMSIS, ou Hardware Abstraction Layer (Cube HAL), que é uma nova base para uso de código ARM desenvolvido pela STMicro. Todavia, caso não queria usar nenhuma das estruturas, você também pode marcar a opção No firmware.
No meu caso, deixei marcada a opção Standard Peripheral Library. Observe pela imagem da janela mostrada na Figura 21 que há um aviso em vermelho, no meio da janela, dizendo “Target firmware has not been found, please download it“. Em inglês, essa mensagem significa que o firmware de base desejado não foi encontrado, e pede para você baixar, o que pode ser muito facilmente feito ao clicar no botão Download target firmware. Clique neste botão para iniciar o download do firmware. Aguarde o término do download para clicar em Finish, e veja adiante a continuação do processo com o download do firmware de base citado.
Após clicar no botão Download target firmware, será dado início ao processo de download do firmware de base. Mas antes disso, irá aparecer uma janela com aviso de que o firmware é disponibilizado sob licença STLiberty, contendo partes em GPL, e por fim destacando a necessidade de contato caso queira fazer uso comercial. Marque a caixa I accept the agreement e clique no botão OK, como mostrado na janela da Figura 22.
Bom, agora que você está ciente das licenças envolvidas, a ferramenta irá fazer o download da estrutura de código de base relacionada ao firmware Standard Peripheral. Observe o andamento do download na parte inferior da janela do Project Firmware configuration, tal como mostrado agora na Figura 23.
Terminado o download, agora irá aparecer um aviso de “Firmware STM32F429I-Discovery_FW_V1.0.1 has been found“, que em português quer dizer que a ferramenta agora é capaz de localizar o firmware da opção selecionada. Agora, também observe que mais opções estão disponíveis na mesma janela. Deixe marcada a caixa de seleção Add low level drivers in the project, que adicionará então drivers para controle de GPIO, Clock, ADC, dentre outros, e marcada esta caixa ainda é possível escolher se os drivers serão adicionados As sources (como fontes) ou As static external libraries (como bibliotecas estáticas externas). No meu caso, deixei marcada a opção As sources. Veja também que a ferramenta agora disponibiliza, para a opção de firmware selecionada, opções para incorporar drivers adicionais (STemWin, USB Device, Host, OTG), e adicionais de terceiros tais como suporte FreeRTOS e fat_fs (usado para leitura de sistemas de arquivos). Detalhes da minha configuração são apresentados na janela da Figura 24. Finalizado todo o processo, clique em Finish para encerrar a configuração e gerar o projeto.
Após clicar em Finish, a ferramenta irá carregar a estrutura do projeto e então passará a exibir uma perspectiva tal como mostrada na Figura 25. Caso isso não ocorra, clique na opção C/C++, localizada no canto superior direito da IDE para levar a visualização para perspectiva de edição de código C/C++. Dentre toda a estrutura-base criada para o nosso novo projeto, o principal código é o famoso main.c, localizado no diretório src da raiz do projeto. Os demais diretórios correspondem a bibliotecas e drivers de suporte, conforme as seleções que fizemos na criação do projeto.
Pronto! Vamos agora criar um código exemplo para fazer a seguinte atividade: Ao pressionar o botão AZUL da placa, serão acesos 2 LEDs presentes na placa.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
/** ****************************************************************************** * @file main.c * @author Andre Curvello * @version V1.0 * @date 08-December-2015 * @brief Codigo de exemplo para piscar LEDS com botao na STM32F429I-Disco ****************************************************************************** */ #include "stm32f429i_discovery.h" #include "stm32f4xx.h" #include "stm32f4xx_rcc.h" #include "stm32f4xx_gpio.h" int main(void) { //Criamos uma estrutura para configuracao de GPIO GPIO_InitTypeDef GPIO_InitDef; // Com este comando habilitamos o GPIOG, port onde estao conectados os LEDs // com Real-Time Clock Control (RCC) RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE); //Aqui indicamos que iremos configurar pinos 13 e 14 (led verde e vermelho do PortG. GPIO_InitDef.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14; //Aqui indicamos que serao como saida. GPIO_InitDef.GPIO_Mode = GPIO_Mode_OUT; //Tipo de saida eh "push-pull - pp" GPIO_InitDef.GPIO_OType = GPIO_OType_PP; //Aqui indicamos que os GPIOs serao sem pullup. GPIO_InitDef.GPIO_PuPd = GPIO_PuPd_NOPULL; //Indicamos que o sinal do GPIO eh com clock de 100MHz. GPIO_InitDef.GPIO_Speed = GPIO_Speed_100MHz; //Inicializa sinal do GPIOG com as definicoes parametrizadas GPIO_Init(GPIOG, &GPIO_InitDef); //Agora habilitamos o GPIOA (port onde esta conectado o botao) //com RCC - Real-time Clock Control RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //Agora setamos na estrutura o GPIO 0 - sinal do botao GPIO_InitDef.GPIO_Pin = GPIO_Pin_0; //Definimos esse sinal como entrada GPIO_InitDef.GPIO_Mode = GPIO_Mode_IN; //Sinal de saida do tipo "push-pull" GPIO_InitDef.GPIO_OType = GPIO_OType_PP; //O sinal do botao eh configurado com pull-down GPIO_InitDef.GPIO_PuPd = GPIO_PuPd_DOWN; //Sinal de clock do GPIO com 100MHz GPIO_InitDef.GPIO_Speed = GPIO_Speed_100MHz; //Inicializa o GPIO PortA com a estrutura de configuracao. GPIO_Init(GPIOA, &GPIO_InitDef); //Loop infinito. Le o botao, e seta ou reseta os bits. while (1) { //Se o sinal de entrada do GPIO0 do GPIOA for 1 if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)) { //Seta em 1 os sinais 13 e 14 do GPIOG GPIO_SetBits(GPIOG, GPIO_Pin_13 | GPIO_Pin_14); } else { //Caso contrario, reseta (coloca em 0) os sinais 13 e 14 de GPIOG GPIO_ResetBits(GPIOG, GPIO_Pin_13 | GPIO_Pin_14); } } } |
Após isso, precisamos compilar o projeto para gerar o binário a ser carregado no microcontrolador. Esse mesmo binário é também usado para o processo de debug, que é o que usaremos tanto para carregar o binário, como para controlar e monitorar sua execução.
Para fazer compilar o projeto, basta clicar com o botão direito do mouse no diretório de projeto na aba lateral Project Explorer, e no menu que irá aparecer, clique na opção Build Project. Isso dará início ao processo de compilação. Veja como é o menu na Figura 26.
Se tudo correr bem, e assim esperamos que corra, você verá o andamento do processo de compilação na aba Console, mostrada na parte inferior do System Workbench. Adiante, na Figura 27, mostro uma imagem do Console exibindo o resultado final do processo de compilação, onde é destacado o arquivo blinkLed.elf, que é o firmware a ser carregado na placa. A última mensagem “Build Finished”, escrita em azul, indica que o processo de compilação foi realizado com sucesso.
Bom, visto que o projeto foi compilado sem complicações, vamos então iniciar o processo de Debug para ver o código em execução na placa? Pois bem, para realizar o Debug do projeto, é preciso clicar com o botão direito do mouse no diretório do projeto na aba lateral Project Explorer, e agora iremos na opção Debug As, e nessa opção iremos escolher o item Ac6 STM32 C/C++ Application, assim como é mostrado na Figura 28.
Quando você clicar nessa opção, a IDE irá lhe avisar que será feita uma mudança de perspectiva. Como assim? Antes, estávamos na perspectiva C/C++, voltada para edição de código e gestão de projeto. Agora iremos para a perspectiva Debug, que é voltada para o controle da execução e acompanhamento da execução do código no microcontrolador. Assim, irá aparecer uma janela de aviso tal qual mostrada na Figura 29. Marque a caixa Remember my decision para que essa janela não seja mais exibida e clique em Yes para continuar.
Após clicar em Yes, a IDE irá carregar os componentes necessários e irá mudar o visual para a perspectiva de Debug, ficando então com uma aparência tal como a mostrada na Figura 30.
Para executar o código na placa, é preciso então clicar no botão Play (na verdade ele se chama Resume), o que também pode ser feito ao se pressionar a tecla F8, como mostrado na Figura 31. Ao clicar neste botão, o código (que já foi carregado na placa quando você entrou na perspectiva de Debug), será liberado para execução.
Com o código em execução, vamos então ver seu funcionamento na placa! Ao apertar o botão azul da STM32F429i-Disco, os dois LEDs próximos ao botão devem acender, sendo um na cor vermelha, outro na cor verde. E ao soltar o botão, ambos os LEDs devem ser apagados. Vejam o que acontece ao pressionar o botão na Figura 32.
Para encerrar o processo, basta clicar no botão “Terminate” (que eu gosto de chamar de Stop), ou usar o atalho de teclado Ctrl+F2, tal como mostrado na Figura 33. Após isso, o código em execução será suspenso (mas ele está gravado no microcontrolador!). Com isso, você pode, por exemplo, mudar de perspectiva e voltar à C/C++ para fazer eventuais modificações no código, por exemplo.
Mas, de nada adiantaria tudo isso sem um simples exemplo do tipo… pisca LED, não? Então. Vamos voltar à perspectiva de desenvolvimento C/C++ clicando no respectivo botão, localizado no canto superior direito da IDE e mostrado em destaque na Figura 34.
De volta à perspectiva C/C++, coloquem o seguinte código abaixo para fazer um pisca LED com frequência de 1 Hz (ou seja, os LEDs irão piscar 1 vez por segundo). Tomei como base o código mostrado neste link.
Observem os comentários no código para acompanhar a lógica da aplicação, e o que cada rotina faz. O que este código faz de diferente é que agora é implementado um simples tratamento de interrupção do recurso SysTick do microcontrolador. Na rotina principal, main(), configuramos o SysTick para gerar uma interrupção a cada milissegundo. E depois usamos uma rotina chamada SysTick_Handler() para tratar cada ocorrência de SysTick. Para mais detalhes sobre o mecanismo de resposta ao clock de sistema, veja este link sobre SysTick.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
/** ****************************************************************************** * @file main.c * @author Andre Curvello * @version V1.0 * @date 01-December-2013 * @brief Codigo exemplo para piscar os LEDs da STM32F429i-Disco a cada 1Hz ****************************************************************************** */ #include "stm32f4xx.h" #include "stm32f429i_discovery.h" #include "stm32f4xx_rcc.h" #include "stm32f4xx_gpio.h" //Variavel uint32 para contar milissegundos. //volatile determina que pode ser acessada e modificada //em diversas partes do codigo. volatile uint32_t msTicks; //A cada ocorrencia de SysTick, o sistema faz uma chama a essa rotina void SysTick_Handler (void) { //E nessa rotina, incrementamos +1 a variavel msTicks. msTicks++; } //Funcao de delay - recebe atraso em ms void Delay(uint32_t dlyTicks) { //Variavel uint32 para ponto de partida de contagem uint32_t curTicks; //Ponto de partida recebe msTicks original neste ponto curTicks = msTicks; //Segura a execucao do codigo enquanto a diferenca //entre msTicks (modificado pelo sistema) e curTicks (do ponto de chamada) //for menor que o delay passado por parametro pra funcao. while ((msTicks - curTicks) < dlyTicks); } int main(void) { //Configura a interrupcao de SysTick a cada milissegundo SysTick_Config (SystemCoreClock / 1000); //Habilita clock no GPIOG - Leds RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE); //Cria estrutura para configuracao de GPIO. GPIO_InitTypeDef GPIO_InitDef; //Define GPIOs como sinais 13 e 14 GPIO_InitDef.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14; //Sinal de saida como Push-Pull GPIO_InitDef.GPIO_OType = GPIO_OType_PP; //GPIO como sinal de saida GPIO_InitDef.GPIO_Mode = GPIO_Mode_OUT; //Sinal do GPIO sem pull-up nem pull-down GPIO_InitDef.GPIO_PuPd = GPIO_PuPd_NOPULL; //GPIO com clock de 100MHz GPIO_InitDef.GPIO_Speed = GPIO_Speed_100MHz; //Inicializa os sinais com a estrutura de GPIO usada GPIO_Init(GPIOG, &GPIO_InitDef); while (1) { // Essa rotina faz com que os sinais sejam invertidos. // Ou seja, se forem 0, viram 1. Se forem 1, viram 0. // De modo a causar o efeito de alternancia do pisca LED // a cada 1 segundo do delay GPIO_ToggleBits(GPIOG, GPIO_Pin_13 | GPIO_Pin_14); // Dispara o delay de 1 segundo = 1000 ms. Delay(1000); } } |
Seguindo a mesma abordagem apresentada anteriormente, faça então primeiramente o Build do projeto, e depois de completado o Build com sucesso, inicie o seu Debug, selecionando Debug As -> Ac6 STM32 C/C++ Application. Na perspectiva de Debug, clique no botão Resume para iniciar o código na placa, e visualizar então seu pisca LED!
Veja no GIF abaixo o funcionamento da placa com o código de pisca LED em execução.
Muito legal o artigo!
O SW4STM32 vai ser o novo substituto do CooCox para desenvolvimento gratuito, e já melhorou kilometros desde sua versão 1.0.0
E o melhor, tem suporte ao CubeMX! 😀
Como sugestão, seria muito legal um artigo sobre o uso da pilha gráfica STemWin nessa placa, o que acelera muito o desenvolvimento com TFTs.
Abraço!
Rapaz, curti a sugestão!
Vou levar em consideração.
A próxima publicação que eu tenho em mente é um overview sobre os demos pra placa, mas falar da STemWin é uma bolada!
André, primeiramente parabéns pelo artigo, estou iniciando os estudos sobre a linha STM32 e estou gostando muito, aqui no embarcados achei muita informação sobre ela. Encontrei o projeto da Maple Mini STM32F103CB e fiquei muito interessado devido ao tamanho, porém parece que o projeto foi descontinuado, você conhece algum projeto que tenha a STM32 que seja Mini ?
Obrigado pelo feedback positivo!
Perdão, mas não entendi direito. Você procura é uma placa “pequena” com STM32? Posso indicar algumas se for esse o caso.
Isso mesmo André, uma placa pequena com a STM32, você conhece algumas ? eu estava olhando a STM32F103RCBT6 ARM Cortex-M3 leaflabs Leaf maple mini module for arduino STM32.
Olá!
Pequena como a Leaf Maple eu não conheço.
Mas eu sempre recomendo a linha de mbed da ST, que são as placas NUCLEO. Tem desde Cortex M0 até M4, e você pode tanto usar a plataforma mbed quanto as ferramentas usadas na industria como as citadas nos posts aqui no Embarcados (CubeMX, IAR, Keil, SW4STM32, etc…)
Gosto muito das NUCLEO e possuo uma, mas encontrar ela no br é complicado, essa que tenho trouxe da Europa… alguém sabe aonde encontrar no Brasil?
Diego?
nao sei se ajuda, mas tem uma placa controladora de drones que usa o stm32 e aindda tem codigos abertos na internet (eh bem barata). Procure por NAZE32 (a placa) e por Cleanflight/Betaflight (firmware). Acredito que seja um otimo repositorio para aprendizado, já que a placa tem interface para gravacao de fw via usb e ainda interage com portas softserial e chips com acelerometro/giroscopio (alem de controlar motores).
Gente, por favor, estou tendo um problema muito crítico com o Workbench
Ele não está compilando alterações no meu código.
Eu modifico as coisas, mando compilar, mas ele diz que não tem nada a alterar e o make não faz nada
Por favor, alguém poderia me ajudar?
Email: [email protected]