segunda-feira, 7 de abril de 2014

Linguagem C para Sistemas Embarcados

Ola pessoal. Vou iniciar uma série de artigos sobre linguagem C para sistemas embarcados e linux embarcado. E este é o primeiro artigo.

Iniciando no mundo de sistemas embarcados


A nível de sintaxe, não existem muitas diferenças entre o C de PC e o C de sistemas embarcados. A estrutura básica do programa é a mesma: os arquivos de cabeçalho, as definições, a função principal, as funções secundarias, etc. Porém, há algumas diferenças entre a biblioteca padrão ANSI C do PC e do sistema embarcado. Depende de microcontrolador e do compilador usado. 
Em muitos compiladores usados em sistemas embarcados não há a função printf(). Isso mesmo! Você terá que implementá-la manualmente! E também não existe a mesma disponibilidade de bibliotecas que tem para PC.
Também é necessário levar em consideração que muitos microcontroladores têm uma quantidade de memoria limitada. Tanto memoria de armazenamento (ROM/FLASH), quanto memoria temporária (RAM). Mas depende da arquitetura e do fabricante. Os microcontroladores da arquitetura 8051 normalmente têm 8KB de ROM e 128B de RAM. Os da arquitetura PIC já possuem mais memoria RAM e ROM. O pic18f4620, por exemplo, tem 64KB de memoria flash e 3986 de memoria RAM. Já os da arquitetura ARM estão mais próximos de um PC. Eles são microcontroladores de 32 bits e podem endereçar memoria externa. Então, é preciso ter um cuidado redobrado para não estourar a memoria (RAM/ROM) ou a pilha. Já tive problemas sérios com isso!
Quando comparamos a linguagem C do Linux embarcado com a C do linux de PC, praticamente não há diferença. Em muitos casos, você pode até rodar o mesmo programa no Linux do PC e no Linux da placa.

É necessário saber eletrônica?

Sim. Você precisa saber um pouco de eletrônica, para saber o que está fazendo e entender os termos técnicos, além de ler documentos em inglês. Percebeu que no texto acima eu usei palavras como memoria flash, memoria RAM, microcontroladores, arquitetura... Então você precisa saber um pouco de eletrônica analógica, eletrônica digital e principalmente sobre microcontroladores.

Testando e rodando um programa para sistemas embarcados


Normalmente nós escrevemos o código C no computador, compilamos e o executável é gravado na memoria flash do microcontrolador. O fabricante da placa disponibiliza um compilador especifico para gerar o arquivo executável no formato que o microcontrolador entende. Ou o fabricante pode também ter uma IDE completa, com editor, compilador, debugador, gravador, tudo em um só. A Microchip, por exemplo, tem uma IDE completa chamada MPLAB: mplabx.
Para arquitetura ARM existe o keil: mdk. Existe ainda muitos outros compiladores para ARM, incluindo o gcc. E para gravar o executável na memoria flash  use o FlashMagic: http://www.flashmagictool.com/. Alguns desses softwares são pagos, como o Keil.
A partir de agora darei enfase a arquitetura ARM, porque é a mais usada no mercado hoje e também a mais robusta. Nos próximos artigos usaremos o compilador gcc para ARM. Você pode baixar de graça nesse link: gcc-arm-embedded. Também mostrarei exemplos usando a arquitetura PIC, considerando que algumas empresas ainda o usam. O compilador usado para o PIC será o MPLAB c18: MPLAB c18.

Toolchain


Quando você pesquisa na internet sobre compiladores para sistemas embarcados ou para Linux embarcado verá muitas vezes a palavra toolchain ou cross compiler. Toolchain é um programa que roda no PC (chamado de host) e que irá gerar executáveis que rodam na placa alvo (chamado de target). Então nós podemos ter uma toolchain que roda num host x86 que gera código para um target ARM ou MIPS. Mas quando se trabalha com Linux embarcado é possível desenvolver o projeto na própria placa, embora isso não seja recomendado.
Há pelo menos três tipos de configuração possíveis: Configuração Ligada, Configuração de Armazenamento Removível e Configuração Standalone. Na Configuração Ligada o target e o host são permanentemente ligados usando um cabo físico como serial ou ethernet. Na Configuração de Armazenamento Removível não há ligações fisicas diretas entre o host e o target. Apenas um dispositivo de armazenamento é gravado pelo host, transferido para o target, e então usado para iniciar o dispositivo. Configuração Standalone é conforme citei antes, um sistema de desenvolvimento contido em si mesmo e que inclui todo o software necessário para a construção do projeto. Para mais detalhes veja o livro Construindo Sistemas Linux Embarcados do autor Karim Yaghmour.
Um ótimo artigo que fala sobre GNU toolchain pode ser lido no seguinte endereço:

Quando usar um Sistema Operacional


Só é necessário usar um sistema operacional no microcontrolador quando se tem demanda de tarefas de tempo real ou projetos que exigem o controle de vários periféricos ao mesmo tempo, necessitando para isso vários processos ou threads. Ou ainda quando um cliente exija uma interface gráfica para um projeto, porque com simples firmware seria quase impossível ou inviável projetar uma interface gráfica do zero.

Primeiro exemplo de C para sistemas embarcados


Por ser simples e como primeiro exemplo faremos um "Hello Word":

#include <stdio.h>
int main ()
{
     printf("Ola mundo!");
     return 0;
}

Para compilar e testar digite estes comandos (instale o compilador antes):
$ arm-none-eabi-gcc -mthumb -march=armv7 -mfix-cortex-m3-ldrd -T lm3s6965.ld main.c reset.S syscalls.c -o main
$ arm-none-eabi-objcopy -O binary main main.bin
$ qemu-system-arm -M lm3s6965evb --kernel main.bin --serial stdio


Para funcionar você precisa instalar o compilador gcc-arm-embedded e o emulador qemu! Você encontrará os outros arquivos no link de referencia. O arquivo para o linker lm3s6965.ld é especifico para o ARM LM3S6965 da Texas Instruments. Da mesma forma é com os arquivos reset.S e syscall.c. Para cada ARM é preciso configurar um arquivo diferente. E saiba que várias empresas fazem microcontroladores com um núcleo ARM. Samsung, Texas Instruments, NXP, Freescale, AMD, Qualcomm... apenas para citar algumas. Veja a lista completa aqui: http://www.arm.com/products/processors/licensees.php



Nenhum comentário:

Postar um comentário