Upload
erduarte
View
217
Download
4
Embed Size (px)
Citation preview
2www.sctec.com.br
A Empresa
A Sctec Eletrônica foi fundada em abril de 2003 com o objetivo de desenvolver soluções e produtos eletrônicos utilizando a mais moderna tecnologia disponível, atuando no desenvolvimento de hardware e software.
3www.sctec.com.br
Áreas de Atuação
• Produtos Automotivos• Automação Industrial• Comunicação com ou sem fio• Sensoriamento Remoto• Embedded Systems• Desenvolvimento de Projetos para
Terceiros
4www.sctec.com.br
Produtos
5www.sctec.com.br
Produtos
MOD711• ARM7• 256 Kb FLASH• 64 Kb RAM• USB 2.0• JTAG
6www.sctec.com.br
Projetos
Computador de Bordo – M8 Octopus
7www.sctec.com.br
Educacional
Livros
8www.sctec.com.br
Parcerias
Otimização de Programas C para
Sistemas Embarcados
10www.sctec.com.br
Introdução
Sistemas embarcados formam um campo cada vez mais numeroso na área de desenvolvimento de software. No entanto, muitos programadores desconhecem aspectos importantes e essenciais ao desenvolvimento neste tipo de plataforma.
11www.sctec.com.br
Introdução
Nesta apresentação veremos alguns aspectos importantes da utilização da linguagem C no desenvolvimento de aplicações embarcadas mais eficientes.
12www.sctec.com.br
Introdução
Aspectos importantes para um programa C eficiente:1. Conheça o compilador2. Conheça a CPU3. Utilize o tipo de dado mais eficiente4. Evite utilizar funções de biblioteca5. Programe de forma a auxiliar o
trabalho do compilador
Tipos de Dados e Alocação de
Memória
14www.sctec.com.br
Signed x Unsigned
Signed versus unsigned
Qual o tipo ideal para a minha aplicação?
A aplicação necessita de um dado signed?
Há diferença de performance?
15www.sctec.com.br
Signed x Unsigned
Extensão de sinal!
Ocorre sempre nas atribuições entre variáveis sinalizadas e de tamanhos diferentes (por exemplo a atribuição de uma variável signed char para uma variável signed int).
16www.sctec.com.br
Signed x Unsigned
0123456S012345670123456S01234567
01234567012345670123456701234567
0123456SSSSSSSSS
0123456789101112131415
0123456700000000012345678910111213141501234567000000000123456789101112131415
Zero filling
Sign extension
17www.sctec.com.br
Signed x Unsigned
Atribuição de char para int nos PIC18:
Unsigned
;uiv = ucvMOVFF ucv,uivMOVLB 0 CLRF uiv+1, BANKED
Signed
;siv = scvMOVFF scv,sivMOVLB 0CLRF siv+1, BANKEDBTFSC siv,7, BANKED SETF siv+1, BANKED
18www.sctec.com.br
Signed x Unsigned
Atribuição de char para int nos PIC18:
Unsigned
;uiv = ucvMOVFF ucv,uivMOVLB 0 CLRF uiv+1, BANKED
Signed
;siv = scvMOVFF scv,sivMOVLB 0CLRF siv+1, BANKEDBTFSC siv,7, BANKED SETF siv+1, BANKED
8 bytes8 ciclos
12 bytes12/13 ciclos
19www.sctec.com.br
Signed x Unsigned
Atribuição de char para int nos MSP430:
Unsigned
;uiv = ucvMOV.B &ucv,R15MOV.W R15,&uiv
Signed
;siv = scvMOV.B &scv,R15SXT R15MOV.W R15,&siv
20www.sctec.com.br
Signed x Unsigned
Atribuição de char para int nos MSP430:
Unsigned
;uiv = ucvMOV.B &ucv,R15MOV.W R15,&uiv
Signed
;siv = scvMOV.B &scv,R15SXT R15MOV.W R15,&siv8 bytes
7 ciclos 10 bytes15 ciclos
21www.sctec.com.br
Signed x Unsigned
Algumas operações aritméticas também podem sofrer impactos negativos pelo uso de tipos signed:
22www.sctec.com.br
Signed x Unsigned
Unsigned
118 bytes238 ciclos
Divisão de 16 bits nos HCS08
Signed
160 bytes356 ciclos
23www.sctec.com.br
Signed x Unsigned
Unsigned
456 bytes51 ciclos
Divisão de 32 bits nos ARM7
Signed
472 bytes48 ciclos
24www.sctec.com.br
Seleção de Tipos
Tipos nativos tendem a ser mais rápidos:unsigned char cfatorial(unsigned char val){ unsigned char aux, result=1; for(aux=1;aux<=val;aux++) result *= aux; return result;}unsigned int ifatorial(unsigned int val){ unsigned int aux, result=1; for(aux=1;aux<=val;aux++) result *= aux; return result;}
25www.sctec.com.br
Seleção de Tipos
107
6472
47
115
60
83
48
68
49
8876
0
20
40
60
80
100
120
CFv1 ARM Thumb CM-3 MIPS32 MIPS16
cfatorial(10)ifatorial(10)
Velocidade (ciclos de clock):
26www.sctec.com.br
Seleção de Tipos
2620
52
40
32
2026
18
48
40
28
20
0
10
20
30
40
50
60
CFv1 ARM Thumb CM-3 MIPS32 MIPS16
cfatorial(10)ifatorial(10)
Tamanho de código (bytes):
27www.sctec.com.br
Seleção de Tipos
Variáveis locais devem utilizar preferencialmente tipos nativos da CPU em questão (char para chips de 8 bits, int para chips de 16/32 bits).
Campos de Bits
29www.sctec.com.br
Campos de bits
Muitas aplicações tendem a utilizar variáveis apenas como flags, assumindo dois valores: verdadeiro ou falso.A utilização de campos de bits permite reduzir consideravelmente a quantidade de RAM ocupada, mas será o código resultante mais eficiente?
30www.sctec.com.br
Campos de bits
struct{ unsigned char bit0 : 1; unsigned char bit1 : 1; unsigned char bit2 : 1;} teste;
31www.sctec.com.br
Campos de bits
Atribuições utilizando bits e bytes (HCS08):
Bit:teste.bit0 = 1;
BSET 0,teste
Byte:flag = 1;
LDA #0x01LDHX #flagSTA ,X
32www.sctec.com.br
Campos de bits
Atribuições utilizando bits e bytes (HCS08):
Bit:teste.bit0 = 1;
BSET 0,teste
Byte:flag = 1;
LDA #0x01LDHX #flagSTA ,X
2 bytes FLASH1 bit RAM10 ciclos
6 bytes FLASH1 byte RAM
16 ciclos
33www.sctec.com.br
Campos de bits
Teste de flag utilizando bits e bytes (HCS08):
Bit:If (teste.bit0)...
BRCLR 0,teste,falso// verdadeiro
Byte:If (flag) ...
LDA testeBEQ falso// verdadeiro
34www.sctec.com.br
Campos de bits
Teste de flag utilizando bits e bytes (HCS08):
Bit:If (teste.bit0)...
BRCLR 0,teste,falso// verdadeiro
Byte:If (flag) ...
LDA testeBEQ falso// verdadeiro
3 bytes FLASH1 bit RAM10 ciclos
5/6 bytes FLASH1 byte RAM12/14 ciclos
35www.sctec.com.br
Campos de bits
Atribuições utilizando bits e bytes (PIC16/18):
Bit:teste.bit0 = 1;
BSF teste,0
Byte:flag = 1;
MOVLW 0x01MOVWF flag
36www.sctec.com.br
Campos de bits
Atribuições utilizando bits e bytes (PIC16/18):
Bit:teste.bit0 = 1;
BSF teste,0
Byte:flag = 1;
MOVLW 0x01MOVWF flag
1 word FLASH1 bit RAM4 ciclos
2 words FLASH1 byte RAM
8 ciclos
37www.sctec.com.br
Campos de bits
Teste de flag utilizando bits e bytes (PIC16/18):
Bit:If (teste.bit0)...
BTFSS teste,0GOTO falso// verdadeiro
Byte:If (flag) ...
MOVF flag,FBTFSC STATUS,ZGOTO falso// verdadeiro
38www.sctec.com.br
Campos de bits
Teste de flag utilizando bits e bytes (PIC16/18):
Bit:If (teste.bit0)...
BTFSS teste,0GOTO falso// verdadeiro
Byte:If (flag) ...
MOVF flag,FBTFSC STATUS,ZGOTO falso// verdadeiro
2 words FLASH1 bit RAM8/12 ciclos
3 words FLASH1 byte RAM12/16 ciclos
39www.sctec.com.br
Campos de bits
Atribuições utilizando bits e bytes (MSP430):
Bit:teste.bit0 = 1;
BIS.B #1,&teste
Byte:flag = 1;
MOV.B #1,&teste
40www.sctec.com.br
Campos de bits
Atribuições utilizando bits e bytes (MSP430):
Bit:teste.bit0 = 1;
BIS.B #1,&teste
Byte:flag = 1;
MOV.B #1,&teste4 bytes FLASH
1 bit RAM4 ciclos
4 bytes FLASH1 byte RAM
4 ciclos
41www.sctec.com.br
Campos de bits
Teste de flag utilizando bits e bytes (MSP430):
Bit:If (teste.bit0)...
BIT.B #1,&testeJNC falso// verdadeiro
Byte:If (flag) ...
TST.B &flagJEQ falso// verdadeiro
42www.sctec.com.br
Campos de bits
Teste de flag utilizando bits e bytes (MSP430):
Bit:If (teste.bit0)...
BIT.B #1,&testeJNC falso// verdadeiro
Byte:If (flag) ...
TST.B &flagJEQ falso// verdadeiro
6 bytes FLASH1 bit RAM6 ciclos
6 bytes FLASH1 byte RAM
6 ciclos
43www.sctec.com.br
Campos de bits
Em máquinas de 32 bits, a utilização de campos de bit causa uma degradação na performance e um aumento no tamanho do código (código menos eficiente).
44www.sctec.com.br
Campos de bits
Atribuições utilizando bits e bytes (Coldfire):
Bit:teste.bit0 = 1;
BSET #0,x(Ay)
Byte:flag = 1;
MOVE.B #1,x(Ay)
45www.sctec.com.br
Campos de bits
Atribuições utilizando bits e bytes (Coldfire):
Bit:teste.bit0 = 1;
BSET #0,x(Ay)
Byte:flag = 1;
MOVE.B #1,x(Ay)6 bytes FLASH
1 bit RAM4 ciclos
6 bytes FLASH1 byte RAM
1 ciclo
46www.sctec.com.br
Campos de bits
Teste de flag utilizando bits e bytes (Coldfire):
Bit:If (teste.bit0)...
MVZ.B 8(A5),D0LSL.L D1,D0LSR.L D1,D0TST.B D0BEQ.S falso// verdadeiro
Byte:If (flag) ...
TST.B 11(A5)BEQ.S falso// verdadeiro
47www.sctec.com.br
Campos de bits
Teste de flag utilizando bits e bytes (Coldfire):
Bit:If (teste.bit0)...
MVZ.B 8(A5),D0LSL.L D1,D0LSR.L D1,D0TST.B D0BEQ.S falso// verdadeiro
Byte:If (flag) ...
TST.B 11(A5)BEQ.S falso// verdadeiro
12 bytes FLASH1 bit RAM8 ciclos
6 bytes FLASH1 byte RAM
5 ciclos
48www.sctec.com.br
Campos de bits
Segunda versão do teste de bit:
Bit:If (teste.bit0)...
MVZ.B 8(A5),D0BTST #0,8(A5)BEQ.S falso// verdadeiro
8 bytes FLASH1 bit RAM6 ciclos
49www.sctec.com.br
Campos de bits
Atribuições utilizando bits e bytes (ARM-ARM):
Bit:teste.bit0 = 1;
LDR R0,[PC,#offset1]LDR R1,[PC,#offset2]LDR R1,[R1,#+0]ORRS R1, R1, #0x01STR R1,[R0,#+0]
Byte:flag = 1;
LDR R0,[PC,#+offset3]MOV R1, #1STRB R1,[R0,#+0]
50www.sctec.com.br
Campos de bits
Atribuições utilizando bits e bytes (ARM-ARM):
Bit:teste.bit0 = 1;
LDR R0,[PC,#offset1]LDR R1,[PC,#offset2]LDR R1,[R1,#+0]ORRS R1, R1, #0x01STR R1,[R0,#+0]
Byte:flag = 1;
LDR R0,[PC,#+offset3]MOV R1, #1STRB R1,[R0,#+0]
20 bytes FLASH1 bit RAM8 ciclos
12 bytes FLASH1 byte RAM
4 ciclos
51www.sctec.com.br
Campos de bits
Bit:teste.bit0 = 1;
LDR R0,[PC,#offset1]LDR R1,[PC,#offset2]LDR R1,[R1,#0]MOV R2, #1ORR R2, R1STR R2,[R0,#0]
Byte:flag = 1;
LDR R0,[PC,#offset3]MOV R1,#1STRB R1,[R0,#0]
Atribuições utilizando bits e bytes (ARM-Thumb):
52www.sctec.com.br
Campos de bits
Bit:teste.bit0 = 1;
LDR R0,[PC,#offset1]LDR R1,[PC,#offset2]LDR R1,[R1,#0]MOV R2, #1ORR R2, R1STR R2,[R0,#0]
Byte:flag = 1;
LDR R0,[PC,#offset3]MOV R1,#1STRB R1,[R0,#0]
12 bytes FLASH1 bit RAM9 ciclos
6 bytes FLASH1 byte RAM
4 ciclos
Atribuições utilizando bits e bytes (ARM-Thumb):
Alinhamento de Dados
54www.sctec.com.br
Alinhamento de dados
Outro aspecto importante a ser considerado quando se programa um sistema embarcado é o alinhamento de dados.Plataformas como os ARMs possuem restrições quanto a localização dos dados na memória.
55www.sctec.com.br
Alinhamento de dados
struct{ char campo1; int campo2; short campo3;} teste;
ARM7:
0xuuuuuuu9campo3
0xuuuuuuu80xuuuuuuu7
campo2
---
campo1
0xuuuuuuu40xuuuuuuu50xuuuuuuu6
0xuuuuuuu30xuuuuuuu20xuuuuuuu10xuuuuuuu0
56www.sctec.com.br
Alinhamento de dados
struct{ char campo1; int campo2; short campo3;} teste;
ARM7:
0xuuuuuuu9campo3
0xuuuuuuu80xuuuuuuu7
campo2
---
campo1
0xuuuuuuu40xuuuuuuu50xuuuuuuu6
0xuuuuuuu30xuuuuuuu20xuuuuuuu10xuuuuuuu0
Memória RAM útil: 7 bytesMemória RAM utilizada: 10 bytes!
57www.sctec.com.br
Alinhamento de dados
Chips de 8 bits não sofrem de problemas de alinhamento de dados.Algumas plataformas de 32 bits também permitem otimização da alocação de memória mediante o uso de diretivas especiais:
58www.sctec.com.br
Alinhamento de dados
struct{ char campo1; int campo2; short campo3;} teste;
0xuuuuuuu4
campo30xuuuuuuu50xuuuuuuu6
0xuuuuuuu30xuuuuuuu20xuuuuuuu10xuuuuuuu0
campo2
campo1
Coldfire, Cortex e MIPS:
59www.sctec.com.br
Alinhamento de dados
struct{ char campo1; int campo2; short campo3;} teste;
0xuuuuuuu4
campo30xuuuuuuu50xuuuuuuu6
0xuuuuuuu30xuuuuuuu20xuuuuuuu10xuuuuuuu0
campo2
campo1
Coldfire, Cortex e MIPS:
Memória RAM útil: 7 bytesMemória RAM utilizada: 7 bytes!
60www.sctec.com.br
Alinhamento de dados
struct{ char campo1; int campo2; short campo3;} teste;
0xuuuuuuu4
campo30xuuuuuuu50xuuuuuuu6
0xuuuuuuu30xuuuuuuu20xuuuuuuu10xuuuuuuu0
campo2
campo1
Coldfire, Cortex e MIPS:
IAR: modificador __packedCodewarrior: diretiva #pragma pack(x)GCC (MIPS): __attribute__((packed))
61www.sctec.com.br
Alinhamento de dados
Atenção: acessos não-alinhados à memória podem necessitar de ciclos adicionais de clock para a sua efetivação!
62www.sctec.com.br
Organização de dados
Também é importante organizar os dados dentro da estrutura de forma a melhorar a distribuição dos mesmos na memória do dispositivo:
63www.sctec.com.br
Organização de dados
struct{ char campo1; int campo2; char campo3; short campo4;} teste;
ARM7:
0xuuuuuuuBcampo4
0xuuuuuuuA-
campo3
campo2
---
campo1
0xuuuuuuu90xuuuuuuu80xuuuuuuu7
0xuuuuuuu40xuuuuuuu50xuuuuuuu6
0xuuuuuuu30xuuuuuuu20xuuuuuuu10xuuuuuuu0
64www.sctec.com.br
Organização de dados
struct{ char campo1; int campo2; char campo3; short campo4;} teste;
ARM7:
0xuuuuuuuBcampo4
0xuuuuuuuA-
campo3
campo2
---
campo1
0xuuuuuuu90xuuuuuuu80xuuuuuuu7
0xuuuuuuu40xuuuuuuu50xuuuuuuu6
0xuuuuuuu30xuuuuuuu20xuuuuuuu10xuuuuuuu0
Memória RAM útil: 8 bytesMemória RAM utilizada: 12 bytes!
65www.sctec.com.br
Organização de dados
struct{ char campo1; char campo3; short campo4; int campo2; } teste;
campo2
campo4
campo3campo1
0xuuuuuuu7
0xuuuuuuu40xuuuuuuu50xuuuuuuu6
0xuuuuuuu30xuuuuuuu20xuuuuuuu10xuuuuuuu0
66www.sctec.com.br
Organização de dados
struct{ char campo1; char campo3; short campo4; int campo2; } teste;
campo2
campo4
campo3campo1
0xuuuuuuu7
0xuuuuuuu40xuuuuuuu50xuuuuuuu6
0xuuuuuuu30xuuuuuuu20xuuuuuuu10xuuuuuuu0
Memória RAM útil: 8 bytesMemória RAM utilizada: 8 bytes!
Estudo de Casos
68www.sctec.com.br
Timers e ContadoresOtimização de timers e contadores:
if (va<10) va++;......
if (va) va--;......
69www.sctec.com.br
Timers e ContadoresTempos relativos dos contadores decrementais:
93
75
9587
100 10091 94 95
0102030405060708090
100
HCS08 PIC16 MSP CFv1 ARM Thumb CM-3 MIPS32 MIPS16
dec
70www.sctec.com.br
Timers e ContadoresVerificação do contador dentro do programa:
if (va==VALOR)......
if (!va)......
Mais eficiente!
71www.sctec.com.br
FunçõesRedução do número de parâmetros de chamada:
void lcd_ks0108_write_byte(unsigned char rs, unsigned char data){ KS0108_RW = 0; KS0108_DATA_PORT = data; KS0108_RS = rs; KS0108_EN=1; delay(_KS0108_DELAY/2); KS0108_EN=0;}
72www.sctec.com.br
FunçõesRedução do número de parâmetros de chamada:
void lcd_ks0108_write_data(unsigned char data){ KS0108_RW = 0; KS0108_DATA_PORT = data; KS0108_RS = 1; KS0108_EN=1; delay(_KS0108_DELAY/2); KS0108_EN=0;}void lcd_ks0108_write_cmd(unsigned char data){ KS0108_RW = 0; KS0108_DATA_PORT = data; KS0108_RS = 0; KS0108_EN=1; delay(_KS0108_DELAY/2); KS0108_EN=0;}
73www.sctec.com.br
FunçõesExame do MAP file:
74www.sctec.com.br
FunçõesExame do MAP file:
Redução de 17 bytes no tamanho do código !
75www.sctec.com.br
Interpolação de 8 bits
Utilizando int:
int interpola(int x, int x1, int x2, int y1, int y2){ if (x==x1) return y1; else if (x==x2) return y2; else return ((x%(x2-x1))*(y2-y1))/(x2-x1)+y1; }
76www.sctec.com.br
Interpolação de 8 bits
Utilizando int:
int interpola(int x, int x1, int x2, int y1, int y2){ if (x==x1) return y1; else if (x==x2) return y2; else return ((x%(x2-x1))*(y2-y1))/(x2-x1)+y1; }
376 bytes FLASH1188 ciclos
77www.sctec.com.br
Interpolação de 8 bits
Utilizando char:char interpola(char x, char x1, char x2, char y1, char y2){ if (x==x1) return y1; else if (x==x2) return y2; else { return ((x%(x2-x1))*((signed char)y2- (signed char)y1))/(x2-x1)+y1; }}
78www.sctec.com.br
Interpolação de 8 bits
Utilizando char:char interpola(char x, char x1, char x2, char y1, char y2){ if (x==x1) return y1; else if (x==x2) return y2; else { return ((x%(x2-x1))*((signed char)y2- (signed char)y1))/(x2-x1)+y1; }}
357 bytes FLASH1060 ciclos
79www.sctec.com.br
Interpolação de 8 bits
Forçando uchar na operação %:char interpola(char x, char x1, char x2, char y1, char y2){ if (x==x1) return y1; else if (x==x2) return y2; else { return (((uchar)x%(uchar)(x2-x1))*((signed char)y2-(signed char)y1))/(x2-x1)+y1; }}
80www.sctec.com.br
Interpolação de 8 bits
Forçando uchar na operação %:char interpola(char x, char x1, char x2, char y1, char y2){ if (x==x1) return y1; else if (x==x2) return y2; else { return (((uchar)x%(uchar)(x2-x1))*((signed char)y2-(signed char)y1))/(x2-x1)+y1; }}
311 bytes FLASH802 ciclos
81www.sctec.com.br
Interpolação de 8 bits
Utilizando apenas uchar:char interpola(char x, char x1, char x2, char y1, char y2){ char aux; aux = x%(uchar)(x2-x1); if (x==x1) return y1; else if (x==x2) return y2; else { if (y2>y1) return (((uchar)x%(uchar)(x2-x1))*(uchar)(y2-y1))/(x2-x1)+y1; else return ((uchar)((uchar)(x2-x1)-(uchar)x%(uchar)(x2-x1))*(uchar)(y1-y2))/(x2-x1)+y2; } }
82www.sctec.com.br
Interpolação de 8 bits
Utilizando apenas uchar:char interpola(char x, char x1, char x2, char y1, char y2){ char aux; aux = x%(uchar)(x2-x1); if (x==x1) return y1; else if (x==x2) return y2; else { if (y2>y1) return (((uchar)x%(uchar)(x2-x1))*(uchar)(y2-y1))/(x2-x1)+y1; else return ((uchar)((uchar)(x2-x1)-(uchar)x%(uchar)(x2-x1))*(uchar)(y1-y2))/(x2-x1)+y2; } }
292 bytes FLASH628 ciclos
83www.sctec.com.br
Interpolação de 8 bits
Variação de x constante:char interpola(char x, char x1, char x2, char y1, char y2){ char aux; aux = x%20; if (x==x1) return y1; else if (x==x2) return y2; else { if (y2>y1)return ((uchar)aux*(uchar)(y2-y1))/20 + y1; else return ((uchar)(20-aux)*(uchar)(y1-y2))/20 + y2; } }
84www.sctec.com.br
Interpolação de 8 bits
Variação de x constante:char interpola(char x, char x1, char x2, char y1, char y2){ char aux; aux = x%20; if (x==x1) return y1; else if (x==x2) return y2; else { if (y2>y1)return ((uchar)aux*(uchar)(y2-y1))/20 + y1; else return ((uchar)(20-aux)*(uchar)(y1-y2))/20 + y2; } }
254 bytes FLASH558 ciclos
85www.sctec.com.br
Interpolação de 8 bits
Estatísticas de otimização:
376
1188
357
1060
254
558
0
200
400
600
800
1000
1200
int char final
TamanhoCiclos
86www.sctec.com.br
Seleção de Tipos
Interpolação de 8 bits no Coldfire v1:
uchar interpola(uchar x, uchar x1, uchar x2, uchar y1, uchar y2){ if (x==x1) return y1; else
if (x==x2) return y2; elsereturn (((uchar)x%(uchar)(x2-
x1))*((signed char)y2-(signed char)y1))/(x2-x1)+y1; }
87www.sctec.com.br
Seleção de Tipos
Interpolação de 8 bits no Coldfire v1:
uchar interpola(uchar x, uchar x1, uchar x2, uchar y1, uchar y2){ if (x==x1) return y1; else
if (x==x2) return y2; elsereturn (((uchar)x%(uchar)(x2-
x1))*((signed char)y2-(signed char)y1))/(x2-x1)+y1; }
358 bytes FLASH222 ciclos
88www.sctec.com.br
Seleção de Tipos
Interpolação de 32 bits no Coldfire v1:
int interpola(int x, int x1, int x2, int y1, int y2){ if (x==x1) return y1; else if (x==x2) return y2; else return ((x%(x2-x1))*(y2-y1))/(x2-x1)+y1; }
89www.sctec.com.br
Seleção de Tipos
Interpolação de 32 bits no Coldfire v1:
int interpola(int x, int x1, int x2, int y1, int y2){ if (x==x1) return y1; else if (x==x2) return y2; else return ((x%(x2-x1))*(y2-y1))/(x2-x1)+y1; }
340 bytes FLASH156 ciclos
90www.sctec.com.br
Configuração do Linker
HCS08:
•Utilização da página direta•Otimização de acessos a memória•Otimização da pilha
91www.sctec.com.br
Configuração do Linker
Utilização da página direta nos HCS08:
92www.sctec.com.br
Configuração do Linker
Utilização da página direta nos HCS08:
93www.sctec.com.br
Explorando MAP files
• Estrutura e disposição das funções e dados na memória
• Verificação de utilização e referências a funções e dados
• Permite conhecer a ocupação da memória do MCU para fins de otimização de código
94www.sctec.com.br
Explorando MAP files
95www.sctec.com.br
Explorando MAP files
96www.sctec.com.br
Explorando MAP files
97www.sctec.com.br
Explorando MAP files
98www.sctec.com.br
Explorando MAP files
Com endereçamento extendido:
99www.sctec.com.br
Explorando MAP files
Modificação para endereçamento direto:
100www.sctec.com.br
Explorando MAP files
Com endereçamento direto:
-1 byte/-1 ciclo
101www.sctec.com.br
Explorando MAP files
Com endereçamento extendido:
-47 bytes
-20 bytes
-31 bytes
-105 bytes
102www.sctec.com.br
Pilha
Falhas ocasionadas por overflow da pilha são difíceis de ser diagnosticadas e podem provocar diversos efeitos colaterais, desde funcionamento errático esporádico até crashes completos.
103www.sctec.com.br
Pilha
Lembre-se de que as variáveis locais que não podem ser armazenadas em registradores da CPU são mantidas na pilha durante a execução da função!
104www.sctec.com.br
Pilha
Como dimensionar corretamente o tamanho da pilha?
105www.sctec.com.br
Pilha
Call Graph:
106www.sctec.com.br
Pilha
Call Graph:
107www.sctec.com.br
Pilha
O MAP file não possui Call Graph ?
Calcule a utilização da pilha utilizando as árvores de dependência presentes no
MAP file (juntamente com a observação do código gerado pelo compilador)!
108www.sctec.com.br
Pilha
13 bytes!
7 bytes!
109www.sctec.com.br
Pilha
Alocação de pilha:
ARM/CM3:
SUB SP,SP,#X
MSP430:
SUB.W #X,SP
MIPS16:
SAVE #X
Coldfire:
LEA –X(A7),A7
MIPS32:
ADDIU SP,SP,#-X
HCS08:
AIS #-X
110www.sctec.com.br
Máquinas de Estado
IDLE
ST1
ST2
ST4 ST3
ST5
ST6
111www.sctec.com.br
Máquinas de Estadovoid fsm1(unsigned int new_state){ static unsigned int fsm_state; if (new_state) fsm_state = new_state; if (fsm_state==FSM1_ST1) { // estado 1 va = 10; fsm_state = FSM1_ST2; } else if (fsm_state==FSM1_ST2) { // estado 2 va = 20; fsm_state = FSM1_ST3; } else if (fsm_state==FSM1_ST3) { // estado 3 if (va<10) fsm_state = FSM1_ST1; else if (va==255) fsm_state = FSM1_IDLE; else fsm_state = FSM1_ST4; } else if (fsm_state==FSM1_ST4) { // estado 4 va--; fsm_state = FSM1_ST5; } else if (fsm_state==FSM1_ST5) { // estado 5 if (!va) fsm_state = FSM1_ST6; } else if (fsm_state==FSM1_ST6) { // estado 6 va = 100; fsm_state = FSM1_ST1; }}
112www.sctec.com.br
Máquinas de Estadovoid fsm1(unsigned int new_state){ static unsigned int fsm_state; if (new_state) fsm_state = new_state; if (fsm_state==FSM1_ST1) { // estado 1 va = 10; fsm_state = FSM1_ST2; } else if (fsm_state==FSM1_ST2) { // estado 2 va = 20; fsm_state = FSM1_ST3; } else if (fsm_state==FSM1_ST3) { // estado 3 if (va<10) fsm_state = FSM1_ST1; else if (va==255) fsm_state = FSM1_IDLE; else fsm_state = FSM1_ST4; } else if (fsm_state==FSM1_ST4) { // estado 4 va--; fsm_state = FSM1_ST5; } else if (fsm_state==FSM1_ST5) { // estado 5 if (!va) fsm_state = FSM1_ST6; } else if (fsm_state==FSM1_ST6) { // estado 6 va = 100; fsm_state = FSM1_ST1; }}
138 bytes FLASH
113www.sctec.com.br
Máquinas de Estado
#define FSM1_IDLE 0#define FSM1_ST1 1#define FSM1_ST2 2#define FSM1_ST3 3#define FSM1_ST4 4#define FSM1_ST5 5#define FSM1_ST6 6
114www.sctec.com.br
Máquinas de Estadovoid fsm2(unsigned int new_state){ static unsigned int fsm_state; if (new_state) fsm_state = new_state; switch (fsm_state) { case FSM1_IDLE: // não faz nada break; case FSM1_ST1: // estado 1 va = 10; fsm_state = FSM1_ST2; break; case FSM1_ST2: // estado 2 va = 20; fsm_state = FSM1_ST3; break; case FSM1_ST3: // estado 3 if (va<10) fsm_state = FSM1_ST1; else if (va==255) fsm_state = FSM1_IDLE; else fsm_state = FSM1_ST4; break; case FSM1_ST4: // estado 4 va--; fsm_state = FSM1_ST5; break; case FSM1_ST5: // estado 5 if (!va) fsm_state = FSM1_ST6; break; case FSM1_ST6: // estado 6 va = 100; fsm_state = FSM1_ST1; }}
115www.sctec.com.br
Máquinas de Estadovoid fsm2(unsigned int new_state){ static unsigned int fsm_state; if (new_state) fsm_state = new_state; switch (fsm_state) { case FSM1_IDLE: // não faz nada break; case FSM1_ST1: // estado 1 va = 10; fsm_state = FSM1_ST2; break; case FSM1_ST2: // estado 2 va = 20; fsm_state = FSM1_ST3; break; case FSM1_ST3: // estado 3 if (va<10) fsm_state = FSM1_ST1; else if (va==255) fsm_state = FSM1_IDLE; else fsm_state = FSM1_ST4; break; case FSM1_ST4: // estado 4 va--; fsm_state = FSM1_ST5; break; case FSM1_ST5: // estado 5 if (!va) fsm_state = FSM1_ST6; break; case FSM1_ST6: // estado 6 va = 100; fsm_state = FSM1_ST1; }}
134 bytes FLASH
116www.sctec.com.br
Máquinas de Estadounsigned int fsm3(unsigned int new_state){ static unsigned int fsm_state; if (new_state) fsm_state = new_state; switch (fsm_state) { case FSM1_IDLE: // não faz nada break; case FSM1_ST1: // estado 1 va = 10; fsm_state = FSM1_ST2; break; case FSM1_ST2: // estado 2 va = 20; fsm_state = FSM1_ST3; break; case FSM1_ST3: // estado 3 if (va<10) fsm_state = FSM1_ST1; else if (va==255) fsm_state = FSM1_IDLE; else fsm_state = FSM1_ST4; break; case FSM1_ST4: // estado 4 va--; fsm_state = FSM1_ST5; break; case FSM1_ST5: // estado 5 if (!va) fsm_state = FSM1_ST6; break; case FSM1_ST6: // estado 6 va = 100; fsm_state = FSM1_ST1; } return fsm_state;}
117www.sctec.com.br
Máquinas de Estadounsigned int fsm3(unsigned int new_state){ static unsigned int fsm_state; if (new_state) fsm_state = new_state; switch (fsm_state) { case FSM1_IDLE: // não faz nada break; case FSM1_ST1: // estado 1 va = 10; fsm_state = FSM1_ST2; break; case FSM1_ST2: // estado 2 va = 20; fsm_state = FSM1_ST3; break; case FSM1_ST3: // estado 3 if (va<10) fsm_state = FSM1_ST1; else if (va==255) fsm_state = FSM1_IDLE; else fsm_state = FSM1_ST4; break; case FSM1_ST4: // estado 4 va--; fsm_state = FSM1_ST5; break; case FSM1_ST5: // estado 5 if (!va) fsm_state = FSM1_ST6; break; case FSM1_ST6: // estado 6 va = 100; fsm_state = FSM1_ST1; } return fsm_state;}
132 bytes FLASH
118www.sctec.com.br
Máquinas de Estadounsigned int fsm4(unsigned int new_state){ static unsigned int fsm_state; unsigned int temp_state; if (new_state) fsm_state = new_state; switch (fsm_state) { case FSM1_IDLE: // não faz nada break; case FSM1_ST1: // estado 1 va = 10; temp_state = FSM1_ST2; break; case FSM1_ST2: // estado 2 va = 20; temp_state = FSM1_ST3; break; case FSM1_ST3: // estado 3 if (va<10) temp_state = FSM1_ST1; else if (va==255) temp_state = FSM1_IDLE; else temp_state = FSM1_ST4; break; case FSM1_ST4: // estado 4 va--; temp_state = FSM1_ST5; break; case FSM1_ST5: // estado 5 if (!va) temp_state = FSM1_ST6; break; case FSM1_ST6: // estado 6 va = 100; temp_state = FSM1_ST1; } fsm_state = temp_state; return fsm_state;}
119www.sctec.com.br
Máquinas de Estadounsigned int fsm4(unsigned int new_state){ static unsigned int fsm_state; unsigned int temp_state; if (new_state) fsm_state = new_state; switch (fsm_state) { case FSM1_IDLE: // não faz nada break; case FSM1_ST1: // estado 1 va = 10; temp_state = FSM1_ST2; break; case FSM1_ST2: // estado 2 va = 20; temp_state = FSM1_ST3; break; case FSM1_ST3: // estado 3 if (va<10) temp_state = FSM1_ST1; else if (va==255) temp_state = FSM1_IDLE; else temp_state = FSM1_ST4; break; case FSM1_ST4: // estado 4 va--; temp_state = FSM1_ST5; break; case FSM1_ST5: // estado 5 if (!va) temp_state = FSM1_ST6; break; case FSM1_ST6: // estado 6 va = 100; temp_state = FSM1_ST1; } fsm_state = temp_state; return fsm_state;}
120 bytes FLASH
120www.sctec.com.br
Máquinas de Estado
enum efsm{ FSM2_IDLE, FSM2_ST1, FSM2_ST2, FSM2_ST3, FSM2_ST4, FSM2_ST5, FSM2_ST6};
Enumerações
121www.sctec.com.br
Máquinas de Estadoenum efsm fsm5(enum efsm new_state){ static enum efsm2 fsm_state; unsigned int temp_state; if (new_state) fsm_state = new_state; switch (fsm_state) { case FSM2_IDLE: // não faz nada break; case FSM2_ST1: // estado 1 va = 10; temp_state = FSM2_ST2; break; case FSM2_ST2: // estado 2 va = 20; temp_state = FSM2_ST3; break; case FSM2_ST3: // estado 3 if (va<10) temp_state = FSM2_ST1; else if (va==255) temp_state = FSM2_IDLE; else temp_state = FSM2_ST4; break; case FSM2_ST4: // estado 4 va--; temp_state = FSM2_ST5; break; case FSM2_ST5: // estado 5 if (!va) temp_state = FSM2_ST6; break; case FSM2_ST6: // estado 6 va = 100; temp_state = FSM2_ST1; } fsm_state = temp_state; return fsm_state; }
122www.sctec.com.br
Máquinas de Estadoenum efsm fsm5(enum efsm new_state){ static enum efsm2 fsm_state; unsigned int temp_state; if (new_state) fsm_state = new_state; switch (fsm_state) { case FSM2_IDLE: // não faz nada break; case FSM2_ST1: // estado 1 va = 10; temp_state = FSM2_ST2; break; case FSM2_ST2: // estado 2 va = 20; temp_state = FSM2_ST3; break; case FSM2_ST3: // estado 3 if (va<10) temp_state = FSM2_ST1; else if (va==255) temp_state = FSM2_IDLE; else temp_state = FSM2_ST4; break; case FSM2_ST4: // estado 4 va--; temp_state = FSM2_ST5; break; case FSM2_ST5: // estado 5 if (!va) temp_state = FSM2_ST6; break; case FSM2_ST6: // estado 6 va = 100; temp_state = FSM2_ST1; } fsm_state = temp_state; return fsm_state; }
Lembre-se de que o tipo enum é normalmente um signed int!
Em algumas plataformas de 8 bits pode haver um impacto negativo no uso de enumerações!
123www.sctec.com.br
Operandos e Operações
HCS08 - separação de operações:
if (aux++) ...
LDA auxTAXINCASTA auxTSTXBEQ falso...
if (aux) ...aux++;
TST auxBEQ falso...INC aux
124www.sctec.com.br
Operandos e Operações
HCS08 - separação de operações:
if (aux++) ...
LDA auxTAXINCASTA auxTSTXBEQ falso...
if (aux) ...aux++;
TST auxBEQ falso...INC aux
9 bytes FLASH24 ciclos
6 bytes FLASH24 ciclos
125www.sctec.com.br
Operandos e Operações
HCS08 - separação de operações:
if (aux++) ...
LDA auxTAXINCASTA auxTSTXBEQ falso...
if (aux) ...aux++;
TST auxBEQ falso...INC aux
9 bytes FLASH24 ciclos
6 bytes FLASH24 ciclos
Este tipo de situação
deve ser avaliada
individualmente !!!
126www.sctec.com.br
Operandos e Operações
127www.sctec.com.br
Operandos e Operações
if (CURRENT_TASK<(IDLE_TASK))
128www.sctec.com.br
Operandos e Operações
if ((char)CURRENT_TASK<(char)(IDLE_TASK))
129www.sctec.com.br
Operandos e Operações
130www.sctec.com.br
ReferênciasC:• ISO/IEC 9899:TC3 – ISO C Standard
http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
• The Firmware Handbook
ARM:• ARM Architecture Reference Manual• ARM DDI 0405A-01 ARM v7-M Architecture Application Level
Reference Manual• ARM DDI 0337D Cortex-M3 Technical Reference Manual• Tecnologia ARM: Microcontroladores de 32 bits• AN34 – ARM – Writing Efficient C for ARM• AN36 – ARM – Using C Global Data
131www.sctec.com.br
Referências
Coldfire:• Coldfire Family – Programmer’s Reference Manual
HCS08:• HCS08 Unleashed – Designer’s Guide to the HCS08
Microcontrollers• HCS08RMv1/D – HCS08 Family Reference Manual
MSP430:• Microcontroladores MSP430: Teoria e Prática• MSP430 IAR C/C++ Compiler Reference Guide
132www.sctec.com.br
Referências
PIC:• MPLAB C32 C Compiler User’s Guide• DS61113B – PIC32MX Family Reference Manual• MD00249-2B-M4K-SUM – MIPS32 M4K Software User’s Manual• MD00076 IV-a – MIPS16e Extension to the MIPS32 Architecture