Desenvolvimento para Sistemas Embarcados (CEA 513) · * Camada de sw mais alta, engloba as...
Transcript of Desenvolvimento para Sistemas Embarcados (CEA 513) · * Camada de sw mais alta, engloba as...
Universidade Federal de Ouro Preto Departamento de Computação e Sistemas - DECSI
Vicente [email protected]/vicente
Desenvolvimento para Sistemas Embarcados (CEA 513)Desenvolvimento & Ferramentas
www.decom.ufop.br/vicente
Sumário
* Introdução
* Camada de Aplicação
* SO / Camada de Sistema
* Ferramentas de desenvolvimento
www.decom.ufop.br/vicente
Introdução
* Analogamente às ferramentas para desenvolvimento de sw para desktops/workstations, ambiente embarcado também necessita de ferramentas específicas.
* Compiladores, link-editores, IDEs, etc também podem ser encontrados para o ambiente embarcado.
* Entretanto, ferramentas utilizam o conceito de cross-development.
* Ajustes finos precisam ser feitos para se configurar um ambiente de desenvolvimento.
www.decom.ufop.br/vicente
Introdução* Conceitos básicos:
- Antes de se fazer uso efetivo da plataforma final embarcada é necessário analisar qual a aplicação da mesma.
- Customizações podem ser requeridas de forma a se melhor utilizar todo o poder do hardware.
✓ Componentes podem ser adicionados/removidos.
- Há de se diferenciar o que é software de plataforma com os aplicativos relacionados a camada do usuário.
- Ambos os níveis de abstração devem ser considerados pelo desenvolvedor embarcado.
www.decom.ufop.br/vicente
Camada de Aplicação
* Camada de sw mais alta, engloba as aplicações finais de usuário.
www.decom.ufop.br/vicente
Camada de Aplicação
* Camada de sw mais alta, engloba as aplicações finais de usuário.
- Processo de desenvolvimento engloba os mesmos conceitos de cross-development.
- Pode ser facilitado fazendo-se uso de uma IDE específica na máquina host.
- Código binário gerado deve estar de acordo com a plataforma-alvo (target).
- Otimizações aqui se restringem ao nível de aplicação.
www.decom.ufop.br/vicente
Camada de Aplicação
* Exemplo: Configuração da IDE eclipse para a plataforma beaglebone black:
Passo 1: Download da IDE eclipse para desenvolvimento C/C++ contida no site: https://www.eclipse.org/downloads/
Passo 2: Extração do arquivo compactado e execução do eclipse kepler.
www.decom.ufop.br/vicente
Camada de Aplicação
* Exemplo: Criação e configuração da IDE eclipse para a plataforma beaglebone black:
www.decom.ufop.br/vicente
Camada de Aplicação
Passo 3: Configurações internas do eclipse para cross-development:
✓ Necessário ter plugin “Remote Systems” instalado:
✓ Menu Window -> Show View -> Other e busque por “Remote Systems”.
* Exemplo: Configuração da IDE eclipse para a plataforma beaglebone black:
www.decom.ufop.br/vicente
Camada de Aplicação
Passo 4: Aba “Remote Systems” deve estar disp. na interface principal:
✓ Clique com botão direito no item “Local”;
✓ New -> Connection
✓ Selecione a opção Linux.
* Exemplo: Configuração da IDE eclipse para a plataforma beaglebone black:
www.decom.ufop.br/vicente
Camada de Aplicação
Passo 5: Configuração
✓ Preencha as opções “Host name” e “Connection name” conforme a figura.
✓ Clique em “Finish”.
✓ Caso perguntado, selecione opções relacionadas a “SSH” e acesso vi “Shell Linux”.
* Exemplo 1: Configuração da IDE eclipse para a plataforma beaglebone black:
www.decom.ufop.br/vicente
Camada de Aplicação
Passo 6: Iniciando
✓ Ao final, localize a conexão remota recém criada na aba “Remote Systems”.
✓ Inicie a conexão a partir da opção “Launch Terminal” do ícone “Session”, como mostrado na figura.
* Exemplo 1: Configuração da IDE eclipse para a plataforma beaglebone black:
www.decom.ufop.br/vicente
Camada de Aplicação
Passo 6: Iniciando
✓ Com tudo executando corretamente, o comportamento da figura abaixo poderá ser observado.
✓ Acesso remoto configurado com sucesso.
* Exemplo 1: Configuração da IDE eclipse para a plataforma beaglebone black:
www.decom.ufop.br/vicente
Camada de Aplicação
Passo 1: Na janela principal da IDE eclipse, clique com o botão direito -> New -> C++ Project.
* Exemplo 2: Criação de um projeto cross-development para a beaglebone black:
✓ Dê um nome ao projeto.
✓ Selecione a opção “Cross GCC” uma vez que iremos utilizar um compilador cruzado.
www.decom.ufop.br/vicente
Camada de Aplicação
Passo 2: Configurações do projeto.
* Exemplo 2: Criação de um projeto cross-development para a beaglebone black:
✓ Preencha as configurações do projeto com suas informações de acordo com as figuras ao lado e seguinte.
www.decom.ufop.br/vicente
Camada de Aplicação
* Exemplo 2: Criação de um projeto cross-development para a beaglebone black:
www.decom.ufop.br/vicente
Camada de Aplicação
Passo 3: Configuração do relativas ao compilador (cross-compiler):
* Exemplo 2: Criação de um projeto cross-development para a beaglebone black:
www.decom.ufop.br/vicente
Camada de Aplicação
Passo 3: Configuração do relativas ao compilador (cross-compiler):
* Exemplo 2: Criação de um projeto cross-development para a beaglebone black:
✓ Caso o compilador não esteja previamente instalado, a instalação do mesmo pode ser feita utilizando-se o comando:
‣ $ sudo apt-get install gcc-4.4-arm-linux-gnueabi
www.decom.ufop.br/vicente
Camada de Aplicação
Passo 3: Configuração do relativas ao compilador (cross-compiler):
* Exemplo 2: Criação de um projeto cross-development para a beaglebone black:
✓ Alterar compilador e link-editor padrão - para as opções listadas - acessando o menu: Project -> Properties -> C/C++ Build -> Settings.
www.decom.ufop.br/vicente
Camada de Aplicação
Passo 3: Configuração do relativas ao compilador (cross-compiler):
* Exemplo 2: Criação de um projeto cross-development para a beaglebone black:
✓ Alterar caminho para diretórios contendo header files corretos: Project -> Properties -> C/C++ General -> Paths and Symbols -> “aba” Includes.
✓ Selecionar “GNU C” -> Add -> File System
www.decom.ufop.br/vicente
Camada de Aplicação
Passo 3: Configuração do relativas ao compilador (cross-compiler):
* Exemplo 2: Criação de um projeto cross-development para a beaglebone black:
✓ Alterar caminho para diretórios contendo bibliotecas: Project -> Properties -> C/C++ General -> Paths and Symbols -> “aba” Library Paths.
✓ Clicar em Add -> File System
www.decom.ufop.br/vicente
Camada de Aplicação
Passo 3: Configuração do relativas ao compilador (cross-compiler):
* Exemplo 2: Criação de um projeto cross-development para a beaglebone black:
✓ Compilar o código de exemplo através da opção Project -> Build All.
www.decom.ufop.br/vicente
Camada de Aplicação
Passo 4: Execução do código de forma remota.
* Exemplo 2: Criação de um projeto cross-development para a beaglebone black:
✓Altere as configurações de execução do projeto, em:
✓Ao clicar no botão “Run” o código deverá ser executado no target.
www.decom.ufop.br/vicente
SO / Camada de Sistema
* Camada que armazena os softwares de sistema.
* Nela reside SO e todos os componentes internos.
* Também conhecida como kernel:- Microkernel: Sistema operacional provê recursos mínimos necessários ao ambiente.
www.decom.ufop.br/vicente
SO / Camada de Sistema
* Também conhecida como kernel:- Monolítico: Acesso a maioria das funcionalidades se dá através do kernel space.
* kernel:- Gerência de usuários, memória, arquivos, etc.
- Escalonamento e gerência de processos, etc.
- Acesso a dispositivos de hardware via device drivers.
- etc...
www.decom.ufop.br/vicente
SO / Camada de Sistema
* Kernel é parte integrante do sistema como um todo, assim como a camada de aplicação.
* Funcionalidades do kernel podem ser expandidas/reduzidas de acordo com a necessidade.
* Código aberto.
* Flexibilidade: Pode ser adaptável a diversas áreas/plataformas.
- De desktops/workstations a sistemas embarcados e de tempo-real.
www.decom.ufop.br/vicente
SO / Camada de Sistema
* Processo de configuração, compilação e deploy pode passar pelas seguintes etapas:
1) Configuração do ambiente e instalação de ferramentas;
2) Configuração e instalação do bootloader;
4) Configuração e compilação do kernel;
5) Preparação e empacotamento do sistema de arquivos.
6) Criação da imagem final.
3) Obtenção do código-fonte do kernel;
www.decom.ufop.br/vicente
SO / Camada de Sistema
* Processo de configuração, compilação e deploy pode passar pelas seguintes etapas:
1) Configuração do ambiente e instalação de ferramentas:
✓ Em sistemas embarcados normalmente se faz o esquema de compilação cruzada.
✓ Ferramentas Linux normalmente necessárias para o processo de build:
‣ $ sudo apt-get install gcc-arm-linux-gnueabi git ncurses-dev make build-essential u-boot-tools
‣ É comum que sejam necessários mais que as ferramentas acima, dependendo da plataforma para a qual se está considerando.
www.decom.ufop.br/vicente
SO / Camada de Sistema
* Processo de configuração, compilação e deploy pode passar pelas seguintes etapas:
2) Configuração e instalação do bootloader
✓ Dentre os vários existentes no mercado, consideraremos aqui o “das u-boot”.‣ $ wget ftp://ftp.denx.de/pub/u-boot/u-boot-latest.tar.bz2‣ $ tar xvf u-boot-latest.tar.bz2
✓ Dentro do diretório descompactado, execute: ‣ $ make am335x_evm_config‣ $ make CROSS_COMPILE=arm-linux-gnueabi- -j2
www.decom.ufop.br/vicente
SO / Camada de Sistema
* Processo de configuração, compilação e deploy pode passar pelas seguintes etapas:
3) Obtenção do código-fonte do kernel:
✓ Repositório do código-fonte do kernel pode variar dependendo da plataforma-alvo.
✓ Pode ser obtido oficialmente a partir de: https://www.kernel.org/.
✓ Conteúdo do código também pode variar dependendo da plataforma-alvo escolhida.
www.decom.ufop.br/vicente
SO / Camada de Sistema
* Processo de configuração, compilação e deploy pode passar pelas seguintes etapas:
4) Configuração e compilação do kernel
✓ Normalmente já existem configurações pré-definidas para diversas plataformas.
www.decom.ufop.br/vicente
SO / Camada de Sistema
* Processo de configuração, compilação e deploy pode passar pelas seguintes etapas:
4) Configuração e compilação do kernel
✓ Para se escolher uma dessas configurações pré-existentes:‣ $ make <platf>_defconfig
✓ Customizações podem ser feitas antes ou após escolha da plataforma:
‣ $ make menuconfig; ou‣ $ make xconfig
www.decom.ufop.br/vicente
SO / Camada de Sistema
* Processo de configuração, compilação e deploy pode passar pelas seguintes etapas:
4) Configuração e compilação do kernel
www.decom.ufop.br/vicente
SO / Camada de Sistema
* Processo de configuração, compilação e deploy pode passar pelas seguintes etapas:
4) Configuração e compilação do kernel
✓ Antes de se compilar o kernel é necessário informar:‣ Arquitetura para a qual o mesmo será compilador:
$ export ARCH=arm
‣ Localização do toochain/cross-compiler:$ export CROSS_COMPILE=arm-linux-gnueabi-
✓ Compilação:
‣ $ make
www.decom.ufop.br/vicente
SO / Camada de Sistema
* Processo de configuração, compilação e deploy pode passar pelas seguintes etapas:
5) Preparação e empacotamento do sistema de arquivos
✓ Uma vez compilado o bootloader e o kernel é necessário se preparar o sistema de arquivos raiz (root filesystem).
✓ O buildroot pode ser uma boa opção para se obter um sistema de arquivos limpo ou mesmo customizado com pacotes mais comuns.
www.decom.ufop.br/vicente
SO / Camada de Sistema
* Processo de configuração, compilação e deploy pode passar pelas seguintes etapas:
5) Preparação e empacotamento do sistema de arquivos
✓ Obtendo o buildroot:$ wget http://buildroot.net/downloads/buildroot-2014.08.tar.gz
✓ Configurando:
$ tar xvf buildroot-2014.08.tar.gz
$ cd buildroot-2014.08
$ make menuconfig
‣ Escolha da arquitetura e pacotes deve ser feita:
www.decom.ufop.br/vicente
SO / Camada de Sistema
* Processo de configuração, compilação e deploy pode passar pelas seguintes etapas:
5) Preparação e empacotamento do sistema de arquivos
www.decom.ufop.br/vicente
SO / Camada de Sistema
* Processo de configuração, compilação e deploy pode passar pelas seguintes etapas:
5) Preparação e empacotamento do sistema de arquivos
✓ Compilando:$ make
✓ Os pacotes selecionados durante a configuração serão automaticamente baixados para a máquina host.
✓ Uma vez baixados, tudo é compilado e um novo sistema de arquivos é gerado:
$ ls output/images/ rootfs.tar
www.decom.ufop.br/vicente
SO / Camada de Sistema
* Processo de configuração, compilação e deploy pode passar pelas seguintes etapas:
5) Preparação e empacotamento do sistema de arquivos✓ Download do script para preparação da imagem.
$ git clone https://github.com/sergioprado/mediacreate.git
$ ls mediacreate configs LICENSE mediacreate README.md
✓ Script auxiliará na preparação da imagem final e gravação no cartão SD.
www.decom.ufop.br/vicente
SO / Camada de Sistema
* Processo de configuração, compilação e deploy pode passar pelas seguintes etapas:
5) Preparação e empacotamento do sistema de arquivos✓ Empacotando todos os componentes:
#!/bin/bash #Environment vars export BBB_IMAGE_PATH=$BBB_PATH/image export UBOOT_VERSION="2013.07" export BUILDROOT_VERSION="2014.08" export FILES_PATH=./mediacreate #Creating dir files mkdir -p $FILES_PATH #Copying the files cp -av $BBB_PATH/u-boot-${UBOOT_VERSION}/MLO ./${FILES_PATH} cp -av $BBB_PATH/u-boot-${UBOOT_VERSION}/u-boot.img ./${FILES_PATH} cp -av $BBB_PATH/kernel/kernel/arch/arm/boot/uImage ./${FILES_PATH} cp -av $BBB_PATH/kernel/kernel/arch/arm/boot/dts/am335x-boneblack.dtb ./${FILES_PATH} cp -av $BBB_PATH/buildroot-${BUILDROOT_VERSION}/output/images/rootfs.tar ./${FILES_PATH} echo 'bootargs=console=ttyO0,11500n8 root=/dev/mmcblk0p2 rw rootfstype=ext4 rootwait' > ./${FILES_PATH}/uEnv.txt echo 'uenvcmd=mmc dev ${mmcdev};load mmc ${mmcdev} ${loadaddr} uImage;load mmc ${mmcdev} ${fdtaddr} am335x-boneblack.dtb;bootm ${loadaddr} - ${fdtaddr}' >> ./${FILES_PATH}/uEnv.txt
$ ./buildImage.sh
www.decom.ufop.br/vicente
SO / Camada de Sistema
* Processo de configuração, compilação e deploy pode passar pelas seguintes etapas:
5) Preparação e empacotamento do sistema de arquivos✓ Conteúdo da pasta mediacreate após execução do script:
$ ls am335x-boneblack.dtb LICENSE MLO rootfs.tar uEnv.txt configs mediacreate README.md u-boot.img uImage
www.decom.ufop.br/vicente
SO / Camada de Sistema
* Processo de configuração, compilação e deploy pode passar pelas seguintes etapas:
6) Criação da imagem final
✓ Bootloader, kernel e sistema de arquivos raíz foram criados corretamente.
✓ Criação da imagem final dos arquivos se faz necessária:$ sudo ./mediacreate -f -z -c configs/bbb_linux.cfg -d /dev/sdb
www.decom.ufop.br/vicente
SO / Camada de Sistema
* Processo de configuração, compilação e deploy pode passar pelas seguintes etapas:
7) Execução na plataforma beaglebone black
www.decom.ufop.br/vicente
SO / Camada de Sistema
* Considerações Finais
- Utilizamos o buildroot como exemplo de uma imagem funcional para a plataforma beaglebone black.
- Hardware e Software podem variar fazendo com que sejam necessários ajustes nos procedimentos.
- Os passos aqui demonstrados são uma visão geral das tarefas que devem ser executadas para a criação de uma imagem para uma plataforma embarcada.
- Roteiro apresentado pode diferir de acordo com a plataforma/distro considerada.
www.decom.ufop.br/vicente
SO / Camada de Sistema
* Referências- beagleboard.org. http://beagleboard.org/linux
- Build Angstrom for BeagleBone from source. http://derekmolloy.ie/building-angstrom-for-beaglebone-from-source/.
- sergioprado.org. Como desenvolver um sistema linux do zero para a beaglebone black. http://sergioprado.org/desenvolver-sistema-linux-zero-beaglebone-black/
- www.embarcados.com. Criando uma imagem customizada para a Beaglebone black com o buildroot. http://www.embarcados.com.br/beaglebone-black-buildroot/
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Outras ferramentas de desenvolvimento podem (e devem) ser utilizadas no ambiente embarcado.
* IDEs avançadas e com várias opções podem ser utilizadas, entretanto, algumas vezes algo mais simples pode solucionar o problema.
* Várias das opções de ambiente de desenvolvimento/editores disponíveis em Linux.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Editores texto mais comuns/populares no Linux:- Vim:
✓ Ambiente poderoso com várias opções de customização para auxílio no desenvolvimento.
✓ Acesso feito via linha de comando.
✓ Interação com o ambiente através de comandos em modo texto.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Editores texto mais comuns/populares no Linux:- eMacs:
✓ Assim como o “vim” não depende de ambiente gráfico para sua execução.
✓ Pode ser integrado a ferramentas de debug.
✓ Facilita e reduz o tempo do ciclo: edição - compilação - debug - edição.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Editores texto mais comuns/populares no Linux:- Outros
✓ gEdit.
✓ Nano.
✓ gVim.
✓ Eclipse.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Editores texto mais comuns/populares no Linux:- Referências:
✓ Tutorial: Emacs for Programmers. http://www.linuxjournal.com/article/2821.
✓ How to use the Emacs editor in Linux. https://www.digitalocean.com/community/tutorials/how-to-use-the-emacs-editor-in-linux.
✓ Vi and Vim: Tutorial and advanced features. http://www.yolinux.com/TUTORIALS/LinuxTutorialAdvanced_vi.html
✓ Vim tutorial. http://linuxconfig.org/vim-tutorial.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Além de editores de texto, é comum que lancemos mão de outros utilitários durante o desenvolvimento.
* Uma dessas ferramentas é especialmente relacionada ao processo de testes e correção de erros.
* Em ambientes Linux/Unix o mais famoso depurador é o GDB (GNU Debugger).
* Provê múltiplas funcionalidades além de suporte a várias linguagens.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Quando fazer uso de um depurador?- Antes de remover algum bug, esse precisa ser “encontrado” no código.
- Exemplo:✓ Em falhas de segmentação é útil enxergar em qual linha do código a falha ocorre.
✓ Uma vez encontrada a linha, é desejável saber os valores de variáveis no dado ponto, quem chamou o método, causa do erro, etc.
✓ Utilização de um depurador faz todas as tarefas acima ficar fácil.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* GDB- Tarefa principal de um depurador é auxiliar na localização de erros de forma mais detalhada.
- Consegue executar passo-a-passo um programa descrevendo os estados de cada um dos componentes.
- Supervisiona a execução do programa de forma a propiciar uma verificação de como o mesmo está funcionando.
- Mensagens do compilador estão restritas a essa etapa. Depurador permite que se analise o código em tempo de execução.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* GDB- GDB só funciona para códigos compilados com o GNU compiler: gcc.
- Caso o GDB ainda não exista em sua distribuição Linux, basta executar: $ sudo apt-get install gdb
- Compilação em modo de debug:✓ Para que o GDB possa controlar um programa é necessário que algumas informações especiais (tabela de símbolos) sejam adicionadas ao mesmo.
✓ Deve-se incluir no comando de compilação as flags “-g -ggdb”.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* GDB- Exemplo:
$ g++ -o <nome_exec> -g -ggdb Carro.cpp main.cpp
✓ Compilando com suporte ao GDB. ‣ Pelo terminal, na pasta do código-fonte, digite:
✓ Invocando o GDB:$ gdb <nome_exec>
✓ Importante: Ao tentar debugar um programa que não foi compilado com a flag “-g”:
Reading symbols from /media/sf_android_card/Codigos/GDB/t...(no debugging symbols found)...done.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* GDB- Exemplo:
✓ Comandos básicos: (inicialização/término)‣ run: Indica ao GDB que a execução do seu programa deve ser iniciada.
‣ kill: Faz com que o GDB force o término do seu programa.
‣ quit: Sai em definitivo do GDB.
‣ Se o comando “run” é executado logo após o carregamento do GDB, o programa é executado normalmente (como se não estivesse sendo monitorado).
‣ list <n>: Lista trechos do código fonte. Se parâmetro “n” é passado, lista linhas de código próximas à especificada.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* GDB- Exemplo:
✓ Comandos básicos: (controle de fluxo)‣ break <valor>: Insere um breakpoint no programa. É possível utilizar break <funcao> para fazer com que o programa seja parado no início de uma função. Ou ainda, break <n_linha> para fazer com que o programa seja parado na linha especificada.
‣ step <n>: Executa a linha atual e passa para a próxima. Argumento numérico indica o número de linhas a serem “saltadas”. (entra na chamada de uma função).
‣ next <n>: Como o step, entretanto ao encontrar uma função o fluxo de depuracão não entra dentro da mesma. Argumento indica o número de linhas a serem “saltadas”.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* GDB- Exemplo:
✓ Comandos básicos: (exibição)
‣ display <variável>: Imprime o valor atual da variável passada como argumento. Se uma expressão for passada como argumento, o resultado da mesma será impresso.
‣ undisplay <n>: Remove a entrada “n” da lista de exibição.
‣ print <expressão>: Imprime o valor de uma variável ou expressão sem adicioná-los à lista de exibição.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* GDB- Exemplo:
✓ Comandos intermediários: ‣ continue: Continua a execução de um programa até que um breakpoint seja encontrado.
‣ break <lugar> if <condição>: Insere um breakpoint condicionado. Se a cláusula de “condição” for verdadeira o breakpoint será considerado.
‣ watch <expressão>: Insere a expressão na “lista de vigília”. Se o valor da expressão mudar, a execução é interrompida.
‣ info breakpoints: Lista os breakpoints cadastrados até o momento.
‣ delete <n>: Remove o breakpoint cadastrado de índice “n” da lista.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* GDB- Exemplo:
✓ Comandos avançados: ‣ backtrace: Mostra a pilha de execução com informações até o ponto corrente do programa.
‣ set variable <var>=<value>: Altera o valor de uma variável durante o tempo de execução do programa.
‣ set disassembly-flavor <valor>: Altera o padrão assembly para <valor> quando “disassemblando” um programa.
‣ disassemble: Converte o programa atual para linguagem assembly no padrão informado pelo comando acima.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* GDB- Exemplo:
✓ Comandos avançados: ‣ layout asm: Altera o layout de exibição para linguagem assembly.
‣ layout src: Altera o layout de exibição para o código em C/C++.
‣ stepi / nexti: Versão para código assembly dos comandos step / next.
‣ info registers: Exibe conteúdo dos registradores em utilização.
‣ info all-registers: Exibe conteúdo de todos os registradores.
‣ help: Exibe listagem de todos os comandos disponíveis no GDB.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Um bom depurador por auxiliar e muito o processo de desenvolvimento e remoção de bugs.
* Entretanto, determinados tipos de erros não são passíveis de facilmente serem encontrados com o auxílio de um depurador.
* Desenvolvedores de software embarcado precisam estar atentos ao detalhes e peculiaridades de cada linguagem.
* Muitas vezes, o gerenciamento de memória é de responsabilidade do desenvolvedor.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Manipulação direta do heap/stack normalmente provê um “poder” adicional a linguagem/desenvolvedor.
* Todavia, cuidados devem ser tomados para evitar potenciais problemas.
* É comum nestes cenários se fazer uso da chamada “programação defensiva”.
* Vazamentos de memória (memory leaks) são extremamente preocupantes em embarcados.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Depuradores comuns são incapazes de localizar um vazamento de memória.
* Problema se torna ainda mais sério pois normalmente o erro não se manifesta de modo imediato.
* Somente após determinado tempo de execução nota-se que não existe mais memória disponível.
* Vazamentos de memória podem ainda levar a redução do desempenho do sistema.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Ferramentas específicas podem auxiliar a encontrar problemas.
* É comum que tais ferramentas sejam divididas em duas classes de acordo com o classe de análise executada:
- Estáticas: Analisam o código-fonte de forma estática. Isto é, cada arquivo texto é filtrado na busca por possíveis problemas. Método mais simplista e menos eficiente.
- Dinâmicas: Análise do sistema é feita durante sua execução. Método mais complexo, entretanto, mais eficiente.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Para ambientes Linux embarcados é comum a utilização do software Valgrind.
* Valgrind é um “framework de instrumentação para a construção de ferramentas de análises dinâmicas”.
* Detecta automaticamente erros de memória, threads e provê profile do programa em detalhes.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* O que mais valgrind pode detectar?- Uso de regiões de memória não inicializadas.
- Leitura/escrita em mem. após uma região ter sido liberada.
- Leitura/escrita em mem. além dos limites da região alocada.
- Vazamento de memória (memory leaks).
- Uso incorreto de malloc/new/new[] vs. free/delete/delete[].
- Cópia incorreta de dados ultrapassando limites em memcpy().
- Alguns usos incorretos das pthreads (POSIX threads).
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Valgrind:- Instalação:
$ sudo apt-get install valgrind
Exemplo:#include <stdio.h> #include <stdlib.h>
void f(void) { int *x = malloc(10 * sizeof(int)); x[10] = 0; }
int main() { f(); return 0; }
- Compilação com suporte a tabela de símbolos:
$ gcc -o <nome_exec> main.c -g
- Execução:$ valgring ./<nome_exec>
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Valgrind:==2380== Memcheck, a memory error detector ==2380== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al. ==2380== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info ==2380== Command: ./t ==2380== ==2380== Invalid write of size 4 ==2380== at 0x80483FF: f (in /media/sf_android_card/Codigos/Valgrind/t) ==2380== by 0x8048411: main (in /media/sf_android_card/Codigos/Valgrind/t) ==2380== Address 0x41f1050 is 0 bytes after a block of size 40 alloc'd ==2380== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==2380== by 0x80483F5: f (in /media/sf_android_card/Codigos/Valgrind/t) ==2380== by 0x8048411: main (in /media/sf_android_card/Codigos/Valgrind/t) ==2380== ==2380== ==2380== HEAP SUMMARY: ==2380== in use at exit: 40 bytes in 1 blocks ==2380== total heap usage: 1 allocs, 0 frees, 40 bytes allocated ==2380== ==2380== LEAK SUMMARY: ==2380== definitely lost: 40 bytes in 1 blocks ==2380== indirectly lost: 0 bytes in 0 blocks ==2380== possibly lost: 0 bytes in 0 blocks ==2380== still reachable: 0 bytes in 0 blocks ==2380== suppressed: 0 bytes in 0 blocks ==2380== Rerun with --leak-check=full to see details of leaked memory ==2380== ==2380== For counts of detected and suppressed errors, rerun with: -v ==2380== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Valgrind:- Execução (c/ mais informações):
$ valgring --leak-check=full ./<nome_exec>
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Valgrind:==2408== Memcheck, a memory error detector ==2408== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al. ==2408== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info ==2408== Command: ./t ==2408== ==2408== Invalid write of size 4 ==2408== at 0x80483FF: f (main.c:7) ==2408== by 0x8048411: main (main.c:12) ==2408== Address 0x41f1050 is 0 bytes after a block of size 40 alloc'd ==2408== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==2408== by 0x80483F5: f (main.c:6) ==2408== by 0x8048411: main (main.c:12) ==2408== ==2408== ==2408== HEAP SUMMARY: ==2408== in use at exit: 40 bytes in 1 blocks ==2408== total heap usage: 1 allocs, 0 frees, 40 bytes allocated ==2408== ==2408== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==2408== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==2408== by 0x80483F5: f (main.c:6) ==2408== by 0x8048411: main (main.c:12) ==2408== ==2408== LEAK SUMMARY: ==2408== definitely lost: 40 bytes in 1 blocks ==2408== indirectly lost: 0 bytes in 0 blocks ==2408== possibly lost: 0 bytes in 0 blocks ==2408== still reachable: 0 bytes in 0 blocks ==2408== suppressed: 0 bytes in 0 blocks ==2408== ==2408== For counts of detected and suppressed errors, rerun with: -v ==2408== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Valgrind:- Exemplo corrigido:
#include <stdio.h> #include <stdlib.h>
void f(void) { int *x = malloc(10 * sizeof(int)); x[9] = 0; free(x); }
int main() { f(); return 0; }
==2421== Memcheck, a memory error detector ==2421== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al. ==2421== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info ==2421== Command: ./t ==2421== ==2421== ==2421== HEAP SUMMARY: ==2421== in use at exit: 0 bytes in 0 blocks ==2421== total heap usage: 1 allocs, 1 frees, 40 bytes allocated ==2421== ==2421== All heap blocks were freed -- no leaks are possible ==2421== ==2421== For counts of detected and suppressed errors, rerun with: -v ==2421== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Depuração utilizando símbolos é suficiente para encontrar e corrigir erros em programas.
* Tal tipo de depuração não oferece muita ajuda quando tenta-se encontrar bugs de interações entre aplicativos/processos.
* Utilizando tracing é possível observar em detalhes as interações entre uma aplicação e o kernel do Linux (por exemplo).
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Tracing- Muito útil para monitorar system calls e os parâmetros enviados através das mesmas.
- Algumas vezes, observar o comportamento de um processo isoladamente não é suficiente.
- tracing é então muito útil durante a depuração de sistemas distribuídos.
- Nos exemplos aqui levantados será utilizado o comando strace.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Tracing- Listando as chamadas de sistema:
$ strace <nome_exec>
execve("./t", ["./t"], [/* 36 vars */]) = 0 brk(0) = 0x87e6000 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7739000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=66719, ...}) = 0 mmap2(NULL, 66719, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7728000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/lib/i386-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0000\226\1\0004\0\0\0"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=1734120, ...}) = 0 mmap2(NULL, 1743580, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb757e000 mmap2(0xb7722000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a4) = 0xb7722000 mmap2(0xb7725000, 10972, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7725000 close(3) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb757d000 set_thread_area({entry_number:-1 -> 6, base_addr:0xb757d900, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 mprotect(0xb7722000, 8192, PROT_READ) = 0 mprotect(0x8049000, 4096, PROT_READ) = 0 ...
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Tracing- Listando as chamadas de sistema específicas:
$ strace -e <nome_chamadas_sistema> <nome_exec>
- Salvando o tracing para um arquivo:$ strace -o <output_file_name> <nome_exec>
- tracing em um processo já em execução$ sudo strace -p <pid_processo>
- Imprimir saída com timestamp absoluto$ strace -t <nome_exec>
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Tracing- Imprimir saída com timestamp relativo
$ strace -r <nome_exec>
- Gerar estatísticas com tracing$ strace -c <nome_exec>
- tracing com tempo gasto em cada chamada de sistema$ strace -c <nome_exec>
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Além de uma correta execução, um sistema embarcado também pode ter que respeitar limites de tempo.
* Restrições temporais normalmente caracterizam os sistemas de tempo-real.
* Entretanto, é possível melhorar o desempenho de um sistema sem contudo enquadrá-lo no modelo formal de sistemas de tempo-real.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Antes de efetivamente “colocar a mão na massa” é necessário se avaliar o desempenho do sistema.
* O “profiling” é um mecanismo que ajuda na compreensão da execução interna de um sistema/processo.
* Entre outras coisas, o profiling permite a obtenção do tempo gasto em cada função/procedimento.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento* Em Linux, normalmente o profiling se dá através de uma combinação de diretivas de compilação e o utilitário gprof.
* Os dados gerados durante a execução do sistema são posteriormente analisados pelo software gprof.
* Profiling permite aprender a como programar de forma eficiente.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* gprof:- No ubuntu, instalação pode ser feita através do seguinte comando:
$ sudo apt-get install binutils
- Utilização do gprof requer três passos básicos:✓ Habilitação do profiling através de uma flag de compilação específica.
✓ Execução do programa-alvo para a geração dos dados de profiling.
✓ Execução da ferramenta gprof para interpretação dos dados gerados.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* gprof:#include <stdio.h>
void new_func1(void);
void func1(void) { printf("Dentro func1() \n"); int i = 0; for(;i<0xFFFFFFFF;i++); new_func1();
return; }
void func2(void) { printf("Dentro func2() \n"); int i = 0;
for(;i<0xFFFFFFAA;i++); return; }
int main(void) { printf("Dentro main() \n"); int i = 0;
for(i;i<0xFFFFFFFF;i++); func1(); func2();
return 0; }
#include <stdio.h>
void new_func1(void) { printf("Dentro new_func1() \n"); int i = 0;
for(;i<0xFFFFFFEE;i++); return; }
- Códigos base:
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* gprof:- Compilação:
$ gcc -pg main.c test_code.c -o <nome_exec>
- Flag -pg deve ser utilizada para indicar que o código gerado será analisado por uma ferramenta de profiling.
- Metadados são gerados após a execução do programa.
- Após a execução, um arquivo chamado gmon.out será criado.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* gprof:- Execução da ferramenta de análise:
$ gprof <nome_exec> gmon.out
Flat profile:
Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls s/call s/call name 25.65 10.10 10.10 main 25.37 20.09 9.99 1 9.99 19.66 func1 24.56 29.76 9.67 1 9.67 9.67 new_func1 24.41 39.37 9.61 1 9.61 9.61 func2
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* gprof:- Resultado:
✓ Descrito principalmente através da parte chamada Flat Profile.
‣ Contém tempo de execução de cada função.
‣ Porcentagem do tempo gasto por cada função.
‣ Número de chamadas executadas a cada função.
‣ etc.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* gprof:- Impressão somente de informações relevantes:
$ gprof -b <nome_exec> gmon.out
- Impressão somente do flat profile:$ gprof -b -p <nome_exec> gmon.out
- Impressão de infos relacionadas a uma função específica:$ gprof -b -p<nome_func> <nome_exec> gmon.out
- Impressão somente de informações relacionadas às chamadas:$ gprof -q <nome_exec> gmon.out
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* valgrind:- Valgrind também pode ser utilizado para profiling.
- Utilizado em conjunto com as ferramentas callgrind e kcachegrind.
- Execução do código com valgrind deve conter a seguinte flag:$ valgrind --tool=callgrind <nome_exec>
- Um arquivo com o prefixo callgrind.out.<n> é gerado.
- Invocação da ferramenta kcachegrind para interpretação do arquivo gerado.
$ kcachegrind callgrind.out.<n>
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Outras opções:- Existem ainda outras possíveis ferramentas a serem utilizadas para análise de desempenho:
✓ bootchart.
✓ OProfile.
✓ Valgrind (kcachegrind).
✓ Google perftools.
✓ xprofiler.
✓ etc.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Exercício:- Utilizando o arquivo provido como entrada, faça:
✓ Um programa para ordenar os N números.
✓ Execução do profiling do mesmo e análise de seu desempenho.
✓ Implementação de um programa multithread para a ordenação.
✓ Compare os dois desempenhos.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Debug de memória: - Uso da memória em Linux embarcado deve ser feita de forma diferente que no Linux convencional.
- Aplicações não podem fazer uso de memória da memória principal como em desktops/workstations.
- Se uma aplicação consome muita memória, em um embarcado não existe a figura do usuário para “resolver” o problema.
- Durante o desenvolvimento é possível utilizarmos ferramentas para controlar o uso da memória e alertar sobre algum erro.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Debug de memória: - Iremos dar foco na principal ferramenta para este tipo de trabalho: Electric Fence.
- Biblioteca deve ser linkada junto ao código final em desenvolvimento. Nunca deve ser utilizada em código de produção.
- Substitui as funções de alocação de memória da linguagem C por funções otimizadas para debugging de mem. (não desempenho).
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Debug de memória: - Electric Fence:✓ Substitui as funções de manipulação da memória (malloc() / free() …) por outras com teste interno de acesso fora dos limites.
✓ Muito efetiva em detectar acessos à memória fora dos limites alocados.
✓ Resumidamente, um acesso incorreto à memória fará com que a aplicação quebre imediatamente.
✓ Ao se executar a aplicação com o gdb é possível ver exatamente o local do acesso incorreto.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Debug de memória: - Electric Fence:
✓ Código-fonte base:#include <stdio.h>
int main() { int *x = (int *) malloc(2*sizeof(int)); x[3] = 5; return 0; }
✓ Instalação:$ sudo apt-get install electric-fence
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Debug de memória: - Electric Fence:
✓ Compilação:$ gcc -o <nome_exec> main.c -g -lefence
✓ Execução:$./t
Electric Fence 2.1 Copyright (C) 1987-1998 Bruce Perens. Segmentation fault (core dumped)
✓ Execute o código com o gdb e poderá acompanhar onde o erro acontece: Program received signal SIGSEGV, Segmentation fault.
0x080484d4 in main () at main.c:6 6 x[3] = 5; (gdb)
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Debug de memória: - Electric Fence:
✓Opções: Devem ser exportadas como variáveis de ambiente.
‣ EF_ALIGMENT=x : Faz com que memória alocada seja alinha por “x” bytes. Default é sizeof(int).
‣ EF_PROTECT_BELOW=0/1 : Coloca uma página de memória em branco “antes" da região a ser alocada. Possibilita detectar buffer under-runs.
‣ EF_PROTECT_FREE=0/1 : Possibilita ou não que memória alocada previamente (e liberada) seja realocada a um novo pedido - pode fazer com que o sistema aumente o gasto de memória.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Debug de memória: - Electric Fence:
✓Opções: Devem ser exportadas como variáveis de ambiente.
‣ EF_ALLOW_MALLOC_0=0/1 : Monitoramento de malloc’s com tamanho zero.
‣ EF_FILL=0~255 : Valor no qual a memória alocada será inicializado.
www.decom.ufop.br/vicente
Ferramentas de Desenvolvimento
* Debug de memória: - Outra Opção:
✓ MEMWATCH
‣ Mesma ideia do electric fence.
‣ Substituição das chamadas malloc()/free() por específicas que mantêm o gerenciamento dos espaços alocados.
‣ Não é tão eficiente quanto o electric fence.
‣ Mais referências ao projeto podem ser encontradas em: http://www.linkdata.se/sourcecode.html.