Diferencia entre revisiones de «Errores en Simulacion - Codewarrior 6.3»
Línea 2: | Línea 2: | ||
==Error de Valor Fuera de Rango== | ==Error de Valor Fuera de Rango== | ||
− | |||
− | |||
Revisión del 00:52 25 mar 2013
En el desarrollo de un programa, al momento de una depuración de un proyecto nos puede salir los siguientes mensajes de error:
Contenido
Error de Valor Fuera de Rango
Este error es muy común a la hora de realizar programas y ocurre cuando la definición de una subrutina o una etiqueta se realiza muy lejos al llamado de la misma. Generalmente se utiliza la instrucción BSR (aunque el problema se presenta en general para cualquier branch que se utilice: BCC, BCS, BEQ, BHCC, BHCS, BHI, BHS, BIH, BIL, BLO, BLS, BMC, BMI, BMS, BNE, BPL, BRA, BRN , BSR).
El error se debe a que el branch posee un offset relativo que indica cuanto se le puede sumar a la dirección actual para obtener la nueva dirección (PC -> PC + $0002 + rel). El ensamblador calcula un offset relativo de 8 bits, como este offset puede ser tanto positivo como negativo tendrá un rango que va desde -128 (salto hacia arriba en el código) hasta 127 (salto hacia abajo en el código), por lo tanto si una subrutina se define a más de 127 lineas por debajo al llamado a la misma, se presentara este error.
Soluciones
Se pueden establecer tres tipos de soluciones para este caso:
A. Si el código principal es muy largo, se debe definir las subrutinas justo después de las llamadas con BSR, una vez realizada cada una de estas realizamos un BRA al código principal
;***************************************************************************************************
; Codigo de Ejemplo *
;***************************************************************************************************
; Include derivative-specific definitions
INCLUDE 'derivative.inc'
;
; export symbols
ABSENTRY Configurar_SP_COP
;
; definicion de variables
ORG Z_RAMStart
Contador: DS.B 1
Num1: DS.B 1
Num2: DS.B 1
; code section
ORG ROMStart
Configurar_SP_COP:
LDHX #RAMEnd+1
TXS ; SP / $17FF
LDA #$42
STA SOPT1 ; Se guarda en SOPT1
; COPE = 0, COPT = 1, STOPE= 0
; 0, 0, RSTOPE= 0
; BKGDPE= 1 --- Habilita el backroung debug mode
; RSTPE = 0 --- Deshabilita el RESET
Configuracion_Previa:
BSR Configurar_GPIO
BSR Configurar_RTC
BRA main
; -------------------------------------------------------------------
Configurar_GPIO:
;Se configura los 6 bits inferiores de PTC y los 2 bits superiores de PTE como salida
;Corresponden a los leds de la tarjeta
LDA #$3F
STA PTCDD
LDA #$C0
STA PTEDD
LDA #$3F
STA PTCD
LDA #$C0
STA PTED
RTS
; ---------------------------------------------------------------------------
Configurar_RTC:
LDA #$04
STA SCGC2 ; Habilitamos el Clock Gate para el RTC
LDA #00
STA RTCMOD ; Definimos el valor del registro modulo del RTC
LDA #%00011000 ; Configuramos el RTCSC / Reloj configurado a 1ms. Fuente reloj interna 1khz.
; Interrupciones habilitadas (bit 4)
; RTIF=0, RTCLKS6=0 RTCLKS5=0
; RTIE=1, RTCPS3=1, RTCPS2=0
; RTCPS1=0, RTCPS0=0
STA RTCSC
RTS
main:
MOV #10, Contador
MOV #1, Num1
MOV #2, Num2
...
...
...
CLI
...
...
...
BRA *
;**************************************************************
;* RUTINAS DE INTERRUPCION *
;**************************************************************
;Limpiamos las banderas de interrupcion. Se escribe un 1 en la bandera RTIF
LDA RTCSC
ORA #%10000000
STA RTCSC
...
...
...
RTI
;**************************************************************
;* INTERRUPT VECTORS *
;**************************************************************
ORG $FFFE
DC.W Configurar_SP_COP ; Reset
ORG $FFCE
DC.W Interrupcion_RTC
B. Por cuestiones de estética del código muchos programadores no podrían elegir la primera solución, como alternativa de ello se puede establecer la siguiente configuración, el cual consiste en sustituir los BSR por etiquetas
Configurar_SP_COP:
LDHX #RAMEnd+1
TXS ; SP / $17FF
LDA #$42
STA SOPT1 ; Se guarda en SOPT1
; COPE = 0, COPT = 1, STOPE= 0
; 0, 0, RSTOPE= 0
; BKGDPE= 1 --- Habilita el backroung debug mode
; RSTPE = 0 --- Deshabilita el RESET
; -------------------------------------------------------------------
Configurar_GPIO:
;Se configura los 6 bits inferiores de PTC y los 2 bits superiores de PTE como salida
;Corresponden a los leds de la tarjeta
LDA #$3F
STA PTCDD
LDA #$C0
STA PTEDD
LDA #$3F
STA PTCD
LDA #$C0
STA PTED
; ---------------------------------------------------------------------------
Configurar_RTC:
LDA #$04
STA SCGC2 ; Habilitamos el Clock Gate para el RTC
LDA #00
STA RTCMOD ; Definimos el valor del registro modulo del RTC
LDA #%00011000 ; Configuramos el RTCSC / Reloj configurado a 1ms. Fuente reloj interna 1khz.
; Interrupciones habilitadas (bit 4)
; RTIF=0, RTCLKS6=0 RTCLKS5=0
; RTIE=1, RTCPS3=1, RTCPS2=0
; RTCPS1=0, RTCPS0=0
STA RTCSC
main:
MOV #10, Contador
MOV #1, Num1
MOV #2, Num2
...
...
...
CLI
...
...
...
BRA *
C. En vez de aplicar BRS, se puede manejar el comando JSR (Jump Subrutine)eliminado por completo este error, ya que esta última instrucción no presenta limitaciones en cuanto al salto:
Configurar_SP_COP:
LDHX #RAMEnd+1
TXS ; SP / $17FF
LDA #$42
STA SOPT1 ; Se guarda en SOPT1
; COPE = 0, COPT = 1, STOPE= 0
; 0, 0, RSTOPE= 0
; BKGDPE= 1 --- Habilita el backroung debug mode
; RSTPE = 0 --- Deshabilita el RESET
Configuracion_Previa:
JSR Configurar_GPIO
JSR Configurar_RTC
main:
MOV #10, Contador
MOV #1, Num1
MOV #2, Num2
...
...
...
CLI
...
...
...
BRA *
; -------------------------------------------------------------------
Configurar_GPIO:
;Se configura los 6 bits inferiores de PTC y los 2 bits superiores de PTE como salida
;Corresponden a los leds de la tarjeta
LDA #$3F
STA PTCDD
LDA #$C0
STA PTEDD
LDA #$3F
STA PTCD
LDA #$C0
STA PTED
RTS
; ---------------------------------------------------------------------------
Configurar_RTC:
LDA #$04
STA SCGC2 ; Habilitamos el Clock Gate para el RTC
LDA #00
STA RTCMOD ; Definimos el valor del registro modulo del RTC
LDA #%00011000 ; Configuramos el RTCSC / Reloj configurado a 1ms. Fuente reloj interna 1khz.
; Interrupciones habilitadas (bit 4)
; RTIF=0, RTCLKS6=0 RTCLKS5=0
; RTIE=1, RTCPS3=1, RTCPS2=0
; RTCPS1=0, RTCPS0=0
STA RTCSC
RTS
Si el problema no es con el BSR, sino con algún otro branch, una forma de solucionar el problema (aunque no es la más eficiente) es hacer que el branch salte a una etiqueta y en esta etiqueta se hace un JMP (jump) que salte a la dirección deseada.
Supongamos que se quieren encender los leds de PTCD si estos se encuentran apagados, sin embargo la rutina Encender_Leds se encuentra muy lejos, entonces:
LDA #$FF
CMP PTCD
BEQ jump
jump: JMP Encender_Leds
Pantalla en blanco en el True-Time Simulator & Real-Timer Debugger
AL momento de realizar cualquier programa debemos tomar en cuenta el manejo de los vectores de interrupción (Ver Interrupciones.), ya que los mismo permiten al momento de realizar el Debugger establecer todos los parámetros del micro se posicionen en la memoria.
Cabe destacar que si compilamos el programa en la opción Full Chip Simulation el mismo realizará la compilación, pero si por ejemplo no se ha definido el vector de interrupción para el reset (Vreset), al momento de realizar un Reset Target en el True-Time Simulator & Real-Timer Debugger el programa no va entrar a dicha a rutina. Ahora si realizamos la depuración en la opción P&E Multilink/ Cyclone Pro aparecerá la pantalla en blanco.
Solución
Para eliminar la pantalla en blanco solo hace falta definir correctamente los vectores de interrupción. Entre los vectores de interrupción mas usados tenemos
;**************************************************************
;* Interrupt Vectors *
;**************************************************************
ORG $FFCE
DC.W Vrtc ; Interrupcion del RTC
ORG $FFFA
DC.W Virq ; Interrupcion del IRQ
ORG $FFCE
DC.W Vreset ; Reset del programa
Para mas información sobre la direccion de origen de los vectores de interrupcion revisar la pagina 54 del reference manual.
Error de Valor Truncado a 1 Byte
Este error generalmente aparece al compilar cuando en el código se está utilizando una instrucción cuyo modo de direccionamiento no se puede aplicar sobre el operando utilizado, por ejemplo se está trabajando con una instrucción cuyo modo de direccionamiento es directo y un operando fuera de PPAGE 0.
Se sabe que el modo de direccionamiento directo solo funciona para posiciones de memoria entre $0000 y $17FF, (revisar página 51 del reference manual). Un registro u operando en general que se utilice y esté definido fuera de esos rangos de memoria no podrá ser accedido mediante el modo de direccinamiento directo. Un error muy común es colocar:
BSET RTCSC_RTIE, RTCSC
Sin embargo el modo de direccionamiento de BSET es directo y el registro RTCSC se encuentra en la posición de memoria $1830 donde ya no funciona esta instrucción.
Existen otras razones por las cuales Codewarrior muestra este error:
- Este error se presenta si se trata de cargar al acumulador o a algún registro un valor superior a 255 ($FF). Esto sucede ya que tanto el acumulador como los registros del MC9S08QE128 son de 8 bits, por lo que el máximo número que se puede cargar en ellos es $FF.
- Hay ocasiones en las cuales este error se presenta cuando se define una variable (con DS.B) en el origen de la RAM, en lugar de hacerlo en Z_RAMStart. El problema se corrige cambiando:
ORG RAMStart
por:
ORG Z_RAMStart
en la sección de variables del código.
Error de Definición de Macro Esperada
Este error de directiva, se presenta cuando el compilador espera la definición de una macro, esto sucede cuando no se deja un espacio (o sangría) antes de escribir la instrucción. Las únicas veces que no se deja sangría antes de escribir una instrucción es cuando se definen variables o se realizan macros. Este error se puede corregir fácilmente colocando unos espacios (o tab) antes de escribir la instrucción.
Si se tiene:
LDA #$00
STA PTCD
El programa dara error. En cambio este funcionara si se coloca:
LDA #$00
STA PTCD
Referencia
- Freescale CodeWarrior 6.3 (CodeWarrior Help System)