Hi All,
I downloaded the Keil USB Examples for the MCB2300 board on the website. All examples worked well (except USBMem, because of the 16 kb limit for the evaluation version) when with the default compiler.
I adapted the code to work with the GCC compiler (that also came with the evaluation tools), but I had problems:
When I run the examples, Windows XP "almost" recognizes the board (almost = you hear the "dong-ding" but the "USB Device not recognized" little window popped up).
I suspect I made some mistakes on the 'translation' ; something with the __packed & __inline keywords.
1) Does anybody have a clue about what is happening?
2) I translated __packed to __attribute__(__packed__)) , but had to put the keyword after "struct" (when I left it at the left of struct I got a warning saying that __packed__ was ignored. And the device did not even made XP do the "dong-ding". Is this correct? I read in somewhere that in GCC even if you pack a structure or every item on the structure, the structure itself has its size aligned (even if the members inside are packed).
3) __inline is the same as "static" ? (I defined a macro #define __inline static ), Is this correct?
Thank you very much for any help!! Sergio P. Sider
After some substantive hair loss, I found the solution to my problem...
GCC does not correctly handles unaligned packed pointers, as found on the USB_ReadEP and USB_WriteEP functions
In Keil C:
*((__packed DWORD *)pData) = RX_DATA; pData += 4;
In GCC, converting to the pack attribute was not enough:
*((DWORD __attribute__((__packed__)) *)pData) = RX_DATA; pData += 4;
I had to change the code to handle it one byte at time:
DWORD x = RX_DATA; *pData++ = x; x >>= 8; *pData++ = x; x >>= 8; *pData++ = x; x >>= 8; *pData++ = x; x >>= 8;
and in the USB_WriteEP function, instead of:
TX_DATA = *((DWORD __attribute__((__packed__)) *)pData);
I used:
TX_DATA = (pData[3] << 24) | (pData[2] << 16) | (pData[1] << 8) | pData[0];
And, just to make sure, in the USB_GetStatus, I changed:
*((__packed WORD *)EP0Buf) = 0;
to:
EP0Buf[0]=0; EP0Nuf[1]=0;
and changed:
*((__packed WORD *)EP0Buf) = (USB_EndPointHalt & m) ? 1 : 0;
EP0Buf[1]=0; EP0Buf[0]=(USB_EndPointHalt & m) ? 1 : 0;
Finally, just to be on the safe side, I used the __attribute__((__packed__)) on ALL structs and unions, even when not done on the original code for Keil C.
"GCC does not correctly (sic?) handle unaligned packed pointers"
I suspect that the handling of unaligned packed pointers is, at best, implementation defined; so you cannot say that GCC is "incorrect" - only that it is "different".
Portable software must never rely upon implementation-defined behaviour!
Hi Andy,
You are right. Although the "__attribute__((__packed__))" keyword was supposed to do the 'trick'. And the code is far from portable... ;-)
Regards, Sergio.
"the code is far from portable"
Did it ever claim to be?
It was, presumably, supplied as sample code for the Keil compiler?
Therefore, one would expect it do demonstrate the particular features of that compiler - and this would naturally make it non-portable, wouldn't it...?
Hi again,
Just to clarify: When I said "GCC does not correctly handle unaligned packed pointers". I was saying that the keyword "__attribute__((__packed__))" was not doing what it was intended to do.
About portable code, I did not mention it originally. If the code is portable or not, I really don't care. I am not a believer in 'portable code' for embedded systems anyway. ;-)
IMHO the code was supplied as sample code for the Keil product (not just the compiler, as it claims to work with GCC also) and the MCB2300 board that they sell (and I bought, so I am not stealing code). I was trying to make it work in one of its available configurations.
I would like to thank Sergio Sider you as your efforts also helped to solve this USB issue.
Akshat mehra.akshat@rediffmail.cim
Hello Sergio,
If you change the USBMEM example in such a way that it uses allocated memory (heap) instead of static memory (byte array) than it should be possible to use the default compiler in evaluation version.
Best Regards, Martin
Akshat, you're welcome...
Martin, thanks.. good idea!