Análise estática de código para sistemas embebidos
O Visao verifica C e C++ embebido com a sua toolchain cruzada, antes de o código chegar a uma placa.
Com o perfil MISRA C:2012, cada ocorrência indica o número da regra, e a execução termina com um resumo das regras verificadas e não verificadas.
$visao --compiler-path "gcc:/opt/arm/bin/arm-none-eabi-gcc" \ --cpu arm --os baremetal --standard misra-c-2012 \ --baseline visao-baseline.sarif --fail-on high \ build/compile_commands.json Using toolchain arm-none-eabi-gcc (gcc) Solving … src/uart.c:88:14: error: Possible integer overflow MISRA C:2012 Rule 12.4 (Advisory) ✓ Finished successfully · 2.1 s $echo $? 1
Análise estática para código embebido.Verificar o firmware antes da placa.
A análise estática de código para sistemas embebidos verifica C e C++ para microcontroladores e Linux embebido sem o executar. Não precisa de placa, de debugger nem de tempo na bancada.
No trabalho embebido isto pesa mais do que noutros lados. Quando o código já corre num dispositivo, uma falha é difícil de ver: muitas vezes só há uma consola e alguns logs. Um defeito encontrado no código-fonte corrige-se no merge request. O mesmo defeito encontrado na bancada demora mais a isolar, porque o código e o hardware atuam em conjunto.
O Visao lê o compile_commands.json que o seu build cruzado escreve. Usa o seu compilador, as suas flags e os seus caminhos de include. Por isso, vê o código tal como o build do alvo o vê.
Como funciona a análise, com um exemplo completo: Análise estática de código.
Cobertura MISRA C:2012.O que um build verifica, regra a regra.
Este é o resumo de conformidade de exemplo da documentação do Visao, dividido pelos capítulos da norma. Escolha um capítulo para ver que regras esse build verifica.
regras verificadas por este build
- 19Verificadas, com ocorrências na execução de exemplo
- 48Verificadas, sem ocorrências
- 107Não verificadas por este build
Por categoria MISRA
visao --standard misra-c-2012 -- src/*.c▎ Compliance (174)
• MISRA C:2012
↳ rules in the standard: 174
↳ checked by this build: 67
↳ checked rules with findings: 19
↳ Rule 21.3 (Required) - 2 finding(s): Use of the memory-allocation functions
↳ not checked by this build: 107
↳ Dir 1.1 (Required), Dir 3.1 (Required), …
Capítulos da norma
Diretivas
6 de 17 regras verificadas
Verificadas por este build
- Dir 2.1RequiredUma unidade de tradução que não compila
- Dir 4.7RequiredUma indicação de erro devolvida que nunca é testada
- Dir 4.11RequiredUm valor passado a uma função de biblioteca sem ser verificado
- Dir 4.12RequiredUso de alocação dinâmica de memória
- Dir 4.13AdvisoryOperações sobre um recurso chamadas fora de ordem
- Dir 4.14RequiredUm valor de uma fonte externa usado sem ser verificado
Não verificadas por este build
Dir 1.1, Dir 3.1, Dir 4.1, Dir 4.2, Dir 4.3, Dir 4.4, Dir 4.5, Dir 4.6, Dir 4.8, Dir 4.9, Dir 4.10
1. Um ambiente C normalizado
1 de 3 regras verificadas
Verificadas por este build
- Rule 1.3RequiredConstruções cujo comportamento a norma deixa indefinido
Não verificadas por este build
Rule 1.1, Rule 1.2
2. Código não usado
4 de 7 regras verificadas
Verificadas por este build
- Rule 2.1RequiredCódigo que nunca pode ser alcançado
- Rule 2.2RequiredUma instrução cuja remoção não muda nada
- Rule 2.6AdvisoryUma etiqueta a que nenhum goto se refere
- Rule 2.7AdvisoryUm parâmetro que a função nunca lê
Não verificadas por este build
Rule 2.3, Rule 2.4, Rule 2.5
3. Comentários
0 de 2 regras verificadas
Verificadas por este build
Nenhuma
Não verificadas por este build
Rule 3.1, Rule 3.2
4. Conjuntos de caracteres e convenções léxicas
0 de 2 regras verificadas
Verificadas por este build
Nenhuma
Não verificadas por este build
Rule 4.1, Rule 4.2
5. Identificadores
1 de 9 regras verificadas
Verificadas por este build
- Rule 5.3RequiredUm identificador num âmbito interior que esconde outro de um âmbito exterior
Não verificadas por este build
Rule 5.1, Rule 5.2, Rule 5.4, Rule 5.5, Rule 5.6, Rule 5.7, Rule 5.8, Rule 5.9
6. Tipos
0 de 2 regras verificadas
Verificadas por este build
Nenhuma
Não verificadas por este build
Rule 6.1, Rule 6.2
7. Literais e constantes
0 de 4 regras verificadas
Verificadas por este build
Nenhuma
Não verificadas por este build
Rule 7.1, Rule 7.2, Rule 7.3, Rule 7.4
8. Declarações e definições
2 de 14 regras verificadas
Verificadas por este build
- Rule 8.2RequiredUma função declarada sem protótipo
- Rule 8.14RequiredUso do qualificador restrict
Não verificadas por este build
Rule 8.1, Rule 8.3, Rule 8.4, Rule 8.5, Rule 8.6, Rule 8.7, Rule 8.8, Rule 8.9, Rule 8.10, Rule 8.11, Rule 8.12, Rule 8.13
9. Inicialização
1 de 5 regras verificadas
Verificadas por este build
- Rule 9.1MandatoryUm objeto lido antes de ter um valor
Não verificadas por este build
Rule 9.2, Rule 9.3, Rule 9.4, Rule 9.5
10. O modelo de tipos essenciais
3 de 8 regras verificadas
Verificadas por este build
- Rule 10.3RequiredUm valor atribuído a um objeto de tipo mais estreito ou diferente
- Rule 10.4RequiredOperandos de categorias de tipo essencial diferentes
- Rule 10.6RequiredUma expressão composta atribuída a um objeto mais largo
Não verificadas por este build
Rule 10.1, Rule 10.2, Rule 10.5, Rule 10.7, Rule 10.8
11. Conversões de tipos de ponteiro
2 de 9 regras verificadas
Verificadas por este build
- Rule 11.3RequiredUm ponteiro convertido para um ponteiro de tipo de objeto não relacionado, e usado
- Rule 11.4AdvisoryUma conversão entre um ponteiro e um inteiro
Não verificadas por este build
Rule 11.1, Rule 11.2, Rule 11.5, Rule 11.6, Rule 11.7, Rule 11.8, Rule 11.9
12. Expressões
3 de 5 regras verificadas
Verificadas por este build
- Rule 12.2RequiredUm deslocamento que a largura do operando esquerdo não comporta
- Rule 12.3AdvisoryUso do operador vírgula
- Rule 12.4AdvisoryUma expressão constante que dá a volta
Não verificadas por este build
Rule 12.1, Rule 12.5
13. Efeitos secundários
3 de 6 regras verificadas
Verificadas por este build
- Rule 13.2RequiredUm valor que depende da ordem de avaliação dos operandos
- Rule 13.4AdvisoryO resultado de uma atribuição usado como valor
- Rule 13.6MandatoryUm operando de sizeof com efeitos secundários
Não verificadas por este build
Rule 13.1, Rule 13.3, Rule 13.5
14. Expressões das instruções de controlo
1 de 4 regras verificadas
Verificadas por este build
- Rule 14.3RequiredUma expressão de controlo cujo valor nunca muda
Não verificadas por este build
Rule 14.1, Rule 14.2, Rule 14.4
15. Fluxo de controlo
6 de 7 regras verificadas
Verificadas por este build
- Rule 15.1AdvisoryUso de goto
- Rule 15.2RequiredUm goto que salta para trás
- Rule 15.4AdvisoryMais do que um break ou goto a terminar o mesmo ciclo
- Rule 15.5AdvisoryUm return em qualquer ponto que não o fim da função
- Rule 15.6RequiredO corpo de uma instrução de controlo que não é uma instrução composta
- Rule 15.7RequiredUma cadeia if ... else if sem else final
Não verificadas por este build
Rule 15.3
16. Instruções switch
4 de 7 regras verificadas
Verificadas por este build
- Rule 16.3RequiredUma cláusula de switch que não termina com break
- Rule 16.4RequiredUm switch sem cláusula default
- Rule 16.5RequiredUma cláusula default que não é a primeira nem a última
- Rule 16.6RequiredUm switch com menos de duas cláusulas
Não verificadas por este build
Rule 16.1, Rule 16.2, Rule 16.7
17. Funções
6 de 8 regras verificadas
Verificadas por este build
- Rule 17.1RequiredUso das funcionalidades variádicas de <stdarg.h>
- Rule 17.2RequiredUma função que se chama a si própria, diretamente ou através de outras
- Rule 17.3MandatoryUma chamada a uma função que nunca foi declarada
- Rule 17.4MandatoryUm caminho de saída de uma função não void sem valor de retorno
- Rule 17.7RequiredUm valor devolvido que nunca é usado
- Rule 17.8AdvisoryUm parâmetro a que a função atribui um valor
Não verificadas por este build
Rule 17.5, Rule 17.6
18. Ponteiros e arrays
7 de 8 regras verificadas
Verificadas por este build
- Rule 18.1RequiredAritmética de ponteiros que sai do objeto onde começou
- Rule 18.2RequiredUma subtração de ponteiros para objetos diferentes
- Rule 18.4AdvisoryAritmética de ponteiros que não é indexação de arrays
- Rule 18.5AdvisoryMais de dois níveis de indireção de ponteiros
- Rule 18.6RequiredO endereço de um objeto automático que sobrevive ao seu tempo de vida
- Rule 18.7RequiredUm membro de array flexível
- Rule 18.8RequiredUm array de comprimento variável
Não verificadas por este build
Rule 18.3
19. Armazenamento sobreposto
2 de 2 regras verificadas
Verificadas por este build
- Rule 19.1MandatoryUm objeto copiado para outro que se sobrepõe a ele
- Rule 19.2AdvisoryUso de uma union
20. Diretivas de pré-processamento
0 de 14 regras verificadas
Verificadas por este build
Nenhuma
Não verificadas por este build
Rule 20.1, Rule 20.2, Rule 20.3, Rule 20.4, Rule 20.5, Rule 20.6, Rule 20.7, Rule 20.8, Rule 20.9, Rule 20.10, Rule 20.11, Rule 20.12, Rule 20.13, Rule 20.14
21. Bibliotecas normalizadas
12 de 21 regras verificadas
Verificadas por este build
- Rule 21.3RequiredUso das funções de alocação de memória de <stdlib.h> 2 ocorrências no exemplo da documentação
- Rule 21.4RequiredUso de <setjmp.h>
- Rule 21.5RequiredUso de <signal.h>
- Rule 21.6RequiredUso das funções de entrada/saída de <stdio.h>
- Rule 21.7RequiredUso de atof, atoi, atol ou atoll
- Rule 21.8RequiredUso de abort, exit, getenv ou system
- Rule 21.9RequiredUso de bsearch ou qsort
- Rule 21.10RequiredUso das funções de data e hora
- Rule 21.11RequiredUso de <tgmath.h>
- Rule 21.12AdvisoryUso das funcionalidades de exceções de <fenv.h>
- Rule 21.17MandatoryUma operação de strings que vai além do objeto que recebeu
- Rule 21.18MandatoryUm tamanho passado a uma função de <string.h> que o objeto não comporta
Não verificadas por este build
Rule 21.1, Rule 21.2, Rule 21.13, Rule 21.14, Rule 21.15, Rule 21.16, Rule 21.19, Rule 21.20, Rule 21.21
22. Recursos
3 de 10 regras verificadas
Verificadas por este build
- Rule 22.1RequiredUm recurso obtido e nunca libertado
- Rule 22.2MandatoryUm bloco libertado duas vezes, ou libertado pela função errada
- Rule 22.6MandatoryUm ponteiro FILE usado depois de o stream ser fechado
Não verificadas por este build
Rule 22.3, Rule 22.4, Rule 22.5, Rule 22.7, Rule 22.8, Rule 22.9, Rule 22.10
A divisão por capítulo e por categoria vem da lista de regras do mesmo build do Visao. Outra versão pode verificar um conjunto diferente. Cada descrição diz o que o Visao procura, o que muitas vezes é mais restrito do que a própria regra. Os textos das regras pertencem à MISRA e não estão reproduzidos aqui.
Evidências de conformidade não são certificação.
O resumo só fala das regras que este build verifica. Uma regra que o Visao não verifica aparece como não verificada, nunca como cumprida.
A conformidade assenta no documento MISRA e nos registos de desvios do seu projeto. O resumo do Visao é uma evidência para esse argumento. Nem o Visao nem o Midair certificam código.
Antes da placa.Cinco passos do commit ao dispositivo.
Escolha um passo para ver o que acontece nele. Os comandos e a saída são exemplos.
Escrever o código
Um programador altera o código C ou C++ para o alvo e abre um merge request.
git · uart-dmasrc/uart.c +42 -7 src/dma.c +18 -3 merge request !214 opened
Compilar com arm-none-eabi-gcc
O build corre com a toolchain cruzada e escreve o compile_commands.json. O Visao lê esse ficheiro, por isso usa o mesmo compilador, as mesmas flags e os mesmos caminhos de include.
$ cmake -B build -DCMAKE_TOOLCHAIN_FILE=arm-none-eabi.cmake \ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON$ cmake --build build [100%] Built target firmware.elf build/compile_commands.json
Analisar com uma linha de base
O Visao analisa a alteração para um alvo bare-metal com o perfil MISRA. A linha de base do branch principal retira todas as ocorrências que já lá estavam.
$ visao --os baremetal --standard misra-c-2012 \ --baseline visao-baseline.sarif \ --report-format sarif --report-output visao.sarif \ build/compile_commands.jsonsrc/uart.c:88:14: error: Possible integer overflow 1 ocorrência nova, 213 ocorrências conhecidas retiradas pela linha de base
Só as ocorrências novas bloqueiam o merge
Com --fail-on high, o passo só falha quando uma ocorrência nova é High ou superior. As ocorrências conhecidas ficam no ficheiro da linha de base e não bloqueiam o merge.
$ visao ... --baseline visao-baseline.sarif --fail-on highsrc/uart.c:88:14: error: Possible integer overflow $ echo $? 1 merge request !214: pipeline falhou
Testar no dispositivo mais tarde
Depois, o mesmo build vai para a placa. O Midair executa a suite de testes em hardware real e guarda as evidências de cada execução.
Testes de firmwarefw-smoke · board rev Aboot/time_to_shell PASSED 6.1 s update/keep_config PASSED 12 as expected
Leituras recomendadas.Guias, investigação e páginas relacionadas.
Perguntas.Respostas curtas.
O que é a análise estática de código para sistemas embebidos?
A análise estática de código para sistemas embebidos verifica C e C++ para o alvo sem o executar numa placa. Encontra defeitos como overflows, índices além do fim de um array e memória usada depois de libertada, e pode verificar regras MISRA C:2012.
O Visao suporta MISRA C:2012?
Sim. Execute-o com --standard misra-c-2012. As ocorrências correspondentes indicam o número da regra MISRA, e a execução termina com um resumo de conformidade. No exemplo da documentação, esse build verifica 67 das 174 regras e indica as 107 que não verifica.
Um resumo MISRA sem ocorrências significa que o código está certificado?
Não. O resumo só cobre as regras que o build verifica. A conformidade assenta na norma e nos seus registos de desvios, e o resumo é uma evidência para esse argumento. O Visao e o Midair não certificam nada.
Com que toolchains e alvos funciona?
Com qualquer toolchain cruzada do tipo GCC que registe com --compiler-path, por exemplo arm-none-eabi-gcc. Os alvos incluem --os baremetal e --cpu arm, arm64 ou mips. O Visao lê o compile_commands.json, por isso usa as flags do build do alvo.
Temos muitas ocorrências antigas. Podemos bloquear merges na mesma?
Sim. Escreva uma vez uma linha de base a partir do branch principal. Depois, --baseline retira as ocorrências conhecidas e --fail-on só faz falhar o merge com ocorrências novas. A correspondência usa a regra, o ficheiro, a mensagem e a linha de código, por isso código movido não parece novo.
Podemos usar a nossa própria seleção de regras?
Sim. --standard-rules recebe um ficheiro com uma regra por linha, para uma edição revista ou para a seleção do seu projeto. O resumo conta as regras desse ficheiro que o build conhece e conta as restantes à parte.
Comece por um repositório de firmware.Veja que regras MISRA o seu build cobre.
Compare os planos na página de preços. Os preços são mensais, em euros.
Entrar na lista de espera