Der Democode BootCheckSums funktioniert in der Praxis nicht, da
die globalen Variablen
_CalcFlashPageA
_CalcFlashAddrA
_CalcFlashCA
nach einem "power on reset" nicht initialisiert sind. CalcFlashCheck_A schlägt fehl.
Abhilfe schafft z.B.
_CalcFlashPageA := 0;
_CalcFlashAddrA := 0;
_CalcFlashCA := 0;
repeat
bc:= CalcFlashCheck_A($1000); // BUG: NO RAM INIT DONE BEFORE, FlashCheck fails
until bc <> 0;
oder eine Komplettinitialisierung des RAMs vorher.
Bitte das Demo verbessern.
program BootCheckSums;
{ $W+ Warnings} {Warnings off}
// Device = mega32, VCC = 5;
// {$BOOTRST $03E00} {Reset Jump to $03E00} // word address
Device = mega128, VCC=5;
{$BOOTRST $0F000} {Reset Jump to $0F000 = $1E000}
Import SysTick, SerPort, Flashwrite;
From System Import FlashCheck_B, FlashCheck_A, FlashCheck_S, BootVectors;
Define
ProcClock = 8000000; {Hertz}
SysTick = 10; {msec}
StackSize = $0128, iData;
FrameSize = $0108, iData;
SerPort = 19200;
TxBuffer = 100, iData;
FlashChkSum = (2 * BOOTRST) -2; // byte addr of checksum placement
// at app area end, required for FlashCheck_A
Implementation
Const
// mega32
// BootCheckF[$7BF8] : Word = $AA55; // byte address, last 6bytes used
// {$PHASE BootBlock $03E00} // word address
// mega128
{$PHASE BootBlock $0F000}
ConstPage : byte = 1;
BootCheckF[$1DFF8] : word = $AA55;
{$IDATA}
const
var
bc : byte;
procedure BootTest;
begin
{$IFNDEF BootVectors}
// without BootVectors we need a working stack/frame pointer
Boot_Init;
{$ENDIF}
// we can use a port bit which the user can pull down
// to force a flash download
// .....
// .....
// check the Boot Checksum
if not CalcFlashCheck_B then
nop;
// big problem !!!!!!!
endif;
{ mega32
ASM;
; check last self programming valid
LDI _ACCCLO, %.BOOTCHECKF AND 0FFh
LDI _ACCCHI, %.BOOTCHECKF SHRB 8
LPM _ACCA, Z+
CPI _ACCA, 055h
BRNE BootTestX
LPM _ACCA, Z+
CPI _ACCA, 0AAh
BRNE BootTestX
ENDASM;
}
// mega128
ASM;
; check last self programming valid
LDI _ACCCLO, %.BOOTCHECKF AND 0FFh
LDI _ACCCHI, %.BOOTCHECKF SHRB 8
ELPM _ACCA, Z+
CPI _ACCA, 055h
BRNE BootTestX
ELPM _ACCA, Z+
CPI _ACCA, 0AAh
BRNE BootTestX
ENDASM;
// now calc the application checksum
repeat
bc:= CalcFlashCheck_A($1000); // BUG: NO RAM INIT DONE BEFORE, FlashCheck fails
until bc <> 0;
case bc of
1 : // check ok
|
2 : // check failed !
// what shall we do now ?
// jump to the Downloader ?
FlashDownloader;
|
endcase;
ASM;
// normal program start
JMP 0000h;
BootTestX:
// check failed, try to download
ENDASM;
FlashDownloader;
end;
Procedure BootEntry;
begin
FLASHDOWNLOADER;
end;
procedure FlashLoaderInit;
begin
ASM;
; > > SERPORT Init < <
; > > Baudrate 19200Baud < <
; > > Parameters are clock and CPU type dependent !! < <
LDI _ACCA, 018h; Rx and Tx enanable, polling
OUT ucr1, _ACCA;
LDI _ACCA, 0; // 00Ch; 38400 Baud
OUT ubrr1, _ACCA;
SBI ucr1, 1; 2 stop bits
SBI ucr1, 0; 2. stopbit = 0
ENDASM;
end;
procedure FlashLoaderRecv;
begin
ASM;
SBIS usr1, 7; Receiver ready?
RJMP %.FLASHLOADERRECV; if not
IN _ACCA, udr1
ENDASM;
end;
procedure FlashLoaderTransm;
begin
ASM;
SBI usr1, 6; clear Transmitter empty
FLDRTXLP0:
SBIS usr1, 5; Transmitter ready?
RJMP FLDRTXLP0; if not
OUT udr1, _ACCA
FLDRTXLP1:
SBIS usr1, 6; Transmitter empty?
RJMP FLDRTXLP1; if not
SBI usr1, 6; Transmitter empty?
ENDASM;
end;
procedure FlashLoaderExit;
begin
ASM: JMP System.VectTab;
end;
{$DEPHASE BootBlock}
{$IDATA}
Const
{--------------------------------------------------------------}
{ Type Declarations }
Type
{--------------------------------------------------------------}
{ Var Declarations }
Var
bb : byte;
// Main
begin
repeat
bb:= CalcFlashCheck_S($1000);
until bb <> 0;
case bb of
1 : // check ok
|
2 : // check failed
|
endcase;
end BootCheckSums.
die globalen Variablen
_CalcFlashPageA
_CalcFlashAddrA
_CalcFlashCA
nach einem "power on reset" nicht initialisiert sind. CalcFlashCheck_A schlägt fehl.
Abhilfe schafft z.B.
Code
_CalcFlashPageA := 0;
_CalcFlashAddrA := 0;
_CalcFlashCA := 0;
repeat
bc:= CalcFlashCheck_A($1000); // BUG: NO RAM INIT DONE BEFORE, FlashCheck fails
until bc <> 0;
oder eine Komplettinitialisierung des RAMs vorher.
Bitte das Demo verbessern.
Code
program BootCheckSums;
{ $W+ Warnings} {Warnings off}
// Device = mega32, VCC = 5;
// {$BOOTRST $03E00} {Reset Jump to $03E00} // word address
Device = mega128, VCC=5;
{$BOOTRST $0F000} {Reset Jump to $0F000 = $1E000}
Import SysTick, SerPort, Flashwrite;
From System Import FlashCheck_B, FlashCheck_A, FlashCheck_S, BootVectors;
Define
ProcClock = 8000000; {Hertz}
SysTick = 10; {msec}
StackSize = $0128, iData;
FrameSize = $0108, iData;
SerPort = 19200;
TxBuffer = 100, iData;
FlashChkSum = (2 * BOOTRST) -2; // byte addr of checksum placement
// at app area end, required for FlashCheck_A
Implementation
Const
// mega32
// BootCheckF[$7BF8] : Word = $AA55; // byte address, last 6bytes used
// {$PHASE BootBlock $03E00} // word address
// mega128
{$PHASE BootBlock $0F000}
ConstPage : byte = 1;
BootCheckF[$1DFF8] : word = $AA55;
{$IDATA}
const
var
bc : byte;
procedure BootTest;
begin
{$IFNDEF BootVectors}
// without BootVectors we need a working stack/frame pointer
Boot_Init;
{$ENDIF}
// we can use a port bit which the user can pull down
// to force a flash download
// .....
// .....
// check the Boot Checksum
if not CalcFlashCheck_B then
nop;
// big problem !!!!!!!
endif;
{ mega32
ASM;
; check last self programming valid
LDI _ACCCLO, %.BOOTCHECKF AND 0FFh
LDI _ACCCHI, %.BOOTCHECKF SHRB 8
LPM _ACCA, Z+
CPI _ACCA, 055h
BRNE BootTestX
LPM _ACCA, Z+
CPI _ACCA, 0AAh
BRNE BootTestX
ENDASM;
}
// mega128
ASM;
; check last self programming valid
LDI _ACCCLO, %.BOOTCHECKF AND 0FFh
LDI _ACCCHI, %.BOOTCHECKF SHRB 8
ELPM _ACCA, Z+
CPI _ACCA, 055h
BRNE BootTestX
ELPM _ACCA, Z+
CPI _ACCA, 0AAh
BRNE BootTestX
ENDASM;
// now calc the application checksum
repeat
bc:= CalcFlashCheck_A($1000); // BUG: NO RAM INIT DONE BEFORE, FlashCheck fails
until bc <> 0;
case bc of
1 : // check ok
|
2 : // check failed !
// what shall we do now ?
// jump to the Downloader ?
FlashDownloader;
|
endcase;
ASM;
// normal program start
JMP 0000h;
BootTestX:
// check failed, try to download
ENDASM;
FlashDownloader;
end;
Procedure BootEntry;
begin
FLASHDOWNLOADER;
end;
procedure FlashLoaderInit;
begin
ASM;
; > > SERPORT Init < <
; > > Baudrate 19200Baud < <
; > > Parameters are clock and CPU type dependent !! < <
LDI _ACCA, 018h; Rx and Tx enanable, polling
OUT ucr1, _ACCA;
LDI _ACCA, 0; // 00Ch; 38400 Baud
OUT ubrr1, _ACCA;
SBI ucr1, 1; 2 stop bits
SBI ucr1, 0; 2. stopbit = 0
ENDASM;
end;
procedure FlashLoaderRecv;
begin
ASM;
SBIS usr1, 7; Receiver ready?
RJMP %.FLASHLOADERRECV; if not
IN _ACCA, udr1
ENDASM;
end;
procedure FlashLoaderTransm;
begin
ASM;
SBI usr1, 6; clear Transmitter empty
FLDRTXLP0:
SBIS usr1, 5; Transmitter ready?
RJMP FLDRTXLP0; if not
OUT udr1, _ACCA
FLDRTXLP1:
SBIS usr1, 6; Transmitter empty?
RJMP FLDRTXLP1; if not
SBI usr1, 6; Transmitter empty?
ENDASM;
end;
procedure FlashLoaderExit;
begin
ASM: JMP System.VectTab;
end;
{$DEPHASE BootBlock}
{$IDATA}
Const
{--------------------------------------------------------------}
{ Type Declarations }
Type
{--------------------------------------------------------------}
{ Var Declarations }
Var
bb : byte;
// Main
begin
repeat
bb:= CalcFlashCheck_S($1000);
until bb <> 0;
case bb of
1 : // check ok
|
2 : // check failed
|
endcase;
end BootCheckSums.