You are on page 1of 17

Copyright2007HansJrgSchneebeli

Cparamicrocontroladores
HansJrgSchneebeli

Objetivo

O objetivo mostrar como se pode programar dispositivos, como


microcontroladores,comrestriesseverasderecursos(memriaevelocidade),
de uma maneira eficiente usando C. suposto que o leitor j tenha
conhecimentosbsicosdeC.

Introduo
Devidoarestriesdecusto,tamanhoeconsumo,emsistemasembarcadosso
usados microcontroladores com pouca memria e baixa velocidade. Deve ser
notadoqueocustodeprogramaoumcustonorecorrente,equeocustode
um microcontrolador maior se refletir em um custo maior por cada unidade
fabricada. Alm disso, deve ser notado ainda que um tempo maior de
desenvolvimentoaumentaocustoediminuiotempodemercadodeumproduto.

Porfim,geralmente,existemrestriesdetempoderespostaqueexigemtcnicas
eficientesdeprogramao.

Alternativasparaprogramao
Entre as linguagens usadas ou projetadas para uso em sistemas embarcados,
destacamse:
Assemblypossibilitacdigomaiseficienteemtermosdevelocidadeeuso
dememria,masinerentementenoportveleexigetempomuitogrande
dedesenvolvimento.
Cpermitetempomenordedesenvolvimento,masexigeumadisciplinado
programador, similar a exigida em Assembly. No tem suporte direto a
concorrncia.
C++permiteousodetcnicasdeprogramaoorientadaaobjetos,mas
apresenta problemas de tamanho de memria e de velocidade. Para
diminuir estes problemas existe uma verso mais enxuta, chamada

1de17
Embedded C++, que impede o uso de mecanismos que aumentam
demasiadamente o consumo de memria, ou tornam o comportamento
temporaldificildeprever.Entreosmecanismosdescartadosestoherana
multipla,exceesetemplates.
Java embora tenha sido inicialmente planejada para sistemas
embarcados,ademandapormemriaexcessivaparaamaiorpartedas
aplicaes.Ofatodenoserocomportamentonotemponoserprevisvel
devidoaogarbagecollectorimpedeoseuusoemcertasaplicaes.
Ada foi desenvolvida especialmente para sistemas embarcados, tem
suporteembutidoaconcorrncia,existeumpadroparaalinguagem,mas
verbosaeocdigoresultantemaioremaislentodoqueogeradoporC.
Esterelrepresentaumaalternativainteressanteparaaprogramaode
sistemasreativos,comoocasodesistemasembarcados.
Outras Existem ainda linguagens como Forth e dialetos de Basic ou
Pascal,masousodestesmuitoraro.

Originalmente,ossistemasembarcadoseramdesenvolvidosemAssembly.Como
aumentodecomplexidadedestessistemaseapressoportemposmenoresde
desenvolvimento, o uso exclusivo de Assembly tem diminuido, e hoje alcana
apenas cerca de 8% dos projetos. Devido a facilidade de se construir um
compiladorC,eofato dequealinguagemimplementa um nveldeabstrao
bastante prximo ao hardware, a linguagem C representa um excelente
compromisso entre eficincia e facilidade de programao. Atualmente, a
absolutamaioria,cercade90%dossistemas,sodesenvolvidosemC/C++,as
vezes com alguma parte pequena em Assembly. O uso do Embedded C++
crescente mas ainda representa uma parte menor do uso do C. Finalmente o
restantefeitobasicamenteemJava,masdeseesperaroaumentodeseuuso,
principalmenteemsistemascomocelularesePDAs.

AlinguagemC
C foi desenvolvido por Richie e Kernighan na dcada de 70 para servir como
ferramentadeumsistemaoperacional,quemaistardepassouaserconhecido
comoLinux.Anfasefoiemdesempenhoeportabilidade.Ousuriotpicoseria
programador experiente, que necessitasse acessar recursos de hardware,
manipularbitsegerenciarmemria.

OUNIXfoiusadoemambientesuniversitriosnadcadade80.Pelofatodeum
compiladorCfazerpartedamaiorpartedasinstalaesUNIX,muitosoftwarefoi
escrito usando este compilador j disponvel. Alm disso, no final da dcada
passou a haver uma verso livre de um compilador C bastante eficiente

2de17
(chamandoGNUCC,oumaispopularmentegcc).AssimoCacabousendousado
no desenvolvimento de aplicaes fora de suas intenes originais. Isto por
exemplo,ocasodesoftwarematemticabaseadoemmanipulaodematrizes,
ondeosuportedalinguagemcatastrfico.

OresultadoquealinguagemCumadasmaisusadasatualmenteebase
para vrias outras linguagens como C++, Java e C#. No entanto, no
desenvolvimentodesistemasembarcadosqueso,pornatureza,maisprximos
as intenes originais da linguagem que ele mais usado, representado uma
alternativaaousodelinguagensdemontagem(assembly)comresultadosmuito
bons.Emboraumbomprogramadorusandoassemblypossagerarcdigomenor
e mais rpido que o gerado por um compilador C, atualmente a diferena em
desempenhoetamanhonorelevante.Nopiordoscasos,otrechocrticopode
serprogramadoemAssemblyeorestanteemC.

AdiferenadetamanhodecdigogeradoededesempenhodevidoaousodoCou
doassemblydependentedaarquiteturadomicroprocessadoralvo.Emalgumas
arquiteturas,comconjuntodeinstruesmaisadequados,adiferenapodeser
daordemde10%,emoutrasdeat300%.

OusodoCimplicananecessidadededisciplinaporpartedoprogramador.Dois
errossomuitocomuns:
Usarumareaquejfoiliberada(danglingpointers)
Usaralmdareaalocada(memoryoverflow)

Este soresponsveis por uma grandequantidadede falhas desegurana em


cdigos para PC. Algumas linguagens como Java e C# possuem um esquema
automtico de liberao da rea e de controle de acesso. Isto, no entanto,
representaumcustoadicional,emtermodememriaedevelocidadedeexecuo
almdoaceitvelparaomaiorpartedosprojetosdesistemasembarcados.Como
alinguagemCdeixaporcontadoprogramadorocontroledeacesso,estedeve
colocarexplicitamenteostestesdeverificaodelimites.

Ascaractersticasprincipaisdalinguagemso:
Estruturasimplescompoucaspalavraschave.
Operaesdeentradaesadasofeitaspormeiodebiblioteca.
Flexibilidadedeimplementao.
Manuseiodememriapormeiodeapontadores.
Operadoresincrementoedecremento.
Portabilidade.

O modelo de execuo simples, baseado em uma estrutura de pilha. No

3de17
momento em que uma rotina chamada, suas variveis locais so alocadas.
Quandodesuaexecuo,diretamenteapenassuasvariveislocaiseasglobais
(definidasforadocontextodequalquerrotina)soacessveis.Quandoarotinase
encerra,aexecuocontinuanarotinaqueachamou,restaurandooacessoa
suasvariveislocais.

Figura:AchamaB,quechamaC

Paragarantiraportabilidade,aespecificaodetamanhodevariveisemC
extremamenteflexvel.Elaestabeleceapenasonmeromnimodebitsdecada
tipo,comomostradonatabelaabaixo.

TamanhosTipicosusadosemCompiladores

Tipo mnimo 8bits 16bits 32bits 64bits 64bits


(ILP64) (LP64)

char 8 8 8 8 8 8

short 16 16 16 16 16 16

int 16 16 32 32 32 64

long 32 32 32 64 64 64

longlong* 64 64 128 128

ponteiro 16 16 32 64 64 64

float 32 32 32 32 64 64

double* 32 32 32 64 64 64

longdouble* 128 128 128 128


*PadroC9X

Outrasreasquenosepodegarantirotipodeoperaodedeslocamentopara
adireita(serepeteounoobitdesinal)earepresentaodenmerosnegativos.

VersesdoC
KR Verso original. no havia checagem de parmetros (exceto por uma
ferramentaexternachamadalint).
C89 VersopadronizadapelaANSI.Bibliotecaspadronizadas.Sointroduzidos
prottiposderotinaseapalavrachavevoidindicaausnciadeparmetros
oudevalorderetorno.
C99 Tipospadrodetamanhodeterminado(stdint.h).Comentrioscom//.

4de17
UsoemMicrocontroladores
Emmuitasarquiteturasdemicroprocessadores,aspilhassoimplementadasde
maneiramuitoineficientee/ouapresentaolimitaessriasparaotamanho
oucontedo.Porexemplo,pilhasnoMicrochipPICpodemconteremalgunscaso,
soitoendereosderetorno.

MISRA
Cyclone

A maior parte do compiladores para microcontroladores atuais usa ainda o


padroC89.OsitensdopadroC9Xestosendopaulatinamenteincorporados.
Porexemplo,quasetodosjaceitamcomentriosdotipo//.

TiposdeDados
Ostipospadrodedadossoinadequadoparaousoemsistemasembarcados,
se houver necessidade de definio de tamanho. Existem ento algumas
alternativasparadefiniodevariveiscomtamanhoconhecido:
Padro(somenteC9X)
Usodepreprocessador
Usodedefiniodenovotipo

OpadroC9Xestabeleceumcabealhoquedefineumconjuntodetipospadro
comtamanhoprestabelecido.Aimplementaopodeserfeitapelocompilador
dediversasmaneiras,inclusiveusandosimplesmenteumadefinicodenovotipo.
Oarquivocabealhoostdint.hedefine,entreoutros,

inteiroscomsinal int8_t int16_t int32_t int64_t


inteirossemsinal uint8_t uint16_t uint32_t uint64_t

Quandonohouverestearquivo,uma maneira aindacomumousodepr


processadorparadefinirostiposabaixo.Istodeveserajustadodeacordocomo
compiladoreoprocessador.

BYTE Byte 8bits unsignedchar


WORD Word 16bits unsignedshort
INT Int 16/32bits
LONGWORD Long 32bits

5de17
BYTE Byte 8bits unsignedchar
POINTER Pointer 32bits

Usamse todos os caracteres em maisculo ou apenas o inicial, para evitar


confusocompalavraschave,quesempresoemminusculas.

Existemduasmaneirasdedefinirestestipos:
Usandooprprocessador.

#define BYTE unsigned char


#define WORD unsigned short
#define LONG unsigned long

ouusandotypedef

typedef unsigned char BYTE; /* 8 bits */


typedef unsigned short WORD; /* 16 bits */
typedef unsigned long LONG; /* 32 bits */

Umavantagemdosegundoesquemaqueostiposdefinidossoconhecidospelo
compilador.Noesquemausandooprprocessador,todasasreferenciasaostipos
so substitudas pelos equivalentes antes que o compilador processe o cdigo
fonte.

Parasedescobrirascaractersticasimportantesdoprocessadoredocompilador,
veroapndiceA.

EntradaeSaida
O acesso a registradores de CPU, como apontador de pilha ou contador de
programa, em geral s necessrio, na inicializao. Durante a execuo, o
modelodeexecuodeCcontrolaestesregistradores.

Em sistemas embutidos, o mais importante o acesso a registradores que


controlam o hardware. O modo deste acesso dependente da arquitetura do
processadoreexistembasicamenteduasmaneiras:
acessoporinstruesespeciais
acessocomoposiesdememria

Emboraarquiteturasmaismodernasno usemmaisinstruesespeciaispara
acessoahardware,aarquiteturadoIntel8086eseusderivadosusaestaforma.
Existem ento instrues especiais (no caso, IN e OUT) e um espao de

6de17
endereamentoseparadoparaosregistradoresdehardware.Externamente,deve
haverumpinoquesinalizequalaformadeendereamentousado.Adesvantagem
que este pino poderia ser usado para duplicar a quantidade de memria
endereavel.

Para o acesso em C, usamse rotinas de bibliotecas para o acesso a estes


registradores.Tipicamenteparaacessoaregistradoresde8bits,hasrotinas
inportbeoutportb,quesousadascomomostradoabaixo.

WORD e = 0x243; // endereco


...
BYTE b = inportb(e); // leitura
...
outportb(e,b); // escrita

ExistemvariaesparaacessoaregistradoresdotipoWORDcom16bits(inportw
e outportw). Alm disso, em muitos casos, por motivos de eficiencia podese
inserir diretamente o cdigo assembly na posio do chamado da rotina,
evitandoseocursodepassagemdeparametrosechamadoeretornodarotina.
Seocompiladoraceitarumaextensonopadrodeinserodecdigoassembly
nomeiodecdigoC,arotinaacimapodeserdefinida(preferencialmenteemum
arquivocabealho)atravsdasinstruesdeprprocessadorabaixo.

#define inportb(e) asm( IN AL,e;);


#define outport(e,b) asm( MOV AL,e; OUT e,AL;);

Atendnciaatualousodeendereosderegiesdememriaparaacessoao
registradoresdehardware.Avantagemquepodemserusadas asinstrues
normais de acesso a memria e a desvantagem, a diminuio da rea de
memriarealmenteutilizvel.

Omecanismobsicoousodeapontadores,comomostradoabaixo.

BYTE p = (BYTE *) 0x876; // inteiro convertido para ponteiro


BYTE b;
...
b = *p; // leitura
*p = '\x12'; // escrita
...

Nestecaso,umapontadorinicializadocomovalorinteiro.Ocast(BYTE*)s
usadoparaindicarocompilador,queopadrodebitsaseguir(uminteiro)seja
interpretadocomoumapontador.Aseguireleusadoparaumacessodeleitura
eoutrodeescrita.Comoobservao,'\x11'poderiaserescritotambm0x11,mas

7de17
algunscompiladores,usariamumainstruoparamanipulaodeinteirospara
manipulalo e usaria somente os bits menossignificativos para a operao de
escrita.

Istotudopodeserfeitoemumaunicainstruodeleituraeoutradeescrita.

BYTE b;
...
b = *((BYTE *) 0x876); // leitura
*((BYTE *) 0x876) = '\x12'; // escrita
...

Parafacilitaraindamais,podeserusadooprprocessadordefinindoumsimbolo
comonoexemploabaixo,quesemduvidabemmaislegivel.

#define PORTA *((BYTE *) 0x876)


...
BYTE b;
...
b = PORTA;
PORTA = '\x12';
...

Oconjuntodedefiniesdestetipopodesercolocadoemumarquivocabealho,
especificoparaummodelodeumaarquiteturacontendoasdefiniesdetodosos
registradoresdehardwaredodispositivo.Assim,temsecdigocomleituramais
facileaomesmotempo,umnomepadroparaseacessarestesregistradores.
Deveserlevadoemcontaqueocompiladornoesforodeotimizarocdigopode
prejudicar o funcionamento deste tipo de acesso. Isto acontece, por que o
compiladorassume,queoprogramaonicoresponsvelpelamodificaodos
valoresemmemriaeprocuramanterovaloremumregistradordeacessomais
rpido.Assimumaestruturadotipoabaixo,queesperaqueovalordaportaseja
zero
while ( PORTA != 0 ) {}
resulteemumcdigodotipo
MOVE 0x876,R0 ; move valor da memria para R0
LOOP: BNZ R0,LOOP ; testa se valor diferente de zero
; e repete o teste sem buscar
; o novo valor na memria

A soluo indicar ao compilador que uma determinada posio de memria

8de17
podeterovalormodificadoindependentedaaodoprograma.Istofeitocoma
palavrachavevolatile.Assim,definindosePORTAatravsdainstruoabaixo,
resolveseesteproblema.
#define PORTA *( (volatile BYTE *) 0x876)

ManipulaodeBits
Na programao de sistemas embarcados muito importante e freqente a
necessidadedesesetarumbit(fazloiguala1),resetarumbit(fazloiguala
0),complementarumbit(troclode1para0ouviceversa)efinalmentetestaro
valor.

O C padro no tem suporte para variveis tipo tipo booleano (embora C9X
especifique variveis tipo bool_t, que podem assumir os valores false e true,
atravsdeumarquivocabealhostdbool.h).
Tambm no tem suporte para a definio de constantes inteiras em formato
binrio.comum,noentanto,quecompiladoresimplementemcomoextenso,
constantesdotipo0b0101ou0B0111,valendo5e7respectivamente.Ocorreto
usar a representao decimal (5 ou 7) para valores de contadores e a
representaohexadecimal(0x05ou0x07ouainda,emcasodebytes,'\x05'ou
'\x07'),paraamanipulaodebits.

Usandostructs
Umadasmaneirasmaisfceisparaacessarbitsusandoofatopoucoconhecido
decampodebitsemestruturas.Porexemplo,adeclaraoabaixo,especificaos
bitsdeumtipobyte.
typedef struct {
unsigned bit7 : 1;
unsigned bit6 : 1;
unsigned bit5 : 1;
unsigned bit4 : 1;
unsigned bit3 : 1;
unsigned bit2 : 1;
unsigned bit1 : 1;
unsigned bit0 : 1;
} Port;

UmavariveldotipoBytepodeserdefinidaatravsde
Port x;
eosbitsindividuaisatravsde
x.bit4 = 1;

9de17
x.bit2 = 0;
x.bit1 = ~x.bit1;
if( x.bit3 ) ....

Deve ser chamada a ateno para o fato que o tamanho da tipo de dado,
sizeof(Port),acimanoprecisaserexatamenteumbyte.Emboraistosejacomum
emcompiladoresparamicrocontroladores,EmcompiladoresparaPCusualque
otamanhodaestruturasejaigualaodeuminteiro,isto,sizeof(byte)iguala
sizeof(int).
Umcompiladordeboaqualidadeusarasinstruesdemanipulaodebitsdo
processador,seesteastiver.Emoutroscasos,asinstruesusaroasoperaes
bitabitquesodescritasaseguir.
Umdosproblemasquenosepodeacessartodososbitsembloco,oquepode
resultaremcdigoineficiente.Paraisto,usaseumaconstruoobscuradoC
quedefinedoistiposdedadosocupandoamesmaregiodememria.
typedef union {
BYTE val;
struct {
unsigned bit7 : 1;
unsigned bit6 : 1;
unsigned bit5 : 1;
unsigned bit4 : 1;
unsigned bit3 : 1;
unsigned bit2 : 1;
unsigned bit1 : 1;
unsigned bit0 : 1;
};
} Port;

Assimpossvelseacessarosbitsdeformaindividualoutodooregistradorcomo
mostradoabaixo.
Port PORTA;
...
PORTA.bit7 = 1;
if ( PORTA.bit5 ) {
....
}
...
PORTA.val = 0;
...

Usandooperaesbitabit
Paraamanipulaodebitemvariveisinteiraspodemserusadasasoperaes

10de17
Operao OperadorC
E &
OU |
OUExclusivo ^
Negao ~

EstesnodevemserconfundidoscomosoperadoreslgicosE(&&),OU(||)ede
negao(!),queretornamovalor0ou1.

Parasesetarumbitemumavariveldeveseusarumamascara,quetemtodos
osbitszero,excetoobitnaposiodesejada.Porexemplo,parasesetarobit2
devese usar a mascara 000000100, que em C, representada por 0x04 em
formatohexadecimal,4(formatodecimal)ou04(formatooctal).Aoperao
x=x|0x4;
oumelhor
x|=0x4;
setaobit2dointeirodotipochar,short,intoulong.

Problemascomacessocompartilhado
Domesmomodoqueosvalorespresentesemumaportadeummicrocontrolador
podem variar, valores de uma varivel podem variar em funo de outros
processos ou de interrupo. A linguagem C no tem suporte direto a
concorrncia.Istoexigequeoprogramadortenhaclaroosperigosenvolvidos.

ProcessosconcorrentessoimplementadosemCatravsdebibliotecas.

Interrupes
Noexisteumamaneirapadrodesedefinirrotinasdeinterrupo.Emborauma
rotina de interrupo seja semelhante a um rotina normal que no retorne
nenhum valor e tambm no receba nenhum parmetro (com o prottipo void
intproc(void)),elaapresentacaractersticasespecificas:

11de17
Ocomandoderetornodeumarotinadeinterruponoidnticoaodo
retornodeumarotinacomum.
A rotina de interrupo deve restaurar todos os registradores, mas as
rotinascomunspodem,emmuitossistemas,modificaralgunsregistradores
(chamados registrados de rascunho (scratch registers), sem que seja
necessriorestaurlos.
Portanto,ocompiladordeveterainformaoseumarotinaparatratamentode
interrupoparagerarocdigocorreto.Amaneiratradicionalousodapalavra
chave interrupt (em alguns casos, __interrupt, pois simbolos iniciados com
sublinhado so de uso exclusivo da implementao). Assim uma rotina de
interruposeriadescritacomo
interrupt void intproc(void) {
...
}

Amaneiramaismoderna,compativelcomopadro,ousodocomandopragma
parapassarestainformao.Assimarotinaacimaseriadescritacomo
#pragma interrupt
void intproc(void) {
...
}

Isto, noentanto, emsistemas comvetores de interrupo,sresolve parte do


problema, pois ainda necessrio que o processador saiba associar uma
interrupoaumarotinadeinterrupo.Quandoovetordeinterrupoestiver
em memria RAM, este deve ser inicializado quando do inicio da execuo do
programa.
Porexemplo,emumamquinade16bits(endereostambmcom16bits)como
vetor de interrupo para 8 nveis nas 16 primeiras posies de memria, o
endereodarotinadeinterrupodenvelnobtidocomocdigo
WORD endereco = *( (WORD *)( n*2 ));

Emgeral,existeumarotinadotiposetintproc,quemodificaumaposiodovetor
de interrupo para que aponte para a rotina especificada. Ela retorna um
apontadorparaarotinaqueestavaencarregadadainterrupo,Existemduas
maneiras de se definir esta rotina, uma usando typedef, que a forma mais
legvel,comomostradoabaixo.

typedef void (*pfunc)(void);

12de17
pfunc setintproc(int level,pfunc f) {
...
}

Aoutramaneiradefineamesmafunodeformadireta,semauxiliodeumtipo
dedados,quefazcomquefiquemenoslegvel.
void (*setintproc(int level, void (*f)(void) ))(void) {
...
}

A forma de usar idntica, s havendo diferena na definio do ponteiro da


funo.
void func(void) {
...
}

int main(void) {
void (*oldfunc)(void); // poderia ser pfunc oldfunc;
...
oldfunc = setintproc(10,func);
...
}

Deve ser observado que a notao pfunc oldfunc pode ser usada com a
definiodiretaeviceversa.Aindadeveserobservadoquepodesernecessrio,
emboranosejacomum,queaespecificaodarotinaincluaapalavrachave
interrupt.

Mapeamentodememria
ProgramasemC,umavezcompilados,possuemdiversostiposdesegmentospara
osvriostiposdeinformaonecessriosemumcdigoobjeto.
Cdigo
Constantes
Dadosinicializados
Dadosnoinicializados
Pilha
Em principio, o cdigo objeto relocvel, isto , pode ser adaptado para ser

13de17
executadoemqualquerendereodememria.Atarefadoligadorjuntarestes
cdigos objeto, coloclos nas posies adequadas de memria e acertar as
referncias. O acertar de referncias mencionado ajustar uma instruo de
chamadoderotinaparaquetenhaoendereocorretodopontodeentrada.Istos
podeserfeito,depoisdomapeamentodosdiversossegmentosdoscdigosobjeto
nas regies de memria adequadas. O procedimento bsico concatenar os
segmentos de diversos tipos separadamente. Por exemplo, todos os segmentos
cdigosoconcatenadosgerandoosegmentocdigodomduloexecutvel.

Emtermosdehardware,osmicrocontroladorestemumaregiodememriano
volatil(ROM)eumadememriavoltil(RAM).Emalgunscasos,estasnoso
contguas.

Figura

O ligador deve ento mapear os segmentos de cdigo e constantes para uma


regiodeROMeossegmentosdedados(inicializadosouno)emumareade
RAM.Almdisso,devemanterumacpiadareadedadosinicializadosemROM
paraquesejacopiadaparaaregioadequadanaRAMduranteainicializao.
Istoumaduplicaodesnecessriaequedesperdiaumrecursovalioso.
OscompiladoresCdeterminamqmequesegmentoumavarivelserarmazenada
(se constante ou dado inicializado) pelo contexto ou, acordo com instrues
fornecidaspeloprogramador.
NasversesantigasdeChaviaumproblemintx[10];
intx[10]={0,1,2,3,4,5,6,7,8,9};
char*p=texto;

Oproblemadealinhamento
Alocaodinmicadememria

14de17
Interfacecomassembly

Referencias
Kernighan,Richie.TheCProgrammingLanguage.
Jack Ganssle. Microcontroller C Compilers. Electronic Engineering Times,
November1990.
JackGanssle.MylovehaterelationshipwithC.Embedded.com.10/16/03.
Wikipedia.LinguagemdeprogramaoC.
JamesACJoyce. Why C Is Not My Favourite Programming Language.
http://www.kuro5hin.org/print/2004/2/7/144019/8872
Harsha S. Adiga. Porting Linux applications to 64bit systems.http://www
128.ibm.com/developerworks/linux/library/lport64.html.12Apr2006.
MISRA. Guidelines for the use of the C language in critical systems.
http://www.misrac2.com/
The Open Group. 64Bit Programming Models: Why LP64?.
http://www.unix.org/version2/whatsnew/lp64_wp.html.

15de17
ApndiceA

O programa abaixo pode ser usado para descobrir as caracteristicas do


processadoredocompilador.Paraisto,eledevesercompiladonocomputador
hospedeiroeexecutadonoprocessadoralvo.

/*
* imprime tamanhos de tipos de variaveis em C
*
* Hans 2006
*/

#include <stdio.h>

int main (void) {


unsigned char b,c;
unsigned short s = 0x1234;
unsigned int i = 0x1234;

b = 1;
c = 0;
while( b ) {
b <<= 1;
c++;
}
printf("Caracteristicas do processador\n");
printf ("Tamanho de um Byte .. %3d bits\n\n",c);
if( *((unsigned char *) &s) == 0x12 ) {
printf("Big Endian (Byte MAIS significativo primeiro)\n");
} else if( *((unsigned char *) &s) == 0x34 ) {
printf("Little Endian (Byte MENOS significativo
primeiro)\n");
} else {
printf("Endianness indeterminado\n");
}

printf ("Tamanhos tipos em Bytes\n");


printf ("char ................ %3d\n", sizeof (char));
printf ("unsigned char ....... %3d\n", sizeof (unsigned char));
printf ("signed char ......... %3d\n", sizeof (signed char));
printf ("int ................. %3d\n", sizeof (int));
printf ("unsigned int......... %3d\n", sizeof (unsigned int));
printf ("signed int...,,...... %3d\n", sizeof (signed int));
printf ("short int ........... %3d\n", sizeof (short int));
printf ("unsigned short int .. %3d\n", sizeof (unsigned short
int));
printf ("signed short int .... %3d\n", sizeof (signed short

16de17
int));
printf ("long int ............ %3d\n", sizeof (long int));
printf ("signed long int ..... %3d\n", sizeof (signed long
int));
printf ("unsigned long int ... %3d\n", sizeof (unsigned long
int));
printf ("float ............... %3d\n", sizeof (float));
printf ("double .............. %3d\n", sizeof (double));
printf ("long double ......... %3d\n", sizeof (long double));

#ifdef OUTRAS
printf( "long char .......... %3d\n", sizeof(long char) );
printf( "unsigned long char . %3d\n", sizeof(unsigned long
char) );
printf( "short char ......... %3d\n", sizeof(short char) );
printf( "unsigned short char. %3d\n", sizeof(unsigned short
char) );
printf( "long float ......... %3d\n", sizeof(long float) );
printf( "short float ........ %3d\n", sizeof(short float) );
printf( "short double ....... %3d\n", sizeof(short double) );
#endif

return 0;
}

Se o processador alvo, no tiver um dispositivo de sada ou no dispuser da


bibliotecapadro,deveseusaroesquema

17de17

You might also like