2 Comentários

Curso de C com microcontroladores MCF51QE128 e MC9S08QE128 – Parte 2

Curso de C com MCF51QE128 MC9S08QE128

MATERIAL DESENVOLVIDO PARA TREINAMENTOS DURANTE O LANÇAMENTO DA LINHA FLEXIS DA FREESCALE EM 2009.

1. A placa de exercícios: DEMOQE128

c-flaxis-1
c-flaxis-2

1.1. Esquemas elétricos da DEMOQE128

1.1.1 Alimentação

c-flexis-3

1.1.2 RS232 e USB

c-flexis-4

1.1.3 Botões

c-flexis5

1.1.4 BDM

c-flexis-6

1.1.5 Resistores

c-flexis7

1.1.6 Acelerômetro

c-flexis8

1.1.7 Buzzer e I2C

c-flexis9

1.1.8  Leds

c-flexis-10

1.1.9  Microcontrolador

c-flexis-11

1.1.10  Potenciômetro

c-flexis-12

1.2 Instalando os drives do gravador

Ao colocar a placa DEMOQE numa porta USB, o Windows XP abrirá a tela abaixo, solicitando a instalação do driver. Para tanto o Code Warrior já deve estar instalado. 

c-flexis-13

Deve-se clicar em NÃO, NÃO AGORA, e em seguida em AVANÇAR. 

c-flexis-14

O próximo passo é indicar onde estão os arquivos do driver DEMOQE para o os microcontroladores Flexis. Assim deve-se selecionar a opção INSTALAR DE UMA LISTA OU LOCAL ESPECÍFICO na tela abaixo, clicando em seguida no botão AVANÇAR. 

c-flexis-15

Ao clicar em avançar, clique no combo Box INCLUIR ESTE LOCAL NA PERQUISA, e clique no botão procurar:

c-flexis16

O endereço a ser selecionado é: C:\Arquivos de programas\Freescale\CodeWarrior for Microcontrollers V6.2\Drivers\ , Como pode ser visto na figura a seguir.

c-flexis17

Clique em OK para selecionar o caminho mostrado na janela acima.

Com o caminho selecionado, clique em AVANÇAR. Aparecerá a janela de confirmação de instalação, como é mostrado a seguir. Note que está sendo instalado o USB Multilink (i0). Após este processo ainda faltará instalar o USB Serial Port (i1), que abordaremos a seguir.

c-flexis18

Aguardando poucos segundo, deve ser finalizada a instalação do USB Multilink (i0) na  DEMOQE. O mesmo procedimento deve ser inteiramente repetido, passo a passo, para a instalação do USB Serial Port (i1). Após a instalação do segundo elemento, surgirá a tela de finalização (figura a seguir), onde basta clicar em concluir para finalizar a instalação.

c-flexis19

Ao clicar em CONCLUIR, a instalação do PEMicro USB Serial Port será finalizada, permitindo que o kit passe a ser utilizado normalmente.

Para conferir se está tudo corretamente instalado, vá até o gerenciador de dispositivos e verifique se aparece o PEMicro USB Serial Port e o PEMicro USB Multilink, como pode ser visto na figura a seguir. 

c-flexis20

2. O Ambiente Code Warrior

O Code Warrior é um ambiente IDE completo. Suas ferramentas de auxilio de configuração de periféricos e criação de códigos são o grande diferencial deste IDE em relação aos demais de mercado. O Device Inicialization e o Processor Expert, mostrados nas figuras abaixo.

c-flexis-21

Estes dois processos de criação, configuração e edição de projetos no Code Warrior (o Device Inicialization e o Processor Expert) serão abordados apenas no curso de periféricos, a ser ministrado após este primeiro treinamento de linguagem C.

2.1. Começando do zero: criando um novo projeto

Abra o Code Warrior. A primeira tela que será mostrada é para a seleção de uma ação (criar um novo projeto, abrir um projeto de exemplo, abrir um projeto criado anteriormente, rodar um tutorial ou já começar a trabalhar com o Code Warrior), como pode ser visto na figura a seguir.

c-flexis-22

Como a idéia aqui será começar do zero, partindo do pressuposto que não há projetos anteriores, então clicaremos Create New Project. Isto fará com que a tela de configuração de projeto seja aberta, como pode ser visto na figura abaixo.

c-flexis-23

O primeiro passo é selecionar qual o dispositivo que será utilizado no projeto. Nosso curso é focado na família Flexis. Então é necessário clicar nesta família e fazer a escolha, como é mostrado a seguir.

c-flexis-24

Para o nosso primeiro projeto será selecionado o chip de 8 bits (MC9S08QE128). Depois será o momento de selecionar o que você deseja fazer com ele: apenas simular no computador, gravar numa placa de protótipos, etc, o que é feito através da janela ao lado, mostrada na figura abaixo:

c-flexis-25

Durante o nosso treinamento, como utilizamos a placa da P&E, quando quisermos fazer gravações diretamente na placa deveremos utilizar a segunda opção (P&E Multilink/Cyclone Pro). A primeira opção (Full Chip Simulation) é para fazer a simulação completa no software, sem a necessidade da placa de experimentos.

Com estas opções ativadas, basta clicar em avançar para passar ao próximo passo.

c-flexis-26

Agora é o momento de definir a linguagem que será utilizada no projeto. Como nosso curso é focado na linguagem C, esta será a nossa opção.

Além da linguagem de programação utilizada, nesta tela é necessário definir qual será o nome do projeto e onde ele será salvo.

c-flexis-27

Ao definir o nome do projeto, o Code Warrior sempre criará uma pasta com o mesmo nome no local indicado. É nesta pasta que serão armazenados todos os dados referentes ao projeto. Com estas informações definidas, clica-se em avançar. Aparecerá a próxima tela:

c-flexis-28

Nesta tela podem ser acrescentados ao projetos arquivos externos, que estão em endereço diferente daquele que foi definido como local para gravação do projeto.

Por exemplo: uma rotina previamente montada para um periférico, num arquivo do tipo .h (header), pode ser adicionada a um projeto através desta tela.

Se não existem arquivos a serem adicionados, então basta clicar em avançar. Este será o caso do nosso primeiro projeto. Assim, aparecerá a próxima tela, mostrada a seguir.

c-flexis-29

Nesta tela podem ser selecionadas as ferramentas de ajuda de desenvolvimento de projetos: o Device Initialization e o Processor Expert. Abordaremos estas ferramentas apenas quando tratarmos do periféricos do dispositivos. Então por enquanto clicaremos em NONE e em Avançar.

c-flexis-30

Na janela de opções da linguagem C/C++ são definidas as configurações que o código escrito assumirá dentro do compilador e do microcontrolador. A primeira opção é se um código iniciará com as informações mínimas possíveis ou se seguirá o padrão ANSI.

Depois deve-se selecionar o modelo de memória a ser seguido pelo compilador. As opções
são Tiny, Small e Banked:

  • Small: neste modelo todas as variáveis estão fora da página zero (localizam-se na memória de acesso extendido). Se existirem variáveis na página zero elas poderão ser utilizadas com pragmas ou palavras chave próximas. Ponteiros terão, por padrão, 16 bits de tamanho e o compilador não usará o modo de endereçamento direto.
  • Tiny: por padrão todas as variáveis estarão dentro página zero (localizam-se na memória de acesso direto). As variáveis que estiverem fora da página zero podem ser acessadas com pragmas ou palavras chaves distantes. Os ponteiros são declarados como 8 bits e o endereçamento direto é o método utilizado pelo compilador.
  • Banked: a memória será dividida em bancos com tamanhos fixos.
c-flexis-31

É necessário pensar bem qual será a escolha a ser feita nesta seleção, pois isto pode impactar que os ponteiros de seu programa não podem acessar regiões de memória distantes, como mostra a figura a seguir:

c-flexis-32

Apenas utilizar a condição padrão que vem setada no Code Warrior (Small), pode deixar
indisponíveis os ponteiros que foram declarados na opção Tiny.

Outro ponto a ser observado é que quando criamos um projeto novo o software seleciona a biblioteca ANSI compatível com o modelo de memória que foi adotado. Quando mudamos este modelo manualmente o programador deve ter em mente que as opções de compilação do projeto devem ser alteradas.

A última opção desta tela é o formato do ponto flutuante que será utilizado caso uma variável seja declarada deste modo no programa. Aqui vai uma dica: uso ponto flutuante em seu programa apenas se isto for extremamente necessário, dada a quantidade de recursos de processamento e alocação de memória que um ponto flutuante consome.

Feitas todas estas considerações e configurações, basta clicar em avançar para passar para a próxima tela.

c-flexis-33

Não utilizaremos o recursos PC-Lint nos nossos treinamentos, portanto clicaremos na opção NO e em seguida em CONCLUIR.

Após esta configuração inicial deve ser aberta a tela de trabalho do Code Warrior, como é mostrado na figura abaixo.

c-flexis-34

O projeto criado terá a estrutura mostrada a seguir.

c-flexis-35

O programa principal recebe o nome padrão de main.c. Clicar duas vezes nele fará com que ele seja aberto, mostrando a estrutura básica que é criada pelo Code Warrior, como se pode visualizar na figura abaixo:

c-flexis-36

A partir deste ponto o programador deve escrever o seu código, compilar, retirar os erros de digitação, testar, debugar, etc., até que o programa atinja o objetivo proposto.

Para exemplificar o que queremos dizer, vamos escrever um código simples, que  simplesmente fará piscar um led na placa DEMOQE. O código está abaixo.

c-flexis-37

Após a digitação, devemos gravar o código na placa. Para isto, basta clicar no ícone DEBUG que fica na barra logo abaixo do nome do projeto, como pode ser visto na figura abaixo:

c-flexis-38

Mas lembre-se que para a gravação ocorra, é necessário estar selecionado o P&E Multilink/Cyclone Pro, pois caso contrário o Code Warrior apenas fará uma simulação no computador, não se comunicando com a placa de experimentos.

Se tudo estiver correto, deve aparecer a tela mostrada a seguir.

c-flexis-39

Com o kit conectado a porta USB do microcomputador, basta clicar no botão CONNECT (RESET) para dar início a gravação, o que é indicado pela seguinte tela, que informa que o conteúdo anterior da memória flash será sobre escrito, ou seja, totalmente apagado.

c-flexis-40

Clicando em YES, dá-se início ao processo de gravação, o que pode ser acompanhado através de uma tela de mensagens.

c-flexis-41

Ao término desta atividade será aberta uma nova janela, que será utilizado para o processo de depuração em tempo real do programa, que é mostrada abaixo.

c-flexis-42

Será nesta tela que abriremos as janelas para verificar todo o comportamento do chip e do programa. Nesta parte do software é possível acompanhar o funcionamento do dispositivo bit a bit.

Ela será o nosso maior aliado durante esse treinamento.

2.2. Como funciona o compilador

2.2.1. Quais detalhes devem ser observados na escolha de um compilador?

Praticamente todas as aplicações embarcadas atuais tem a necessidade de um compilador. Atualmente não é necessário gastar um grande tempo na escolha do mesmo, já que muitos fabricantes desenvolvem ferramentas em conjunto com os dispositivos que colocam no mercado. Mas a escolha de um compilador deve ser acompanhada de uma pequena lembrança: o diabo mora nos detalhes. A diferença entre uma boa e uma péssima ferramenta de trabalho pode estar em pequenas coisas. Algumas características que podem
fazer toda a diferença em compiladores são:

  • Inserção de trechos de programa em Assembly: quase 40 anos depois do invento da linguagem C, ainda é comum, para sistemas embarcados, a necessidade de trechos de programa serem escritos em linguagem Assembly, para garantir a velocidade de acesso a determinados periféricos.
  • Funções de interrupção: outra função extremamente desejada de um compilador para sistemas embarcados é que ele possa trabalhar com interrupções. Esta não é uma função nativa para o C de desktops. Quando utilizada como parte de uma declaração de função, é informado ao compilador que ele terá que trabalhar uma ISR (interrupt service routine). Deste modo o compilador terá que gerar informações extras sobre a pilha e salvar os registradores de trabalho importantes, devendo ter um mecanismo de restauração a cada saída de interrupção. No Code Warrior, isto é feito através da estrutura do microcontrolador, mais especificamente, através de sua tabela de vetores de interrupção. Assim, o modo de adicionar funções de interrupção é feito através de um pragma, como #pragma interrupt(0x1E).
  • Geração de código em linguagem Assembly: ter um compilador que faça a geração de listas em linguagem Assembly como parte do processo de compilação é extremamente desejável. Esta funcionalidade é muito útil para uma otimização manual do código, pois permite que facilmente seja visto o código que é produzido para cada comando dado em linguagem C. Assim é possível perceber o quanto determinado comando em uma linguagem de alto nível, como é o caso do C, impacta na produção da linguagem de baixo nível, caso do Assembly. Com estes dados em mãos o programador tem ferramentas para decidir como direciona seu código em C para produzir um código em Assembly com o melhor aproveitamento possível.
  • Bibliotecas padrão: quando você está desenvolvendo o software para a sua aplicação em um computador de uso geral, você espera que o compilador inclua o conjunto de bibliotecas padrão da linguagem C, bibliotecas matemáticas e talvez até as bibliotecas de classes C++. Isto irá incluir diversas rotinas como memcpy(), sin(), e cout, respectivamente. Porém, como estas funções destas bibliotecas não são estritamente parte do C e do C++, muitas vezes o fabricante do compilador as omite.
  • Código de inicialização: este pode ser um pedaço extra do software que é executado antes do main. O código de inicialização é geralmente escrito em linguagem Assembly e é conectado com os demais executáveis quando o programa é construído. A sua função é preparar a maneira como os programas que foram escritos em linguagem de alto nível serão executados.

É óbvio que compiladores que não tenham algumas destas características podem ser considerados bons. E sem dúvidas, muitas pessoas questionam que funções como colocação de trechos em Assembly no código reduz muito a portabilidade do mesmo. Porém, se você tiver poder de escolha entre diversos compiladores, observem estas características.

2.2.2. O que acontece quando eu clico em construir (build)?

c-flexis-43

O compilador pega os arquivos em código de máquina (Assembly), em linguagem C e, para os mais corajosos, em C++. Todos os arquivos de cabeçalho (headers) também são  introduzidos. De posse de todos estes arquivos o compilador os combina para criar arquivos objeto de saída.

Arquivos de saída em código Assembly também podem ser gerados, no entanto, é  necessário ter a consciência de que os locais e endereços absolutos das funções ainda são desconhecidos neste momento.

O vinculador (linker) é o responsável por pegar os arquivos objeto de saída e colocá-los  dentro do mapa de memória do dispositivo alvo. O compilador não tem conhecimento do mapa da memória. Assim, com a exceção dos recursos colocados explicitamente através de endereçamento absoluto, o compilador não tem nenhum conhecimento a respeito de onde  as funções serão colocados. Então, você pode esperar para ver, neste momento, um monte  de endereços de 0x0000.

Diferentemente de um programa para desktop, o compilador para programas embarcados precisa ser capaz de gerar um código que será executado em ROM e, esperamos, que caiba na ROM disponível, através da aplicação de uma variedade de otimizações que podem ser configuráveis pelo usuário.

Qualquer compilador que suporta ANSI C deve ser capaz de gerar um código reentrante.

E, obviamente, o conjunto de ferramentas deve apoiar todos os membros de uma família de microcontroladores e seus modelos de memória diferentes. O Code Warrior faz tudo isso.

c-flexis44

2.2.3. Qual a função do vinculador (linker)?

c-flexis-45

O vinculador (linker) é responsável por combinar os arquivos do de saída do compilador e, com a ajuda de um parâmetro de descrição de arquivos de destino, determinar o lugar de cada objeto dentro do mapa de memória do microcontrolador alvo.

A saída do vinculador é um arquivo de dados hexadecimais utilizado para programar o dispositivo de destino. Na Freescale, temos tradicionalmente utilizado um arquivo de saída referida como "S-Records".

Um S-Record é um arquivo ASCII de saída de texto que é bastante fácil de ler e fornece endereço de memória de dados e informações para a ferramenta de programação do dispositivo. Cada linha em um S-Record começa um "S" seguido de um número único dígito, que é o comprimento da linha, o endereço e dados de informação, e um checksum de 8 bits no final.

A linha S0 contém apenas o texto que descreve o arquivo ou nome do projeto.

A linha S1 usa um endereço de 16 bits seguido de dados. Um arquivo S-Record típico irá conter muitas linhas S1. A última linha desta série será um S9. Daí o sufixo .S19 que é adotado como padrão de saída do vinculador.

Apenas para conhecimento, as linhas "S2" utilizam 24 bits de resolução e são terminadas por uma linha S8. As linhas "S3" empregam 32 bits de resolução, terminando com uma linha S7. Como as famílias a HCS08 e V1 tem um mapa de memória de 128k, o vinculador irá gerar S37 arquivos.

O vinculador (linker) também irá gerar um arquivo de mapa que é utilizado por depuradores
e contém mais informações de descrição sobre onde tudo correu.

3. Como estruturar um projeto em linguagem C?

3.1. Como fazer a organização dos arquivos

A principal recomendação que é seguida pelo Code Warrior é que os projetos sejam divididos em três níveis de software: Fundação, tradução e aplicação.

  • FUNDAÇÃO: é composto de arquivos que são usados para descrever os recursos do  microcontrolador, em uma linguagem que o compilador possa entender.
    • Normalmente, estes arquivos estão disponíveis e requerem pouca ou nenhuma modificação introduzida pelo projetista. Entre estes arquivos estão:
    • os arquivos de cabeçalho que são traduções diretas das folhas de dados (mcu.h) arquivos de parâmetro em que o vinculador (linker) descreve o mapa de memória (target.prm)
    • arquivos de biblioteca (ansixx.lib) e rotina de inicialização (Start08.c) em ANSI C algumas outras biblioteca de baixo nível e arquivos de tradução como o "bin2hex.h".

• APLICAÇÃO: é composto por arquivos que descrevem a aplicação. Aqui é onde vamos  encontrar a rotina principal (main.c), que é o ponto de partida tradicional para programas em C. Note que aqui não é onde são redefinidos os pontos dos vetores de reset. Após um  power-on reset, o hardware precisa ser inicializado, bem como alguns recursos do software. Por exemplo, o ponteiro da pilha da CPU e as variáveis pré-inicializadas que são globais e/ou estáticas, todas atendidas no "Start08.c". E tudo isto precisa acontecer antes que o "main.c" começe a ser executado. A fim de aproveitar as capacidades de portabilidade de código  existentes na linguagem de programação C, o software escrito em nível de aplicativo não deve ter nenhum dispositivo especificado em suas rotinas ou descrições. Não é desejável  haver linhas de código em Assembly também. Um aplicativo pode precisar ter um conversor AD, escolher um canal deste conversor e ser capaz de iniciar e parar o AD, mas os métodos  exatos necessários para executar essas operações não devem ser colocado no nível da  aplicação. Eles devem pertencer ao nível de tradução

  • TRADUÇÃO: este nível é constituído de funções específicas de projeto e parâmetros que ligam os MCUs alvo com o aplicativo, definindo como é necessário usá-los. Aqui são definidas as macros, os drivers de baixo nível, as rotinas de tempo crítico que pode ou não requerem comando em linguagem Assembly, e rotinas de interrupção de serviço.

A combinação de todos estes arquivos é que gera um projeto, como pode ser visto na figura
abaixo:

c-flexis-46

Quando analisamos os projetos de uma determinada empresa que desenvolve sistemas embarcados, vemos muita semelhança na sua função e operação. Como estes produtos tem que cada vez mais serem melhorados, cada vez mais suas interfaces e outros recursos ganham mais e mais funcionalidades.

Re-escrever o software, quando os produtos devem migrar de uma plataforma de hardware para outra plataforma de hardware pode ser um incrível desperdício de tempo. Mais e mais, o software está se tornando o componente essencial para uma empresa de propriedade intelectual.

O núcleo desta propriedade intelectual, de um produto para outro, normalmente não tem alterações drásticas, apenas ganha alguns aprimoramentos. E, a fim de cumprir prazos cada vez mais curtos para a entrega dos projetos, muitas vezes precisamos confiar no trabalho já feito anteriormente.

Se o software do projeto é montado como foi mostrado na figura anterior, tirando vantagens do design portátil e a capacidade de reutilização da linguagem C, migrar entre os projetos  se torna muito mais fácil, como pode ser visto na figura abaixo.

c-flexis-48

Uma das atividades que faremos constantemente no nosso treinamento, por conta de estarmos trabalhando com dois chips compatíveis pino a pino mas de tamanho de  barramento e arquiteturas de CPU diferentes, é migrar um projeto para outro  microcontrolador, passando de uma CPU de 8 bits para uma CPU de 16 bits.

Como os arquivos do nível de fundação são de baixo nível, em um novo projeto eles podem ser substituídos por atacado. Estes são novos conjunto de arquivos que descrevem o novo MCU alvo. Note que o arquivo anterior Start08.C (core HCS08 de 8 bits) deve ser substituído pelo StartCF.c (core V1 de 32 bits).

Os arquivos de aplicação podem ser copiados cegamente, sem alterações, assumindo que a funcionalidade do projeto não foi alterado. Naturalmente, o motivo para a migração para uma plataforma 32 bits poderia ser adicionar mais recursos e funções. Assim, seria de se esperar que mais arquivos sejam adicionado ao nível de aplicação.

Todo o esforço do nosso software para a portabilidade é focado principalmente no nível de tradução. Aqui é onde os controladores de periféricos, rotinas de interrupção de serviços e funções usando linguagem Assembly residem.

3.2. Uma sugestão de estrutura de um projeto em linguagem C

c-flexis-49

Outros artigos da série

<< Curso de C com microcontroladores MCF51QE128 e MC9S08QE128 - Parte 1Curso de C com microcontroladores MCF51QE128 e MC9S08QE128 - Parte 3 >>
Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Software » Curso de C com microcontroladores MCF51QE128 e MC9S08QE128 - Parte 2
Comentários:
Notificações
Notificar
guest
2 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
Alejandro Mesias Perez
Alejandro Mesias
28/11/2016 07:56

ótimo artigo, bem didático principalmente na parte de explicar como funciona compilação para embarcado.
Queria fazer apenas uma observação, no 3.2 na parte de eventos o fundo cinza com fonte branca ficou difícil de ler o nome dos eventos, talvez fazer um contraste maior de cores.

Talvez você goste:

Séries



Outros da Série

Menu

WEBINAR
 

Soluções inteligentes para acionamento de MOSFETs/IGBTs com família STDRIVE

Data: 08/10 às 15:00h - Apoio: STMicroelectronics
 
INSCREVA-SE AGORA »



 
close-link