Pergunta

Fundo:

Estou desenvolvendo um projeto largo usando no Atmel AVR ATMEGA2560. Este projeto contém muitas funções baseadas em hardware (7 dispositivos SPI, 2 I2C, 2 portas Modbus RS485, muita E/S analógica e digital). Desenvolvi "drivers" para todos esses dispositivos que fornecem ao loop de aplicativos principal uma interface para acessar os dados necessários.

Pergunta:

O projeto que estou desenvolvendo acabará por atender aos padrões do SIL.

Eu gostaria de poder testar o código e fornecer um bom nível de cobertura de código. No entanto, não consigo encontrar nenhuma informação para me iniciar sobre como essa estrutura de teste deve ser configurada.

A idéia é que eu possa ter um conjunto de testes automatizados, o que permitirá que as correções de bugs futuras e as adições de recursos sejam testadas para verificar se elas quebram o código. O problema é que não entendo como o código pode ser testado no chip.

Preciso de hardware para monitorar a E/S no dispositivo e imitar dispositivos conectados externamente? Quaisquer indicadores que pudessem ser fornecidos seriam muito apreciados.

-Steve

Foi útil?

Solução

Esta é uma pergunta muito boa - uma preocupação comum para os desenvolvedores incorporados. Infelizmente, a maioria dos desenvolvedores incorporados não está tão preocupada quanto você e apenas teste o código em hardware real. Mas, como outra resposta apontou, isso pode basicamente testar apenas a funcionalidade nominal do código e não os casos de canto/erro.

Não existe uma solução única e simples para esse problema. Existem algumas diretrizes e técnicas, no entanto, para fazer um trabalho relativamente bom.

Primeiro, separe seu código em camadas. Uma camada deve ser "agnóstica de hardware" - ou seja, chamadas de função. Não peça ao usuário que grava nos registros HW diretamente. A outra camada (inferior) lida com o HW. Essa camada pode ser "ridicularizada" para testar o nível mais alto. O nível mais baixo não pode ser realmente testado sem o HW, mas não vai mudar com frequência e precisa de uma integração profunda de HW, por isso não é um problema.

Um "chicote de teste" será todo o seu código agnóstico HW de alto nível com um nível inferior "falso" especificamente para testes. Isso pode simular os dispositivos HW para funcionalidade correta e incorreta e, assim, permitir que você execute testes automatizados no PC.

Outras dicas

Nunca execute os testes de unidade no hardware ou contra o hardware real. Sempre zombe de suas interfaces de E/S. Caso contrário, você não pode simular condições de erro e, mais importante, não poderá confiar no teste para ter sucesso.

Então, o que você precisa é dividir seu aplicativo em várias peças que você pode testar de forma independente. Simulador (ou simulado) Todo o hardware necessário para esses testes e execute -os no seu PC de desenvolvimento.

Isso deve cobrir a maior parte do seu código e deixar você com os motoristas. Tente criar o máximo possível de código do driver sem o hardware. Para o resto, você terá que descobrir uma maneira de fazer o código funcionar no hardware. Isso geralmente significa que você deve criar uma cama de teste com dispositivos externos que respondam a sinais, etc. Como isso é quebradiço (como em "Seus testes não podem fazer com que isso funcione automaticamente"), você deve executar esses testes manualmente após a preparação do hardware.

Vectorcast é uma ferramenta comercial para executar testes de unidade no hardware com cobertura de código.

Você tem um conector JTAG? Você pode usar o JTAG para simular condições de erro no chip.

Eu gosto de separar as tarefas. Por exemplo, quando fiz um buffer circular para o meu atmel avr, escrevi tudo no código :: blocos e o compilei com o compilador GCC regular em vez do compilador AVR GCC, depois crio um teste de unidade para ele. Usei um arquivo de cabeçalho especial para fornecer os tipos de dados adequados com os quais queria trabalhar (uint8_t, por exemplo). Encontrei erros com os testes de unidade, corrigi -os e, em seguida, peguei o código fixo para o AVR Studio e o integrei. Depois disso, usei funções de suporte e ISRs de escreva para ajustar o buffer no código útil (ou seja, pop um byte do buffer, empurre -o no registro de saída de dados UART, anexa uma string constante ao buffer à função Printf, etc.). Em seguida, usei o simulador AVR para garantir que minhas ISRs e funções estivessem sendo chamadas e que os dados certos aparecessem nos registros. Depois disso, eu o programei no chip e funcionou perfeitamente.

Eu prefiro muito os recursos de depuração do código :: Blocks em comparação com o AVR Studio, por isso uso a abordagem acima sempre que posso. Quando não posso, geralmente estou lidando apenas com hardware. Por exemplo, tenho um cronômetro que produz automaticamente uma onda quadrada. O melhor que pude fazer foi ver que o bit pino estava sendo girado no simulador. Depois disso, eu apenas tive que conectar um escopo e ter certeza.

Eu gosto de usar uma abordagem de vários níveis ao depurar problemas. Por exemplo, com o relógio, a primeira camada é 'colocar uma sonda no pino do relógio e ver se há um sinal lá'. Caso contrário, sonda o pino no UC e procure o sinal. Em seguida, codifiquei uma interface de depuração em um dos meus UARTs, onde posso analisar valores de registro específicos e garantir que eles sejam o que deveriam ser. Portanto, se não funcionar, a próxima etapa for 'Ligue para o valor do registro e verifique se está correto.'

Tente pensar com quatro etapas ou mais sempre que planejar sua depuração. Deveria haver +5V aqui, mas e se não houver? Escreva na interface de depuração uma maneira de alternar o pino e ver se isso altera. E se isso não funcionar? Faça outra coisa, etc etc etc. Você chega a um ponto em que se depara com 'Eu não tenho idéia do porquê dessa coisa não funciona !!!!' Mas espero que você descubra o motivo de antemão.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top