USBD_API->hw->Init() will fail by garbage beyond the end of USB_FsConfigDescriptor[]

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

USBD_API->hw->Init() will fail by garbage beyond the end of USB_FsConfigDescriptor[]

2,245 Views
shigeuratan
Contributor II

Hi.

I'm testing LPC11U35FHI33/501, now about USB-ROM driver
with the example of 'nxp_lpcxpresso_11u37_usbd_rom_composite' from
lpcopen_v2_03_lpcxpresso_nxp_lpcxpresso_11u37h.zip.

The sample works well, but I've noticed that some garbage following
USB_FsConfigDescriptor[] can make USBD_API->hw->Init() to fail.
(The marking on my chip is "0 11U35 / Z 57 02 / 4492A50")

Let me show the sample case.

CASE I

Change the 'Terminator' description of USB_FsConfigDescriptor[]
in composite_desc.c like below,
then USBD_API->hw->Init() will fail with ERR_USBD_BAD_EP_DESC.

+-------------------------------------------------
| /* Terminator */
| 0 /* bLength */
+-------------------------------------------------
  | | |
  V V V
+-------------------------------------------------
| /* Terminator */
|// 0 /* bLength */
| 0x00, 0x05, 0x85, 0x00, 0x00, 0x00, 0x00
+-------------------------------------------------

First 0x00 shall be the terminator, but by second 0x05,
Init() may continue to process it as USB_ENDPOINT_DESCRIPTOR,
then may sense third 0x85 as bEndpointAddress,
and will fail if it is out of usb_param.max_num_ep.

CASE II

Change the 'Terminator' description of USB_FsConfigDescriptor[]
in composite_desc.c like below,
then USBD_API->hw->Init() will fail with ERR_USBD_BAD_MEM_BUF.

+-------------------------------------------------
| /* Terminator */
| 0 /* bLength */
+-------------------------------------------------
  | | |
  V V V
+-------------------------------------------------
| /* Terminator */
|// 0 /* bLength */
| 0x00, 0x05, 0x01, 0x00, 0x00, 0x0B, 0x00
+-------------------------------------------------

First 0x00 shall be the terminator, but by second 0x05,
Init() may continue to process it as USB_ENDPOINT_DESCRIPTOR,
then may sense 0x00,0x0B (0x0B00) as wMaxPacketSize,
and will fail if it will not satisfy usb_param.mem_size.


How can I terminate USB_FsConfigDescriptor[] TRULY and *completely* ?

(I did not investigate about any types other than USB_ENDPOINT_DESCRIPTOR.)


Further more, I think, this is the real reason that
"only USB_FsConfigDescriptor[] don't have modifier 'const'".

(We normally don't care what other constant-data will be placed
just after USB_FsConfigDescriptor[], only the linker knows.)

Again, how can I terminate USB_FsConfigDescriptor[] TRULY and *completely* ?

Labels (3)
0 Kudos
Reply
7 Replies

2,118 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Hello Shige,

Let me know if I'm understanding correctly, the example by default works fine but you want to be sure the descriptor ends correctly by adding more information at the end of the descriptor, am I right?

if this is the case I will suggest not add more elements to the structure and if you want to check this behavior modify directly in run time this memory section.

Best Regards,

Alexis Andalon

0 Kudos
Reply

2,118 Views
shigeuratan
Contributor II

> Let me know if I'm understanding correctly,
> the example by default works fine but you want to be sure the descriptor ends
> correctly by adding more information at the end of the descriptor, am I right?

Yes. I only want to know how to stop Init() before processing out of
USB_FsConfigDescriptor[].

> if this is the case
> I will suggest not add more elements to the structure
> and if you want to check this behavior modify directly in run time
> this memory section.

I watched near Terminator memory area just before calling Init()
by printf() like:
+------------------------------------
|if(0) {
| u_char *mem;
| int i;
|
| mem = (u_char *)&USB_FsConfigDescriptor[0x5d];
| for(i=0; i<14; i++) {
| rprintf(" %02x", mem[i]);
| if(i==6) rprintf("\r\n");
| }
| rprintf("\r\n");
|}
+------------------------------------
Was that not enough ?


- * - * -


The USB_FsConfigDescriptor[] is always followed by some data
because the address space is continous and there are no 'NO-DATA' space.
(except the end of memory device, HardwareFault may occure
when accessing no-existance-memory area)

If the problem mentioned by me is true,
most easy and secure way is to describe it in the source code
(not in linker script) explicitly, I think.

In the first place, there is no description about the Terminator in:
full_speed_desc / high_speed_desc section,
10.5.17 _USB_CORE_DESCS_T, in UM10462 (Rev.5.5),
but I added a '0' by imitating sample code.

It might just be two zeros like '0,0' if we are lucky, but
no one knows the true action of Init() except the author of ROM code.

Also, I wish, the description about return value ERR_USBD_BAD_EP_DESC
should be added in: Init section, 10.5.34 USBD_HW_API, UM10462,
if it returns it.

- * - * -

P.S.

To Decrease usb_param.max_num_ep back before
"WORKAROUND for artf44835 ROM driver BUG:"
may not have any relation with the problem.

0 Kudos
Reply

2,118 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Hello Shigue,

What I mean with my suggestion and as you mention, since we don't know how the ROM code calculates the size of the descriptor, will be better to not add anything at the same structure. Have you try using a pointer to the end of the structure and not adding more elements to it?

This will let us know more accurately if there's a problem detecting the end of the descriptor.

Best Regards,

Alexis Andalon

0 Kudos
Reply

2,118 Views
shigeuratan
Contributor II

Something doesn't mesh...

The USB_FsConfigDescriptor[] has an exaggerated name
but it is just a plain byte array, not a structure.

  uint8_t USB_FsConfigDescriptor[] = {...};


My first report is based on a sample code:
   'nxp_lpcxpresso_11u37_usbd_rom_composite'
from
   'lpcopen_v2_03_lpcxpresso_nxp_lpcxpresso_11u37h.zip'.

Please get it from NXP site and examine it.

Only 1 line change reported in my first report
should reproduce the phenomenon reported....


- * - * -


By the way, my USB HID device: thumbUZK has begun to work
with USB on-chip driver, including suspend/Power-down/resume.
   (I am now remaking this: http://aid.her.jp/uratan/ArmUZK/)

So I have seen a description:
   "See \ref USBD_ZeroCopy * for more details on zero-copy concept."
in usbd/usbd_hiduser.h, but I could not reach it.

Would anyone teach me where can I get the detail about 'USBD_ZeroCopy' ?


Cause I have found that different methods are used about passing data for
on-chip driver by "HID get report callback function: HID_GetReport".

[a] In Mouse_GetReport() in nxp_lpcxpresso_11u37_usbd_rom_composite/example/src/hid_mouse.c,
   only the pointer is passed to *pBuffer.
     (means the buffer memory is prepared by me)

[b] In Keyboard_GetReport() in nxp_lpcxpresso_11u37_usbd_rom_hid_keyboard/example/src/hid_keyboard.c,
   the data is memcpy()ed onto *pBuffer.
     (means the buffer memory is prepared by on-chip driver, how large is it ?)

Are both OK ?

0 Kudos
Reply

2,118 Views
shigeuratan
Contributor II

I wrote:

> By the way, my USB HID device: thumbUZK has begun to work
> with USB on-chip driver, including suspend/Power-down/resume.

I've found that the USB_WAKEUP bit in STARTERP1 register accepts
not only USB_WAKEUP interrupt but also normal USB_IRQ,
and found my device recovered from Power-down mode(*) by normal DEV_INT
(DSUS_C=1/DSUS=0) without special handling about USB need_clcok signal
described in UM10462: "11.7.6.1 Waking up from Deep-sleep and Power-down modes on USB activity"

(*) it seems to be in Power-down mode because:
  (a) external 12MHz oscillator is stopped (confirmed by oscilloscope).
  (b) internal IRC might be stopped (confirmed thru CLKOUT pin).
  (c) power consumption 5.5mA is lower than that of 6.6mA while RESET-hold, or 8.9mA uart-ISP mode.

And also found that Systick interrupt has ability to wake up the chip from Power-down mode.
  (accurately, pending request of Systick prevent to sleep/WFI)

If these are true, please describe them somewhere in the UM10462, I hope...

0 Kudos
Reply

2,118 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Hello Shige,

In the following note, it mentions that the wake-up event is called from the USB_ISR:

pastedImage_1.png

But only to ensure the behavior of the module, I will suggest following the process mention in the 11.7.6 USB wake-up.

Best Regards,

Alexis Andalon

0 Kudos
Reply

2,118 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Hello Shige,

Check my answers below:

Would anyone teach me where can I get the detail about 'USBD_ZeroCopy'?

Zero-copy buffers can improve system performance over copied buffers when transferring large amounts of data. Zero-copy buffers also use less memory for data storage, since you have a dedicated DMA engine in the USB module.

[a] In Mouse_GetReport() in nxp_lpcxpresso_11u37_usbd_rom_composite/example/src/hid_mouse.c, only the pointer is passed to *pBuffer.
 (means the buffer memory is prepared by me)

That's right but the report size is fixed, MOUSE_REPORT_SIZE = 3;

 

[b] In Keyboard_GetReport() in nxp_lpcxpresso_11u37_usbd_rom_hid_keyboard/example/src/hid_keyboard.c, 

the data is memcpy()ed onto *pBuffer.
(means the buffer memory is prepared by on-chip driver, how large is it ?)

This also is prepared by you, in the memcpy function, the pbuffer is at the destination section and the length is also fixed, KEYBOARD_REPORT_SIZE = 8;

Best Regards,

Alexis Andalon

0 Kudos
Reply