View previous topic :: View next topic |
Author |
Message |
i.dobson
Joined: 05 Jan 2006 Posts: 1570 Location: Basel, Switzerland
|
Posted: Thu Apr 26, 2012 9:33 am Post subject: Bug in XModem bootloader |
|
|
Hi,
After playing with a bootload written in C & ASM and getting really frustrated (It worked but the code was really ugly), I decided to have a look at the Bascom Bootloader samples, and I think I've found a bug in the code or better said not specification conform.
Looking at the code I see that the the localblock numer is incemented after recieving the SOH and before checking if the block is OK (Block number & checksum). I believe the localblock number should only be incremented if the Blocknumber and the data are correct.
Code: | SENDER RECIEVER
Times out after 10 seconds,
<--- <nak>
<soh> 01 FE -data- <xx> --->
<--- <ack>
<soh> 02 FD -data- <xx> ---> (data gets line hit)
<--- <nak>
<soh> 02 FD -data- <xx> --->
<--- <ack>
<soh> 03 FC -data- <xx> --->
(ack gets garbaged) <--- <ack>
<soh> 03 FC -data- <xx> --->
<--- <ack>
<eot> --->
<--- <ack> |
Copied from http://techheap.packetizer.com/communication/modems/xmodem.html.
Note how the Block number is only incremented after accepting the block (ACK).
Although this is not a major problem, it just took me a while to realise why the transfer didn't always work.
Regards
Ian Dobson _________________ Walking on water and writing software to specification is easy if they're frozen. |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Fri Apr 27, 2012 10:16 am Post subject: |
|
|
I had no sample to look at so i had to code it from some spec i found on line. the link you gave does not work.
I will see if i can find a link/spec that works and then change it if required. the loader never failed for me but maybe i did not noticed.
If i understand you correct, only thing you need to do is the dec the Bblocklocal in case NAK is sent in state '1'
If you inc after the test, the local block will not match the remote block, so increasing later is not an option. _________________ Mark |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Fri Apr 27, 2012 10:24 am Post subject: |
|
|
The link i found which works :
http://techheap.packetizer.com/communication/modems/xmodem.html
dont know why your link (same one) does not work. I think this is the same page i used to write the loader. At wikipedia i see what i missed : the block stats with 1, not 0.
so this should work:
Code: | Do
Bstarted = 0 ' we were not started yet
[b]Bblocklocal =1 [/b]
Csum = 0 'checksum is 0 when we start
Print Chr(nak); ' firt time send a nack
Do
Bstatus = Waitkey() 'wait for statuse byte
Select Case Bstatus
Case 1: ' start of heading, PC is ready to send
[i]' Incr Bblocklocal 'increase local block count[/i]
Csum = 1 'checksum is 1
Bblock = Waitkey() : Csum = Csum + Bblock 'get block
Bcsum1 = Waitkey() : Csum = Csum + Bcsum1 'get checksum first byte
For J = 1 To 128 'get 128 bytes
Buf(j) = Waitkey() : Csum = Csum + Buf(j)
Next
Bcsum2 = Waitkey() 'get second checksum byte
If Bblocklocal = Bblock Then 'are the blocks the same?
If Bcsum2 = Csum Then 'is the checksum the same?
Gosub Writepage 'yes go write the page
Print Chr(ack); 'acknowledge
[b] Incr Bblocklocal 'increase local block count[/b]
Else 'no match so send nak
Print Chr(nak);
End If
Else
Print Chr(nak); 'blocks do not match
End If
|
_________________ Mark |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Fri Apr 27, 2012 10:25 am Post subject: |
|
|
hmmm seems bold does not work inside 'code'. any way the [b] /[b] means bold _________________ Mark |
|
Back to top |
|
|
Luciano
Joined: 29 Nov 2004 Posts: 3149 Location: Italy
|
Posted: Fri Apr 27, 2012 11:39 am Post subject: |
|
|
Hi,
The URL (link) posted by Ian is terminated with a full stop (.) and
therefore it doesn't work.
Best regards,
Luciano |
|
Back to top |
|
|
i.dobson
Joined: 05 Jan 2006 Posts: 1570 Location: Basel, Switzerland
|
Posted: Fri Apr 27, 2012 11:57 am Post subject: |
|
|
Hi Mark ,
The local block number should only be incremented if the block recieved is the same blocknumber and the checksum is correct.
If the block number is incremented incorrectly, it'll wrap around after 255 blocks and eventually the PC and the uC will get back into sync.
So the code shoudl be:-
Code: |
Do
Bblocklocal =1
Csum = 0 'checksum is 0 when we start
Print Chr(nak); ' firt time send a nack
Do
Bstatus = Waitkey() 'wait for statuse byte
Select Case Bstatus
Case 1: ' start of heading, PC is ready to send
Csum = 1 'checksum is 1
Bblock = Waitkey() : Csum = Csum + Bblock 'get block
Bcsum1 = Waitkey() : Csum = Csum + Bcsum1 'get checksum first byte
For J = 1 To 128 'get 128 bytes
Buf(j) = Waitkey() : Csum = Csum + Buf(j)
Next
Bcsum2 = Waitkey() 'get second checksum byte
If Bblocklocal = Bblock Then 'are the blocks the same?
If Bcsum2 = Csum Then 'is the checksum the same?
Gosub Writepage 'yes go write the page
Print Chr(ack); 'acknowledge
Incr Bblocklocal 'increase local block count
Else 'no match so send nak
Print Chr(nak);
End If
Else
Print Chr(nak); 'blocks do not match
End If
|
It's not a major problem, the PC and the uC should get back into sync after 255 blocks (If the PC is following the specification and only incrementing the block number after an ACK).
For me it was just a question, why is the Bascom bootloader so much slower than the C version I wrote. The zigbee communication I'm using have a very high latency which hurts for every packet I must send/wait for response. And all it took was one bad packet to cause the PC and the uC to get out of sync, and the subsequent 255 packets that needed to be sent before the two synced again.
If you have good communications (and never see a NAK during the transfer) then you won't see this.
Regards
Ian Dobson _________________ Walking on water and writing software to specification is easy if they're frozen. |
|
Back to top |
|
|
|