O nosso benchmarking utilizou o código abaixo:
void main( void )
{
MCU_init();
populate_buffers();
while(1)
{
// Operações de I/O
evaluate_sba(0xAA); // Transmissão serial bitbang de 8 bits
evaluate_wrt4(); // escrita de buffer em porta de 4 bits
evaluate_wrt8(); // escrita de buffer em porta de 8 bits
// Manipulação de dados
evaluate_dtr8(); // transferência seletiva de bloco de dados de 8 bits
evaluate_dtr16(); // transferência seletiva de bloco de dados de 16 bits
evaluate_dtr32(); // transferência seletiva de bloco de dados de 32 bits
evaluate_bmp(); // manipulação de bits
evaluate_str(); // manipulação de string
evaluate_prd(0xAA); // conversão de byte em string decimal
// Operações aritméticas e afins
evaluate_calc8(); // cálculo de equação de 8 bits
evaluate_calc16(); // cálculo de equação de 16 bits
evaluate_calc32(); // cálculo de equação de 32 bits
evaluate_mma(); // cálculo de mínimo, máximo e média de um buffer de 16 bytes
evaluate_crc(); // cálculo de CRC
// Máquina de estados
evaluate_fsm(); // teste de máquina de estados
}
}
O código das funções de teste e a declaração das variáveis de teste encontra-se em um arquivo a parte (benchmark.c):
#define BUF_SIZE 16
volatile unsigned char buffer_A[BUF_SIZE], buffer_B[BUF_SIZE];
volatile unsigned int buffer_C[BUF_SIZE], buffer_D[BUF_SIZE];
volatile unsigned long int buffer_E[BUF_SIZE], buffer_F[BUF_SIZE];
unsigned char tx_buffer[BUF_SIZE];
volatile unsigned char va8, vb8, vc8, complete;
volatile unsigned int va16, vb16, vc16;
volatile unsigned long int va32, vb32, vc32;
volatile unsigned char USART_TXBUF;
unsigned char tx_write_pointer, tx_read_pointer;
volatile struct
{
char tx_be : 1; // buffer de transmissão vazio
char flag1 : 1;
char flag2 : 1;
char flag3 : 1;
char flag4 : 1;
char flag5 : 1;
} flags;
enum efsm_states
{
FSM_START, FSM_ST1, FSM_ST2, FSM_ST3, FSM_ST4,
FSM_WAIT, FSM_IDLE, FSM_NONE
};
void delay(unsigned char units)
{
unsigned char temp;
for (;units;units–) for (temp=10;temp;temp–);
}
void populate_buffers(void)
{
unsigned char cnt;
for (cnt=0;cnt<BUF_SIZE;cnt++)
{
buffer_A[cnt] = (cnt+3)*(cnt+1);
buffer_C[cnt] = ((unsigned int)buffer_A[cnt]*(cnt+1)*5)+cnt*5;
buffer_E[cnt] = ((unsigned long)buffer_C[cnt]*(cnt+1)*1234)+(cnt*7);
}
}
unsigned char serial_bitbang_assync(unsigned char data)
{
static unsigned char tx_temp_data, tx_state;
if (!tx_state)
{
tx_temp_data = data;
PIN_0 = 0;
tx_state++;
} else if (tx_state<=8)
{
if (tx_temp_data & 0x80) PIN_0=1; else PIN_0=0;
tx_temp_data <<= 1;
tx_state++;
} else
{
PIN_0=1;
tx_state++;
if (tx_state==10) tx_state = 0;
}
return (tx_state);
}
void serial_write_char(unsigned char data)
{
tx_buffer[tx_write_pointer] = data;
tx_write_pointer++;
if (tx_write_pointer>=BUF_SIZE) tx_write_pointer = 0;
flags.tx_be = 0;
}
void serial_write_string(unsigned char *string)
{
while (*string)
{
serial_write_char(*string);
string++;
}
}
void evaluate_prd(unsigned char data)
{
unsigned char printable_char, printed;
printable_char = 0;
printed = 0;
while (data>=100)
{
data -= 100;
printable_char++;
printed = 1;
}
if (printable_char) serial_write_char(‘0’+printable_char);
printable_char = 0;
while (data>=10)
{
data -= 10;
printable_char++;
printed = 1;
}
if (printed) serial_write_char(‘0’+printable_char);
else if (printable_char) serial_write_char(‘0’+printable_char);
serial_write_char(‘0’+data);
}
void evaluate_sba(unsigned char data)
{
unsigned char result;
do
{
result = serial_bitbang_assync(data);
} while (result);
}
void evaluate_str(void)
{
serial_write_string(“Hello World!\r\n”);
while (!flags.tx_be)
{
va8 = tx_buffer[tx_read_pointer++];
if (tx_read_pointer>=BUF_SIZE) tx_read_pointer = 0;
if (tx_read_pointer==tx_write_pointer) flags.tx_be = 1;
}
}
void evaluate_dtr8(void)
{
unsigned char cnt, pointer;
pointer = 0;
for (cnt=0;cnt<BUF_SIZE;cnt++)
{
if (buffer_A[cnt]>1) buffer_B[pointer++]=buffer_A[cnt];
}
}
void evaluate_dtr16(void)
{
unsigned char cnt, pointer;
pointer = 0;
for (cnt=0;cnt<BUF_SIZE;cnt++)
{
if (buffer_C[cnt]>1) buffer_D[pointer++]=buffer_C[cnt];
}
}
void evaluate_dtr32(void)
{
unsigned char cnt, pointer;
pointer = 0;
for (cnt=0;cnt<BUF_SIZE;cnt++)
{
if (buffer_E[cnt]>1) buffer_F[pointer++]=buffer_E[cnt];
}
}
void evaluate_bmp(void)
{
flags.flag1 = flags.flag2;
if (flags.flag3) flags.flag4 = 1;
flags.flag2 = 0;
flags.flag5 = ! flags.flag5;
}
unsigned int calc_crc(unsigned int old_crc, unsigned char data)
{
unsigned int crc, temp;
temp = old_crc>>8 ^ data;
temp ^= temp>>4;
crc = (old_crc << 8) ^ (temp << 12) ^ (temp <<5) ^ temp;
return crc;
}
void evaluate_crc(void)
{
unsigned char temp;
unsigned int crc;
crc = 0xFFFF;
for (temp=0; temp<16; temp++) crc = calc_crc(crc, buffer_A[temp]);
}
void write_4bit(unsigned char data)
{
PIN_0 = 0;
PORT = data>>4;
PIN_0 = 1;
PIN_0 = 0;
PORT = data & 0x0F;
PIN_0 = 1;
PIN_0 = 0;
}
void write_8bit(unsigned char data)
{
PIN_0 = 0;
PORT = data;
PIN_0 = 1;
PIN_0 = 0;
}
void evaluate_wrt4(void)
{
unsigned char temp;
for (temp=0; temp<16; temp++) write_4bit(buffer_A[temp]);
}
void evaluate_wrt8(void)
{
unsigned char temp;
for (temp=0; temp<16; temp++) write_8bit(buffer_A[temp]);
}
unsigned char evaluate_sum8(unsigned char va, unsigned char vb)
{
return (va+vb);
}
void evaluate_calc8(void)
{
va8 = ((vb8+vc8)/(vb8-vc8))*va8;
}
void evaluate_calc16(void)
{
va16 = ((vb16+vc16)/(vb16-vc16))*va16;
}
void evaluate_calc32(void)
{
va32 = ((vb32+vc32)/(vb32-vc32))*va32;
}
void evaluate_mma(void)
{
unsigned char cnt, min, max, value, avg;
unsigned int sum;
sum = 0;
avg = 0;
min = 0xFF;
max = 0x00;
for (cnt=0; cnt<BUF_SIZE; cnt++)
{
value = buffer_A[cnt];
sum += value – avg;
avg = sum / 4;
if (value>max) max = value;
if (value<min) min = value;
}
va8 = avg;
vb8 = min;
vc8 = max;
}
void test_fsm(enum efsm_states new_state)
{
static enum efsm_states fsm_state, next_state;
static unsigned char counter;
if (new_state!=FSM_NONE) fsm_state = new_state;
switch (fsm_state)
{
case FSM_START:
PIN_0 = 0;
complete = 0;
fsm_state = FSM_ST1;
break;
case FSM_ST1:
PIN_0 = 1;
counter = 1;
next_state = FSM_ST2;
fsm_state = FSM_WAIT;
break;
case FSM_ST2:
PIN_0 = 0;
counter = 1;
next_state = FSM_ST3;
fsm_state = FSM_WAIT;
break;
case FSM_ST3:
PIN_0 = 1;
counter = 1;
next_state = FSM_ST4;
fsm_state = FSM_WAIT;
break;
case FSM_ST4:
PIN_0 = 0;
counter = 1;
next_state = FSM_IDLE;
fsm_state = FSM_WAIT;
break;
case FSM_WAIT:
if (counter) counter–; else fsm_state = next_state;
break;
case FSM_IDLE:
complete = 1;
}
}
void evaluate_fsm(void)
{
test_fsm(FSM_START);
while (!complete) test_fsm(FSM_NONE);
}