|
From: Al W. <al....@aw...> - 2010-09-18 04:41:28
|
Thanks to some help from people on the list, I have what seems to be a pretty
interesting "rescue" mode that can recover from corrupt EEPROM as long as the
basic flash portion and the bootloader flash are intact.
My development boards all have a MAX232 or a USB dongle attached so I assume
that the RX pin will be high when we start up at least some of the time. If I
isolate the RX pin and ground it on restart, I reload a pure copy of the
EEPROM stuff that is built into the high part of flash.
This is on the 4.1 trunk
Here's inside my main file:
;; enable Rescue mode
;; These settings use the RS232 in port
.equ RESCUE_PIN = PIND
.equ RESCUE_PIN_NUM = 0
.equ RESCUE_PIN_SENSE = 0
;; .equ RESCUE_PULLUP = 1
###
Next, are changes in amforth.asm:
; allocate space for User Area
.set here = here + SYSUSERSIZE + APPUSERSIZE
; NEW CODE HERE
.ifdef RESCUE_PULLUP
.if RESCUE_PULLUP
sbi RESCUE_PIN+1,RESCUE_PIN_NUM
.endif
.endif
.ifdef RESCUE_PIN
clr temp1 ; 256 cycles of rescue sense or no rescue
rescue_check:
.ifndef RESCUE_PIN_SENSE
.equ RESCUE_PIN_SENSE = 0
.endif
.if RESCUE_PIN_SENSE == 0
sbic RESCUE_PIN,RESCUE_PIN_NUM
.else
sbis RESCUE_PIN,RESCUE_PIN_NUM
.endif
rjmp rescue_no
dec temp1
brne rescue_check
ldi XL, low(PFA_RESCUE)
ldi XH, high(PFA_RESCUE)
jmp_ DO_NEXT
rescue_no:
.endif
; END OF NEW CODE
; load Forth IP with starting word
ldi XL, low(PFA_COLD)
ldi XH, high(PFA_COLD)
; its a far jump...
jmp_ DO_NEXT
####
Then again at the end of asmforth:
; 1st free address in EEPROM.
edp:
.cseg
; NEW CODE FROM HERE DOWN TO END
.ifdef NEED_RESCUE_DATA
RESCUE_DATA:
.dw XT_APPLTURNKEY
.dw UBRR_VAL
.dw XT_DO_ISTORE
.dw lowflashlast ; DP
.dw here ; HERE
.dw edp ; EDP
.dw VE_ENVHEAD ; environmental queries
.dw EE_FORTHWORDLIST; forth-wordlist
.dw EE_FORTHWORDLIST
.dw VE_HEAD ; pre-defined (compiled in) wordlist
.dw EE_FORTHWORDLIST ; get/set-order
.dw -1
.dw -1
.dw -1
.dw -1
.dw -1
.dw -1
.dw -1
.dw -1 ; NUMWORDLISTS + 1 entry, this entry has to be -1
.set RESCUE_DATA_END = pc
.endif
#####
I have a new file: core/words/rescue.asm:
;; rescue logic - Williams
VE_RESCUE:
.dw $ff07
.db "_rescue"
.dw VE_HEAD
.set VE_HEAD = VE_RESCUE
;; : _rescue baseadd size 0 do dup i + i@ i 2* e! loop drop ;
XT_RESCUE:
.dw DO_COLON
PFA_RESCUE:
.dw XT_DOLITERAL
.dw RESCUE_DATA
.dw XT_DOLITERAL
.dw RESCUE_DATA_END-RESCUE_DATA
.dw XT_ZERO
.dw XT_DODO
.dw PFA_RESCUE2
PFA_RESCUE1:
.dw XT_DUP
.dw XT_I
.dw XT_PLUS
.dw XT_IFETCH
.dw XT_I
.dw XT_2STAR
.dw XT_ESTORE
.dw XT_DOLOOP
.dw PFA_RESCUE1
PFA_RESCUE2:
.dw XT_DROP
.dw XT_COLD
.dw XT_EXIT ; never reached?
.set NEED_RESCUE_DATA = 1
###
Then in dict_appl_core.inc I simply add in words/rescue.asm. That way the
saved state and the _rescue word is in the bootloader area which can be
locked. Of course, would be good to move the reset vector up there too and get
all the code up in protected flash. Might do that yet.
Obvioiusly you can set the rescue pin to whatever you want, active high or
low, and with or without pull up (default is low and no pull up). When the
boot process sees an active rescue pin you lose everything back to the initial
load.
This seems to work. You can put some words in and reboot all you like with no
problems. Then if you ground the rescue pin, you lose your custom words. In
addition I got one lock up crash and recovered from it.
I'd be interested to hear any success or failures. Also, I'm really new at
digging into amforth's internals so any suggestions on making this better are
welcome too.
|