Bytes disappearing into nowhere... [solved]
Patrick1ab
Posts: 136
Hi everyone!
I've got a strange little problem over here. While trying to read data from the buffer of my W5100 ethernet chip, I can see that some bytes (which should be there) are missing.
For example:
"icy-metaint: 16384" becomes "icy-metain: 16384"
I should mention, that it's always the same byte of the above example which is missing.
I tried to find the problem by comparing the "rxTCP" function of the driver with the pseudocode description in the W5100 datasheet, but everything looks fine to me. Am I missing something?
This is the code I'm using to read a line of up to 127 characters:
In the attachments, I added a copy of the W5100 driver I'm using and the datasheet of this chip.
Post Edited (Patrick1ab) : 5/31/2010 8:04:48 PM GMT
I've got a strange little problem over here. While trying to read data from the buffer of my W5100 ethernet chip, I can see that some bytes (which should be there) are missing.
For example:
"icy-metaint: 16384" becomes "icy-metain: 16384"
I should mention, that it's always the same byte of the above example which is missing.
I tried to find the problem by comparing the "rxTCP" function of the driver with the pseudocode description in the W5100 datasheet, but everything looks fine to me. Am I missing something?
This is the code I'm using to read a line of up to 127 characters:
[b]VAR[/b] [b]byte[/b] strTemp[noparse][[/noparse]*128] ... [b]PRI[/b] readLine | i, rx i := 0 [b]repeat[/b] [b]if[/b] net.rxTCP(0, @rx, 1) == 0 'Copy one byte to "rx"; If the number of received bytes is zero, terminate string and abort strTemp[noparse][[/noparse]*i] := 0 [b]abort[/b] -1 [b]elseif[/b] rx == 13 'If the character is carriage return, check next byte [b]next[/b] [b]elseif[/b] rx == 10 [b]or[/b] i => 127 'Check if the current character is line feed or if the string contains 127 characters [b]quit[/b] strTemp[noparse][[/noparse]*i++] := rx strTemp[noparse][[/noparse]*i] := 0 'Terminate string [b]return[/b] i
In the attachments, I added a copy of the W5100 driver I'm using and the datasheet of this chip.
Post Edited (Patrick1ab) : 5/31/2010 8:04:48 PM GMT
Comments
Try using my website, www.phipi.com/format, to format your code. You won't have the italics problem.
-Phil
Bill
Oh, it is. Just another case of forum software eating up indices [noparse]:)[/noparse]
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pullmoll's Propeller Projects
If you don't check, you can send things too quickly and overwrite something before it gets sent on its way.
And these things always turn out to be something simple. An array not large enough, maybe halting reading before the last byte is read, etc. Of course finding that "simple thing" can take days of hunting!
What about ethernet "collisions"? When traffic is busy and data gets lost? I have no idea how that gets handled, but I suppose something would need to retransmit?
Thanks for the replies everyone.
This is great! Thanks.
Yes, it's definitely being transmitted. I checked with my computer and Wireshark:
0180 2e 66 6d 0d 0a 63 6f 6e 74 65 6e 74 2d 74 79 70 .fm..content-typ
0190 65 3a 20 61 75 64 69 6f 2f 6d 70 65 67 0d 0a 69 e: audio/mpeg..i
01a0 63 79 2d 70 75 62 3a 20 31 0d 0a 69 63 79 2d 6d cy-pub: 1..icy-m
01b0 65 74 61 69 6e 74 3a 20 31 36 33 38 34 0d 0a 69 etaint: 16384..i
01c0 63 79 2d 62 72 3a 20 39 36 0d 0a 0d 0a cy-br: 96....
This chip has a similar mechanism for both sending and receiving data. This is a brief overview of how it works if you want to receive data:
- First you have to check if data has been received, reading the receive size register of a specified socket (in my case socket 0):
- If this register isn't zero, then you need to read the "Socket 0 RX Read Pointer" and calculate the start address to read data from:
- Afterwards you can read the number of bytes according to the receive size register. Of course there is a special case if the buffer rolls over, but this is all handled by the "rxTCP" function.
The hardwired TCP stack of this chip should take care of this.
If you don't have a copyright issue, you should always post the whole code and not an extract.
With the next call you'd skip the linefeed, copy all not processed data to the beginning of the buffer with a bytemove and fill the buffer up to the end by reading the next chunk of bytes via rxTCP.
You can repeat this until rxTCP returns 0 AND all characters in the buffer have been processed.
I don't know what you want to do, but maybe you can alos utilize the ConfigReader I put into the object exchange (Tools) to read the TCP-stream instead of a SD card-file.
thanks for your reply.
The code is running in the initial SPIN COG.
Sounds good. I will try to modify the code and see what happens.
However, the error must be somewhere else. I just made some tests and it looks like the bytes are also missing/skipped if I read 32 bytes at once.
I think that I have to check the driver again... Maybe it has something to do with the RX_mask or the start address calculation.
What I want to do is reading the header of a shoutcast stream. In particular the metaint information, which tells me how many bytes of music data are between the meta data.
Hmm, it turns out that there is one major disadvantage, reading these 128 bytes at once.
Either you have to go through the whole string again afterwards or you have to modify the rx function of the driver to be able to check if there is a value of 13.
This is already included in the current solution.
You overwrite only the lowest byte of the rx variable with net.rxTCP(0, @rx, 1), but check then the whole 32 bit variable against 13, 10 and =>128.
The states of rx bits 8..31 are unknown because rx is never initalized to zero.
I don't know if that fixes your problem, but I would set rx := 0 before the loop.
Andy
If you analyze the code you'll see that this will be much faster than the loop reading byte by byte. The copy-job which then copies the not processed bytes to the beginning of the buffer can be done by a bytemove, which is very fast as well.