Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Industrial Internet of Things >> Integrado

Por que você deve usar práticas de desenvolvimento baseadas em padrões (mesmo se você não precisar)


Todo um setor se desenvolveu em torno de práticas de verificação e validação que são defendidas por padrões de segurança e codificação funcionais, como IEC 61508, ISO 26262, IEC 62304, MISRA C e CWE. Claro, nem todos são obrigados a seguir os processos e metodologias formais que esses padrões promovem, especialmente se seu software não precisa atender aos rigores desses padrões. Mas os padrões defendem as práticas recomendadas porque a experiência diz que eles representam a maneira mais eficaz de obter software robusto, confiável e de alta qualidade.

As técnicas de desenvolvimento de práticas recomendadas que seguem esses padrões ajudam a garantir que os erros não sejam introduzidos no código em primeiro lugar, reduzindo a necessidade de atividades de depuração extensas que podem retardar o tempo de lançamento no mercado e adicionar custos. Obviamente, nem todos os desenvolvedores podem se dar ao luxo do tempo e do orçamento destinados aos aplicativos vistos nas indústrias aeroespacial, automotiva ou de dispositivos médicos. As técnicas que eles implantam, no entanto, representam uma caixa de ferramentas com enormes benefícios potenciais para qualquer equipe de desenvolvimento, independentemente de a criticidade impor seu uso ou não.

Tipos de erros e ferramentas para resolvê-los

Dois tipos principais de erros podem ser encontrados no software e resolvidos usando ferramentas para evitar a introdução de erros:

Erros de codificação e revisão de código

A análise estática é uma técnica eficaz para detectar bugs de codificação, especialmente quando é implantada desde o início de um projeto. Uma vez que o código foi analisado, existem diferentes tipos de resultados que podem ser visualizados. A revisão do código é onde o código é verificado em relação a um padrão de codificação, como MISRA C:2012, que é o que vamos nos concentrar neste artigo.

O ideal é que uma linguagem segura, como Ada, seja usada para todos os projetos incorporados. Ada inclui inúmeras características para forçar um processo de pensamento que reduz naturalmente os erros (como digitação estrita, por exemplo). Infelizmente, é difícil encontrar programadores com conhecimento e experiência em Ada, então a maioria das empresas usa C e / ou C ++. Essas linguagens, no entanto, apresentam armadilhas até mesmo para desenvolvedores experientes. Felizmente, realizando a revisão do código, a maioria dessas armadilhas em potencial pode ser evitada.

A melhor maneira de evitar defeitos no código é evitar colocá-los lá. Isso parece óbvio, mas é exatamente o que um padrão de codificação faz. No mundo C e C ++, cerca de 80% dos defeitos de software são causados ​​pelo uso incorreto de cerca de 20% da linguagem. Se o uso da linguagem for restrito para evitar as partes da linguagem que são sabidamente problemáticas, então os defeitos são evitados e a qualidade do software aumenta muito.

As causas fundamentais de falhas nas linguagens de programação C / C ++ relacionadas à linguagem são o comportamento indefinido, o comportamento definido pela implementação e o comportamento não especificado. Esses comportamentos levam a bugs de software e problemas de segurança.

Como um exemplo de comportamento definido pela implementação, considere a propagação do bit de ordem superior quando um inteiro com sinal é deslocado para a direita. O resultado é 0x40000000 ou 0xC0000000?


Figura 1:O comportamento de algumas construções C e C ++ depende do compilador usado. (Fonte:LDRA)

A resposta depende de qual compilador você está usando (Figura 1). Pode ser qualquer um. A ordem em que os argumentos de uma função são avaliados não é especificada na linguagem C. No código mostrado na Figura 2 - onde o rollDice () função simplesmente lê o próximo valor de um buffer circular contendo os valores "1, 2, 3 e 4" - o valor retornado esperado seria 1234. Não há, entretanto, nenhuma garantia disso e pelo menos um compilador irá gerar o código que retorna o valor 3412.


Figura 2:O comportamento de algumas construções C e C ++ não é especificado pelas linguagens. (Fonte:LDRA)

As linguagens C / C ++ apresentam muitas armadilhas como essa, mas com o uso de um padrão de codificação, esses comportamentos indefinidos, não especificados e definidos pela implementação podem ser evitados. Da mesma forma, o uso de construções como goto ou malloc pode levar a defeitos, portanto, um padrão de codificação pode ser usado para evitar que essas construções sejam usadas. Muitos problemas ocorrem ao misturar valores assinados e não assinados, o que não gera nenhum problema na maioria das vezes, mas às vezes pode haver um caso extremo em que o valor assinado transborda e se torna negativo.

Os padrões de codificação também podem verificar se o código foi escrito em um estilo específico; por exemplo, verificar se o caractere de tabulação não é usado, se o recuo tem um tamanho específico ou se os parênteses estão posicionados em uma posição específica. Isso é importante porque alguma revisão manual do código será necessária e quando o código for visualizado em um editor diferente onde o caractere de tabulação tem um tamanho diferente, então o layout estranho distrai o revisor de se concentrar na revisão do código.

Alguns desenvolvedores são culpados de escrever um código “inteligente” que pode ser altamente eficiente e compacto, mas também pode ser enigmático e complexo, tornando-o difícil para outros entenderem. É muito melhor mantê-lo simples e deixar que o compilador se encarregue de fazer um binário eficiente. Mais uma vez, o uso de um padrão de codificação pode ajudar a evitar que os desenvolvedores criem código não documentado e complexo demais.

Os padrões de programação mais conhecidos são talvez os padrões MISRA, que foram publicados pela primeira vez em 1998 para a indústria automotiva. A popularidade desses padrões se reflete no número de compiladores incorporados que oferecem algum nível de verificação MISRA. A última versão do MISRA é MISRA C:2012, que tem quase o dobro do número de páginas de seu antecessor. A maior parte desta documentação adicional consiste em explicações úteis sobre por que cada regra existe, junto com detalhes das várias exceções a essa regra. MISRA tem várias diretrizes e, quando aplicável, elas contêm referências a padrões ou ao comportamento indefinido, não especificado e definido pela implementação. Um exemplo disso pode ser visto na Figura 3.


Figura 3:Referências do MISRA C a comportamento indefinido, não especificado e definido pela implementação. (Fonte:LDRA)

A maioria das diretrizes da MISRA são “Decidíveis”, o que significa que uma ferramenta deve ser capaz de identificar se há uma violação ou não. No entanto, algumas diretrizes são “Indecidíveis”, o que significa que nem sempre é possível para uma ferramenta deduzir se há uma violação ou não. Um exemplo disso é quando uma variável não inicializada é passada como um parâmetro de saída para uma função do sistema que deve inicializá-la. No entanto, a menos que a análise estática tenha acesso ao código-fonte da função do sistema, ela não será capaz de saber se essa função usa a variável antes de inicializá-la. Se um verificador MISRA simples for usado, ele pode não relatar essa violação, possivelmente levando a um falso negativo. Alternativamente, se um verificador MISRA não tiver certeza, ele pode relatar a violação, possivelmente levando a um falso-positivo. O que e melhor? Não saber que pode haver um problema? Ou saber exatamente onde gastar o tempo para garantir que definitivamente não haja um problema? Certamente é preferível ter falsos positivos em vez de falsos negativos.

Em abril de 2016, o Comitê MISRA emitiu uma alteração ao MISRA C:2012 que acrescentou 14 diretrizes adicionais para ajudar a garantir que o MISRA fosse aplicável não apenas para software crítico de segurança, mas também crítico de segurança. Uma dessas diretrizes foi a Diretriz 4.14, que, como pode ser visto na Figura 4, ajuda a prevenir armadilhas por comportamento indefinido.


Figura 4:MISRA e considerações de segurança. (Fonte:LDRA)

Teste de erros e requisitos do aplicativo

Bugs de aplicativo só podem ser encontrados testando se o produto faz o que deve fazer, e isso significa ter requisitos. Para evitar bugs de aplicativo, é necessário projetar o produto certo e projetar o produto da maneira certa.

Projetar o produto certo significa estabelecer os requisitos antecipadamente e garantir a rastreabilidade bidirecional entre os requisitos e o código-fonte, de forma que cada requisito tenha sido implementado e cada função de software seja rastreada até um requisito. Qualquer funcionalidade ausente ou desnecessária (que não atenda a um requisito) também é um bug do aplicativo. Projetar o produto certo é o processo de confirmação de que o código do sistema desenvolvido atende aos requisitos do projeto, o que pode ser alcançado por meio da realização de testes baseados em requisitos.

A Figura 5 mostra um exemplo de rastreabilidade bidirecional. Neste exemplo simples, uma única função foi selecionada e a rastreabilidade upstream é destacada da função para um requisito de baixo nível, depois para um requisito de alto nível e, finalmente, para um requisito de nível de sistema.


Figura 5:Rastreabilidade bidirecional, com função selecionada. (Fonte:LDRA)

Na Figura 6, um requisito de alto nível foi selecionado e o destaque mostra a rastreabilidade upstream para um requisito de nível de sistema e a rastreabilidade downstream para requisitos de baixo nível e funções de código-fonte.

clique para ampliar a imagem

Figura 6:Rastreabilidade bidirecional, com requisito selecionado. (Fonte:LDRA)

Essa capacidade de visualizar a rastreabilidade pode levar à detecção de problemas de rastreabilidade (bugs de aplicativo) no início do ciclo de vida.

Testar a funcionalidade do código exige uma consciência do que ele deve fazer, e isso significa ter requisitos de baixo nível para definir o que cada função faz. A Figura 7 mostra um exemplo de requisito de baixo nível, que, neste caso, descreve totalmente uma única função.


Figura 7:Exemplo de requisito de baixo nível. (Fonte:LDRA)

Os casos de teste são derivados de requisitos de baixo nível, conforme ilustrado na Tabela 1.

Tabela 1:Casos de teste derivados de requisitos de baixo nível. (Fonte:LDRA)

Usando uma ferramenta de teste de unidade, esses casos de teste podem ser executados no host ou no destino para garantir que o código se comporte de acordo com os requisitos. A Figura 8 mostra que todos os casos de teste foram regredidos e aprovados.


Figura 8:Executando testes de unidade. (Fonte:LDRA)

Quando os casos de teste forem executados, a cobertura estrutural deve ser medida para garantir que todo o código foi executado. Se a cobertura não for 100 por cento, é possível que sejam necessários mais casos de teste ou que haja código supérfluo que deve ser removido.

Conclusão

Com o aumento da complexidade do software, os erros de software em potencial também aumentam. As técnicas de desenvolvimento de práticas recomendadas ajudam a evitar que esses erros ocorram. O desenvolvimento de melhores práticas consiste no uso de um padrão de codificação de última geração, como MISRA C:2012, medindo métricas no código, rastreando requisitos e implementando testes baseados em requisitos. A extensão em que essas técnicas são aplicadas onde não há obrigações de atender aos padrões fica claramente a critério da equipe de desenvolvimento. No entanto, os padrões defendem essas práticas porque a experiência diz que elas representam a maneira mais eficaz de obter software de qualidade, confiável e robusto. E se um produto é crítico para a segurança ou não, esse é certamente um resultado que só pode ser benéfico para sua equipe de desenvolvimento.

Integrado

  1. Por que você deve mudar para Connext DDS Secure
  2. Por que você deve parar de programar seus robôs
  3. Por que você precisa usar corantes agrícolas?
  4. O que é NuttX RTOS e por que você deveria se importar?
  5. Por que você deve escolher equipamento industrial recondicionado
  6. Por que você deve usar um reator de linha
  7. Por que você deve considerar uma carreira em máquinas e equipamentos
  8. Quando você deve usar um guindaste de cabeça de martelo? Um guia
  9. Por que você deve usar uma solução Remote Expert?
  10. Por que você deve usar vendas em consignação para seu equipamento usado?