How to close virtual com?

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

How to close virtual com?

2,047 Views
monroe
Contributor I

I use the virtual com to receive data from PC, and it works normal.

After finish receive data I want to disconnect and close virtual com.

I try call USB_Class_CDC_Deinit(g_app_handle) to finish the receive job.

Then I got a task error "mqx_not_resource_owner" on doing "_usb_device_deinit".

my flow is -

1. Init virtual com.

2. Receive data from PC.

3. call USB_Class_CDC_Deinit to disconnect with PC.

I try call USB_Class_CDC_Deinit on callback function.

It works normal.

but this not meet my requirement.

Is there something wrong with me?

Labels (1)
Tags (5)
0 Kudos
13 Replies

1,587 Views
monroe
Contributor I

Hi Juraj,

Is this what you need?

USB_Class_CDC_Deinit    .....(usb_cdc.c)

    _usb_device_deinit      ......(dev_main.c)

        _usb_device_shutdown     .....(dev_shut.c)

             USB_mem_free((pointer)usb_dev_ptr->SERVICE_HEAD_PTR) ==>(as _lwmem_free)   .....(lwm_free.c)

0 Kudos

1,587 Views
JuroV
NXP Employee
NXP Employee

Yes, thank you.

What happens if you remove the lines from khci_dev_main.c:2184 - 2196:

    /* Free all the Callback function structure memory */

    USB_mem_free((pointer)state_ptr->SERVICE_HEAD_PTR);

 

    /* Free all internal transfer descriptors */

    USB_mem_free((pointer)state_ptr->XD_BASE);

 

    /* Free all XD scratch memory */

    USB_mem_free((pointer)state_ptr->XD_SCRATCH_STRUCT_BASE);

 

    /* Free the temp ep init XD */

    USB_mem_free((pointer)state_ptr->TEMP_XD_PTR);

 

    /* Free the USB state structure */

    USB_mem_free((pointer)state_ptr);

and then rebuild USB DDK?

1,587 Views
monroe
Contributor I

I have same error on doing "USB_mem_free((void*)(handle))" after _usb_device_shutdown.

uint_8 _usb_device_deinit(_usb_device_handle  handle)

{

   USB_DEV_STATE_STRUCT_PTR usb_dev_ptr;

   uint_8 error;

   error = _usb_device_shutdown(handle);

  USB_mem_free((void*)(handle));

   return error;

}

USB_STATUS _usb_device_shutdown(_usb_device_handle handle)

{

    USB_STATUS error;

    volatile USB_DEV_STATE_STRUCT_PTR usb_dev_ptr;

    ....

    usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;

    ...

    /* Free the USB state structure */ 

    USB_mem_free((pointer)usb_dev_ptr);

    return  error;  

}

There seems a problem on free memory.

The handle was already free in "_usb_device_shutdown".

After that, on _usb_device_deinit, it try to free handle again.

0 Kudos

1,587 Views
JuroV
NXP Employee
NXP Employee

Thank you for pointing to that again. In the shutdown, it should be removed. But what is the state after that?

0 Kudos

1,587 Views
monroe
Contributor I

After that I can do USB_Class_CDC_Deinit without errors.

But there is a new problem that I can not reopen vcom.

Though reopen vcom got no error, but PC side shows the USB device is not

available.

For now I don't try to deinit USB cdc device.

I just make a software flag to indicate vcom staste for up layer api.

0 Kudos

1,587 Views
JuroV
NXP Employee
NXP Employee

Hello, the task that initialized CDC class instance should also deinitialize it.

0 Kudos

1,587 Views
monroe
Contributor I

Thank you for reply.

I do USB_Class_CDC_Init and USB_Class_CDC_Deinit in the same task.

But only on callback function USB_Class_CDC_Deinit can working normal.

I think even I do USB_Class_CDC_Init on task A, the usb device resource owner is system but not task A.

So Task A can not deinitialize the usb resource.

Since there is no example code for close vcom, I don't know what is wrong with my procedure.

My project is K60, and I had tried MQX 3.8 and 4.0.

They both have the same problem.

0 Kudos

1,587 Views
JuroV
NXP Employee
NXP Employee

Hi monroe,

I tried to call USB_Class_CDC_Deinit and it returns with USB_OK, there is no issue.

0 Kudos

1,587 Views
monroe
Contributor I

Hi Juraj,

Do you set MQX_CHECK_ERRORS to 1 in mqx_cnfg.h

===============  clip in function _lwmem_free(lwm_free.c)   =====================

#if MQX_CHECK_ERRORS

   /* Verify the passed in parameter */

   if (! ((block_ptr->U.S.TASK_NUMBER == TASK_NUMBER_FROM_TASKID(kernel_data->ACTIVE_PTR->TASK_ID)) ||

          (block_ptr->U.S.TASK_NUMBER == SYSTEM_TASK_NUMBER)))

   {

      _task_set_error(MQX_NOT_RESOURCE_OWNER);

      return(MQX_NOT_RESOURCE_OWNER);

   } /* Endif */

#endif

===================================================================

I always got this error, if I call USB_Class_CDC_Deinit from task not from system callback.

0 Kudos

1,587 Views
JuroV
NXP Employee
NXP Employee

Hi monore,

yes, I have it set, but I have tried Mk70F, that could be a problem as there is another memory management set. I will try with MK60.

0 Kudos

1,587 Views
JuroV
NXP Employee
NXP Employee

I have now tried MQX 4.0 + twrk60n512 + virtual_com example with additional USB_Class_CDC_Deinit call. It works normally without the issue found.

Could you please paste here the call stack to see where your problem happened?

Thank you.

0 Kudos

1,587 Views
monroe
Contributor I

Hi Juraj,

There is my flow:

====================================================

int vcom_test()  // virtual com test func

{

...

    while (1) {

        ch = keypad_getchar();

        if (ch == '1')

              open_com(1, 0);

        if (ch == '2')

              close_com(1);

        if (ch == '3')

              write_com(1, buf);

        if (ch == '9')

              break;

        if (read_com(1, &c))

              printf("read %02x\n", c);

        _time_delay(1);

    }

    return 0;

}

====================================================

static int init_vcom()

{

    CDC_CONFIG_STRUCT cdc_config;

    if (vcom_initd == TRUE)

        return 1;

    if (g_curr_recv_buf == NULL)

        g_curr_recv_buf = _mem_alloc_uncached(DATA_BUFF_SIZE);

    if (endPoint_ptr == NULL)

        endPoint_ptr = USB_mem_alloc_zero(sizeof(USB_CLASS_CDC_ENDPOINT) * CDC_DESC_ENDPOINT_COUNT);

    cdc_config.comm_feature_data_size = COMM_FEATURE_DATA_SIZE;

    cdc_config.usb_ep_data = &usb_desc_ep;

    cdc_config.desc_endpoint_cnt = CDC_DESC_ENDPOINT_COUNT;

    cdc_config.cdc_class_cb.callback = usb_cdc_callback;

    cdc_config.cdc_class_cb.arg = &g_app_handle;

    cdc_config.vendor_req_callback.callback = NULL;

    cdc_config.vendor_req_callback.arg = NULL;

    cdc_config.param_callback.callback = usb_para_callback;

    cdc_config.param_callback.arg = &g_app_handle;

    cdc_config.desc_callback_ptr = &desc_callback;

    cdc_config.ep = endPoint_ptr;

    cdc_config.cic_send_endpoint = CIC_NOTIF_ENDPOINT;

    /* Always happend in control endpoint hence hard coded in Class layer*/

    cdc_config.dic_send_endpoint = DIC_BULK_IN_ENDPOINT;

    cdc_config.dic_recv_endpoint = DIC_BULK_OUT_ENDPOINT;

    if (MQX_OK != _usb_device_driver_install(USBCFG_DEFAULT_DEVICE_CONTROLLER)) {

        return 1;

    }

    /* Initialize the USB interface */

    g_app_handle = USB_Class_CDC_Init(&cdc_config);

    flag_vcom_status = 1;

    vcom_initd = TRUE;

    ...

    return 0;

}

====================================================

int open_vcom()

{

    if (vcom_initd == FALSE) {

        return init_vcom();

    }

    if (flag_vcom_status == 0) {

      ...

        flag_vcom_status = 1;

        return 0;

    }

    return 1;

}

====================================================

int close_vcom()

{

    USB_Class_CDC_Deinit(g_app_handle);

    ...

    return 1;

}

====================================================

int read_vcom(char *c)

{

   if (g_recv_size > 0) {

       *c = get_ring_buf();

       return 1;

   } else {

        //       printf("Buffer is empty\n");

        return 0;

   }

}

====================================================

int write_vcom(const char *s)

{

    int size = strlen(s);

    if ((start_app == TRUE) && (start_transactions == TRUE)) { // non block write

        uint_8 error;

        error = USB_Class_CDC_Send_Data(g_app_handle, DIC_BULK_IN_ENDPOINT, (uint_8_ptr)s, (uint_32)size);

        if (error == USB_OK) {

           return size;

        } else { /* Failure to send Data Handling code here */

        }

    } else { // USB not ready

        return 0;

    }

}

0 Kudos

1,587 Views
JuroV
NXP Employee
NXP Employee

Hello monroe,

I meant if you could type here the program flow since call of USB_Class_CDC_Deinit until _task_set_error(MQX_NOT_RESOURCE_OWNER) happens- what is called and where.

0 Kudos