Download Dudas frecuentes - Universidad Politécnica de Madrid
Document related concepts
no text concepts found
Transcript
Departamento de Ingeniería Electrónica E.T.S.I. de Telecomunicación Universidad Politécnica de Madrid Dudas y preguntas frecuentes del LSED Autores: Juan Manuel Montero Martínez Rubén San Segundo Hernández Ricardo de Córdoba Herralde Fernando Fernández Martínez Fecha última revisión: febrero-2009 Índice 1 Dudas y Preguntas Frecuentes............................................................................................................. 4 1.1 Configuración general................................................................................................................. 4 1.1.1 ¿Qué registros del MCF5272 es necesario configurar?............................................... 4 1.1.2 ¿Se debe trabajar en modo usuario o supervisor?....................................................... 4 1.2 Configuración del HW – Mapa de memoria .............................................................................. 4 1.2.1 ¿El vector de RESET se puede modificar?................................................................... 4 1.2.2 ¿En qué posiciones de memoria debe residir el programa?........................................ 4 1.2.3 Posición a la que apunta inicialmente el puntero de pila.............................................. 4 1.3 Problemas con la plataforma de desarrollo ENT2004CF......................................................... 5 1.3.1 El programa indica que no puede abrir el puerto COM1 al que está conectado la plataforma de desarrollo................................................................................................. 5 1.3.2 El programa tarda mucho en cargarse en la plataforma .............................................. 5 1.3.3 No aparece ningún error ni ningún warning pero el programa no funciona o no se genera el fichero .hcf....................................................................................................... 5 1.4 Estrategias / problemas de depuración ..................................................................................... 6 1.4.1 ¿Cómo se visualizan las salidas de la plataforma? ...................................................... 6 1.4.2 ¿Qué debo hacer cuando ejecuto el programa y falla?................................................ 6 1.4.3 ¿Se puede ejecutar una TRAP en modo de “ejecución paso a paso”? ...................... 6 1.4.4 ¿Cómo se puede ver el valor de una variable? ............................................................ 7 1.4.5 Se produce un Error de dirección .................................................................................. 7 1.4.6 Se produce un Error de bus ........................................................................................... 7 1.5 Problemas con la sintaxis / ensamblador .................................................................................. 7 1.5.1 Las etiquetas deben estar SIEMPRE en la misma línea que un instrucción .............. 7 1.5.2 Utilización de la etiqueta PPAL ...................................................................................... 8 1.5.3 Las instrucciones lógicas deben operar siempre en LONG......................................... 8 1.5.4 Las instrucciones deben ir en direcciones pares .......................................................... 8 1.5.5 ¿Cómo se carga una dirección en un registro de direcciones?................................... 8 1.5.6 ¡Cuidado con los tamaños de las variables!.................................................................. 8 1.5.7 ¿Se pueden usar etiquetas de más de 8 caracteres?.................................................. 9 1.5.8 El programa principal debe acabar con un bucle infinito .............................................. 9 1.5.9 ¿Para qué sirve la directiva END?................................................................................. 9 1.5.10 RTS al principio de la línea............................................................................................. 9 1.5.11 Paso de datos entre subrutinas ..................................................................................... 9 1.5.12 Puntos de comienzo y terminación en subrutinas ...................................................... 10 1.5.13 Terminación en subrutinas de atención a interrupciones ........................................... 10 1.6 Modos de direccionamiento ..................................................................................................... 10 1.6.1 ¿Qué modo de direccionamiento hay que utilizar para el acceso a un búfer o array?............................................................................................................................. 10 1.6.2 Un modo de direccionamiento inexistente .................................................................. 10 1.6.3 Otro modo de direccionamiento inexistente ................................................................ 10 1.7 Gestión de las interrupciones................................................................................................... 11 2 1.7.1 ¿Cuándo se habilitan las interrupciones? ................................................................... 11 1.7.2 ¿Cómo se habilitan e inhabilitan las interrupciones? ................................................. 11 1.7.3 Inicialización del vector de interrupciones ................................................................... 11 1.7.4 Al habilitar las interrupciones el sistema deja de funcionar........................................ 11 1.7.5 ¿En qué consiste la TRAP 15?.................................................................................... 12 1.7.6 Cuando se produce una interrupción, ¿se puede producir otra antes de ejecutarse la instrucción RTE? .................................................................................... 12 1.8 Problemas con las Entradas/Salidas digitales ........................................................................ 12 1.8.1 Cuando leo los registros de datos de los puertos los valores no tienen sentido ...... 12 1.8.2 Problemas al usar BSET, BCLR o BCHG................................................................... 12 1.8.3 Al escribir en el puerto de salida, aparece el dato duplicado en el byte alto y en el byte bajo........................................................................................................................ 12 1.9 Recomendaciones generales .................................................................................................. 12 1.9.1 Básese en la documentación para escribir el código ................................................. 12 1.10 Programación en C................................................................................................................... 13 1.10.1 Manejo de bits............................................................................................................... 13 1.10.2 Funciones de librería como strlen, memcpy, memset................................................ 13 1.10.3 Declaración e inicialización de un array dentro de una función ................................. 13 1.10.4 Optimización del código ............................................................................................... 13 3 1 Dudas y Preguntas Frecuentes Las dudas y problemas que aquí se comentan provienen de las que tuvieron alumnos del LSED (Laboratorio de Sistemas Electrónicos Digitales) de la ETSITelecomunicación de la Universidad Politécnica de Madrid en promociones anteriores. Agrupándolas aquí, se pretende facilitar al lector el desarrollo de la Práctica. Estas dudas y preguntas frecuentes se organizan por secciones. A través del portal del LSED http://lsed.die.upm.es/, podrá encontrar siempre la versión más reciente de este anexo. 1.1 1.1.1 Configuración general ¿Qué registros del MCF5272 es necesario configurar? Cada vez que se produce un RESET en la plataforma, se ejecuta el programa monitor DBUG que está en la ROM. Dicho programa configura el sistema en general (MBAR, VBR, chip-selects...) e inhabilita las interrupciones. Al programa que se desarrolle sólo le queda configurar el registro de pila A7 y los registros de aquellos dispositivos internos que se vayan a emplear (TMR0...) y habilitar las interrupciones en ICRx y SR. 1.1.2 ¿Se debe trabajar en modo usuario o supervisor? Trabajaremos siempre en modo supervisor, que es el modo en el que queda el microprocesador tras un RESET. 1.2 1.2.1 Configuración del HW – Mapa de memoria ¿El vector de RESET se puede modificar? Escribir sobre las direcciones de memoria $0 y $4 no tiene ningún efecto (en ellas se almacenan los valores de A7 y PC que se cargan cuando se produce un RESET). La razón es que estas direcciones se encuentran en ROM, de modo que tras un RESET quien toma el control es el programa DBUG (también en ROM). 1.2.2 ¿En qué posiciones de memoria debe residir el programa? Dado el mapa de memoria se incluirá en la cabecera del programa en ensamblador una directiva ORG que coloque el programa en una dirección de memoria superior o igual a $20000. 1.2.3 Posición a la que apunta inicialmente el puntero de pila El puntero de pila apunta, por defecto, a $01000000. Esta dirección debe modificarse para no interferir con la pila del monitor DBUG. Recomendamos que se haga que el puntero de pila apunte inicialmente a la posición $30000, por ejemplo, salvo que el código o los datos sean tan granes que necesiten más de 64 KB, en cuyo caso la pila puede situarse en $100000 o incluso en direcciones más altas de la RAM de usuario. 4 1.3 Problemas con la plataforma de desarrollo ENT2004CF 1.3.1 El programa indica que no puede abrir el puerto COM1 al que está conectado la plataforma de desarrollo Se produce este error porque hay otro programa EdColdFire ejecutándose en segundo plano (probablemente “colgado”, por lo que no aparece en la pantalla). Es necesario cerrar dicho EdColdFire, para lo cual hay que pulsar Control+Alt+Supr (ejecución del Administrador de tareas) y finalizar el proceso EdColdFire que estará todavía ejecutándose. 1.3.2 El programa tarda mucho en cargarse en la plataforma Se produce este problema porque en nuestro programa hemos incluido un código del tipo: VARIABLE DS.L Al no indicar el tamaño de la variable el programa reserva casi 2 Mb de memoria y el fichero *.hcf que se genera es de casi 2 Mb. Al intentar cargar este fichero tarda mucho. 1.3.3 No aparece ningún error ni ningún warning pero el programa no funciona o no se genera el fichero .hcf Nunca se debe abrir haciendo doble clic en un archivo de extensión .C o .ASM. Se debe usar el icono creado en el escritorio durante su instalación. Ensamblador incorrecto (no se ha generado el fichero .hcf) 5 Ensamblado correcto 1.4 1.4.1 Estrategias / problemas de depuración ¿Cómo se visualizan las salidas de la plataforma? Necesitará usar un osciloscopio y una sonda. Consulte el How-To de instrumentación Disponible a través del portal del LSED http://lorien.die.upm.es/lsed/. La sonda se la proporcionará un monitor de laboratorio al que deberá entregar un carné de identidad o carné de la escuela. No introduzca el activo de la sonda del osciloscopio en las salidas hembra DB25 de la plataforma (si lo hace, dañará la punta de la sonda). Deberá introducir un extremo de un cable y medir con la sonda en el otro extremo. 1.4.2 ¿Qué debo hacer cuando ejecuto el programa y falla? Cuando el sistema se quede en una situación inestable: 1.4.3 • Analice los contenidos de los registros e intente averiguar por qué ha fallado. • Pulse el botón de RESET de la plataforma ya que éste puede haber alcanzado una situación inestable. • Vuelva a cargar el programa en la plataforma. ¿Se puede ejecutar una TRAP en modo de “ejecución paso a paso”? Sí, pero se ejecuta la rutina de atención a la TRAP completamente (no instrucción a instrucción) y se para en la siguiente instrucción. 6 1.4.4 ¿Cómo se puede ver el valor de una variable? Durante la depuración, en la columna izquierda del listado del programa aparece la posición de memoria de cada variable o instrucción. Observe el valor de la dirección de memoria y visualícela. Para ello seleccione Menú memoria Visualizar Posición. 1.4.5 Se produce un Error de dirección No son habituales. En general, se encuentran en la línea donde se para el programa o en la inmediatamente anterior. La causa del error es un intento de ejecución de una instrucción en una posición impar de memoria, y se puede producir por los siguientes motivos: • Se salta a una instrucción que no esté en una posición par. • Se corrompe la pila (se han guardado y luego recuperado un número diferente de datos o hay un RTS que no está bien situado). En el fichero *.dep que genera el ensamblador se puede comprobar si alguna instrucción que haya quedado en posición impar. A continuación se muestra un ejemplo de código en el que se puede producir dicho desalineamiento: 00020000 00020000 01 ORG $20000 DC.B 1 BUCLE 00020001 60FE BRA BUCLE Donde la instrucción “bra bucle” está en la dirección $20001, que es impar. Para resolver este problemas debemos añadir una nueva variable de tamaño Byte. 1.4.6 Se produce un Error de bus Se producen por acceder a posiciones de memoria no válidas más allá de la máxima dirección de RAM permitida de acuerdo con el mapa de memoria. La causa suele ser: 1.5 1.5.1 • Tabla de vectores de interrupción no inicializada correctamente. • Emplear incorrectamente los modos de direccionamiento indirecto o indirecto con indexación o desplazamiento (por no haber dado valores correctos a los registros que intervienen en el cálculo de la dirección efectiva). • Emplear el modo directo cuando se debería emplear el inmediato (olvidarse la '#'). • Se ha corrompido la pila (se han guardado y luego recuperado un número diferente de datos) y hay un RTS que provoca el salto a una dirección inexistente. Problemas con la sintaxis / ensamblador Las etiquetas deben estar SIEMPRE en la misma línea que un instrucción Todas las etiquetas deben estar en la misma línea que una instrucción de código. En caso contrario, el programa ensambla bien pero al ejecutar falla cuando se quiere saltar a esa 7 etiqueta. El efecto que se produce es que el programa saca un mensaje “INSTRUCCIÓN NO VÁLIDA” y el contador de programa PC se pone a $00000000. 1.5.2 Utilización de la etiqueta PPAL La etiqueta PPAL es una palabra reservada del ensamblador y no se puede utilizar en ningún otro punto del programa, tampoco dentro de comentarios. 1.5.3 Las instrucciones lógicas deben operar siempre en LONG Las instrucciones lógicas, como AND, OR, etc, si no les pones la extensión .L, el ensamblador las interpreta como .W y genera código máquina de esta forma (fichero *.hcf). Cuando este código se carga en la plataforma ENT2004CF, el microcontrolador Cold Fire sigue interpretando dichas instrucciones como si tuvieran operandos de tipo LONG. Este error produce que durante la ejecución, el microcontrolador interprete parte de la instrucción siguiente (a la instrucción lógica) como parte de los datos asociados a la propia instrucción lógica. Así, puede darse el caso que al pasar a ejecutar la instrucción siguiente, intente ejecutar sólo parte de la instrucción produciendo un error de "Instrucción no válida" o incluso saltándosela. 1.5.4 Las instrucciones deben ir en direcciones pares Al final de la zona de variables se puede incluir una directiva que alinea (DS.W 0) ORG $20000 DC.B 1 DS.W 0 PPAL: MOVE.L #$10000,A7 Si no incluyese la directiva, la instrucción estaría en una dirección impar y provocaría un error de dirección al ejecutarse 1.5.5 ¿Cómo se carga una dirección en un registro de direcciones? Sea la variable DATO: DATO DS.B 1 Entonces: LEA DATO,A1 O bien (importante el símbolo #): MOVEA.L 1.5.6 #DATO,A1 ¡Cuidado con los tamaños de las variables! Si se define una variable como DC.B o DS.B, no se puede escribir en ella con un MOVE.W o MOVE.L (corrompería la memoria adyacente al byte reservado para la variable). Como norma general, se recomienda poner siempre el tamaño en las instrucciones para evitar casos como el anterior, es decir, utilizar siempre .B, .W y .L en las instrucciones de acuerdo con el tamaño de la variable referenciada. 8 1.5.7 ¿Se pueden usar etiquetas de más de 8 caracteres? Sí. Aunque coincidan los 8 primeros caracteres de 2 etiquetas, si se diferencian en algún carácter serán consideradas como distintas por el programa ensamblador. 1.5.8 El programa principal debe acabar con un bucle infinito Este bucle tendrá la forma BUCLE <...> BRA BUCLE Donde <...> representa bien un espacio vacío, bien un conjunto de instrucciones en ensamblador. 1.5.9 ¿Para qué sirve la directiva END? Marca el final del archivo fuente y la dirección de entrada al programa, pero no hace que termine la ejecución. Por ello, el programa principal debe terminar con un bucle infinito o en una llamada a la función a la función EXIT mediante la TRAP #15. 1.5.10 RTS al principio de la línea Si se coloca esta instrucción en la primera columna, al principio de la línea, será tratada como si fuese una etiqueta, no se producirá el retorno de subrutina, y a partir de ahí puede pasar cualquier cosa. Un ejemplo erróneo es: SUBRUT: RTS ... ... * ERROR: RTS será interpretada como una etiqueta en vez de una instrucción El ejemplo correcto sería: SUBRUT: FINSUBRUT: ... ... RTS 1.5.11 Paso de datos entre subrutinas La recomendación general es emplear variables para guardar y recuperar datos en una subrutina (nunca registros) y los registros emplearlos localmente (inicializarlos con el valor de una variable, usarlos y actualizar finalmente la variable si hemos modificado el registro). Un ejemplo es: CHARIN: FINCHARIN: CHAROUT: ... FINCHAROUT: ... MOVE.B #INCOD,D7 TRAP #SISTEMA MOVE.B D0,CARACTER * SE GUARDA LO LEÍDO EN LA VARIABLE CARÁCTER ... RTS MOVE.B CARACTER,D0 * CARACTER ES LA VARIABLE DE ENTRADA MOVE.B #OUT,D7 TRAP #SISTEMA ... RTS 9 1.5.12 Puntos de comienzo y terminación en subrutinas En general nuestra recomendación es que cada subrutina tenga un único punto de comienzo y un único punto de terminación, (donde en ambos se realizan los MOVEM correspondientes para guardar y recuperar el valor de los registros). Un ejemplo abstracto con varios saltos intermedios sería: SUBRUT: FINSUBRUT: ... BNE FINSUBRUT ... BRA FINSUBRUT ... RTS Las subrutinas que sean llamadas dentro de una rutina de atención a una interrupción, no deberían usar los MOVEM, porque esto ralentiza la ejecución. 1.5.13 Terminación en subrutinas de atención a interrupciones Debemos terminar la rutina de atención a una interrupción con RTE y no con RTS. Este error produce que la recuperación del contador de programa al salir de la interrupción no sea correcta, produciendo un error de “instrucción no válida”. 1.6 1.6.1 Modos de direccionamiento ¿Qué modo de direccionamiento hay que utilizar para el acceso a un búfer o array? Típicamente es el modo Indirecto, posiblemente con post-incremento. También se puede emplear el modo indirecto indexado, aunque es más lento a la hora de recorrer posiciones consecutivas del búfer. Este modo permite emplear escalado para acceder cómodamente a búferes con datos cuyo tamaño sea .W o .L (en vez de .B). 1.6.2 Un modo de direccionamiento inexistente En el MCF5272 no existe el modo de direccionamiento: (dirección_de_memoria) para acceder indirectamente a una posición de memoria. Al utilizarlo el programa no funciona: al emplear paréntesis en torno a una dirección de memoria, el ensamblador ignora los paréntesis porque no tienen un significado especial (como sí que lo tienen cuando se aplican a un registro de dirección para indicar el direccionamiento indirecto). Por lo tanto, es lo mismo escribir: MOVE.L D0,(DIRECCIÓN_DE_MEMORIA) Que escribir: MOVE.L D0,DIRECCIÓN_DE_MEMORIA Se trata en ambos casos de direccionamiento directo a memoria. 1.6.3 Otro modo de direccionamiento inexistente En el MCF5272 no existe el modo de direccionamiento: dirección_de_memoria ± Offset. Ejemplo: 10 PESCR DC.L ... MOVE.L PESCR-100,D0 Se pretende copiar el contenido de pEscr restándole previamente 100, pero lo que se copia realmente es el contenido de la dirección pEscr-100 (no se le resta 100 al contenido de pEscr sino a su dirección efectiva). Las operaciones aritméticas que se ponen en una instrucción afectan a las etiquetas, que son direcciones, no a los datos contenidos en esas direcciones. 1.7 1.7.1 Gestión de las interrupciones ¿Cuándo se habilitan las interrupciones? Las interrupciones se tienen que habilitar tras haber configurado todo el HW y el SW. 1.7.2 ¿Cómo se habilitan e inhabilitan las interrupciones? En modo supervisor, habilitaremos las interrupciones escribiendo en SR el valor $2000. Inhabilitaremos todas (excepto las no enmascarables) escribiendo en dicho registro el valor $2700. 1.7.3 Inicialización del vector de interrupciones Sea la rutina de atención a la interrupción que comienza en la posición de memoria etiquetada con INTERR: INTERR <...> RTE Entonces, podemos emplear tres métodos para inicializar el vector de interrupciones: LEA MOVE.L INTERR,A0 A0,$<XXX> o bien (es importante el símbolo #) MOVEA.L MOVE.L #INTERR,A0 A0,$<XXX> ORG DC.L $<XXX> INTERR o bien 1.7.4 Al habilitar las interrupciones el sistema deja de funcionar En general, se debe a una configuración incompleta o incorrecta de las mismas (consulte las preguntas referidas a la configuración del sistema). Sin embargo, hay muchas otras posibilidades. Por ejemplo, es muy importante que en la rutina de atención a la interrupción se guarden y se restauren todos los registros en modo .L. La razón es que la TRAP #15 usa muchos registros para sus operaciones internas, no sólo los que menciona el manual (el manual menciona qué registros se ven modificados al finalizar la TRAP, pero no comenta cuáles se modifican durante la ejecución, aunque al final recuperen el valor original). Y no hay que olvidar que las interrupciones hardware (un temporizador, por ejemplo) son más prioritarias, por lo que pueden interrumpen a la TRAP 15, utilizando valores intermedios de los registros. 11 1.7.5 ¿En qué consiste la TRAP 15? La TRAP #15 es una excepción SW: cuando se ejecuta la instrucción TRAP con el parámetro #15, se provoca esta excepción, que es atendida por el vector $BB. La rutina de atención a esta excepción está en ROM y sirve para comunicarse con el PC (escribir en la pantalla y leer el teclado). Las posibilidades que te ofrece en el laboratorio vienen descritas en el capítulo ¡Error! No se encuentra el origen de la referencia.. Esta excepción es menos prioritaria que las interrupciones HW, por lo cual su ejecución se puede ver interrumpida por las interrupciones periódicas temporizadas, por ejemplo. 1.7.6 Cuando se produce una interrupción, ¿se puede producir otra antes de ejecutarse la instrucción RTE? No del mismo nivel, salvo que se emplee el nivel 7 de prioridad de interrupciones (dado que es una interrupción no enmascarable). Siempre y cuando durante la ejecución de la rutina de atención no se cambie la máscara de interrupciones del SR (al entrar en la interrupción se pone a su nivel, lo que impide que entre otra interrupción del mismo nivel). 1.8 1.8.1 Problemas con las Entradas/Salidas digitales Cuando leo los registros de datos de los puertos los valores no tienen sentido Los registros de estos puertos son de sólo escritura (puerto de salida) o de sólo lectura (puerto de entrada). Por lo tanto, no se pueden leer empleando MOVE.W PUERTO_SALIDA,D0 o escribir usando MOVE.W D0,PUERTO_ENTRADA. 1.8.2 Problemas al usar BSET, BCLR o BCHG Los registros de estos puertos son de sólo escritura (puerto de salida) o de sólo lectura (puerto de entrada). Para acceder a los puertos no se puede usar ninguna de las instrucciones de manipulación de bits (BTST, BSET, BCLR o BCHG); aunque aparentemente son instrucciones que sólo manejan 1 bit, realmente leen (o escriben) un byte completo del puerto aunque sólo modifiquen el bit deseado. 1.8.3 Al escribir en el puerto de salida, aparece el dato duplicado en el byte alto y en el byte bajo Los puertos de entrada y salida son de 16 bits y hay que acceder a ellos en modo .W. Si se accede en modo .B, tanto el byte bajo como el alto reciben el mismo dato .B enviado y los LEDs del puerto se iluminan como si hubiésemos enviado datos a los 16 bits del puerto. 1.9 1.9.1 Recomendaciones generales Básese en la documentación para escribir el código Escriba el código inspirándose en la documentación (puede utilizar, por ejemplo, los materiales de apoyo a la asignatura teórica de Sistemas Electrónicos Digitales). Intente no tener que reinventar la rueda. 12 1.10 Programación en C 1.10.1 Manejo de bits Para el manejo de datos a nivel de bit debemos utilizar las funciones lógicas AND (&) y OR (|) con operandos en binario. 1.10.2 Funciones de librería como strlen, memcpy, memset En la librería m5272lib.c se observa la implementación de las funciones strlen, memcpy y memset que tradicionalmente se ofrecen en las librerías del compilador. En este entorno, este tipo de funciones no están disponibles y se deben implementar directamente tal y como vienen en la librería m5272lic.c. 1.10.3 Declaración e inicialización de un array dentro de una función Para declarar e inicializar un array dentro de una función en C debemos declararlo como estático (static). Un ejemplo sería: static char TECLAS[16]={“FEDCBA9876543210”}; En el caso de no poner static generará un error indicando que no encuentra la función memcpy. Una segunda solución sería implementar la función memcpy que realiza una copia de una zona de memoria en otra. 1.10.4 Optimización del código En las opciones de la construcción de un programa en C (Construir→Configurar Construcción ) se puede seleccionar el grado de optimización a la hora de generar el código ensamblador a partir del código en C. Si aumentamos el grado de optimización se consigue programas más rápidos pero este hecho tiene dos inconvenientes: • A la hora de depurar, es más complicado alinear el código C con el código en ensamblador generado. • Puede suprimir código que aparentemente no se útil, como podría ser un bucle de espera o retardo, sin tener en cuenta que hemos puesto ese bucle para esperar a que se produzcan varias interrupciones por ejemplo. 13