PIC12F509 Compensación del problema de la memoria del programa

0

Recientemente estuve experimentando con la protección de código en un PIC12F509 y noté que las direcciones de memoria del programa bajo 0x40 se dejaron legibles. Confirmé que esto era normal cuando miraba la hoja de datos.

Entonces, si un programa es pequeño y solo se extiende a 0x39, será completamente legible incluso si la protección del código está activada.

Así que decidí experimentar con compensar el inicio del código a 0x40 para que estuviera protegido con CP activado.

Estoy usando el ensamblador con MPLAB X, así que para hacer esto cambié el vector de reinicio en el código de 0x000 a 0x040. Luego hice clic derecho en el proyecto y seleccioné las propiedades del proyecto. En PICkit3, especificé manualmente 0x040 como inicio de la memoria del programa.

Los archivos del ensamblador se compilan correctamente sin errores y el programa comienza en 0x040 cuando el microcontrolador se lee con el CP apagado en MPLAB IPE. Pero el código no se ejecuta.

El código funciona bien cuando el vector de restablecimiento es 0x000 y el inicio de la memoria del programa para el PICkit3 se selecciona automáticamente en 0x000 en las propiedades del proyecto.

¿Hay algo que estoy olvidando aquí? No puedo entender por qué el código no se ejecuta.

Aquí está el código, hay dos archivos: el archivo principal y la subrutina de bucle de retardo:

;   Reaction Timer game.                                                *
;                                                                       *
;   Demonstrates use of Timer0 to time real-world events                *
;                                                                       *
;   User must attempt to press button within 200 ms of "start" LED      *
;   lighting.  If and only if successful, "success" LED is lit.         *
;                                                                       *
;       Starts with both LEDs unlit.                                    *
;       2 sec delay before lighting "start"                             *
;       Waits up to 1 sec for button press                              *
;       (only) on button press, lights "success"                        *
;       1 sec delay before repeating from start                         *
;                                                                       *

list        p=12F509   
#include    <p12F509.inc>

EXTERN  delay10       ; W x 10 ms delay


;***** CONFIGURATION
            ; int reset, no code protect, no watchdog, int RC clock
    __CONFIG    _MCLRE_OFF & _CP_OFF & _WDT_OFF & _IntRC_OSC


;***** VARIABLE DEFINITIONS
    UDATA
cnt_8ms res 1                   ; counter: increments every 8 ms


;***** RC CALIBRATION
RCCAL   CODE    0x3FF           ; processor reset vector
    res 1                   ; holds internal RC cal value, as a movlw k

;***** RESET VECTOR *****************************************************
RESET   CODE    0x040           ; effective reset vector
    movwf   OSCCAL          ; apply internal RC factory calibration 
    pagesel start
    goto    start           ; jump to main code

;***** Subroutine vectors
delay10r                         ; delay W x 10 ms
    pagesel delay10
    goto    delay10       


;***** MAIN PROGRAM *****************************************************
MAIN    CODE

;***** Initialisation
start
    ; configure port
    movlw   b'111001'       ; configure GP1 and GP2 (only) as outputs
    tris    GPIO
    ; configure timer
    movlw   b'11010100'     ; configure Timer0:
            ; --0-----          timer mode (T0CS = 0)
            ; ----0---          prescaler assigned to Timer0 (PSA = 0)
            ; -----100          prescale = 32 (PS = 100)            
    option                  ;   -> increment every 32 us

;***** Main loop
main_loop
    ; turn off both LEDs
    clrf    GPIO   

    ; delay 2 sec
    movlw   .200            ; 200 x 10 ms = 2 sec
    pagesel delay10r
    call    delay10r
    pagesel $           

    ; indicate start
    bsf     GPIO,2          ; turn on start LED     

    ; wait up to 1 sec for button press
    banksel cnt_8ms         ; clear timer (8 ms counter)
    clrf    cnt_8ms         ; repeat for 1 sec:
wait1s  clrf    TMR0            ;   clear Timer0        
w_tmr0                          ;   repeat for 8 ms:
    btfss   GPIO,3          ;     if button pressed (GP3 low)
    goto    wait1s_end      ;       finish delay loop immediately 
    movf    TMR0,w        
    xorlw   .250            ;   (250 ticks x 32 us/tick = 8 ms)
    btfss   STATUS,Z        
    goto    w_tmr0
    incf    cnt_8ms,f       ;   increment 8 ms counter
    movlw   .125            ; (125 x 8 ms = 1 sec) 
    xorwf   cnt_8ms,w
    btfss   STATUS,Z
    goto    wait1s
wait1s_end

    ; indicate success if elapsed time < 200 ms       
    movlw   .25             ; if time < 200 ms (25 x 8 ms)
    subwf   cnt_8ms,w
    btfss   STATUS,C
    bsf     GPIO,1          ;   turn on success LED

    ; delay 1 sec
    movlw   .100            ; 100 x 10 ms = 1 sec
    pagesel delay10r
    call    delay10r
    pagesel $        

    ; repeat forever
    goto    main_loop            
    END

Y la subrutina de retardo:

#include    <p12F509.inc>      

GLOBAL  delay10

;***** VARIABLE DEFINITIONS
UDATA
count   res 1
count2  res 1
count3  res 1

;Subroutine
CODE
delay10
banksel count3  ; Select proper bank for variables
movwf   count3  ; Move number Of 10ms loops 10ms * X from W to count3
dly movlw   .252
movwf   count
movlw   .13
movwf   count2
dly2    decfsz  count,f
goto    dly2
decfsz  count2,f
goto    dly2
decfsz  count3,f
goto    dly
retlw   0   ; Return from subroutine with 0 in W register
END

**** Actualización ****

Actualicé el vector de reinicio y creo que lo tengo funcionando correctamente.

;***** RESET VECTOR *****************************************************
RESET   CODE    0x000
goto    0x040
RESET2  CODE    0x040   ; apply internal RC factory calibration 
movwf   OSCCAL
pagesel start
goto    start           ; jump to main code
    
pregunta Krankshaft

1 respuesta

2

Ha colocado la opción de llamar al vector de reinicio en una ubicación diferente, pero al chip no le importa: su hardware todavía comienza a ejecutarse en 0 después de un reinicio. Por lo tanto, para implementar lo que desea, es mejor que tome la sugerencia de Krankshaft: ponga un salto en 0 al código que desea que esté protegido contra la lectura. Mayeb puede poner algunas subrutinas poco interesantes (como un retraso) entre 0 y 40.

    
respondido por el Wouter van Ooijen

Lea otras preguntas en las etiquetas