Inter e Intra #3.1 – Preparando as IDEs!

Estamos de volta, pessoal!
 
Vamos recapitular o que fizemos até então no nosso novo emprego:
  1. Na primeira parte, definimos o nosso repositório, quais os seus diretórios e como os módulos vão ser separados.
  2. Na segunda parte, definimos as interfaces e os cabeçalhos públicos. Montamos nossos primeiros headers!

Parte 3.1? Como assim?

Membro da equipe avaliando os Pull Requests dos trabalhos da nossa segunda parte. 😴
Os trabalhos na empresa continuam agitadíssimos. Todas as equipes estão trabalhando a todo vapor para poderem dar uma aliviada na carga de trabalho no final do ano (como acontece em todo lugar). 😅
 
Mecânica está terminando as suas primeiras peças e Hardware mandou confeccionar as primeiras PCBs. Enquanto isso nós por aqui também mandamos ver nas nossas duas primeiras partes! Mas nem tudo são flores…
 
Esta semana aconteceu uma reunião de planejamento e pediram para nós para mudarmos nossa organização. Nossos épicos estão muito grandes e as nossas entregas estão exageradamente extensas, prejudicando os trabalhos dos revisores.
 
A diretoria te pediu para quebrar os épicos e entregas em partes menores. Com isso, os trabalhos ficarão mais granulares, a visibilidade vai melhorar e as atividades vão fluir mais. Eles têm razão!
 
Voltando pra vida real, o nosso segundo artigo ficou simplesmente… gigantesco. Percebi ao longo das últimas semanas que o conteúdo que quero passar exige muito mais texto do que eu previa e o resultado é que condensar tudo em só seis artigos vai ficar muito ruim…
 
Assim, vou dividir as próximas partes em mais artigos, começando já nesta terceira parte, que vai ter duas. Hoje vamos preparar as IDEs e na próxima vamos tratar dos testes unitários. Vamos ter um 3.1 e um 3.2! 👀
 
Nosso cronograma de hoje:
  1. Preparar a sua máquina e as IDEs para compilação do nosso projeto nas duas placas de desenvolvimento.
  2. Fazer os projetos de cada placa… compilar! 😎
  3. Entender o que já temos pronto!
 
Mas para quem está mais interessado nos testes unitários, não se preocupem! No final deste artigo deixo uma super dica para vocês já irem se inteirando no assunto! 👊

Atividades no Repositório!

O repositório está atualizado com o conteúdo que vou passar aqui hoje. A fim de que você possa entender melhor tudo o que vou mostrar eu fortemente recomendo fortemente 🙂 que você pegue uma cópia dele para você.
 
Eu comecei a ‘taggear’ as coisas por lá, colocando tags nos commits que representam os trabalhos relacionados à cada parte do nosso projeto. Para o artigo de hoje, temos a tag Inter_Intra_#3.
Dá pra baixar um zip com todo o nosso conteúdo!
Sendo assim, ou faça um clone do repositório, ou baixe o código fonte da tag acima, ok? Vamos lá! 👊

As IDEs e os Workspaces

Vamos utilizar as IDEs fornecidas pelos fabricantes dos microcontroladores, ST e NXP. São eles:
  • Para o STM32F103, o STM32CubeIDE.
  • Para o KL25Z, o MCUXpresso, com o SDK para o MKL25Z128xxx4 (SDK_2.x_FRDM-KL25Z)
 
A instalação deles é relativamente simples então não vou entrar em detalhes. Mas, se precisarem de ajuda, me deem um toque, estou por aqui!
 
Bem… com as IDEs instaladas, quando abrirmos elas a primeira coisa que nos perguntam é de locais para os seus Workspaces:
Vão ser nestes diretórios que as IDEs vão salvar as configurações de como você usa elas. Nesta postagem no StackOverflow (santo lugar by the way 😁) tem uma rica resposta aonde é dado uma boa explicação sobre eles.
 
Eu gostaria apenas de ressaltar os seguintes pontos:
  • Nenhuma informação diretamente relacionada aos nossos projetos ficam armazenados neles.
  • Precisamos ter um diretório para cada IDE. Não use uma mesma pasta para os dois workspaces!
  • Estes diretórios não devem estar dentro do repositório de códigos, mas podem estar em qualquer outro lugar do seu computador. Sugiro colocar dentro da sua pasta pessoal mesmo.
  • Esses workspaces são seus. Configure as IDEs para o seu uso. Ajeite elas para ficarem da maneira que você gosta. 🙂
 
Na figura abaixo mostro como eu fiz, tenho um diretório de workspaces e, dentro dele, uma pasta para cada IDE. Bem simples, né? 

Beleza Andre, mas aonde ficam as configurações dos projetos mesmo?

Elas ficam no diretório do nosso produto, no repositório. Os projetos (Bluepill e KL25Z) possuem suas pastas dentro de blinky/projs: 
Dentro de cada uma delas, os arquivos específicos para aquela placa e para a IDE relacionada:

Variáveis de ambiente e Path variables

Quando formos colocar os nossos projetos para compilar as IDEs terão que montar os makefiles e, assim, temos que apontar nelas aonde estão os arquivos importantes para a compilação.
 
São basicamente dois grupos:
  • Include paths: Arquivos de cabeçalho, que são incluídos por outros arquivos.
  • Source paths: Códigos fonte para serem compilados.
 
É importante que tomemos muito cuidado em como apontamos esses arquivos para as IDEs. Lembremos que estamos trabalhando em equipe:
  • Diferentes usuários vão trabalhar no desenvolvimento,
  • Cada um deles com a sua máquina,
  • Cada um com o seu Sistema Operacional favorito,
  • Cada um com o workspace em um local diferente.
 
Portanto, apontar os arquivos não pode ser feito usando caminhos absolutos. Precisamos usar caminhos relativos. Por esse método, usamos de path variables para ‘falar’ para os Eclipses aonde os diretórios estão. As IDEs expandem essas variáveis com os valores da máquina sendo usada e elas que ‘montam’ os caminhos absolutos quando criarem seus makefiles.
 
Assim, precisamos apontar todos os headers paths e source paths usando como referência apenas:
  • O diretório do projeto sendo compilado.
  • O diretório raíz do nosso repositório.
 
Para o primeiro caso, os próprios Eclipses já fornecem as variáveis que precisamos para apontar pro diretório do projeto. Mas, para o segundo, temos que fazer nós mesmos. Vamos fazer isso usando das variáveis de ambiente.
 
Através delas, temos as seguintes vantagens:
  • É independente de Sistema Operacional, permitindo que, por exemplo, tenhamos pessoas da equipe trabalhando em máquinas com Windows enquanto outras em máquinas Linux.
  • Cada máquina pode ter as suas próprias variáveis de ambiente, permitindo que cada pessoa coloque o repositório aonde bem desejar.
 
Para o nosso repositório precisamos de apenas uma, que vamos chamar de ‘REPOSITORY_PATH‘. Aqui na minha máquina, coloco ela com o caminho ‘Y:\PUBLIC\github\blinky’, que é aonde está o meu clone do nosso repositório.

Variáveis de Ambiente no Windows

No caso de sistemas Windows, ela é declarada em ‘Propriedades de Sistema -> Variáveis de Ambiente’.
Você precisa fazer isto aí na sua máquina também. Declare esta variável e coloque nela o caminho para o seu repositório.
 
Importante: Pode ser necessário reiniciar a máquina para que entre em efeito a variável que você acabou de criar!

Variáveis de Ambiente nas IDEs

Nas duas IDEs você vai precisar declarar estas variáveis de ambiente também, com o mesmo caminho que foi passado logo acima.
 
Com a IDE aberta, vá em ‘Window -> Preferences‘. Na janela de configuração aberta, vá em ‘General -> Workspaces -> Linked Resources‘. Nesta tela, adicione a variável de ambiente também.
 
Lembre-se de fazer isso nas duas IDEs! 👀
Vamos testar se está tudo em ordem: Importe os projetos e…. compile! 👊

Colocando a arquitetura Inter em ação

São com os caminhos relativos nos source paths e include paths que vamos diferenciar os projetos, colocando eles para compilarem algumas coisas em comum, enquanto outras são específicas de cada um.
 
Primeiramente, reparem nas árvores dos projetos. Algumas pastas possuem alguns ícones diferentes:
Esses diretórios são especiais:
  • Virtual Folders são diretórios que não existem no sistema de arquivos do computador, somente no projeto Eclipse. Eles são usados para melhorar a organização das pastas na árvore do projeto.
  • Linked Folders são diretórios que existem no sistema de arquivos do computador mas não estão na pasta do projeto. Eles estão em outros lugares.
 
Nas propriedades do projeto é possível ver e editar os caminhos dos Linked Folders. Repare que todos eles são relativos. A maioria deles é em função do ‘REPOSITORY_PATH’ e o último do ‘PROJECT_LOC’. 
Também nas configurações dos projetos temos os nossos include paths. Eles também são relativos. ‘${ProjDirPath}’ e ‘${RepDirPath}’ se expandem com os mesmos caminhos de ‘PROJECT_LOC’ e ‘REPOSITORY_PATH’, respectivamente.
Vocês repararam que os dois projetos possuem muitos caminhos idênticos, com exceção de alguns? Pois é, essas diferenças são nas implementações que precisam ser diferentes em cada projeto. No nosso caso, apenas as nossas seções de drivers e de board que mudam. O resto, é tudo igual! 🙂

O que já está pronto?

Já preparei os projetos para estarem prontos para adicionarmos nossas lógicas e compilarem corretamente. O que eu fiz foi:

main.c

Nossa rotina main já está implementada na sua versão final. O que ela faz:
  • Chama a inicialização da placa (que vai compilar de acordo com o projeto).
  • Chama as inicializações das nossas aplicações.
  • Inicia o RTOS (abstraído pelo CMSIS-OS).
 
Ela só precisa fazer isso, ficando todo o resto a cargo do RTOS e das aplicações de operarem:
int main(void) 
{ 
  /* Start by initializing all that is required by the board.                 */ 
  myBoard_Init(); 

  /* Now start all the required applications.                                 */ 
  appLed_Init(); 
  appButton_Init(); 

  /* Finish by starting the scheduler.                                        */ 
  osKernelStart(); 

  /* The scheduler should never return, but...                                */ 
  while(1); 

  return 0; 
}

CMSIS-OS

Ainda não tivemos tempo para preparar qual o RTOS que vamos usar, então criei uma implementação ‘dummy‘ que apenas compila. 
Como as nossas aplicações ainda não estão implementadas, só precisamos se preocupar com o osKernelStart:
/** 
 * @file cmsis_os.c 
 * @brief Interface source file for CMSIS-OS library. 
 * 
 * This module provides the routines that external parties can call in order 
 *  to use the CMSIS-OS logic. 
 * This is a temporary source file. As the proper libraries are added to the 
 *  repository, the correct files will replace the temporary ones. 
 */ 
/******************************************************************************* 
 *  INCLUDES 
 ******************************************************************************/ 
#include "cmsis_os.h" 

/******************************************************************************* 
 *  PRIVATE DEFINITIONS 
 ******************************************************************************/ 

/******************************************************************************* 
 *  PRIVATE PROTOTYPES 
 ******************************************************************************/ 

/******************************************************************************* 
 *  PRIVATE VARIABLES 
 ******************************************************************************/ 

/******************************************************************************* 
 *  PUBLIC FUNCTIONS / ROUTINES 
 ******************************************************************************/ 
/** 
 * @brief Start the RTOS Kernel. 
 * @return Status code that indicates the execution status of the function. 
 */ 
osStatus osKernelStart(void) 
{ 
  /* Simply keep itself running an infinite loop.                             */ 
  while(1); 
  return osOK; 
}

SDKs

Adicionei todos os SDKs que vamos precisar:
  • CMSIS Core, que contém todas as definições básicas dos processadores.
  • NXP, que contém o HAL fornecido pela NXP para acessar as funções do KL25.
  • STM32, que contém o HAL fornecido pela NXP para acessar as funções do STM32F103.

HAL, Boards

Adicionei as lógicas necessárias para a inicialização dos microcontroladores.

HAL, Drivers

Adicionei implementações para os drivers das duas plataformas, mas ainda estão vazios, dummies.
 
Com isso, terminamos nossa primeira terceira parte! 🎉

Poxa Andre, eu queria tanto ver dos testes unitários agora!

Bem, o próximo artigo vai ser bem recheado sobre eles! Enquanto isso, gostaria de te convidar para assistir a palestra da minha colega Renata! Neste último fim de semana rolou lá no Embarcados o Embarcados Experience e nele ela falou bastante coisa sobre os testes unitários! Dá uma conferida:
É isso, galera! O que estão achando dos nossos artigos? Fiquem à vontade para comentar, perguntar e compartilhar! Nos vemos em breve! 👏