Вы находитесь на странице: 1из 39

Máster Oficial en Sistemas Electrónicos para Entornos

Inteligentes

Técnicas de diseño de sistemas empotrados basados en


microcontroladores. Microkernels.

INTRODUCCIÓN AL IDE MSP430


IAR EW
CURSO ACADÉMICO 2013/2014

V5.0

Dpto. Tecnología Electrónica

Universidad de Málaga
Técnicas de diseño de sistemas empotrados basados en microcontroladores. Microkernels.

ÍNDICE

INTRODUCCIÓN ......................................................................................................................................1

EVALUACIÓN .........................................................................................................................................2

GUÍA DE TRABAJO: IDE IAR EW Y PROGRAMACIÓN EN C .....................................................................3

1. Carga de la aplicación de ejemplo ..............................................................................................3

2. Generación de Proyectos. Espacio de Trabajo...........................................................................5

3. Detección de Errores ...................................................................................................................9

4. Depuración Básica. ....................................................................................................................10

5. Depuración Básica: Puntos de Ruptura. ...................................................................................11

6. Depuración Básica: Inspección de registros. .......................................................................16

7. Depuración básica: Inspección de variables. Tipos de variables. ......................................16

8. Ámbito de variables. Variables globales y locales. Modificadores static, extern, y volatile.


........................................................................................................................................................21

9. Gestión de Memoria. Modelos de datos. Ventana de Memoria. .........................................22

10. Secuencia de inicialización: cstartup.s43 y __low_level_init(). .........................................26

11. Mapeo de memoria. Acceso a registros. ...........................................................................28

12. Mezclando C y ensamblador. Paso de parámetros (Calling Convention). ................29


Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

INTRODUCCIÓN

Este documento describe los conceptos básicos necesarios para comenzar a utilizar el entorno de
desarrollo que se empleará como herramienta para la asignatura Técnicas de diseño de sistemas
empotrados basados en microcontroladores. Microkernels dentro del Máster Universitario en
Inteligencia Ambiental: Sistemas electrónicos para entornos inteligentes. Dicho entorno se basa
en el uso de una placa de desarrollo “MSP-EXP430F5438” de Texas Instruments y la aplicación
“IAR Embedded Workbench”. Además, proporciona información relacionada con la programación
de aplicaciones en lenguaje C mediante dicho entorno.

La placa de desarrollo “MSP-EXP430F5438 de Texas Instruments proporciona todos los


elementos necesarios para implementar sistemas y aplicaciones basados en la familia de
microcontroladores “MSP430”, en particular con un microcontrolador “MSP430F5438”. Dicha
placa posee un conector JTAG de depuración que permite conectarla a un PC mediante una
conexión USB, utilizando para ello el módulo adaptador “MSP430UIF”. Las características básicas
de esta placa así como su utilización en el desarrollo de sistemas se describen en el documento
“MSP-EXP430F5438” y en la unidad 4 de este bloque.
Conexión JTAG
(depuración cable IDE)

Conexión JTAG
(USB PC)
MSP430UIF MSP-EXP430F5438

La aplicación “IAR Embedded Workbench1” constituye un entorno integrado que posee un Editor,
un Ensamblador/Compilador, un Linkador y un Depurador. Con esta aplicación se puede
desarrollar código tanto en ensamblador como en C para la familia de microcontroladores
“MSP430”, así como transferirlo a cualquier placa de desarrollo “MSP-EXP430F5438” mediante el
correspondiente módulo adaptador para su posterior depuración. De esta forma, la aplicación
“IAR Embedded Workbench” permite controlar por completo el ciclo de desarrollo de cualquier
sistema basado en la familia de microcontroladores “MSP430”. La guía de usuario de la aplicación
“IAR Embedded Workbench” se describe en el documento “MSP430 IAR Embedded Workbench”.

La aplicación “IAR Embedded Workbench” se ejecuta desde el menú Inicio: [Inicio – Programas –
IAR Systems – IAR Embedded Workbench for MSP430 VX.x – IAR Embedded Workbench]. La

1
La unidad 5 de este bloque se dedica a la instalación y configuración del IAR EW 5.50.2, que es
la versión que se va a utilizar este curso.

1
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

placa “MSP-EXP430F5438)” se enciende/apaga mediante la conexión/desconexión del conector


USB al PC, y también (mas recomendable) desconectando el cable IDE de la placa. También se
puede conseguir su apagado seleccionando una fuente de alimentación no disponible.

Conector de alimentación de la placa


FET: Alimentación desde interfaz FET MSP430UIF
USB: Alimentación desde interfaz USB
BATT: Alimentación mediante pilas

En esta Guía se introduce el ciclo completo de utilización de la herramienta “IAR Embedded


Workbench” para crear un “espacio de trabajo”, editar, compilar, linkar y depurar una aplicación
sencilla o proyecto programado en C. Los programas de ejemplo permiten introducir conceptos
indispensables para la programación de aplicaciones en lenguaje C, tales como: estructura básica
de un programa; tipos de datos y variables empleadas; palabras claves, directivas pragma,
símbolos predefinidos y funciones de acceso a características de bajo nivel del compilador;
aspectos de configuración de proyectos (modelo de datos, optimización, librerías…);
convenciones en el paso de parámetros a funciones (calling convention), etc.…

EVALUACIÓN

A lo largo de esta guía se van a ir planteando distintas cuestiones, que permitirán evaluar su
realización y compresión de los puntos que trata. Los puntos de esta guía que son obligatorios
para la evaluación se marcaran con el símbolo , mientras que los puntos que son voluntarios se
marcan con el símbolo .

La contestación a las cuestiones planteadas se realizará en: “Guía de tiempos y cuestionario


INTRODUCCIÓN AL IDE MSP430 IAR EW”.

2
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

GUÍA DE TRABAJO: IDE IAR EW Y PROGRAMACIÓN EN C

1. Carga de la aplicación de ejemplo

1.1 Una vez instalado el IAR EW, conectar la placa de desarrollo al JTAG, y éste al puerto USB.
Aliméntala, asegurándote que el interruptor superior izquierdo está en la posición FET o
BATT (esto último solo si tienes pilas insertadas bajo la placa). Abrir el programa IAR
Embedded Workbench. Seleccionar la opción Open existing workspace en la ventana, o la
opción: [File – Open – Workspace] en el menú:

1.2 Descargate de la página WEB el archivo comprimido Aplicación ejemplo MSP-EXP430F5438


archivo zip), descomprímelo, y selecciona, en la carpeta, el fichero MSP-EXP430F5438_
User_Experience.eww. Se abrirá el proyecto de la aplicación de ejemplo.

Es posible que te aparezca un diálogo indicando que el fichero está en un formato antiguo y si deseas
convertirlo al formato mas reciente. Contesta “Si” al diálogo.

1.3 Pulsando en cualquiera de los ficheros de programa “*.c” aparecerá el código de dicho fichero
en el espacio de la derecha. Selecciona la opción [Project – Make] para generar el ejecutable

3
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

de la aplicación. Como alternativa, selecciona el nombre del proyecto MSP-


EXP430F5438_User_Experience (botón izquierdo del ratón), y pulsa a continuación el botón
derecho, seleccionando la opción Make en el menú desplegable.

1.4 Si no habido ningún error en el código o proyecto, el siguiente paso es cargar el ejecutable en
la placa. Para ello selecciona la opción del menú [Project – Download and Debug]; o bien el
icono, , de la barra de menús; o pulsa CTRL+D. Tras cargarse el programa, aparecerá en

4
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

pantalla el menú de modo depuración. En este menú, seleccionar la opción [Debug – Go]; o
bien el icono ; o pulsa F5. Aparece una ventana con el código en lenguaje ensamblador.

Si es la primera vez que se utiliza el sistema de desarrollo, es posible que se muestre una
ventana flotante informando de que es necesario actualizar el firmware de la placa de desarrollo:

Pulse “Sí”. No desconecte la alimentación de la placa mientras se realiza el proceso de


actualización; podría dañar la placa.

1.5 Se encenderá el Display de la placa. Pulsando cualquier botón o el joystick, aparecerá el


menú de ejemplos de la placa. Utiliza el joystick y el botón derecho en la placa para
seleccionar los diferentes ejemplos (mostrar un reloj en pantalla; acelerómetros de la placa;
comunicación con el PC; grabación/reproducción de voz – el micro está junto al joystick, pero
deberás conectar un altavoz a la entrada jack de la placa; led intermitente con control de
velocidad; y cambar las condiciones del LCD, luminosidad, hora, etc…) Pulsando el joystick
se vuelve al menú principal. Si ves la pantalla demasiado oscura o clara, la opción 6 Settings
te permite modificar el contraste (2. Contrast) y el brillo de fondo (3. Backlight).

Además de cargar el programa en la placa, podrás depurar (debug) el funcionamiento del


mismo, ejecutando las instrucciones paso a paso, observando la evolución de los contenidos
de memoria, registros, etc….Esto lo veremos un poco más adelante.

2. Generación de Proyectos. Espacio de Trabajo.

Veremos a continuación como empezar un proyecto desde cero.

5
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

2.1 Crea un nuevo espacio de trabajo (Workspace) para ubicar todos los proyectos que se van a
desarrollar en la asignatura: [File – New – Workspace]:

2.2 Crea un nuevo proyecto tipo C para el Ejemplo 1 dentro del espacio de trabajo recién creado.
Dicho proyecto se debe guardar en la ubicación que se te indique con el nombre “Ejemplo1”:
[Project – Create New Project – C – main]

2.3 Aparecerá una plantilla con los elementos básicos de un programa en C. Configura el
proyecto recién creado “Ejemplo1” con las opciones adecuadas para su correcto uso con el
sistema de desarrollo del que se dispone: [Project – Options] (o bien pulsa el botón derecho
en el nombre del proyecto y selecciona Options).

6
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

Establece las siguientes opciones:

General Options – Target – Device - msp430x5xx Family - msp430F5438

Debugger2 – Setup – Driver – FET Debugger

FET Debugger – Setup – Connection – Texas Instrument USB IF

FET Debugger – Download – Flash Erase - Erase main and Information memory

Activa FET Debugger – Download – Verify download

El resto de opciones puedes dejar las que vienen por defecto. En realidad dependerán de las
características particulares del proyecto (usar más de un fichero fuente, programar en C++,
niveles de compilación más estrictos, generar información adicional de depuración,
optimizaciones, etc…). Se explicarán más en detalle otras opciones cuando sea necesario.

2.4 Escribe el código de la aplicación a partir de la plantilla en el fichero “main.c”. En este caso
particular, utilizaremos un fichero de código ya escrito; por ello, eliminamos el fichero “main.c”
del proyecto: selecciona el fichero, pulsa el botón derecho, y selecciona la opción Remove en
el menú contextual. Para quitar el fichero de código del espacio de trabajo, selecciona su
pestaña, pulsa el botón derecho, y selecciona Close en el menú contextual.

2
Los ejercicios de esta guía que no utilizan la placa pueden realizarse con el simulador. La opción
es: Debugger – Setup – Driver – Simulator

7
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

2.5 Ahora añade el archivo “Ejemplo1.c” que contiene el código fuente correspondiente a este
proyecto. Para ello, selecciona el proyecto Ejemplo1, pulsa el botón derecho, y selecciona
[Add – Add Files] y busca el fichero “Ejemplo1.c” en la carpeta de ejemplos (puedes hacer lo
mismo seleccionando la opción [Project – Add Files]). Pinchando 2 veces en el nombre del
fichero, aparecerá el código del mismo en el espacio de trabajo. Compila el proyecto tal como
viste en el punto 1.3 (antes de compilar, se te pedirá que salves el espacio de trabajo, si no lo
habías hecho antes; sálvalo como “Ejemplo1.eww”. Puedes salvar el espacio de trabajo en
cualquier momento con la opción [File – Save Workspace]).

8
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

Código fuente del Ejemplo1:


// *****************************************************************************
// UNIVERSIDAD DE MALAGA DPTO. TECNOLOGIA ELECTRONICA
// *****************************************************************************
// PROGRAMA : Ejemplo1.c (v1.1)
// TARGET : Placa MSP-TS430PM64 (v1.0) - Microcontrolador MSP430F169
// DESCRIPCION : Apaga el LED1 P1.0 al apretar cualquier botón del LCD o
// joystick. Testeo por polling.
// AUTOR : Ignacio Herrero Reder (basado en M Smertneck / W. Goh)
// FECHA : 23-10-09
// ESQUEMA : Placa de desarrollo MSP-EXP430F5438
//******************************************************************************
#include "msp430x54x.h"
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Detiene el watchdog
P1DIR |= 0x01; // Establece dirección bit 0 de puerto 1
P2REN = 0xFF; // Activa resistencias de pullup asociadas
P2OUT = 0xFF; // a los pines del puerto 2
while (1)
{
if (P2IN == 0xFF) // Testea Puerto 2 (botones LCD y joystick
P1OUT = 0x01; // si alguno pulsado (bit a 0), enciende LED
else
P1OUT = 0x00; // en caso contrario, lo apaga
}
}

2.6 Por último, descarga el ejecutable de la aplicación en la placa de desarrollo y entra en el modo
depuración, tal como vimos en el punto1.4.

3. Detección de Errores

3.1 Al compilar un proyecto aparece la ventana “Build” en la parte inferior, indicando el resultado
del proceso de generación de código ejecutable, y los posibles errores. Se puede abrir con
[View – Messages - Build]. Se cierra pinchando la “X”. Si existe un error en el código, se
indicará en dicha ventana. Además, se marca el error con un círculo rojo al principio de la
línea donde se ha producido. Por ejemplo, modificamos una línea de código cambiando a un
valor inexistente o eliminando un paréntesis. Si ahora generamos el ejecutable con [Project –
Make] se indicará el error:

Errores en
el código

9
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

4. Depuración Básica.

4.1 Inicia la ejecución del programa tal como vimos en el punto 1.4: [Debug – Go] o . Observa
la aparición de 1 nueva ventana, Debug Log (parte inferior) que muestra información
relacionada con la depuración del código (modelo de micro, tensión de alimentación, éxito o
no del inicio de la depuración, e incidencias durante ésta). Detén la ejecución del programa:
[Debug – Break]

Ventana
Debug Log

4.2 El programa se habrá detenido en alguna línea de código dentro del bucle; dicha línea se
marcará en verde claro. En el bucle, se testea el estado del puerto 2 (conectado a los
botones) y se enciende o apaga un LED en consecuencia. Para ver el estado del puerto 2,
podemos abrir la ventana [View – Register]; y buscar el nombre del puerto en la ventana
desplegable.

Ventana de Registros

Línea en ejecución

10
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

4.3 Ejecuta el programa Paso a Paso: [Debug – Step Over] . El resaltado en verde indica la
instrucción que ejecutaremos a continuación. Observa cómo, mientras P2IN está a 0xFF, se
ejecuta la instrucción, P1OUT=0x01, que pone a nivel alto el BIT0 del PUERTO1, con lo cual el
LED permanece encendido, reflejando que ha sufrido un cambio respecto a la instrucción
anterior. Si pulsas alguno de los botones, el bit correspondiente del PUERTO2 se pondrá a 1
(observa cómo el bit modificado aparece en color rojo, y lo mismo ocurre con el nombre del
registro), con lo que se ejecutará la instrucción P1OUT=0x00, que apaga el LED (podrás ver
como el registro P1OUT también aparece en rojo, indicando el cambio de 0x01 a 0x00).

5. Depuración Básica: Puntos de Ruptura.

5.1 Establece un Punto de Ruptura en la instrucción indicada por la flecha roja en la imagen; para
ello pincha antes en la línea con el cursor y haz [Edit – Toggle Breakpoint] . La línea pasa
a roja, con un punto rojo delante.

11
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

5.2 Arranca la ejecución del programa:[Debug – Go] . El programa se ejecutará, y permanecerá


chequeando el estado del puerto 2, y manteniendo el LED encendido mientras no pulsemos
ningún botón (P1OUT = 0x01;). Al pulsar un botón, pasará a ejecutarse la instrucción P1OUT
= 0x00; y, al estar activado un punto de ruptura en esa posición, el programa se detendrá
antes de ejecutarla. En la ventana Debug Log aparece indicada tal detención (Breakpoint hit:
Code @ Ejemplo1.c:25.18).

5.3 Pincha en la línea donde está colocado el punto de ruptura, y deshabilítalo temporalmente:
[Edit – Enable/Disable Breakpoint]. La línea pasa a un color rosa, con un punto rojo “vacío”
delante. Si ejecutamos de forma continua de nuevo [Debug – Go] , ya no se detendrá el
programa en el punto de ruptura aunque pase por él. La misma opción te permite volver a
habilitarlo.

12
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

5.4 Para eliminar el punto de ruptura selecciona [Edit – Toggle Breakpoint] con el cursor
situado en la línea donde está el punto de ruptura a eliminar. Otra forma de hacer lo mismo:
pincha en la línea donde está colocado el punto de ruptura, pulsa el botón derecho, y elimina
el punto de ruptura: [Toggle Breakpoint] (recuerda que el botón derecho permite acceder a
muchos de los menús de la barra superior según el lugar donde se pinche). La línea deja de
tener color.

5.5 Finaliza la ejecución de la sesión de depuración con [Debug – Stop Debugging] .

Volveremos a la ventana de edición de proyectos.

Depuración Avanzada: Puntos de Ruptura Condicionales

5.6 El punto de ruptura que hemos colocado, se activa cada vez que se ejecuta la instrucción
correspondiente. Podemos establecer que solo se detenga cuando se cumpla una
determinada condición. Para ello, habilita de nuevo el punto de ruptura del paso anterior y a
continuación abre la ventana BreakPoints con [View – Breakpoints]. Aparecerá en la parte de
abajo, agrupada con Debug Log (puedes cambiar de una a otra pinchando la pestaña

13
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

correspondiente). En la ventana vemos el punto de ruptura definido, su tipo, el programa en el


que se definió, y la condición (ahora mismo no hay ninguna). Pincha con el boton derecho
sobre el punto de ruptura y selecciona Edit en el menú que aparece.

Acción asociada

Cuenta hasta
condición ruptura

La condición se indica con una expresión en la que pueden aparecer los nombres de los
registros o variables, y diversos operadores (==, |, &,…). Por ejemplo, P2IN==0x3F, variable==20
,(P2IN==0x3F & variable==20), variable > variable2,..etc. Se puede determinar la activación del
punto de ruptura tanto con el cumplimiento de la condición (Condition true) o con el cambio de la
misma (Condition changed).

Además se puede indicar que el programa no se detenga al pasar por la instrucción las
primeras N veces que pase, indicando un valor en el campo Skip Count. Si también se ha
impuesto una condición, el programa no se detendrá las primeras N veces que, al pasar por la
instrucción, se cumpla la condición.

Por último, es posible hacer que, además de detenerse el programa, se realiza una acción
adicional que se debe indicar en el campo Action. Las acciones suelen ser macros diseñadas con
objeto de facilitar la labor de depuración. Por ejemplo puedes crear una macro que envíe a la
ventana Log el estado de la variable variable en cada punto de ruptura: para ello podemos usar
la función intrínseca __message, en una macro como la que viene a continuación:
LogPORT2(){
__message "Valor de P2IN:",P2IN:%x;
}

14
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

Para poder utilizar la macro habría que crearla en un fichero con extensión .mac, añadirla a tu
sesión de depuración, y registrarla. Una vez estás depurando tu programa, con [Debug – Macro]
abres una ventana de configuración de macros. Allí debes seleccionar la macro que desees,
añadirla con Add y registrarla con Register.

15
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

6. Depuración Básica: Inspección de registros.

6.1 A menudo nos interesa conocer como van modificándose los registros de nuestro micro a
medida que se va ejecutando el programa. En el programa del Ejemplo1 el estado del LED
depende de la lectura de un registro, P2IN, que recoge el estado de entrada del puerto 2 al que
hay conectados varios botones activos a nivel bajo. Podemos observar el estado de este registro
en cualquier momento.

Coloca un punto de ruptura en la instrucción if (P2IN == 0xFF), y ejecuta el programa


desde el principio (puedes volver a la primera instrucción con la opción [Debug – Reset]
). Cuando el sistema se detenga en el punto de ruptura, abre una ventana de
observación de registros con [View - Register], y elige en el menú desplegable Port1/2. En
la ventana aparecerán los registros de los puertos 1 y 2. Observa el estado del registro
P2IN.

Ahora pulsa un botón de la placa y, manteniéndolo pulsado, continúa la ejecución del


código (Go). Observa como el registro P2IN ha cambiado, reflejando la pulsación del
botón. Observa también como, tras ejecutarse la siguiente instrucción, se refleja el cambio
correspondiente en el registro P1OUT.

Averigua a qué bit está conectado cada botón de la placa.

7. Depuración básica: Inspección de variables. Tipos de variables.

7.1. Otra facilidad de depuración proporcionada por el entorno de desarrollo nos permite
inspeccionar las variables que hemos definido en el programa, así como expresiones de
datos en los que aparecen algunas de estas variables. Vamos a modificar el programa
anterior para introducir alguna variable.

16
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

Códigos fuente del Ejemplo 2:


// *****************************************************************************
// UNIVERSIDAD DE MALAGA DPTO. TECNOLOGIA ELECTRONICA
// *****************************************************************************
// PROGRAMA : Ejemplo2.c (v2.0)
// TARGET : Placa MSP-TS430PM64 (v1.0) - Microcontrolador MSP430F169
// DESCRIPCION : Apaga el LED1 P1.0) al apretar cualquier botón del LCD o
// joystick. Testeo por polling. Variable intermedia
// AUTOR : Ignacio Herrero Reder (basado en M Smertneck / W. Goh)
// FECHA : 04-10-11
// ESQUEMA : Placa de desarrollo MSP-EXP430F5438
//******************************************************************************
#include "msp430x54x.h"
#include <stdbool.h> // Necesario para poder usar los tipos bool
#include <stdlib.h>

// Definición de variables GLOBALES


bool vblbool;
/* static */char vblchar; // uchar y char representan el mismo tipo
signed char vblschar;
signed int vblsint; // int y short representan el mismo tipo
unsigned int vbluint;
signed long vblslong;
unsigned long vblulong;
signed long long vblslonglong; // La librería CLIB NO soporta los tipos
unsigned long long vblulonglong; // long-long
float vblfloat;
double vbldouble; // Tamaño 32 o 64 bits se indica en las opciones de
// proyecto (General Options)
// long double y double son equivalentes

char variableNoUsada;

void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Detiene el watchdog
// Inicialización de variables GLOBALES
vblbool=false;
vblschar=-35;
vblsint=-30000;
vbluint= 64237;
vblslong=-256000;
vblulong=4294000000;
vblslonglong=-pow(2,63);
vblulonglong=pow(2,64);
vblfloat= 2.3e9;
vbldouble= 1.5e19;
//Definimos algunas variables LOCALES
char vblcharlocal=100;
/* static */ /*volatile*/ char vblcharlocal2;
P1DIR |= 0x01; // Establece dirección bit 0 de puerto 1
P2REN = 0xFF; // Activa resistencias de pullup asociadas
P2OUT = 0xFF; // a los pines del puerto 2
while (1)
{
vblcharlocal=P2IN;
vblcharlocal2=0;
vblcharlocal2=vblcharlocal;
vblchar=vblcharlocal & 0x0F;
if (vblcharlocal == 0xFF) // Testea Puerto 2 (botones LCD y joystick
P1OUT = 0x01; // si alguno pulsado (bit a 0), enciende LED
else
P1OUT = 0x00; // en caso contrario, lo apaga
}
}

7.2 Existen diversas formas de observar la evaluación de estas variables o expresiones.


Colocando el cursor encima de ella y esperando unos instantes, aparece un recuadro con su
valor y tipo. Además, podemos abrir una serie de ventanas de visualización de variables

17
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

eligiendo algunas de las opciones desplegadas al seleccionar el menú [View]: Watch, Locals,
Statics, Auto, Live Watch, y Quick Watch.

Auto. Abre una ventana donde se presenta información de las expresiones


modificadas recientemente: nombre, valor, posición en memoria de la variable, y tipo
de dato. No tenemos control sobre las expresiones que se muestran.

Statics. Lo mismo que en el caso anterior pero para las variables definidas como
globales o estáticas. Mostrará TODAS las variables de este tipo definidas en la
aplicación. Las variables volatile no se muestran en esta ventana.

En el ejemplo del program anterior, ¿por qué no aparece variableNoUsada?

Watch3. Es similar al anterior, pero en este caso podemos elegir exactamente que
variables/expresiones queremos que se muestren. Pincha en el cuadro bajo
Expressions, y escribe el nombre de cualquiera de las variables globales definidas
en el programa; haz lo mismo con vblcharlocal; como alternativa, remarca el
nombre de variable que quieres observar en el código, y arrástrala, con el botón
izquierdo pulsado, hasta el primer cuadro libre bajo Expressions. Tanto en esta
ventana como en las demás, es posible cambiar la forma de representar los valores
de las variables pulsando con el botón derecho en el nombre y eligiendo en los
menús desplegables. También es posible escribir y evaluar expresiones en esta
ventana (por ejemplo “vblcharlocal & 0x0F”).

3
En las últimas versiones del entorno, es posible abrir hasta 4 ventanas WatchX (X de 1 a 4),
para crear grupos de variables separadas a observar.

18
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

Ventana watch

¿Por qué aparece en la imagen la variable vblcharlocal como “no disponible”


(unavailable)? Si sigues ejecutando paso a paso, cambia ese estado? Si es así,
¿cuándo y por qué? ¿Qué es lo que pone en la columna “Location”?

QuickWatch. Similar al anterior, pero permite un control más preciso en la evaluación


de expresiones con efectos colaterales; existe un botón de recarga al lado del
nombre de la expresión/variable. Para las variables no hay diferencia. Solo es
posible enseñar una variable o expresión a la vez.

LiveWatch. Presenta la evolución de las variables escogidas en tiempo real; solo si


las variables son estáticas o globales (o expresiones que incluyan este tipo de
variables). Esta función no está disponible en la versión IAR del MSP430.

Locals. Muestra automáticamente las variables empleadas en el ámbito local de una


función o interrupción. Sustituye, en tu proyecto, el fichero Ejemplo2.c por
Ejemplo2mod.c, añade el fichero Ejemplo2aux.c y compila y ejecuta la aplicación.

// UNIVERSIDAD DE MALAGA DPTO. TECNOLOGIA ELECTRONICA


// *****************************************************************************
// PROGRAMA : Ejemplo2mod.c (v2.0)
// TARGET : Placa MSP-TS430PM64 (v1.0) - Microcontrolador MSP430F169
// DESCRIPCION : Versión modificada de Ejemplo2. Utiliza una función definida
// en Ejemplo2aux.c
// AUTOR : I Herrero Reder y JM Cano
// FECHA : 04-10-11
// ESQUEMA : Placa de desarrollo MSP-EXP430F5438
//******************************************************************************
#include "msp430x54x.h"
#include <stdbool.h> // Necesario para poder usar los tipos bool

char vblchar;

void compruebaP2();
void foo();
void intermitente();

19
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Detiene el watchdog
unsigned int vbllocalnoutil=0;
vblchar='A';
vbllocalnoutil=3;
P1DIR |= 0x01; // Establece dirección bit 0 de puerto 1
P2REN = 0xFF; // Activa resistencias de pullup asociadas
P2OUT = 0xFF; // a los pines del puerto 2
while (1)
{
compruebaP2();
foo();
}
}

// *****************************************************************************
// UNIVERSIDAD DE MALAGA DPTO. TECNOLOGIA ELECTRONICA
// *****************************************************************************
// PROGRAMA : Ejemplo2aux.c (v1.0)
// TARGET : Placa MSP-TS430PM64 (v1.0) - Microcontrolador MSP430F169
// DESCRIPCION : Define una variable y una función que serán usada por el
// : fichero Ejemplo2.c
// AUTOR : Ignacio Herrero Reder
// FECHA : 04-10-11
// ESQUEMA : Placa de desarrollo MSP-EXP430F5438
//******************************************************************************
#include "msp430x54x.h"
#include <stdbool.h>

// Variables globales EXTERNAS (compartidas con otros ficheros)

extern char vblchar;

void compruebaP2(){
char vblcharlocal2;
__no_operation();
vblcharlocal2=P2IN;
if (vblcharlocal2 == 0xFF) // Testea Puerto 2 (botones LCD y joystick
P1OUT = 0x00;
else
P1OUT = 0x01;
}

void foo(){
char vblcharlocal3;
vblcharlocal3=25;
vblchar=’B’;
}

void intermitente(){
unsigned int vblintlocal;
vblintlocal=20;
for(vblintlocal =50000; vblintlocal >0; vblintlocal --);
P1OUT ^= 0x01;
}

Ahora deberás añadir AMBOS ficheros a tu proyecto.

Compila y ejecuta la depuración. Abre la ventana Locals ¿Qué variable/s


aparece/n al inicio? Ejecuta paso a paso las 3-4 primeras instrucciones. ¿Por
qué aparece/n la/s variable/s local/es como “no disponible/s”?

Sal del modo de depuración (ver punto 5.5) y cambia la configuración del
proyecto (punto 2.3). La opción C/C++ Compiler – Optimizations está por
defecto a Low. Pasala a None. Vuelve a ejecutar los pasos del párrafo anterior.
¿Ha cambiado algo? ¿A qué crees que se debe este cambio?

20
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

8. Ámbito de variables. Variables globales y locales. Modificadores static, extern, y volatile.

8.1 Resetea el programa con [Debug – Reset]. Ejecuta Paso a Paso pero esta vez con la opción:
[Debug – Step Into] . Esta opción permite depurar las instrucciones dentro de las funciones
a las que se llama en el código, mientras que Step Over considera una llamada a una función
como una instrucción que se ejecuta en un único paso4. Cuando estés dentro de la función
compruebaP2().

¿Qué aparece ahora en la ventana Locals? ¿En qué lugar Location está definida la
variable? ¿Dónde crees que se almacenó la variable durante la ejecución de la
función?

8.2 En el fichero Ejemplo2aux.c, añade la palabra static al principio de la instrucción char


vblcharlocal2; y vuelve al modo depuración. Pon el cursor en la instrucción
__no_operation(); y clica la opción Paso a Paso [Debug – RuntoCursor] . El programa
se ejecutará de golpe hasta la instrucción marcada por el cursor.

En la ventana Locals, debe aparecer la variable vblcharlocal2 pero, ¿qué aparece


ahora en la columna Location? ¿Qué significa esto?

Pulsa un botón de la placa y ejecuta la instrucción vblcharlocal2=P2IN; observa el


valor tomado por la variable. Vuelve a colocar el cursor en __no_operation(); y a
ejecutar RuntoCursor. ¿Qué valor tiene la variable vblcharlocal2? Si quitas la
palabra static, ¿sigue pasando esto mismo? ¿por qué? PISTA: ejecuta paso a
paso de forma que te metas en la función foo(), y observa que pasa con la variable
definida allí.

Cambia el nivel de optimización del proyecto a High y ejecuta paso a paso todo el
programa con la opción de entrar dentro de las funciones (StepInto). ¿Observas algo
raro? ¿A qué crees que se debe? PISTA: si sabes algo de ensamblador, abre la
ventana Disassembly en la opción View, y observa el código ensamblador generado
a partir del código C. Cuando acabes, vuelve a colocar el nivel de optimización a
Low.

8.3 Ahora ejecuta el programa con RuntoCursor hasta la primera instrucción dentro de la función
foo() ¿Qué valor tiene la variable vblchar en este momento? ¿Se define dicho valor en
alguna parte del fichero Ejemplo2aux.c? ¿Dónde se define el valor entonces? ¿Qué valor
tiene vblchar cuando sales de la función foo() y regresas al código principal?

8.4 ¿Qué ocurre si quitas la palabra clave extern e intentas compilar de nuevo el código? Ahora
sustituye la palabra clave extern por static en la definición de vblchar en

4
Puedes salir de una función en un solo paso utilizando la opción Paso a Paso, Debug – Step
Out, sin importar las instrucciones que queden para finalizar la función.

21
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

Ejemplo2aux.c. Y añade otro static en la misma definición pero en el fichero


Ejemplo2mod.c.¿Qué vale vblchar cuando estamos dentro de las funciones
compruebaP2() y foo()? ¿Y cuando estamos en el programa principal? ¿Por qué crees que
pasa esto ahora?

8.5 Ahora asegúrate de que el nivel de optimización es Low. Sustituye, en el bucle while, las
llamadas a las funciones compruebaP2() y foo(), por una llamada a la función
intermitente(). Ejecuta el programa y observa qué hace. Dentro de dicha función, ¿en qué
momentos te aparece la variable vblintlocal con un valor en la ventana Locals? Se
ejecutan todas las instrucciones que tienen que ver con dicha variable? Sube ahora el nivel
de optimización a High Observa ahora la ejecución del programa. ¿Qué ocurre ahora con
dicha variable?

8.6 Manteniendo el nivel de optimización High, añade el modificador volatile a la definición de


vblintlocal, volatile unsigned int vblintlocal;. ¿Qué ocurre ahora con las
instrucciones que afectan a esta variable? ¿Qué utilidad podría tener volatile?5

9. Gestión de Memoria. Modelos de datos. Ventana de Memoria.

9.1 Para este apartado, partiremos del programa Ejemplo3.c:


// *****************************************************************************
// UNIVERSIDAD DE MALAGA DPTO. TECNOLOGIA ELECTRONICA
// *****************************************************************************
// PROGRAMA : Ejemplo3.c (v2.0)
// TARGET : Placa MSP-TS430PM64 (v1.0) - Microcontrolador MSP430F169
// DESCRIPCION : Gestión de memoria. Modelos de datos. __data16 y __data20.
// #pragma type attribute
// AUTOR : Ignacio Herrero Reder
// FECHA : 07-10-11
// ESQUEMA : Placa de desarrollo MSP-EXP430F5438
//******************************************************************************
#include "msp430x54x.h"

__data20 int i;
int __data20 j;
#pragma type_attribute= __data16
int k;

typedef char __data20 Byte;


typedef Byte* BytePtr;
Byte b;
BytePtr pB;

typedef char __data16 Byte16;


Byte16 b16;
int __data20 *p;
char __data16* __data20 p2;
char *p3;

struct MisManos{
int /* __data16 */ izquierda;
int /* __data20 */ derecha;
};

__data20 struct MisManos mano;

5
El ejemplo de uso de volatile es poco ilustrativo de su verdadera utilidad. Veremos más
ejemplos cuando introduzcamos las interrupciones.

22
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

void main(void)
{
i=23567;
j=32000;
k=-15467;

b=0xA3;
pB=&b;

p=&i;
b16=0x7c;
//p2=&b;
p2=&b16;

//p3=&b;
p3=&b16;

mano.izquierda=21;
mano.derecha=12;
}

Crea un nuevo proyecto, Ejemplo3.ewp, configúrale tal como vimos en los apartados
anteriores, poniendo la optimización a None, y añádele el fichero Ejemplo3.c. Trata de
compilar el programa ¿Qué ocurre? ¿Qué crees que significa el mensaje de la ventana
Build?

9.2 Vamos a cambiar la configuración del proyecto en lo relativo al Modelo de memoria empleado.
Abre la ventana de opciones del proyecto y, en la pestaña Target de General Options, cambia
la opción Data Model de Small a Medium. Intenta compilar de nuevo ahora.

Resulta interesante ver los cambios que se producen en la memoria real cuando modificamos
alguna variable (estática o global). Para ello, abre la ventana de memoria con [View -
Memory]. En la ventana de memoria, indica que quieres observar la variable i, escribiendo el
nombre en la ventana Goto. Observa como se recuadra en negro la zona de memoria
correspondiente a la variable. También puedes representar la memoria word a word (2x
Units), o doble-word a doble-word (4x Units), en formato Little Endian o Big Endian
escogiendo la opción en el menú desplegable.

23
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

Por último, no solo puedes ver la representación en memoria de una variable o dato definido
a través de una etiqueta; puedes ver cualquier zona de memoria indicando una dirección de
inicio en hexadecimal (0xZZZZ) en la ventana Goto. Se puede limitar el tipo de memoria a
observar (SFR, RAM, FLASH, INFO,…).También es posible salvar una zona de memoria,
restaurarla posteriormente, o llenar una zona de memoria con un valor determinado (Memory
Save, Restore, Fill).

¿Qué tamaño en memoria tienen las variables i,j,y k? ¿Es coherente con su tipo de
dato? ¿Para qué crees que pueden servir entonces las palabras clave __data16 y
__data20?

9.3 Descomenta la instrucción p2=&b; y trata de compilar. ¿Por qué esta instrucción falla pero
p2=&b16; no, siendo b y b16 variables tipo char? Pista: coméntala de nuevo, compila, y
visualiza en memoria las variables b y b16, y los punteros p y p2. ¿Has averiguado ya el uso
de __data16 y __data20?

9.4 Descomenta ahora solo la instrucción p3=&b; ¿Puedes compilar el programa? Cambia el
modelo de memoria a Large. ¿Puedes compilar ahora? ¿Qué conclusiones sacas? Pista:
visualiza en memoria el puntero p3 con modelo Medium y con modelo Large.¿A qué crees
que se debe que la instrucción p3=&b16 funcione correctamente con ambos modelos?

9.5 Dentro de la estructura MisManos descomenta la línea int /* __data16 */ izquierda; e


intenta compilar ¿Porqué crees que no funciona? ¿Funcionará si vuelves a comentar la línea
anterior y descomentas int /* __data20 */ derecha? ¿Y con otros modelos de datos?
Intenta razonar a que se debe esto. PISTA: puedes definir una segunda estructura mano2 de
tipo __data16.

24
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

Depuración avanzada: Puntos de Ruptura por cambios en Memoria

9.6. Al igual que podíamos detener el programa cuando se ejecutaba una determinada instrucción
(en unas determinadas condiciones), podemos hacer algo similar respecto a las situaciones
que afectan a la memoria de datos. Es posible establecer un punto de ruptura que salte
cuando se produzca un acceso a un rango de memoria; incluso es posible establecer que
dicho acceso tenga que ser de escritura, lectura, o ambos. Para ello, selecciona antes la con
el ratón las posiciones a vigilar, y a continuación la opción Set Range Breakpoint. Abre la
ventana de puntos de ruptura (ver punto 5). Observa que el punto de ruptura no empieza con
Code, si no con Range @ Memory. Seleccionando el punto de ruptura y botón derecho del
ratón, seleccionamos Edit.

Ventana de Memoria Simbólica

9.7 Otra forma de representar la memoria es mediante la Memoria Simbólica. Selecciónala como
una opción dentro del menú View. En este caso se representa dato a dato, indicando en dos
columnas la posición y el valor del dato correspondiente. Es posible representar esta
memoria con formato de datos byte, word, y doble word.

25
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

10. Secuencia de inicialización: cstartup.s43 y __low_level_init().

La programación en ensamblador permite un control más específico de los parámetros de


configuración de nuestra aplicación. En C, por motivos de compatibilidad, hay aspectos como los
relacionados con la inicialización del sistema que es indispensable realizar en ensamblador, a
través de instrucciones y directivas. En el IAR EW esto se consigue a través de la función
cstartup.s43. Es posible modificar algunas características de compilación del sistema mediante
símbolos de pre-procesamiento que se pasan al compilador pero, en general, suele ser mejor
opción dejar este fichero en su configuración por defecto y utilizar un segundo fichero llamado
LowInit.c que contiene una única función __low_level_init(). Es en esta función donde
debemos colocar todas las operaciones y cambios de configuración que deseemos en el sistema,
ya que se ejecutará justo antes de iniciar el programa main de nuestra aplicación:
/* - lowinit.c -

The function __low_level_init is called by the start-up code before doing


the normal initialization of data segments. If the return value is zero,
initialization is not performed.

In the run-time library there is a dummy __low_level_init, which does


nothing but return 1. This means that the start-up routine proceeds with
initialization of data segments.

To replace this dummy, compile a customized version (like the example


below) and link it with the rest of your code.

*/

/*
* $Revision: 4055 $
*/
#include "msp430x54x.h"
int __low_level_init(void)
{
WDTCTL = WDTPW + WDTHOLD;

/*==================================*/
/* Choose if segment initialization */
/* should be done or not. */
/* Return: 0 to omit seg_init */
/* 1 to run seg_init */
/*==================================*/
return (1);
}

26
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

10.1 Crea un nuevo proyecto con el fichero “Imagen.c” y añádele también el fichero “hal_lcd.c”.
Asegúrate que en el directorio de trabajo se encuentran también los ficheros “hal_lcd.h”,
“hal_lcd_fonts.h” y “LenaC.h”.
// *****************************************************************************
// PROGRAMA : Imagen.c (v1.0)
// TARGET : Placa de desarrollo MSP-EXP430F5438
// DESCRIPCION : Pinta una imagen (LenaC.h) en el LCD
// AUTOR : Ignacio Herrero Reder
// FECHA : 23/11/09
// ESQUEMA :
//CONFIGURACION:
// ****************************************************************************
#include "LenaC.h"
#include "hal_lcd.h"

#define CONTRASTE 85 // 70 < CONTRASTE <127. A mayor valor, mayor contraste

int main(void)
{
halLcdInit(); // Inicia LCD
halLcdBackLightInit(); // Enciende la luz trasera
halLcdClearScreen(); // Borra pantalla
halLcdSetBackLight(100); // y establece un nivel medio de brillo
halLcdSetContrast(CONTRASTE);
halLcdActive(); // Establece el modo activo (preparado para
// recibir instrucciones
halLcdImage(LenaC,16,110,0,0);
}

Compila el proyecto y trata de depurarlo/ejecutarlo. Coloca un punto de ruptura en la


instrucción halLcdImage y ejecútalo ¿llega el programa hasta dicha instrucción? Coloca
un punto de ruptura en la primera instrucción del programa (halLcdInit) ejecuta varios
pasos con Step Into, y cuando llegues a la instrucción __delay_cycles(0x47FF); dale a
ejecución continua (Go) ¿Dónde se detiene el programa?¿Ves esto normal? ¿A que crees
que se debe?

Añade ahora el fichero Lowinit.c al proyecto y vuelve a compilar y ejecuta el programa


¿Ejecuta el programa todas las instrucciones ahora? ¿A qué crees que se debe? PISTA:
Observa el código de __low_level_init().

27
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

11. Mapeo de memoria. Acceso a registros.

Es posible determinar la posición exacta de memoria en la que queremos que se defina una
variable, siempre y cuando dicha posición no esté ya asignada a otra variable. Observa el
siguiente programa, una modificación de Ejemplo1.c:
// *****************************************************************************
// UNIVERSIDAD DE MALAGA DPTO. TECNOLOGIA ELECTRONICA
// *****************************************************************************
// PROGRAMA : Ejemplo1Mod.c (v1.1)
// TARGET : Placa MSP-TS430PM64 (v1.0) - Microcontrolador MSP430F169
// DESCRIPCION : Apaga el LED1 P1.0) al apretar cualquier botón del LCD o
// joystick. Testeo por polling. Ejemplo de mapeo de registros
// AUTOR : Ignacio Herrero Reder
// FECHA : 10-10-11
// ESQUEMA : Placa de desarrollo MSP-EXP430F5438
//******************************************************************************
#include "msp430x54x.h"

#pragma location=0x1C40
no_init volatile char vbleMap;

#pragma location=0x201 // 0x201 es la dirección de memoria asignada al registro P2IN


no_init volatile char BOTONES;

#pragma location=0x202 // 0x202 es la dirección de memoria asignada al registro P1OUT


no_init volatile char LED;

//_no_init volatile char LED@ 0x202;

//#define LED *(volatile char *) (0x202);

void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Detiene el watchdog
P1DIR |= 0x01; // Establece dirección bit 0 de puerto 1
P2REN = 0xFF; // Activa resistencias de pullup asociadas
LED = 0xFF; // a los pines del puerto 2
vbleMap='A';
while (1)
{
if (BOTONES == 0xFF) // Testea Puerto 2 (botones LCD y joystick
LED = 0x01; // si alguno pulsado (bit a 0), enciende LED
else
LED = 0x00; // en caso contrario, lo apaga
}
}

11.1 Abre una ventana Watch, y observa allí las variables vbleMap, BOTONES y LED. Mira su
localización en memoria y su valor mientras ejecutamos el código. Comenta las instrucciones
#pragma location=0x202 y no_init volatile char LED; y descomenta alguna de las
comentadas, para ver que tienen el mismo efecto.

¿crees que tiene alguna ventaja o necesidad la elección de una posición específica de
memoria para vblMap? ¿Y para BOTONES y LED? ¿Para qué crees que pueden servir estas
directivas de mapeo en memoria?

28
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

12. Mezclando C y ensamblador. Paso de parámetros (Calling Convention).

12.1 A menudo resulta útil mezclar porciones de código en C con porciones de código en
ensamblador; por ejemplo para hacer uso de funciones de biblioteca a bajo nivel, o por
cuestiones de eficacia/rendimiento del código. Enlazar llamadas en entre programas C y
ensamblador en los que las funciones no necesitan parámetros resulta muy sencillo. A
continuación podemos ver un ejemplo:

// *****************************************************************************
// UNIVERSIDAD DE MALAGA DPTO. TECNOLOGIA ELECTRONICA
// *****************************************************************************
// PROGRAMA : Ejemplo5.c (v1.0)
// TARGET : Placa MSP-TS430PM64 (v1.0) - Microcontrolador MSP430F169
// DESCRIPCION : Apaga el LED1 P1.0) al apretar cualquier botón del LCD o
// joystick. Testeo por polling. Mezcla código C y ASM.
// AUTOR : Ignacio Herrero Reder
// FECHA : 10-10-11
// ESQUEMA : Placa de desarrollo MSP-EXP430F5438
//******************************************************************************
#include "msp430x54x.h"

/* Prototipos de funciones externas **/


extern void set_ports(void); /* Esta function estará en ensamblador */

void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Detiene el watchdog
set_ports();
while (1)
{
if (P2IN == 0xFF) // Testea Puerto 2 (botones LCD y joystick
P1OUT = 0x01; // si alguno pulsado (bit a 0), enciende LED
else
P1OUT = 0x00; // en caso contrario, lo apaga
}
}

// *****************************************************************************
// UNIVERSIDAD DE MALAGA DPTO. TECNOLOGIA ELECTRONICA
// *****************************************************************************
// PROGRAMA : Ejemplo5ASM.s43 (v1.0)
// TARGET : Placa MSP-TS430PM64 (v1.0) - Microcontrolador MSP430F169
// DESCRIPCION : Configura los puertos 1 y 2en ensamblador
// AUTOR : Ignacio Herrero Reder (basado en M Smertneck / W. Goh)
// FECHA : 10-10-11
// ESQUEMA : Placa de desarrollo MSP-EXP430F5438
//******************************************************************************
#include "msp430x54x.h"

NAME Ejemplo5ASM

RTMODEL "__core","430X" ; Asegura que el modelo de memoria es compatible con


; el indicado en código C

PUBLIC set_ports ; Indica que el símbolo será usado por otras funciones
RSEG CODE ; Codigo dinámico o relocalizable

set_ports;
BIS.B #BIT0,&P1DIR
MOV.B #0xFF,&P2REN
MOV.B #0xFF,&P2OUT
RETA

END

29
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

Crea un nuevo proyecto e incluye en el mismo los dos ficheros anteriores para probar su
funcionamiento. Observa que la configuración de los puertos se realiza en ensamblador (fichero
Ejemplo5ASM.s43).

12.2 Sin embargo, si es necesario pasarle parámetros a la función ensamblador la cosa se


complica, ya que hay que determinar dónde y de qué manera se le va a pasar la información
de parámetros. A las reglas que determinan estos aspectos se las denomina “convención de
llamadas” (Calling Convention) y son específicas del micro y del compilador/linkador
empleados para generar el código ejecutable. En este caso vamos a considerar las reglas
para el paso de parámetros de microcontroladores MSP430 en el entorno de desarrollo IAR
EW v2 (la v1 se mantiene por compatibilidad con versiones anteriores).

Entrada a funciones

12.3 Al igual que en el caso de las variables locales, los parámetros que se pasan a las funciones
se almacenan en registros y en la pila, utilizando preferentemente los primeros. En particular
se usan los registros R12 a R15 (Scratch registers) aunque también se pueden emplear los
R8 a R11 para valores de 64 bits. La pila se emplea cuando no tenemos suficientes registros
para los parámetros (por su número o tamaño); o para ciertos tipos especiales de
parámetros, como las estructuras o parámetros de tamaño variable (printf).

Además, los registros R4 a R11 (Preserved registers) deben ser salvados al inicio de la
propia función llamada si se desea utilizarlos dentro de esta, y recuperarlos al final de la
misma.

Salida desde funciones

12.4 Algunas funciones también necesitan devolver parámetros o resultados de sus operaciones;
en general es posible devolver parámetros tipo escalar (entero o puntero), flotante, y
estructuras. Dependiendo del tamaño del parámetro de vuelta se emplearán diferentes
registros: para menos de 32 bits se emplea R12; para 32 bits, R13:R12; y para 64 bits,
R15:R14:R13:R12. En el caso de las estructuras, se deberá asignar una zona de memoria en
pila para ellas; en el registro R12 se devolverá la dirección inicial de la zona de
almacenamiento de la estructura.

Visualización de Calling Convention: Código Esqueleto

12.5 Para facilitar la generación de código ensamblador según las reglas de Calling Convention,
resulta interesante generar un “código esqueleto” que nos permite visualizar como quedará el
almacenamiento de los parámetros y variables. Para ello hay que añadir una opción más a la
configuración del proyecto activando, en la opción C/C++ Compiler, pestaña List, la casilla
Output assembler file. De esta forma obtendremos ficheros “.s43” correspondientes al código
ensamblador de nuestros ficheros “.c”. Como estamos centrándonos en el estudio de la
Calling Convention, desmarcamos la opción Include call frame information.

30
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

Examinando este fichero podemos observar cosas interesantes, como lo que ocupa cada variable
y donde se sitúa; los registros/operaciones a pila para el paso de parámetros; los registros para la
recepción de parámetros de salida, etc…

Paso de parámetros de tipos “simples”

12.6 Crea un nuevo proyecto con los ficheros “add.c” y “addASM.s43”, en el que se genera el
“esqueleto” en ensamblador del programa en C (ver opción anterior).

// *****************************************************************************
// UNIVERSIDAD DE MALAGA DPTO. TECNOLOGIA ELECTRONICA
// *****************************************************************************
// PROGRAMA : add.c (v1.0)
// TARGET : Placa MSP-TS430PM64 (v1.0) - Microcontrolador MSP430F169
// DESCRIPCION : Realiza operaciones de suma de 2 valores mediante llamadas
// a funciones en C y ensamblador. Ilustra la "calling convention"
// AUTOR : Eva González (modificado por I. Herrero)
// FECHA : 10-10-11
// ESQUEMA : Placa de desarrollo MSP-EXP430F5438
//******************************************************************************
#include "msp430x54x.h"

//Suma parametro 1 (8bit) y parametro 2 (16bit); devuelve 16bit


int assembler_function1(char parametro1,int parametro2);

//Suma parametro 1(16bit), la palabra baja de parametro 2(16bit) y la palabra


//alta de parametro2(16bit); devuelve 16bit
int assembler_function2(int parametro1,long int parametro2);

//Suma parametro 1 (16bit) y parámetro 2 (32bit); devuelve 32bit.


long int c_function(int parametro1,long int parametro2)
{
return parametro1+parametro2;
}

volatile int prueba1, prueba3;


volatile long int prueba2;

int main( void )


{

int i;
long int j;

31
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

// Stop watchdog timer to prevent time out reset


WDTCTL = WDTPW + WDTHOLD;

prueba2=c_function(4,32760);

i=0;
j=0x7FFFE;

while(1)
{
prueba2=c_function(4,j);
prueba3=assembler_function2(4,j);
prueba1=assembler_function1(4,i);
i++;
j++;
}

return 0;
}

// *****************************************************************************
// UNIVERSIDAD DE MALAGA DPTO. TECNOLOGIA ELECTRONICA
// *****************************************************************************
// PROGRAMA : AddASM.s43 (v1.0)
// TARGET : Placa MSP-TS430PM64 (v1.0) - Microcontrolador MSP430F169
// DESCRIPCION : Funciones de suma de dos valores en ensamblador.
// AUTOR : Eva Gonzalez (modificado por I Herrero)
// FECHA : 10-10-11
// ESQUEMA : Placa de desarrollo MSP-EXP430F5438
//******************************************************************************

NAME AddASM

RTMODEL "__core","430X" ; Asegura que el modelo de memoria es compatible


; con el indicado en código C

PUBLIC assembler_function1
PUBLIC assembler_function2

RSEG CODE:CODE:REORDER:NOROOT(1)

assembler_function1:
// MOV.t1 Rw, Rx ; (1)
// ADD.t2 Ry, Rz ; (2)
RETA

assembler_function2:
// ADD.t3 Ra, Rb ; (3)
// inst?.t4 Rc, Rd ; (4)

// Descomentar para introducir efecto lateral indeseable:


//ADD.W R14,R10 ; (5)

// Descomentar para utilizar R10 sin efecto lateral:


//PUSHX.A R10 ; (6)
//ADD.W R14,R10 ; (7)
//POPX.A R10 ; (8)

RETA

END

Compila el fichero “add.c” y abre el fichero “add.s43”. Busca las llamadas a las funciones en C y
ensamblador “CALLA #nombre”. Examina las instrucciones anteriores y deduce cuales son los
registros empleados para el paso de parámetros y recepción del resultado de la función.

32
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

Descomenta las instrucciones marcadas con (1), (2), (3), y (4) y pon los valores
adecuados a los registros, tamaños y tipos de la operación para realizar correctamente las
operaciones de suma. ¿Qué registros hay que poner?

Descomenta la instrucción (5) y observa que ocurre ¿Es el resultado de las operaciones
correcto?

Vuelve a comentar la instrucción (5) y descomenta las instrucciones (6), (7), y (8). ¿Vuelve
a funcionar todo correctamente? ¿Por qué? ¿Para que sirven las instrucciones
descomentadas?

Crea una función assembler_function3, que devuelva el resultado de 3 números tipo


int, hacia una variable tipo long int. Indica donde se almacenan los parámetros de
entrada y salida en la ejecución de la función.

Paso de parámetros de tipo estructura. Visualización en pila.

12.7 Crea un nuevo proyecto con el fichero “unión.c” y compílalo. Recuerda marcar la opción para
generar el “esqueleto” en ensamblador del fichero.
// *****************************************************************************
// UNIVERSIDAD DE MALAGA DPTO. TECNOLOGIA ELECTRONICA
// *****************************************************************************
// PROGRAMA : union.c (v1.0)
// TARGET : Placa MSP-TS430PM64 (v1.0) - Microcontrolador MSP430F169
// DESCRIPCION : Ejemplo de uso de la Calling Convention.
// AUTOR : Eva Gonzalez (modificado por I Herrero)
// FECHA : 10-10-11
// ESQUEMA : Placa de desarrollo MSP-EXP430F5438
//******************************************************************************
#include <msp430x54x.h>
#include <stdio.h>

typedef struct {
unsigned char campo1 :1;
unsigned char campo2 :2;
unsigned char campo3 :3;
unsigned char campo4 :1;
} paquete;

typedef struct {
unsigned char campo1;
unsigned char campo3;
unsigned int campo2;
} paquete2;

typedef union
{
unsigned char byte;
paquete packet;
} ejemplo;

volatile ejemplo i;
volatile unsigned char b;
volatile paquete2 t;

void main(void)
{
WDTCTL = WDTPW+WDTHOLD; // Stop WDT
P5DIR |= 0x02; // P5.1 output

b=0;
i.byte=b;
t.campo1=3;
t.campo2=7;
t.campo3=9;

33
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

while(b<10)
{
b++;
i.byte=b;
printf("%i ",i.packet.campo2);
}
i.packet.campo2= 0x3;
}

A través de este programa estudiaremos como se realiza el paso de parámetros y devolución de


resultados cuando se trabaja con estructuras más complejas.

Observa, en el código “esqueleto” generado (unión.s43), la zona donde se definen las


variables del programa b, t, e i. Fíjate en el espacio de memoria asignado a cada
una, y razona porqué se le ha asignado ese espacio.

Entra en modo depuración y observa, en una ventana Watch, las variables utilizadas
en el programa (Recuerda que puedes desplegar los campos de las estructuras
pulsando en el signo + a la izquierda de cada nombre) ¿qué posición de memoria
ocupa cada variable y campo de las mismas?

Añade un nuevo campo campo5 a la estructura paquete, que tenga 6 bits. ¿Qué
posiciones de memoria ocupan ahora la variable i y sus campos?

Paso de parámetros de tipo estructura. Visualización en pila.

12.8 Vuelve a cargar el proyecto del punto 12.6. Vamos a modificar a añadir una nueva función
que realice la suma de 2 números complejos en ensamblador. Para ello, primero crearemos
una estructura complex de la forma:
typedef struct {
int real;
int imagin;
} complex;

Crea una función en ensamblador, asm_add_complex, que devuelva un número complejo con
valor igual a la suma de dos números complejos que se le pasen como parámetros. Para ello
define primero la llamada a la estructura en C; compila el código para obtener el código
“esqueleto” y observa allí como se pasan los parámetros previamente a la llamada y donde se
reciben a la vuelta.

34
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

12.9 Para visualizar los parámetros en pila debemos abrir una ventana [View – Stack – Stack16].

En la ventana Stack aparece en la parte superior, en verde, el tope de la pila, o posición más alta
ocupada. En cada fila observamos la posición de memoria ocupada; el dato en dicha posición; la
variable a la que representa (si procede); y el marco de llamada a la función en el que se han
almacenado los datos.

Implementa la función en C, genera un nuevo “esqueleto” en ensamblador, y


compárala con tu implementación.

Llamadas recursivas. Pila de llamadas (Call Stack)

12.10 La ventana Call Stack resulta muy útil para seguir la traza de las llamadas a funciones y
subrutinas, especialmente si están anidadas. En estas llamadas la información del marco de
llamadas se guarda en la misma pila en la que se pasan los parámetros7; pero resulta mucho
más sencillo visualizar el flujo de llamadas en esta ventana, en vez de en la ventana Stack.

12.11 Crea un nuevo proyecto y añádele el siguiente fichero de código:


// *****************************************************************************
// UNIVERSIDAD DE MALAGA DPTO. TECNOLOGIA ELECTRONICA
// *****************************************************************************
// PROGRAMA : factorial.c (v1.0)
// TARGET : Placa MSP-TS430PM64 (v1.0) - Microcontrolador MSP430F169
// DESCRIPCION : Ejemplo de recursividad.
// AUTOR : I Herrero Reder
// FECHA : 10-10-11
// ESQUEMA : Placa de desarrollo MSP-EXP430F5438
//******************************************************************************
#include <msp430x54x.h>
#include <stdio.h>

typedef struct{
unsigned int n;
}n_fact;

n_fact factorial(n_fact nf){

6
En realidad se puede usar cualquiera de las 2 ventanas, Stack1 o Stack2.
7
En sistemas monotarea al menos.

35
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014

n_fact result;
n_fact nfsig;
result.n=1;
if (nf.n>1){
nfsig.n=nf.n-1;
result=factorial(nfsig);
}
result.n=result.n*nf.n;
return result;
}

void main(void)
{
n_fact numero, resultado;
numero.n=8;
if (numero.n>8)
printf("El número excede el valor máximo a representar\n");
else
resultado=factorial(numero);
printf("El factorial de %d es %d\n",numero.n,resultado.n);
}

12.12 Ejecútalo paso a paso (Debug Into) abriendo una ventana Stack y otra Call Stack. Observa
ambas ventanas a medida que se van realizando las llamadas anidadas.

¿Qué cantidad de memoria se reserva en pila en cada llamada recursiva? ¿Para qué
se utiliza esa memoria?

¿Qué registros auxiliares se emplean en las llamadas recursivas? Nota: abre una
ventana Disassembly para contestar esta pregunta.

36

Вам также может понравиться