Hallo Christopher,

das ist der ganz alte Bootloader, der nicht mit
dem XModem Protokoll arbeitet. Code unten.
Ja, das gab es mal und funktionierte sogar
perfekt...

Dafür habe ich ein VB-Programm schreiben
lassen, dass dem Kunden recht komfortabel
die Möglichkeit bietet, die Firmware in seinem
Gerät zu aktualisieren (mit Menüführung und
Hinweistexten etc.). Dies kann ich in absehbarer
Zeit nicht neu erstellen lassen.

Kann keinem Kunden zumuten, mit dem
HyperTerminal zu kaspern.
Der MCS-Bootloader ist in der vom Compiler
losgelösten Version eine Möglichkeit, aber
nicht für kommerziellen Einsatz zugelassen.

Danke und Gruß,
Frank

Code:
' Bootloader angepasst
' Taste S2 und S3 liegen hier auf PG1 und PG2
'_______________________________________________________________________________
'Bootloader
'Standard Intel hex file can be sent
':10 0000 00 0C 94 2400189500001895000018950000 25
':00 0000 01 FF
' size , address,record type, data, checksum


'anderes Beispiel-File
' .-- Size (im Beispiel: 10=16 Stellen / 0A=10 Stellen)
' '   .-- Adresse
' '   '   .--Record type
' '   '   '  .-- Data
' '   '   '  '                                .--Checksum
' '   '   '  '                                '
' '   '   '  0 1 2 3 4 5 6 7 8 9 A B C D E F
':10 0000 00 0C944600189500001895000018950000 03
':10 0010 00 18950000189500001895000018950000 2C
':10 0020 00 18950000189500001895000018950000 1C
'...
':10 0240 00 0f920024facf426f6f742d5465737420 9f
':10 0250 00 2E2E2E2E2E2E00004765687420212121 7F
':0A 0260 00 21202020202020200000 93
':00 0000 01 FF

'The same baudrate is used as the main program is using
'but we can change it here when we like. Just unremark the next line and/or change it
'But take in mind that the bootloader sender must use the same baud rate !!!


'#if M128boot = 1


  $asm

  $boot = $fe00



  Ldi R24,$FF                                                 ; hardware stack pointer
  !Out SPL,R24
  Ldi R24,$10
  !Out SPH,R24

  'no interrupts are allowed during bootloader programming
  Disable Interrupts
  Ldi _temp1,&B00011000                                       ; enable TX and RX
  !Out UCR,_temp1
  Ldi r24,6
  Sts $95,r24

  $end Asm
  Baud = 19200
  $asm

  lds r24,$63                     ; port g einlesen  /  PING = $63
  andi r24,&B00000110            ; g1 und g2 ausfiltern  / S2+S3 Taste
  cpi r24,0                      ; port hat das richtige bitmuster ?
  breq Bootloaderbasic           ; ja

  jmp $0000                      ; start the normal program


' Programmteil vom MCS-electronic

Bootloaderbasic:

  'jmp $0000                      ; start the normal program


clr r18                                          ; word counter for written data
clr r22                                          ; page counter LSB
clr r23                                          ; page counter MSB


_read_lines:
  rcall _rec_line                                ; get line into SRAM pointed by X
  ldi r26,$01                                    ; point to start of line
  ldi r27,$01
  ld r24,x+                                      ; get char in r24
  rcall _hex2number                              ; convert result in r17
  ld r24,x+
  rcall _hex2number2                             ; convert second char , r17 holds the number of hex pairs to get
  mov r19,r17                                    ; number of entries
! sub r16,r17                                    ; checksum
  tst r19
  brne _readnext                                 ; not the end record
  rjmp _write_last_page                          ; final line so write the last page

_readnext:
 ldi r25,3
_docheck:
 ld r24,x+                                      ; get char in r24
 rcall _hex2number                              ; convert result in r17
 ld r24,x+
 rcall _hex2number2                             ; convert second char , r17 holds the data
 !sub r16,r17
 dec r25
 brne _docheck

'  adiw xl,6                                      ; point to first pair
_readnextpair:
  ld r24,x+                                      ; get char in r24
  rcall _hex2number                              ; convert result in r17
  ld r24,x+
  rcall _hex2number2                             ; convert second char , r17 holds the data
  mov r0,r17                                     ; save in r0
! sub r16,r17                                    ; checksum
  dec r19                                        ; adjust pair data counter
  ld r24,x+                                      ; get char in r24
  rcall _hex2number                              ; convert result in r17
  ld r24,x+
  rcall _hex2number2                             ; convert second char , r17 holds the data
  mov r1,r17                                     ; save data
! sub r16,r17                                    ; checksum
  rcall _write_page                              ; write into page buffer
  cpi r18,128                                     ; page is 256 bytes is 128 words
  breq _writeit                                  ; write page since it is full
_lbl1:
  dec r19                                        ; adjust data pair
  brne _readnextpair                             ; more data
' ----------------checksum checkining ---------------
  ld r24,x+                                      ; get char in r24
  rcall _hex2number                              ; convert result in r17
  ld r24,x+
  rcall _hex2number2                             ; convert second char , r17 holds the data
  cp r16,r17                                     ; checksum ok?
  breq _checkok                                  ; yes
_lbl2:
  sbis usr,5
  rjmp _lbl2
  ldi r24, asc("!")                              ; load !
  !out udr,r24                                   ; show ! so we know there is an error
' note that you only get an indication something wend wrong,there is no error recovery !!!

_checkok:
  rjmp _read_lines                               ; next line

_writeit:
  rcall _erase_page                              ; erase next page
  rcall _save_page                               ; save page
  Rjmp _lbl1                                     ; continue

_write_last_page:
  rcall _erase_page
  rcall _save_page                               ; save last page
_exit_page:
  jmp $0000                                      ; exit needs a reset

' get 1 byte from serial port and store in R24
_recbyte:
  Sbis USR, 7                                    ; Wait for character
  rjmp _recbyte
  in r24, UDR                                    ; get byte
Ret

'get one line from the serial port and store in location pointed by X
_rec_line:
  ldi r26,$00                                    ; point to first location in SRAM
  ldi r27,$01
  clr r16
_rec_line5:
  sbis usr,5
  rjmp _rec_line5
  ldi r24, 63 ; ?
  !out udr,r24                                   ; show ? so we know we can send next line
_rec_line1:
  rcall _recbyte                                 ; get byte
  cpi r24,13                                     ; enter?
  breq _rec_line2                                ; yes ready
  st x+,r24                                      ; no so store in sram buffer
  rjmp _rec_line1                                ; next byte
_rec_line2:
  clr r24                                        ; string terminator
  st x,r24
ret

' convert HEX byte in r24 into bin value , on exit byte in r17
_hex2number:
  clr r17
_hex2number4:
  Subi R24,65                                    ; subtract 65
  Brcc _hex2number3                              ; in case carry was cleared
  Subi R24,249                                   ; not
_hex2number3:
  Subi R24,246
  Add R17,R24                                    ; add to accu
ret

';called for the second byte
_hex2number2:
  Lsl R17                                        ; shift data
  Lsl R17
  Lsl R17
  Lsl R17
  rjmp _hex2number4                              ; handle the conversion



_enable_page:
 rcall _wait_spm
 ldi r24,17                                      ; reenable page
 sts  {Spmcsr} , R24
 spm
 nop
 nop
 ret
'rjmp _wait_spm

'page address in z7-z13
_erase_page:
 ' rcall _wait_spm
  mov r31,r22                                    ; page address z8-z15
! out rampz,r23                                  ; bit 9 of pageaddress goes into Z16
  clr r30
  ldi r24,3                                      ; page erase command
  sts  {Spmcsr} , R24
  spm
  nop
  nop
  rcall _wait_spm
'  rcall _enable_page
ret

_write_page:
  'rcall _wait_spm
  mov r31,r22                                    ; page address z8-z15
! out rampz,r23                                  ; bit 9 of page address goes into Z16(bit 0 of rampz)
  mov r30,r18                                    ; word address buffer counter
  lsl r30
  ldi r24,1                                      ; buffer fill
  sts  {Spmcsr} , R24
  spm
  nop
  nop
  rcall _wait_spm
  inc r18  ; next word address
ret


_save_page:
'z0-z6 must be 0
'z7-z13 is the page address
'r0 and r1 are ignored
 ' rcall _wait_spm
  mov r31,r22                                     ; LSB of page counter
! out rampz,r23                                   ; bit nine goes into bit 0 of rampz
  clr r30
  ldi r24,5                                       ; write page
  sts  {Spmcsr} , R24
  spm
  nop
  nop
  rcall _wait_spm

  rcall _enable_page
  clr r18                                         ; page word address counter
  subi r22,-1                                     ; increment page counter
  sbci r23,255
ret

_wait_spm:
   LDS R25,{Spmcsr}
   SBRC R25,0
   RJMP _WAIT_SPM                                 ; Wait for SPMEN flag cleared
RET


  $end Asm


'#endif
[/code]