otimização de código c para sistemas embarcados

133

Upload: erduarte

Post on 02-Apr-2015

219 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: Otimização de código C para sistemas embarcados
Page 2: Otimização de código C para sistemas embarcados

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.

Page 3: Otimização de código C para sistemas embarcados

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

Page 4: Otimização de código C para sistemas embarcados

4www.sctec.com.br

Produtos

Page 5: Otimização de código C para sistemas embarcados

5www.sctec.com.br

Produtos

MOD711• ARM7• 256 Kb FLASH• 64 Kb RAM• USB 2.0• JTAG

Page 6: Otimização de código C para sistemas embarcados

6www.sctec.com.br

Projetos

Computador de Bordo – M8 Octopus

Page 7: Otimização de código C para sistemas embarcados

7www.sctec.com.br

Educacional

Livros

Page 9: Otimização de código C para sistemas embarcados

Otimização de Programas C para

Sistemas Embarcados

Page 10: Otimização de código 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.

Page 11: Otimização de código C para sistemas embarcados

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.

Page 12: Otimização de código C para sistemas embarcados

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

Page 13: Otimização de código C para sistemas embarcados

Tipos de Dados e Alocação de

Memória

Page 14: Otimização de código C para sistemas embarcados

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?

Page 15: Otimização de código C para sistemas embarcados

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).

Page 16: Otimização de código C para sistemas embarcados

16www.sctec.com.br

Signed x Unsigned

0123456S012345670123456S01234567

01234567012345670123456701234567

0123456SSSSSSSSS

0123456789101112131415

0123456700000000012345678910111213141501234567000000000123456789101112131415

Zero filling

Sign extension

Page 17: Otimização de código C para sistemas embarcados

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

Page 18: Otimização de código C para sistemas embarcados

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

Page 19: Otimização de código C para sistemas embarcados

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

Page 20: Otimização de código C para sistemas embarcados

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

Page 21: Otimização de código C para sistemas embarcados

21www.sctec.com.br

Signed x Unsigned

Algumas operações aritméticas também podem sofrer impactos negativos pelo uso de tipos signed:

Page 22: Otimização de código C para sistemas embarcados

22www.sctec.com.br

Signed x Unsigned

Unsigned

118 bytes238 ciclos

Divisão de 16 bits nos HCS08

Signed

160 bytes356 ciclos

Page 23: Otimização de código C para sistemas embarcados

23www.sctec.com.br

Signed x Unsigned

Unsigned

456 bytes51 ciclos

Divisão de 32 bits nos ARM7

Signed

472 bytes48 ciclos

Page 24: Otimização de código C para sistemas embarcados

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;}

Page 25: Otimização de código C para sistemas embarcados

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):

Page 26: Otimização de código C para sistemas embarcados

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):

Page 27: Otimização de código C para sistemas embarcados

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).

Page 28: Otimização de código C para sistemas embarcados

Campos de Bits

Page 29: Otimização de código C para sistemas embarcados

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?

Page 30: Otimização de código C para sistemas embarcados

30www.sctec.com.br

Campos de bits

struct{ unsigned char bit0 : 1; unsigned char bit1 : 1; unsigned char bit2 : 1;} teste;

Page 31: Otimização de código C para sistemas embarcados

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

Page 32: Otimização de código C para sistemas embarcados

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

Page 33: Otimização de código C para sistemas embarcados

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

Page 34: Otimização de código C para sistemas embarcados

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

Page 35: Otimização de código C para sistemas embarcados

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

Page 36: Otimização de código C para sistemas embarcados

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

Page 37: Otimização de código C para sistemas embarcados

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

Page 38: Otimização de código C para sistemas embarcados

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

Page 39: Otimização de código C para sistemas embarcados

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

Page 40: Otimização de código C para sistemas embarcados

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

Page 41: Otimização de código C para sistemas embarcados

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

Page 42: Otimização de código C para sistemas embarcados

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

Page 43: Otimização de código C para sistemas embarcados

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).

Page 44: Otimização de código C para sistemas embarcados

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)

Page 45: Otimização de código C para sistemas embarcados

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

Page 46: Otimização de código C para sistemas embarcados

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

Page 47: Otimização de código C para sistemas embarcados

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

Page 48: Otimização de código C para sistemas embarcados

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

Page 49: Otimização de código C para sistemas embarcados

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]

Page 50: Otimização de código C para sistemas embarcados

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

Page 51: Otimização de código C para sistemas embarcados

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):

Page 52: Otimização de código C para sistemas embarcados

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):

Page 53: Otimização de código C para sistemas embarcados

Alinhamento de Dados

Page 54: Otimização de código C para sistemas embarcados

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.

Page 55: Otimização de código C para sistemas embarcados

55www.sctec.com.br

Alinhamento de dados

struct{ char campo1; int campo2; short campo3;} teste;

ARM7:

0xuuuuuuu9campo3

0xuuuuuuu80xuuuuuuu7

campo2

---

campo1

0xuuuuuuu40xuuuuuuu50xuuuuuuu6

0xuuuuuuu30xuuuuuuu20xuuuuuuu10xuuuuuuu0

Page 56: Otimização de código C para sistemas embarcados

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!

Page 57: Otimização de código C para sistemas embarcados

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:

Page 58: Otimização de código C para sistemas embarcados

58www.sctec.com.br

Alinhamento de dados

struct{ char campo1; int campo2; short campo3;} teste;

0xuuuuuuu4

campo30xuuuuuuu50xuuuuuuu6

0xuuuuuuu30xuuuuuuu20xuuuuuuu10xuuuuuuu0

campo2

campo1

Coldfire, Cortex e MIPS:

Page 59: Otimização de código C para sistemas embarcados

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!

Page 60: Otimização de código C para sistemas embarcados

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))

Page 61: Otimização de código C para sistemas embarcados

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!

Page 62: Otimização de código C para sistemas embarcados

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:

Page 63: Otimização de código C para sistemas embarcados

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

Page 64: Otimização de código C para sistemas embarcados

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!

Page 65: Otimização de código C para sistemas embarcados

65www.sctec.com.br

Organização de dados

struct{ char campo1; char campo3; short campo4; int campo2; } teste;

campo2

campo4

campo3campo1

0xuuuuuuu7

0xuuuuuuu40xuuuuuuu50xuuuuuuu6

0xuuuuuuu30xuuuuuuu20xuuuuuuu10xuuuuuuu0

Page 66: Otimização de código C para sistemas embarcados

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!

Page 67: Otimização de código C para sistemas embarcados

Estudo de Casos

Page 68: Otimização de código C para sistemas embarcados

68www.sctec.com.br

Timers e ContadoresOtimização de timers e contadores:

if (va<10) va++;......

if (va) va--;......

Page 69: Otimização de código C para sistemas embarcados

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

Page 70: Otimização de código C para sistemas embarcados

70www.sctec.com.br

Timers e ContadoresVerificação do contador dentro do programa:

if (va==VALOR)......

if (!va)......

Mais eficiente!

Page 71: Otimização de código C para sistemas embarcados

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;}

Page 72: Otimização de código C para sistemas embarcados

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;}

Page 73: Otimização de código C para sistemas embarcados

73www.sctec.com.br

FunçõesExame do MAP file:

Page 74: Otimização de código C para sistemas embarcados

74www.sctec.com.br

FunçõesExame do MAP file:

Redução de 17 bytes no tamanho do código !

Page 75: Otimização de código C para sistemas embarcados

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; }

Page 76: Otimização de código C para sistemas embarcados

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

Page 77: Otimização de código C para sistemas embarcados

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; }}

Page 78: Otimização de código C para sistemas embarcados

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

Page 79: Otimização de código C para sistemas embarcados

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; }}

Page 80: Otimização de código C para sistemas embarcados

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

Page 81: Otimização de código C para sistemas embarcados

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; } }

Page 82: Otimização de código C para sistemas embarcados

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

Page 83: Otimização de código C para sistemas embarcados

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; } }

Page 84: Otimização de código C para sistemas embarcados

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

Page 85: Otimização de código C para sistemas embarcados

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

Page 86: Otimização de código C para sistemas embarcados

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; }

Page 87: Otimização de código C para sistemas embarcados

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

Page 88: Otimização de código C para sistemas embarcados

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; }

Page 89: Otimização de código C para sistemas embarcados

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

Page 90: Otimização de código C para sistemas embarcados

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

Page 91: Otimização de código C para sistemas embarcados

91www.sctec.com.br

Configuração do Linker

Utilização da página direta nos HCS08:

Page 92: Otimização de código C para sistemas embarcados

92www.sctec.com.br

Configuração do Linker

Utilização da página direta nos HCS08:

Page 93: Otimização de código C para sistemas embarcados

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

Page 94: Otimização de código C para sistemas embarcados

94www.sctec.com.br

Explorando MAP files

Page 95: Otimização de código C para sistemas embarcados

95www.sctec.com.br

Explorando MAP files

Page 96: Otimização de código C para sistemas embarcados

96www.sctec.com.br

Explorando MAP files

Page 97: Otimização de código C para sistemas embarcados

97www.sctec.com.br

Explorando MAP files

Page 98: Otimização de código C para sistemas embarcados

98www.sctec.com.br

Explorando MAP files

Com endereçamento extendido:

Page 99: Otimização de código C para sistemas embarcados

99www.sctec.com.br

Explorando MAP files

Modificação para endereçamento direto:

Page 100: Otimização de código C para sistemas embarcados

100www.sctec.com.br

Explorando MAP files

Com endereçamento direto:

-1 byte/-1 ciclo

Page 101: Otimização de código C para sistemas embarcados

101www.sctec.com.br

Explorando MAP files

Com endereçamento extendido:

-47 bytes

-20 bytes

-31 bytes

-105 bytes

Page 102: Otimização de código C para sistemas embarcados

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.

Page 103: Otimização de código C para sistemas embarcados

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!

Page 104: Otimização de código C para sistemas embarcados

104www.sctec.com.br

Pilha

Como dimensionar corretamente o tamanho da pilha?

Page 105: Otimização de código C para sistemas embarcados

105www.sctec.com.br

Pilha

Call Graph:

Page 106: Otimização de código C para sistemas embarcados

106www.sctec.com.br

Pilha

Call Graph:

Page 107: Otimização de código C para sistemas embarcados

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)!

Page 108: Otimização de código C para sistemas embarcados

108www.sctec.com.br

Pilha

13 bytes!

7 bytes!

Page 109: Otimização de código C para sistemas embarcados

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

Page 110: Otimização de código C para sistemas embarcados

110www.sctec.com.br

Máquinas de Estado

IDLE

ST1

ST2

ST4 ST3

ST5

ST6

Page 111: Otimização de código C para sistemas embarcados

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; }}

Page 112: Otimização de código C para sistemas embarcados

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

Page 113: Otimização de código C para sistemas embarcados

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

Page 114: Otimização de código C para sistemas embarcados

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; }}

Page 115: Otimização de código C para sistemas embarcados

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

Page 116: Otimização de código C para sistemas embarcados

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;}

Page 117: Otimização de código C para sistemas embarcados

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

Page 118: Otimização de código C para sistemas embarcados

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;}

Page 119: Otimização de código C para sistemas embarcados

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

Page 120: Otimização de código C para sistemas embarcados

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

Page 121: Otimização de código C para sistemas embarcados

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; }

Page 122: Otimização de código C para sistemas embarcados

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!

Page 123: Otimização de código C para sistemas embarcados

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

Page 124: Otimização de código C para sistemas embarcados

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

Page 125: Otimização de código C para sistemas embarcados

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 !!!

Page 126: Otimização de código C para sistemas embarcados

126www.sctec.com.br

Operandos e Operações

Page 127: Otimização de código C para sistemas embarcados

127www.sctec.com.br

Operandos e Operações

if (CURRENT_TASK<(IDLE_TASK))

Page 128: Otimização de código C para sistemas embarcados

128www.sctec.com.br

Operandos e Operações

if ((char)CURRENT_TASK<(char)(IDLE_TASK))

Page 129: Otimização de código C para sistemas embarcados

129www.sctec.com.br

Operandos e Operações

Page 130: Otimização de código C para sistemas embarcados

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

Page 131: Otimização de código C para sistemas embarcados

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

Page 132: Otimização de código C para sistemas embarcados

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

Page 133: Otimização de código C para sistemas embarcados

133www.sctec.com.br

[email protected]

Obrigado !