HS USB CDC device freezing on K28

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

HS USB CDC device freezing on K28

1,613 Views
jeff_hane
Contributor I

Hello,

  I'm working with a FRDM-K28F board running FreeRtos with SDK version 2.5.0.   I am basing my project on the dev_cdc_vcom_freertos example.  

  The board is booting and I can see /dev/ttyACM1 on my linux box.  I'm using python's serial class to open the device and write to the port.  However, in a very short amount of time the k28 appears to hang and is non-responsive.  I can create problem doing a number of single write less 512 bytes or writing a large chunk of data, like 25k bytes.

  Using usbmon, I can see the bulk writes going out but no response from the device.   If I pause the program, it usually is just spinning in the main task on this code:

if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))
{
   /* User Code */
   if ((0 != s_recvSize) && (0xFFFFFFFF != s_recvSize))

The first if is always true but s_recvSize is always 0.  

I put a breakpoint at the start of the EhciIsr and I never get an interrupt.  However, if I let the host write timeout and then close the serial port I do get the interrupt on the control endpoint and the device responds back.  This tells me it's not totally bricked but it's doesn't seem to be responding to bulk interrupts.  

I'm trying to figure out what to look at next so any ideas would be great.

thanks,

jeff

0 Kudos
7 Replies

1,284 Views
mjbcswitzerland
Specialist V

Hello Jeff

I have just built a uTasker/FreeRTOS reference for the FRDM-K22F which will echo data back for the OpenSDA UART (at 115'200baud) and also a USB-CDC connection on the HS USB interface.
In fact it echoes with "FreeRTOS Echo:" plus the input that it has received.
There are FreeRTOS tasks doing:
- serial reception and echo
- USB-CDC reception and echo
- flashing the red LED
- a uTasker task is flashing the green LED and another controlling low power mode (the CPU will be set to WAIT mode whether nothing is pending).

I only did the K28 port today [received my first FRDM-K28F board yesterday] so I don't know about absolute stability but I would be interested if it withstands your test case (if the echo is not of use there is also a command line interface - not in a FreeRTOS task though - in the serial loader and USB-CDC application that I put on line today at http://www.utasker.com/kinetis/FRDM-K28F.html).

Regards

Mark

0 Kudos

1,284 Views
jeff_hane
Contributor I

Hello,

  Thanks for the example but my problem is not with just a simple echo server.   I'm trying to send variable sized packets ,up to 25K, to the bulk endpoint and the device hangs at random times.  have you tried doing something like that on the CDC device?  I will take a look at your example to look for anything that might be helpful.

thanks,

jeff

0 Kudos

1,284 Views
mjbcswitzerland
Specialist V

Jeff

Since I don't know your application I just used an echo server to check that the packets were correctly received (because if the are they are sent back too).

I threw a few hundred kBytes of data at it (ASCII so that I could also see that it was sending it back correctly) but I don't know whether you do this just as fast as possible or whether you do it with varying packet sizes (1..512 bytes for HS bulk).

I am using the uTasker USB stack and I just did the following in a FreeRTOS task - maybe not optimal in any way - but simple (in fact I have 50ms tick so it is not particularly fast like that but tests that the input flow control is OK):

static void usb_task(void *pvParameters)
{
    QUEUE_TRANSFER length = 0;
    QUEUE_HANDLE usb_handle;
    unsigned char ucRxData[128];
    while ((usb_handle = fnGetUSB_Handle()) == NO_ID_ALLOCATED) {        // get the USB handle
        vTaskDelay(500/portTICK_RATE_MS);                                // wait for 500ms and try again
    }
    FOREVER_LOOP() {
        length = fnRead(usb_handle, ucRxData, sizeof(ucRxData));         // read any usb data received
        if (length != 0) {                                               // if something is available
            fnWrite(usb_handle, (unsigned char *)"FreeRTOS Echo:", 14);  // echo it back
            fnWrite(usb_handle, ucRxData, length);                       // send the data back
            fnWrite(usb_handle, (unsigned char *)"\r\n", 2);             // with termination
        }
        else {                                                           // nothing in the input buffer
            vTaskDelay(1);                                               // wait a single tick to allow other tasks to execute
        }
    }
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Regards

Mark

0 Kudos

1,284 Views
jeff_hane
Contributor I

Hi Mark,

 I am sending variable sized buffers but my problem usually occurs when I write a single large buffer 30 or 40 times.  So basically something like this on the host:

while True:

   ser.write(packet); 

Where packet is 25 kbytes, so most of the packets I get on the NXP  are full with 512 bytes. In the NXP example, echoing back even a single bytes result in a callback to the same function I receive the data in and my theory is at some point this path is taking too long and receive pipe fails to get primed.  I would expect there there would just be a NAK on the bus and the packet would be resent but the problem is the priming in the K28's USB controller.  I just got an USB analyzer so need to check that theory.

Thanks for the input, I'll try to take a look at utasker over the weekend.

jeff

0 Kudos

1,284 Views
mjbcswitzerland
Specialist V

Hi Jeff

The HS USB works with NYET rather than NAK (this saves bus bandwidth since the host doesn't repeat the non-accepted data all the time). But it is true that if the input is not yet ready to receive data it sorts itself out once it can. USB-CDC can tolerate long delays of many seconds or even minutes in this state before the host may start complaining, so short periods (which there always are) where the OUT EP can't yet receive are normal.

You can also try FS USB (there is a switch on the FRDM-K28F ) to compare the behavior between the FS and HS drivers.to see if there is an issue in just one of them.

Regards

Mark



Note that the uTasker project includes simulations of the FS and HS USB so the operation can also be tested in its simulator to see the internal operating details.

0 Kudos

1,284 Views
FelipeGarcia
NXP Employee
NXP Employee

Hi Jeff,

 

By any chance, did you modify the example? Could you please tell me more details abut the modifications you have made if that's the case.

 

dev_cdc_vcom_freertos example echoes back any character it receives, did you change something in the callback in charge to do the echo?

 

Also, could you please run the example as it is mention in the README file, I want to discard that your python's serial class is causing the issue. See the instructions below:

 

Steps:

  1. Connect CDC device to the PC.
  2. In the terminal window, run

# ls /dev/tty*

    Then ’/dev/ttyACM0’ is found.

  1. In the terminal window, run

# minicom -s

  1. To configure the ttyACM0 as the default console and other configurations, run

# minicom

    The ttyACM0 can be opened successfully and user can input characters by using the minicom.

 

Best regards,

Felipe

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

1,284 Views
jeff_hane
Contributor I

Hello,

  I initially tested the demo without modification with minicom with now issues.  However, I want to send large blocks of data so I wrote the python code to try this out and made a modification to the example to just memcpy the recv buffer into the send buffer instead of copying a bytes at a time.  A couple of test seems OK so I started adding packet parsing code to the example.   

   

 I am sending data in chunks of anywhere from 74 bytes to 25K and when I started sending multiple 25K transfers the device started hanging.   I then modified the example to only echo back one byte instead of the full 512 bytes chunks it was received but the problem still persisted.  I also did just try using 'cat' to send data to the tty but same result.

 

 What I have been able to figure out at this time is that to receive another incoming packet the receive endpoint must be primed and this is what "echoing" that data back is doing.  I doesn't need to be the entire buffer, one bytes is sufficient.  However, there seems to be a race somewhere because typically in the middle of a multi-packet transfer, the receive endpoint is NOT being primed.   In other words, I can see when try transfer hangs by looking at the usbmon trace; then if I pause the K28  and look at the USB controller regs on the K28 the prime bit is not set.  

 I have not been able to figure out the exact sequence of event to trigger on to figure out what is causing the priming event to be lost.   I'm surprised this isn't working since this seems like a common thing to want to do.

  Currently I have found if I call 

USB_DeviceCdcAcmRecv(handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_currRecvBufg_UsbDeviceCdcVcomDicEndpoints[0].maxPacketSize);

 

after copying the receive buffer for the kUSB_DeviceCdcEventRecvResponse case, I don't get the hang.  Then I can't parse a single buffer fast enough but that is easier to solve.  

I'm just concerned this is not the right approach since I haven't solve the root problem.

thanks for you input,

jeff

0 Kudos