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?
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)
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?
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.
Thank you for pointing to that again. In the shutdown, it should be removed. But what is the state after that?
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.
Hello, the task that initialized CDC class instance should also deinitialize it.
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.
Hi monroe,
I tried to call USB_Class_CDC_Deinit and it returns with USB_OK, there is no issue.
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.
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.
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.
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;
}
}
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.