Programación de Arduino en Assembly
Programación de Arduino en Assembly
lenguaje ensamblador
Indice
● Introducción
● Consideraciones iniciales
● Herramientas
– AVR-GCC
● avr-as
● avr-ld
● avr-objcopy
– AVRDude
● Detalles de arquitectura y lenguaje
– Correspondencia pines/puertos
– Definición de puertos
● Ejemplo: Blink
Introducción
● Arduino
– Plataforma de placas de desarrollo
– Hardware Libre
– Basada en microcontroladores AVR
– Incluye una serie de herramientas y librerías para
hacer mas fácil su programación
– Su lenguaje de programación principal es C++
Consideraciones iniciales
● Placa de desarrollo: Arduino UNO R3
– Microcontrolador: Atmega 328p
● Sistema Operativo: GNU/Linux
● Herramientas a usar:
– Ensamblador/linkador: AVR-GCC
– Cargador: AVRDude
AVR-GCC
● Colección de herramientas de GCC para
programación de microcontroladores AVR, para
línea de comandos
● Incluye las herramientas:
– Avr-as: ensamblador
– Avr-ld: linkador
– Avr-objcopy: conversor de formatos binarios
AVR-GCC: avr-as
● Herramienta de ensamblado de GCC para
microcontroladores AVR
– Genera el fichero objeto a partir del código
ensamblador
● Sintaxis:
– Similar a la sintaxis de GCC
avr-as -mmcu=[modelo_microcontrolador] -o [nombre_fich_objeto]
[nombre_fich_ensamblador]
– En nuestro caso, el modelo de microcontrolador es “atmega328p”
AVR-GCC: avr-ld
● Linkador de GCC para microcontroladores AVR
● Recibe el fichero objeto y realiza el linkado
– Fichero de salida: binario elf
● Sintaxis:
avr-ld -o [nombre_fich_elf] [nombre_fich_obj]
AVR-GCC: avr-objcopy
● Conversor de formatos binarios
● La programación de microcontroladores AVR se
realiza con ficheros de formato .hex
– avr-objcopy nos permite convertir los binarios de
formato elf a formato .hex, para su posterior grabación
con avrdude
● Sintaxis:
avr-objcopy -O ihex -R .eeprom [fichero_elf]
[fichero_hex]
AVRDude
● Programador
● Carga el programa hexadecimal en el
microcontrolador
● Sintaxis:
avrdude -C /etc/avrdude.conf -p
[modelo_microcontrolador] -c arduino -P /dev/ttyACM0 -b
115200 -D -U flash:w:[fichero_hex]:i
Detalles de arquitectura y lenguaje
Correspondencia pines/puertos
● Nos basaremos en el esquema de conexionado de la pagina
oficial:
https://www.arduino.cc/en/uploads/Main/Arduino_Uno_Rev3-sch
ematic.pdf
Detalles de arquitectura y lenguaje
Correspondencia pines/puertos
Pines de la placa
Conexiones
microcontrolador
Detalles de arquitectura y lenguaje
Correspondencia pines/puertos
● El ATMega328p incluye 3 puertos, de entre 5 y 8 conexiones cada uno
– Puerto B (PB):
● 5 conexiones digitales, correspondientes a los pines 8-13 de la placa
● 1 conexión AREF
DDRB
0 0 0 0 0 1 0 0
Sin Sin PB5 PB4 PB3 PB2 PB1 PB0
usar usar
– El dato saldría por la conexión activa del puerto, en este caso por la 2
Ejemplo: Blink
● Produce el parpadeo de un led
– Intervalos de 1 segundo
– Led conectado al pin 12 de la placa
● Pin 12 = Puerto B, conexión 5 (PB4)
– DDRB ← 00010000
● El fichero de código tendrá por nombre
“simple_led_blink.s”
Ejemplo: Blink
● Código
Ejemplo: Blink
● Código desglosado
Nombramos los puertos con las
direcciones de memoria asociados
a ellos
Inicializamos contadores
Ejemplo: Blink
● Programación del programa en la placa, desde
linea de comandos
– Ensamblado del código
● avr-as -g -mmcu=atmega328p -o simple_led_blink.o
simple_led_blink.s
● avr-ld -o simple_led_blink.elf simple_led_blink.o
● avr-objcopy -O ihex -R .eeprom simple_led_blink.elf
simple_led_blink.hex
– Carga en la placa
● avrdude -C /etc/avrdude.conf -p atmega328p -c arduino -P
/dev/ttyACM0 \ -b 115200 -D -U flash:w:simple_led_blink.hex:i
Ejemplo: Blink
Modificaciones
● Basándonos en este código podemos realizar varios cambios
– Si quisiéramos cambiar el pin de salida, tendríamos que fijarnos en estas
lineas
ldi r16,0x10 ; set port bits to output mode
out DDRB,r16
Cambiado a conexión 2
Cambiado a DDRD
Ejemplo: Blink
Modificaciones
● Otro cambio que podemos hacer es reducir el periodo de encendido del led
– Para ello buscamos la etiqueta wait: y miramos las siguientes lineas:
ldi r16,0x40 ; loop 0x400000 times
ldi r17,0x00 ; ~12 million cycles
ldi r18,0x00 ; ~0.7s at 16Mhz
– Actualmente, el periodo esta definido en 0x400000 iteraciones (0x40), lo cual
equivale a 1 segundo
● Cambiando ese valor, podremos establecer un nuevo periodo de encendido
– Si quisiéramos cambiar el periodo a la mitad, cambiaríamos la primera
linea así:
ldi r16,0x20 ;
Conclusiones
● Existen muchas herramientas para programar dispositivos AVR
– La colección AVR-GCC provee un entorno muy bueno para
programación de este tipo de dispositivos desde GNU/Linux
● Ventajas: Muy ligero, y compatible con la mayoría de
distribuciones GNU/Linux
● Desventajas: Interfaz de linea de comandos
● El juego de instrucciones de AVR es bastante similar al de otros
microcontroladores, como los PIC
– Los esquematicos de hardware libre, y el tener una placa
real, facilita mucho la programación y prototipado
Enlaces de interés
● Esquema de conexionado Arduino UNO R3:
https://www.arduino.cc/en/uploads/Main/Arduino_Uno_Rev3-schemati
c.pdf
● Native Assembler Programming on Arduino:
https://www.cypherpunk.at/2014/09/native-assembler-programming-on
-arduino/
● Programming Arduino UNO in assembly:
https://gist.github.com/mhitza/8a4608f4dfdec20d3879
● Juego de instrucciones AVR
http://www.atmel.com/images/Atmel-0856-AVR-Instruction-Set-Manual
.pdf