english

Durante os desenvolvimentos para a placa FRDM-KL25Z usando minha própria compilação de um crosstoolchain gcc, eu notei um comportamento estranho quando meu código usa operações de divisão (/) e módulo (%) em números inteiros.

Meu crostoolchain arm-none-eabi é baseado em binutils 2.24, gcc 4.8.2 e newlib 2.1.0. Ao executar operações de / ou %, a execução trava numa das chamadas AEABI runtime ____aeabi_[u]idiv[mod]_from_thumb(). Segue um backtrace gdb de uma tentativa de %:

(gdb) bt
#0  Cpu_Interrupt () at Generated_Code/Cpu.c:85
#1  <signal handler called>
#2  0x0000236c in ____aeabi_uidivmod_from_thumb ()
#3  0x000021aa in LEDTimer_OnInterrupt (UserDataPtr=0x0 <__vect_table>) at Sources/Events.c:80
#4  0x00001f98 in TU1_OnCounterRestart (UserDataPtr=0x0 <__vect_table>) at Generated_Code/LEDTimer.c:149
#5  0x00002126 in TU1_Interrupt () at Generated_Code/TU1.c:185
#6  <signal handler called>
#7  main () at Sources/ProcessorExpert.c:66

Esse comportamento persiste mesmo quando o código é compilado com opções próprias para Cortex-M0 tais como -mcpu=cortex-m0 -mthumb -mfloat-abi=soft.

Foi reportado que o gcc está gerando opcodes errados para CPU Cortex-M0 na fase de link para essas chamadas aeabi. Uma solução alternativa é linkar o código com uma biblioteca externa compatível com Cortex-M0 como a libaeabi-cortexm0 escrita por Jörg Mische.

Ao usar a libaeabi-cortexm0 num projeto do Processor Expert para a FRDM-KL25Z em Linux, compile a biblioteca sem crt.S de forma a evitar símbolos duplicados na fase de link.

Eu atualizei minha aplicação de led piscante para utilizar uma operação de % em LEDTimer_OnInterrupt(), e também linkar com a libaeabi-cortexm0: frdm-kl25z-blink3-1.1.tar.gz. Para detalhes sobre como construir essa aplicação no sistema operacional Gentoo Linux, veja Desenvolvendo em Linux para FRDM-KL25Z.

english

Tópicos:

  1. Introdução
  2. Ferramentas
  3. Compilação
  4. Gravação
  5. Debug

Esta série de postagens mostra minhas tentativas de compilar, gravar e debugar um aplicativo de demonstração para a placa Freescale FRDM-KL25Z em um sistema operacional Gentoo GNU/Linux. O aplicativo em questão (um programa simples de piscar o LED multicolorido) foi desenvolvido originalmente no CodeWarrior 10.4 com Processor Expert para Windows. Os arquivos fonte relevantes do aplicativo foram então copiados sem nenhuma modificação e compilados em Linux usando GNU Autotools para configurar o processo de construção do software.

O que é tratado aqui:

  • Montagem de ferramentas de construção cruzada de software para arquitetura ARM em Gentoo Linux;
  • Construção cruzada no Linux de um aplicativo desenvolvido com a IDE CodeWarrior;
  • Gravação de um aplicativo para a placa FRDM-KL25Z em Linux;
  • Debug de um aplicativo da placa FRDM-KL25Z em Linux.

Algumas coisas que NÃO são tratadas aqui:

  • Executar a IDE CodeWarrior em Linux;
  • Atualizar fontes de aplicativos usando Processor Expert em Linux;
  • Integração com Eclipse;
  • Instruções que sabe-se previamente serem efetivas em outras distribuições GNU/Linux além da Gentoo (embora espera-se que grande parte delas seja compatível).

Nota: para um tutorial excelente sobre montagem de ambiente livre com GNU gcc + Eclipse + debugger em Windows para desenvolver para a placa FRDM-KL25Z, dê uma olhada em DIY Free Toolchain for Kinetis

Sempre que possível, as instruções fazem uso de ferramentas de software livre.

Vamos começar em Ferramentas onde são instaladas ferramentas de construção de software para CPUs ARM no seu sistema Gentoo Linux.

english

Tópicos:

  1. Introdução
  2. Ferramentas
  3. Compilação
  4. Gravação
  5. Debug

Anteriormente em Gravação, um aplicativo de piscagem de led foi gravado na placa FRDM-KL25Z para execução. Aqui nós usaremos o GNU debugger para debugar esse aplicativo durante sua execução.

Construa um debugger cruzado para ARM

localhost ~ # crossdev --ex-gdb -t arm-none-eabi
...

Isso deve deixar no seu sistema Gentoo um gdb cruzado para a arquitetura pretendida:

localhost ~ # arm-none-eabi-gdb -ex quit
Python Exception  name 'os' is not defined: 

warning: 
Could not load the Python gdb module from `/usr/share/gdb/python'.
Limited Python support is available from the _gdb module.
Suggest passing --data-directory=/path/to/gdb/data-directory.

GNU gdb (Gentoo 7.7 vanilla) 7.7
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-pc-linux-gnu --target=arm-none-eabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
.
For help, type "help".
Type "apropos word" to search for commands related to "word".

Use o OpenOCD como um remoto para o gdb

O OpenOCD tem a habilidade de servir como o lado remoto de uma sessão gdb, permitindo que comandos de debug sejam enviados ao on-chip debugger da placa. O Makefile dos fontes do frdm-kl25z-blink3 possui um alvo para ativar uma sessão gdb com o openocd como remoto para debugar o aplicativo frdm_kl25z_blink3:

user@localhost /tmp/frdm-kl25z-blink3-1.0 $ make debug
arm-none-eabi-gdb -ex "target remote | openocd -c \"gdb_port pipe; log_output debug.log; interface cmsis-dap\"
 -f ./support/openocd/kl25_init.cfg" -ex "monitor reset init" -ex "break main" -ex "continue" frdm_kl25z_blink3
Python Exception  name 'os' is not defined: 

warning: 
Could not load the Python gdb module from `/usr/share/gdb/python'.
Limited Python support is available from the _gdb module.
Suggest passing --data-directory=/path/to/gdb/data-directory.

GNU gdb (Gentoo 7.7 vanilla) 7.7
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-pc-linux-gnu --target=arm-none-eabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from frdm_kl25z_blink3...done.
Remote debugging using | openocd -c "gdb_port pipe; log_output debug.log; interface cmsis-dap" -f ./support/openocd/kl25_init.cfg
Open On-Chip Debugger 0.8.0-dev-00350-g6c74255 (2014-02-14-16:00)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.sourceforge.net/doc/doxygen/bugs.html
warning: Can not parse XML target description; XML support was disabled at compile time
0x00000000 in __vect_table ()
target state: halted
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x00002038 msp: 0x20003000
Breakpoint 1 at 0x2114: file Sources/ProcessorExpert.c, line 53.
Continuing.

Breakpoint 1, main () at Sources/ProcessorExpert.c:53
53        PE_low_level_init();
(gdb)

Conforme programado, o alvo de debug deverá reiniciar a execução do aplicativo e parar na função main() devido a um breakpoint. Então neste estado a execução está parada (o led RGB para de piscar) e o gdb está aguardando por comandos de debug.

Debug 🙂

Bem, é o gdb; sinta-se livre para fuçar e ter um debug esclarecedor. O que vem a seguir é um exemplo de investigação da função de tratamento de interrupção do timer, que é onde ocorre a virada de cores do led:

(gdb) clear
Deleted breakpoint 1 
(gdb) break LEDTimer_OnInterrupt
Breakpoint 2 at 0x2078: file Sources/Events.c, line 80.
(gdb) continue
Continuing.

Breakpoint 2, LEDTimer_OnInterrupt (UserDataPtr=0x0 ) at Sources/Events.c:80
80              switch (led_state++) {
(gdb) list
75      /* ===================================================================*/
76      void LEDTimer_OnInterrupt(LDD_TUserData *UserDataPtr)
77      {
78        /* Write your code here ... */
79              static int led_state = 0;
80              switch (led_state++) {
81              case 0:
82                      RedLED_SetVal(RedLED_DeviceData);
83                      GreenLED_SetVal(GreenLED_DeviceData);
84                      BlueLED_SetVal(BlueLED_DeviceData);
(gdb) display led_state
1: led_state = 0
(gdb) continue
Continuing.

Breakpoint 2, LEDTimer_OnInterrupt (UserDataPtr=0x0 ) at Sources/Events.c:80
80              switch (led_state++) {
1: led_state = 1
(gdb) next
87                      RedLED_ClrVal(RedLED_DeviceData);
1: led_state = 2
(gdb) next
88                      break;
1: led_state = 2
(gdb) continue
Continuing.

Breakpoint 2, LEDTimer_OnInterrupt (UserDataPtr=0x0 ) at Sources/Events.c:80
80              switch (led_state++) {
1: led_state = 2
(gdb) continue
Continuing.

Breakpoint 2, LEDTimer_OnInterrupt (UserDataPtr=0x0 ) at Sources/Events.c:80
80              switch (led_state++) {
1: led_state = 3
(gdb) clear
Deleted breakpoint 2 
(gdb) continue
Continuing.
^C
Program received signal SIGINT, Interrupt.
main () at Sources/ProcessorExpert.c:66
66        for(;;){}
1: led_state = 6
(gdb) quit
A debugging session is active.

        Inferior 1 [Remote target] will be detached.

Quit anyway? (y or n) y
Detaching from program: /tmp/frdm-kl25z-blink3-1.0/frdm_kl25z_blink3, Remote target
Ending remote debugging.

user@localhost /tmp/frdm-kl25z-blink3-1.0 $ 

english

Tópicos:

  1. Introdução
  2. Ferramentas
  3. Compilação
  4. Gravação
  5. Debug

Anteriormente em Compilação nós geramos um ELF executável como resultado da construção do aplicativo frdm-kl25z-blink3:

user@localhost /tmp/frdm-kl25z-blink3-1.0 $ file frdm_kl25z_blink3 
frdm_kl25z_blink3: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped

Agora iremos gravar esse arquivo na memória flash da placa para execução.

Atualize a placa FRDM-KL25Z com um firmware CMSIS-DAP

Primeiramente, extraia o arquivo CMSIS-DAP.S19 da Nota de Aplicação Keil 232. Esse é um firmware para a FRDM-KL25Z que suporta a interface CMSIS-DAP com o on-chip debugger da placa.

Os passos a seguir devem ser executados em Windows: A seguir, entre em modo Bootloader mantendo o botão Reset pressionado enquanto liga um um cabo USB do seu computador no conector OpenSDA da placa. (Quando o led D4 piscar você pode soltar o botão pois isso indica o modo bootloader.) O Bootloader MSD aparece no Windows como um dispositivo removível chamado BOOTLOADER. Copie o arquivo CMSIS_DAP.s19 para o dispositivo BOOTLOADER, espere alguns segundos e desplugue a placa.

De volta ao Gentoo Linux, replugue a placa e verifique pela existência do dispositivo usb com ID de vendedor 0xc251 e ID de produto 0xf002:

localhost ~ # lsusb
Bus 001 Device 023: ID c251:f002 Keil Software, Inc. 
...

Crie o arquivo /etc/udev/rules.d/99-frdm-kl25z-cmsis-dap.rules contendo:

SUBSYSTEM=="usb", ATTR{idVendor}=="c251", ATTR{idProduct}=="f002", MODE="0660", GROUP="plugdev"
SUBSYSTEM=="hidraw", ACTION=="add", MODE="0660", GROUP="plugdev"

Desplugue e replugue a placa novamente, e verifique que o arquivo de dispositivo hidraw recém criado pertence ao grupo plugdev e possui acesso de escrita de grupo:

localhost ~ # ls -l /dev/hidraw*
crw-rw---- 1 root plugdev 252, 0 Mar 10 21:58 /dev/hidraw0
...

Isso permite que o processo de gravação possa ser feito por usuários normais pertencendo ao grupo plugdev.

Instale o OpenOCD com suporte a CMSIS-DAP

Para comunicação com o on-chip debugger da FRDM-KL25Z de forma a fazer a gravação, usamos o OpenOCD. Infelizmente até o momento da escrita desse texto a versão mais atual do OpenOCD disponível na árvore Portage (0.7.0-r1) não suporta CMSIS-DAP; entretanto eu obtive sucesso na gravação usando o OpenOCD de openocd.zylin.com. Como sugestão, pegue um snapshot da árvore openocd mais recente, descompacte, compile e instale:

localhost ~/src/openocd # ./configure --enable-cmsis-dap
...
OpenOCD configuration summary
--------------------------------------------------
CMSIS-DAP Compliant Debugger            yes

localhost ~/src/openocd # make
...

localhost ~/src/openocd # make install
...

Num sistema Gento recém instalado a fase de configuração irá provavelmente falhar devido a bibliotecas e softwares ausentes; apenas instale (emerge) as coisas solicitadas e retome o processo como mostrado acima. Ao fim do processo você terá uma instalação operacional do openocd:

localhost ~ # openocd --version
Open On-Chip Debugger 0.8.0-dev-00350-g6c74255 (2014-02-14-16:00)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.sourceforge.net/doc/doxygen/bugs.html

Grave frdm_kl25z_blink3 usando OpenOCD

O Makefile nos fontes do frdm-kl25z-blink3 tem um alvo que cuida da gravação:

user@localhost /tmp/frdm-kl25z-blink3-1.0 $ make flash
openocd \
        -c 'interface cmsis-dap' \
        -f ./support/openocd/kl25_init.cfg \
        -f ./support/openocd/kl25_flash.cfg
Open On-Chip Debugger 0.8.0-dev-00350-g6c74255 (2014-02-14-16:00)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.sourceforge.net/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'cmsis-dap'
Info : CMSIS-DAP: SWD  Supported
Info : CMSIS-DAP: Interface Initialised (SWD)
cortex_m reset_config sysresetreq
adapter speed: 50 kHz
Info : add flash_bank kinetis kl25.flash
#0 : kl25.flash (kinetis) at 0x00000000, size 0x00000000, buswidth 0, chipwidth 0
Info : CMSIS-DAP: FW Version = 1.0
Info : SWCLK/TCK = 0 SWDIO/TMS = 1 TDI = 0 TDO = 0 nTRST = 0 nRESET = 1
Info : DAP_SWJ Sequence (reset: 50+ '1' followed by 0)
Info : CMSIS-DAP: Interface ready
Info : clock speed 50 kHz
Info : IDCODE 0x0bc11477
Info : kl25.cpu: hardware has 2 breakpoints, 2 watchpoints
target state: halted
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x00002038 msp: 0x20003000
** Programming Started **
auto erase enabled
Info : Probing flash info for bank 0
Info : Padding image section 0 with 832 bytes
Warn : flash configuration field erased, please reset the device
Warn : Kinetis L Series supports Program Longword execution only.
Info : Kinetis: FLASH Write ...
wrote 11264 bytes from file frdm_kl25z_blink3 in 14.069720s (0.782 KiB/s)
** Programming Finished **
** Verify Started **
verified 10060 bytes in 1.938245s (5.069 KiB/s)
** Verified OK **
** Resetting Target **
shutdown command invoked

Se a gravação é bem sucedida, o aplicativo deverá iniciar automaticamente e o led RGB deverá piscar repetidamente numa sucessão de cores vermelho, verde e azul.

A seguir em Debug iremos usar o OpenOCD como um servidor remoto para o GNU debugger, permitindo o debug do aplicativo gravado.


Referências

english

Tópicos:

  1. Introdução
  2. Ferramentas
  3. Compilação
  4. Gravação
  5. Debug

Apesar de um conjunto considerável de parâmetros operacionais serem necessários de serem passados para o compilador, conceitualmente o processo de gerar executáveis ARM apropriados para a placa FRDM-KL25Z é virtualmente o mesmo de todas as outras gerações de software baseadas em compilação e linkagem:

  • Pré-processamento, no qual os símbolos do pré-processador são resolvidos para cada arquivo de código fonte (.c) do projeto;
  • Compilação, na qual os resultados do pré-processamento são analisados e um arquivo de código objeto (.o) é gerado para cada arquivo de código fonte. Arquivos objeto contém descrições em código de máquina das funções escritas pelo programador;
  • Linkagem, na qual os arquivos de código objeto do projeto são combinados entre si e com bibliotecas do sistema para a resolução das dependências de chamada de funções. Tipicamente o principal resultado do estágio de linkagem é um arquivo executável para a arquitetura alvo de CPU.

Como exemplo de construção eu escrevi um programa simples de piscar o led RGB da FRDM-KL25Z; descompacte-o em algum lugar do seu sistema de arquivos: frdm-kl25z-blink3-1.0.tar.gz

O aplicativo frdm-kl25z-blink3 foi desenvolvido originalmente com o CodeWarrior 10.4 para Windows, a IDE oficial da Freescale para desenvolvimento na plataforma kinetis e outros produtos no momento da escrita desse artigo. O CodeWarrior é baseado em Eclipse, e existe uma versão grátis para Windows que possibilita a configuração rápida dos recursos da placa usando a tecnologia Processor Expert da Freescale. Para a compilação em Linux deste projeto CodeWarrior, eu coletei as seguintes pastas da área de trabalho do projeto:

  • Generated_Code (alocação de recursos da placa)
  • Project_Settings/Linker_Files (definições de linkagem)
  • Project_Settings/Startup_Code (registro de chamadas de funções externas para inicialização e término do programa)
  • Sources (callbacks de eventos e entrada principal do programa; é aqui onde praticamente todo o desenvolvimento posterior ocorre após a configuração da alocação de recursos da placa)

Adicionalmente, uma vez que esses arquivos foram gerados pelo Processor Expert, para pré-processamento e linkagem apropriados eles dependem de cabeçalhos de sistema e de bibiotecas ARM adicionais. Você precisa das seguintes pastas de uma instalação do CodeWarrior (para Windows):

  • MCU/ARM_GCC_Support/ewl (Freescale Embedded Warrior Libraries)
  • MCU/ProcessorExpert/lib/Kinetis/pdd/inc (Kinetis PDD headers)

No caso de uma instalação Windows do CodeWarrior não estar disponível, opcionalmente você pode fazer download do instalador do CodeWarrior for Microcontrollers 10.4 (Eclipse, offline) no site da Freescale, abri-lo com o file-roller (ou outro gerenciador de arquivos de sua preferência) e então:

  • abrir com.freescale.mcu10_4.kinetis.updatesite.zip, abrir binary/com.freescale.kinetis.gcc_root_1.0.2, e copiar MCU/ARM_GCC_Support/ewl
  • abrir Setup.exe, e copiar $_OUTDIR/ProcessorExpert/lib/Kinetis/pdd/inc

O projeto frdm-kl25z-blink3 vem com um script de configuração para verificar a existência destes arquivos, bem como outras pendências que podem afetar a construção. Edite o arquivo build.sh para atualizar PDD_HEADERS_DIR e EWL_DIR com a localização correta das pastas mencionadas acima, e execute-o para construir o arquivo executável ELF para ARM frdm_kl25z_blink3:

user@localhost /tmp/frdm-kl25z-blink3-1.0 $ ./build.sh
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for arm-none-eabi-strip... arm-none-eabi-strip
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for arm-none-eabi-gcc... arm-none-eabi-gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... yes
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether arm-none-eabi-gcc accepts -g... yes
checking for arm-none-eabi-gcc option to accept ISO C89... none needed
checking for style of include used by make... GNU
checking dependency style of arm-none-eabi-gcc... gcc3
checking if Generated_Code/IO_Map.h exists in sources... yes
checking for Kinetis PDD headers location... /opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc
checking for GPIO_PDD.h... yes
checking for LPTMR_PDD.h... yes
checking for EWL headers location... /opt/Freescale/MCU/ARM_GCC_Support/ewl
checking how to run the C preprocessor... arm-none-eabi-gcc -E
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... no
checking for sys/stat.h... no
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... no
checking for strings.h... no
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... no
checking ansi_parms.h usability... yes
checking ansi_parms.h presence... yes
checking for ansi_parms.h... yes
checking CWCPlusLib.h usability... yes
checking CWCPlusLib.h presence... yes
checking for CWCPlusLib.h... yes
checking runtime_configuration.h usability... yes
checking runtime_configuration.h presence... yes
checking for runtime_configuration.h... yes
checking if Project_Settings/Linker_Files/ProcessorExpert.ld exists in sources... yes
checking for __init_registers in -lrt... yes
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: executing depfiles commands
make  all-am
make[1]: Entering directory `/tmp/frdm-kl25z-blink3-1.0'
arm-none-eabi-gcc -DHAVE_CONFIG_H -I.  -I./Sources -I./Generated_Code
-I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm
-mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf -O0
-ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT BlueLED.o -MD
-MP -MF .deps/BlueLED.Tpo -c -o BlueLED.o `test -f 'Generated_Code/BlueLED.c'
|| echo './'`Generated_Code/BlueLED.c
mv -f .deps/BlueLED.Tpo .deps/BlueLED.Po
arm-none-eabi-gcc -DHAVE_CONFIG_H -I.  -I./Sources -I./Generated_Code
-I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm
-mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf -O0
-ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT Cpu.o -MD
-MP -MF .deps/Cpu.Tpo -c -o Cpu.o `test -f 'Generated_Code/Cpu.c' || echo
'./'`Generated_Code/Cpu.c
mv -f .deps/Cpu.Tpo .deps/Cpu.Po
arm-none-eabi-gcc -DHAVE_CONFIG_H -I.  -I./Sources -I./Generated_Code
-I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm
-mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf
-O0 -ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT
GreenLED.o -MD -MP -MF .deps/GreenLED.Tpo -c -o GreenLED.o `test -f
'Generated_Code/GreenLED.c' || echo './'`Generated_Code/GreenLED.c
mv -f .deps/GreenLED.Tpo .deps/GreenLED.Po
arm-none-eabi-gcc -DHAVE_CONFIG_H -I.  -I./Sources -I./Generated_Code
-I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm
-mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf
-O0 -ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT
LEDTimer.o -MD -MP -MF .deps/LEDTimer.Tpo -c -o LEDTimer.o `test -f
'Generated_Code/LEDTimer.c' || echo './'`Generated_Code/LEDTimer.c
mv -f .deps/LEDTimer.Tpo .deps/LEDTimer.Po
arm-none-eabi-gcc -DHAVE_CONFIG_H -I.  -I./Sources -I./Generated_Code
-I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm
-mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf -O0
-ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT PE_LDD.o -MD
-MP -MF .deps/PE_LDD.Tpo -c -o PE_LDD.o `test -f 'Generated_Code/PE_LDD.c'
|| echo './'`Generated_Code/PE_LDD.c
mv -f .deps/PE_LDD.Tpo .deps/PE_LDD.Po
arm-none-eabi-gcc -DHAVE_CONFIG_H -I.  -I./Sources -I./Generated_Code
-I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm
-mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf -O0
-ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT RedLED.o -MD
-MP -MF .deps/RedLED.Tpo -c -o RedLED.o `test -f 'Generated_Code/RedLED.c'
|| echo './'`Generated_Code/RedLED.c
mv -f .deps/RedLED.Tpo .deps/RedLED.Po
arm-none-eabi-gcc -DHAVE_CONFIG_H -I.  -I./Sources -I./Generated_Code
-I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm
-mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf -O0
-ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT TU1.o -MD
-MP -MF .deps/TU1.Tpo -c -o TU1.o `test -f 'Generated_Code/TU1.c' || echo
'./'`Generated_Code/TU1.c
mv -f .deps/TU1.Tpo .deps/TU1.Po
arm-none-eabi-gcc -DHAVE_CONFIG_H -I.  -I./Sources -I./Generated_Code
-I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm
-mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf -O0
-ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT Vectors.o -MD
-MP -MF .deps/Vectors.Tpo -c -o Vectors.o `test -f 'Generated_Code/Vectors.c'
|| echo './'`Generated_Code/Vectors.c
mv -f .deps/Vectors.Tpo .deps/Vectors.Po
arm-none-eabi-gcc -DHAVE_CONFIG_H -I.  -I./Sources -I./Generated_Code
-I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm
-mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf
-O0 -ffunction-sections -fdata-sections -Wall -fmessage-length=0
-MT __arm_end.o -MD -MP -MF .deps/__arm_end.Tpo -c -o __arm_end.o
`test -f 'Project_Settings/Startup_Code/__arm_end.c' || echo
'./'`Project_Settings/Startup_Code/__arm_end.c
mv -f .deps/__arm_end.Tpo .deps/__arm_end.Po
arm-none-eabi-gcc -DHAVE_CONFIG_H -I.  -I./Sources -I./Generated_Code
-I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm
-mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf
-O0 -ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT
__arm_start.o -MD -MP -MF .deps/__arm_start.Tpo -c -o __arm_start.o
`test -f 'Project_Settings/Startup_Code/__arm_start.c' || echo
'./'`Project_Settings/Startup_Code/__arm_start.c
mv -f .deps/__arm_start.Tpo .deps/__arm_start.Po
arm-none-eabi-gcc -DHAVE_CONFIG_H -I.  -I./Sources -I./Generated_Code
-I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm
-mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf -O0
-ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT Events.o
-MD -MP -MF .deps/Events.Tpo -c -o Events.o `test -f 'Sources/Events.c' ||
echo './'`Sources/Events.c
mv -f .deps/Events.Tpo .deps/Events.Po
arm-none-eabi-gcc -DHAVE_CONFIG_H -I.  -I./Sources -I./Generated_Code
-I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm
-mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf
-O0 -ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT
ProcessorExpert.o -MD -MP -MF .deps/ProcessorExpert.Tpo -c -o ProcessorExpert.o
`test -f 'Sources/ProcessorExpert.c' || echo './'`Sources/ProcessorExpert.c
mv -f .deps/ProcessorExpert.Tpo .deps/ProcessorExpert.Po
arm-none-eabi-gcc -DHAVE_CONFIG_H -I.  -I./Sources -I./Generated_Code
-I/opt/Freescale/MCU/ProcessorExpert/lib/Kinetis/pdd/inc
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_C/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include
-I/opt/Freescale/MCU/ARM_GCC_Support/ewl/EWL_Runtime/include/arm
-mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2 -gstrict-dwarf -O0
-ffunction-sections -fdata-sections -Wall -fmessage-length=0 -MT sa_mtb.o
-MD -MP -MF .deps/sa_mtb.Tpo -c -o sa_mtb.o `test -f 'Sources/sa_mtb.c' ||
echo './'`Sources/sa_mtb.c
mv -f .deps/sa_mtb.Tpo .deps/sa_mtb.Po
arm-none-eabi-gcc  -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -gdwarf-2
-gstrict-dwarf -O0 -ffunction-sections -fdata-sections -Wall -fmessage-length=0
-Xlinker --gc-sections -n -L/opt/Freescale/MCU/ARM_GCC_Support/ewl/lib/armv6-m
-T./Project_Settings/Linker_Files/ProcessorExpert.ld -o frdm_kl25z_blink3
BlueLED.o Cpu.o GreenLED.o LEDTimer.o PE_LDD.o RedLED.o TU1.o Vectors.o
__arm_end.o __arm_start.o Events.o ProcessorExpert.o sa_mtb.o  -lrt
make[1]: Leaving directory `/tmp/frdm-kl25z-blink3-1.0'

frdm_kl25z_blink3: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV),
statically linked, not stripped

A seguir em Gravação iremos gravar o ELF frdm_kl25z_blink3 na placa FRDM-KL25Z para execução.

english

Tópicos:

  1. Introdução
  2. Ferramentas
  3. Compilação
  4. Gravação
  5. Debug

De forma a compilar software para a placa FRDM-KL25Z, precisamos ser capazes de gerar código objeto para CPUs ARM. É altamente provável que seu sistema Gentoo Linux rode num computador não ARM, logo precisamos de ferramentas para cuidar da geração de manipulação de código objeto destinado a uma arquitetura de CPU diferente da do seu computador.

Instale crossdev, o gerador de ferramentas de construção cruzada de softwares do Gentoo:

localhost ~ # emerge sys-devel/crossdev

Use o crossdev para construir um compilador cruzado C, biblioteca libc e outras ferramentas de construção para CPUs ARM:

localhost ~ # crossdev -t arm-none-eabi
-----------------------------------------------------------
 * crossdev version:      20131107
 * Host Portage ARCH:     amd64
 * Target Portage ARCH:   arm
 * Target System:         arm-none-eabi
 * Stage:                 3 (C compiler & libc)
 * ABIs:                  default

 * binutils:              binutils-[latest]
 * gcc:                   gcc-[latest]
 * libc:                  newlib-[latest]



 * Log: /var/log/portage/cross-arm-none-eabi-binutils.log
 * Emerging cross-binutils ... [ ok ]
 * Log: /var/log/portage/cross-arm-none-eabi-gcc-stage1.log
 * Emerging cross-gcc-stage1 ... [ ok ]
 * Log: /var/log/portage/cross-arm-none-eabi-newlib.log
 * Emerging cross-newlib ... [ ok ]

Agora o seu sistema Gentoo contém um ótimo conjunto de ferramentas GNU de construção cruzada que pode gerar código para CPUs ARM. Todas a ferramentas são prefixadas com arm-none-eabi- indicando seus propósitos de serem ferramentas cruzadas para ARM no seu sistema não ARM:

user@localhost ~ $ cd /usr/bin
user@localhost /usr/bin $ ls arm-none-eabi-*
arm-none-eabi-addr2line  arm-none-eabi-gcc-4.8.2   arm-none-eabi-nm
arm-none-eabi-ar         arm-none-eabi-gcc-ar      arm-none-eabi-objcopy
arm-none-eabi-as         arm-none-eabi-gcc-nm      arm-none-eabi-objdump
arm-none-eabi-c++filt    arm-none-eabi-gcc-ranlib  arm-none-eabi-pkg-config
arm-none-eabi-cpp        arm-none-eabi-gcov        arm-none-eabi-ranlib
arm-none-eabi-cpp-4.8.2  arm-none-eabi-gcov-4.8.2  arm-none-eabi-readelf
arm-none-eabi-dwp        arm-none-eabi-gdb         arm-none-eabi-run
arm-none-eabi-elfedit    arm-none-eabi-gprof       arm-none-eabi-size
arm-none-eabi-emerge     arm-none-eabi-ld          arm-none-eabi-strings
arm-none-eabi-fix-root   arm-none-eabi-ld.bfd      arm-none-eabi-strip
arm-none-eabi-gcc        arm-none-eabi-ld.gold

Para uma verificação rápida da usabilidade do compilador cruzado, você pode criar um arquivo chamado hello.c contendo:

#include <stdio.h>

int main() {

        printf("Hello world\n");
        return 0;

}

Vamos ver se o compilador cruzado consegue gerar executáveis para ARM:

user@localhost ~ $ arm-none-eabi-gcc -o hello hello.c 
user@localhost ~ $ file hello
hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped

Parece bom.

A seguir em Compilação usaremos as ferramentas de construção cruzada para compilar um aplicativo desenvolvido especificamente para a placa FRDM-KL25Z.

english

Eletromiografia (EMG) é uma técnica de avaliação e registro da atividade elétrica produzida pela musculatura esquelética.

Apresentação sobre EMG