USB read error under linux

USB AVR Programmer and SPI interface. Adafruit's USBtinyISP.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm

Post by adafruit »

well are you using the makefile included to burn the fuse and program the chip?

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm

Post by adafruit »

I just finished installing ubuntu 7.04 (FF) onto a old laptop and got it to work:
http://www.ladyada.net/make/usbtinyisp/ ... html#linux

it was pretty smooth except for forgetting that i needed to run it as root :-?

Zero
 
Posts: 30
Joined: Thu Jul 12, 2007 3:47 am

Post by Zero »

Ok, I've been busy so I just got back to this now. Flashed a new tiny2313 and wrote the fuses with the arguments in the Makefile and got both 1.0 and 1.04 working, but not under Linux (well, now I know I can make spares easy if something happens I guess).

Going back to avrdude, everything shows up like it should in configure, I have libusb and libusb-dev, etc. Still, the avrdude I get will work with every programmer I have but this one. The best I get is:

Code: Select all

USB read error: expected 8, got 4
USB read error: expected 8, got 4
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.
But look closely at that. It expected 8. In your screen shot how many did it expect? 4. I'm getting 4. This is some sort of a bit width problem on the avrdude side. Keep in mind I have an AMD64 system. Are your systems 32bit? Has anyone built and run this avrdude on a non 32bit system? Did they use a 32bit compiler or pass flags to compile in 32bit?

I'll experiment when I have the time (some time next week maybe), but I think I know where to start looking for the problem and have an attack angle now. If you were on a 32bit x86 system could I also get that binary?

I'll tell you if I get anything, and send you any code I modify.

EDIT: updated the make file with the -m32 compiler flag, and attempted to make... libusb comes up as an incompatible version when I do that. I'd have to built a specifically 32bit version (which would probably cause more trouble). I think this is definitely the problem, I'm going to look at the avrdude-usbtiny source later when I have the time and see if I can make it behave.

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm

Post by adafruit »

i wouldnt be surprised if libusb was not properly functioning on your system but its a pretty old project so youd think that issue would have been addressed by now

one thing you can try if you want to really dig in is have the usb functions in usbtiny.c print out the data returned and see if you can just munge it to be 'Right'

Zero
 
Posts: 30
Joined: Thu Jul 12, 2007 3:47 am

Post by Zero »

Well I have other things using libusb without any problem.

I haven't had a lot of time to look around the source, but one thing to note that I saw right off the bat is there was a lot of sizeof(whatever) being used when calling usb_in. On my system I'm quite sure the bit length of most standard types is the same as that on a 32 bit system. That's done now just for consistency, technically an int used to match the bit width of the system (my SGI Octane returns 8 for sizeof(int) unless you pass flags). So I don't think it's an immediately visible problem, but I have feeling there's something to do with the 64bit bit width of the system and how everything was built.

As for "fixing the data" on the other side: we should only be getting 4(bytes) from the USB device while my system is expecting 8 (and yours 4). Unless I missed some part where it is expecting 8 on my quick glance through the code that is. Since we should be expecting 4, fixing the code so it doesn't for some reason expect 8 would sit better with me than attempting to fool it to think it got a valid 8 (which would probably just cause more problems when the data was processed anyway).

I really must inquire again: has anybody gotten this to work on a 64bit system? Was it a Linux system? What bit width was libusb compiled with?

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm

Post by adafruit »

Zero wrote: I really must inquire again: has anybody gotten this to work on a 64bit system? Was it a Linux system? What bit width was libusb compiled with?
most people who get stuff working dont post in the forum, but as far as i know you're the only 64 bit person to try. i dont have any 64 bit machines so its pretty near impossible for me to test...
I haven't had a lot of time to look around the source, but one thing to note that I saw right off the bat is there was a lot of sizeof(whatever) being used when calling usb_in.
ok well, why not try that then?

Zero
 
Posts: 30
Joined: Thu Jul 12, 2007 3:47 am

Post by Zero »

Well, since the types on my system should have the same width as a 32bit system (for what I know) the sizeof may well not be the problem unless something somewhere was defined funny or something. When the 64bit AMD came out I put Debian on it right away, and quite a bit of software had weird bit width errors. That didn't come from standard types (for what I know) but rather just odd structs or funny memory allocation and pointer arithmetic etc. I think I just hit one of those problems, and I intend to fix it. In the process I suspect I'll learn about how to use the usbtiny code and more about libusb, which is something I really wanted to do anyway.

ginge
 
Posts: 1
Joined: Sun Oct 28, 2007 5:51 am

Post by ginge »

I know this is an old thread, but I have discovered, and fixed these problems with the 64bit implementation of the usbtiny code.

It was related to incorrect use of sizeof. I don't have one of your devices, but in fact a home brew version, so the patch below is just a rough indicator.

Instead of taking the size of the pointer to the cmd val, changed to use 4* the size of unsigned char, which on a 64bit system is 8 and 32bit 4.

Code: Select all


function usbtiny_avr_op()
-memset( cmd, 0, sizeof(cmd) );
+memset( cmd, 0, 4*sizeof(unsigned char) );

function usb_command()

-memset( res, '\0', sizeof(res) );
+memset( res, '\0', 4*sizeof(unsigned char) );

-r = usb_in( USBTINY_SPI, (cmd[1] << 8) | cmd[0], (cmd[3] << 8) | cmd[2],            (char*) res, sizeof(res), 8 * sck_period )
+r = usb_in( USBTINY_SPI, (cmd[1] << 8) | cmd[0], (cmd[3] << 8) | cmd[2], (unsigned char*) res, 4, 8 * sck_period );


adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm

Post by adafruit »

neat, thanks!

Zero
 
Posts: 30
Joined: Thu Jul 12, 2007 3:47 am

Post by Zero »

After returning to Japan a big job came in (which I'm still working on) that's all high level software development, so I never got around to fixing this until just now. I'd like to thank ginge for finding which sizeof's were the culprits, and for confirming my suspicions about it being a 32->64bit sizeof problem. I've tested the fixes he put up and they do in fact work, but I have two points:

1. What he lists as 'usb_command' is in fact 'usb_cmd'
2. The function usb_cmd has what appears to be an error in it:
an integer 'r' is created, then used in the return statement uninitialized. Furthermore, it is used in a comparison, which if your compiler isn't nice enough to automatically make r = 0 on creation would cause errors. I took the easy route and just changed:

Code: Select all

- int r;
+int r = 0;
but I have a feeling r is totally unnecessary unless there is some sort of hidden type comparison check or something to make sure that an integer set to 0 does in fact equal 0 and this is somehow necessary. You know, just in case somebody hates integers and made all there integers into floats where 0 doesn't always equal 0 unless it is 0.0 in all environments on a Sunday at brunch.

It would be interesting to see if the fixes provided above are backwards compatible with 32bit systems. If somebody could check that out and confirm that it does work it would no doubt be best to update usbtiny.c so we don't have to see this problem again.

I'll probe for a solution to the whole having to be root thing so we don't have to sudo every time we want to use the dongle. But as it is it is working and I'm loving it. Thanks ladyada! And I saw your picture and read your article in MAKE, very nice!

New edit: doing some debugging, sizeof(byte_t) returns 1 (correct!), but sizeof(res) when res is defined as byte_t res[4] returns... 8? Is this some sort of padding issue or what?

Zero
 
Posts: 30
Joined: Thu Jul 12, 2007 3:47 am

Post by Zero »

I have posted a fixed version at kuroi.net/avr/usbtiny.c . I simply defined a constant CMD_RES_LEN as 4 and changed all instances of sizeof to this, changed the arguement in line 257 of usb_in that was using the sizeof(res) (which was returning 8!?) and all the defintions of cmd[4] and res[4] to cmd[CMD_RES_LEN] and res[CMD_RES_LEN]. This way if that were to change for some reason only changing the define would be required anyway. I also initialized that int r to int r = 0 (though have not tested if you can remove that or not, I'm lazy!). I think I changed something else too but I can't remember off hand.

Anyway, it WORKS, and it should work on 32bit and 64bit systems. Please test it! If it works for enough people then perhaps this should be a permanent fix?

I'm crunched for time, please give me detailed feedback if you want me to do anything else to this.

adafruit
 
Posts: 12151
Joined: Thu Apr 06, 2006 4:21 pm

Post by adafruit »

i actually got some easy fixes for the sudo thing, read the unix install page for usbtiny again, its been updated

the 64 bit thing may not make it into avrdude 5.5 because i had already submitted my patch but maybe if they do a minor rev. it'll go in. thanks for checking up on it. im not a great software hacker :)

Zero
 
Posts: 30
Joined: Thu Jul 12, 2007 3:47 am

Post by Zero »

No problem. If I'd had time I would have fixed this months ago. Now that I realize what it was it was a very easy fix too. I don't see why it wouldn't work on 32bit systems as well, so the code should be good (again, please test it). When you send any patches please keep my changes in mind. Hopefully they will spare someone from some headaches without causing new ones. Also, if you have issues with my fix (as in you want it done differently or there are cases where it does not work) just tell me and I'll see what I can do.

Also, thanks again to ginge. Without those lines that were pointed out I would have had to spend a lot more time looking for what needed to be fixed. I probably would have just given up before I started as my 1.5 year old son refuses to let me use the computer for more than a 5 minute stretch. Still, I'm having trouble with why sizeof is returning 8 for a 4 byte array.

I've just applied your sudo fix and am going to check it out. At the moment I'm on an Ubuntu 7.10 system and the location of the file was a bit different, but operation should be the same. Thanks for pointing me to the fix!

User avatar
jgrauman
 
Posts: 12
Joined: Fri Jan 04, 2008 1:45 am

Post by jgrauman »

Zero: the sizeof(res) returns 8 because res[4] is really a pointer, and on a 64-bit system a pointer is 8 bytes (= 64-bits).

Ladyada: Please update the website where you refer to the 64-bit bug to this post (at least until avrdude is patched correctly). I assumed (wrongly) that there was no fix for the bug since the website has it listed as a bug and spent time trying to fix it... :(

Zero
 
Posts: 30
Joined: Thu Jul 12, 2007 3:47 am

Post by Zero »

jgrauman wrote:Zero: the sizeof(res) returns 8 because res[4] is really a pointer, and on a 64-bit system a pointer is 8 bytes (= 64-bits).

Ladyada: Please update the website where you refer to the 64-bit bug to this post (at least until avrdude is patched correctly). I assumed (wrongly) that there was no fix for the bug since the website has it listed as a bug and spent time trying to fix it... :(
You are correct, thank you for clearing that up!

Locked
Please be positive and constructive with your questions and comments.

Return to “USBtinyISP”