Академический Документы
Профессиональный Документы
Культура Документы
Inteligentes
V5.0
Universidad de Málaga
Técnicas de diseño de sistemas empotrados basados en microcontroladores. Microkernels.
ÍNDICE
INTRODUCCIÓN ......................................................................................................................................1
EVALUACIÓN .........................................................................................................................................2
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.
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
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 .
2
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014
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ú:
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
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:
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
FET Debugger – Download – Flash Erase - Erase main and Information memory
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
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.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.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.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
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.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.
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
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
}
}
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.
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.
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
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>
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;
}
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.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?
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
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?
__data20 int i;
int __data20 j;
#pragma type_attribute= __data16
int k;
struct MisManos{
int /* __data16 */ izquierda;
int /* __data20 */ derecha;
};
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?
24
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014
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.
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
*/
/*
* $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"
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);
}
27
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014
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;
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.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"
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
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).
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.
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.
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…
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"
int i;
long int j;
31
Introducción al IDE MSP430 IAR EW (v5.0) Curso 2013/2014
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
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)
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?
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;
}
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?
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.
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.
typedef struct{
unsigned int n;
}n_fact;
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