各位、ご協力ありがとうございます。
「Virtual_Com_App」 で 送信処理を実施したときに、11回送信後、Hard Fault する現象に関して、解決しましたので報告します。
以下のモジュールによる送信後に、送信するために獲得したバッファの解放がされていない事が原因でした。
< モジュール名:usb_status usb_dci_khci_send() >
└> ここの出口で解放処理を追加すると受信側の解放と重複して動作しませんでした。
バッファの数は「usb_dev_ptr->xd_entries」にエントリされていて、起動時(未接続)は「12」に設定されています。
その状態からターミナルに接続すると接続処理で 2個使用されて「10」に減少します。
そのため、「 /* User Code */ 」の位置に送信処理を追加すると、1回送信する毎に減少していき、
11回目には「0」となっているため、バッファが獲得できず、送信バッファのアドレスが「0」で返り、
上記で説明した箇所で アドレスへの「0」のアクセスにより Hard Fault していました。
「001」の構成で問題無く送信が継続できるのは、受信時にバッファを 1個解放処理を実施しているためです。
<修正案>
以下の修正案は、「Virtual_Com_App」の送信処理で使用したハンドラ「g_app_handle」を継承する
必要があったため、送信処理と同じように「Virtual_Com_App」からの呼び出しルートに従っています。
(左側の数字は行数です。)
----------------------------------------------------------------------------------------------------
・・・\KSDK_1.0.0\usb\example\device\cdc\virtual_com\
virtual_com.c
最初に提示した「002」の 「 /* User Code */ 」の箇所に以下の解放処理を入れる。
static uint32_t Send_Init_Message = 0; /* Global Area に置く */
void Virtual_Com_App(void)
{
/* User Code */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <ここから追加(002)> */
if ((CmdSendRequest == 1)&&(g_recv_size == 0)) {
uint8_t error;
uint8_t cmd_size;
CmdSendRequest = 0;
if ( Send_Init_Message != 0 ) {
usb_cdc_use_buffer_free(g_app_handle); /* ここで send buffer を解放する。*/
}
else {
Send_Init_Message = 1;
}
str_copy(cmd_send_buf, "Prompt> ");
cmd_size = 8;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <追加はここまで> */
if(g_recv_size)
{
int32_t i;
/* Copy Buffer to Send Buff */
for (i = 0; i < g_recv_size; i++)
{
//printf("Copied: %c\n", g_curr_recv_buf[i]);
g_curr_send_buf[g_send_size++] = g_curr_recv_buf[i];
}
g_recv_size = 0;
CmdSendRequest = 1; /* - - - - - - - - - - - - - - - - - - <ここを追加> */
}
:
:
----------------------------------------------------------------------------------------------------
・・・\KSDK_1.0.0\usb\usb_core\device\sources\classes\cdc\
usb_cdc.c
[以下を最後の「/* EOF */」の前に追加]
861 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* @name usb_cdc_use_buffer_free <external application call module>*/
/* @param None */
/* @return usb_status */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
usb_status usb_cdc_use_buffer_free(cdc_handle_t handle)
{
usb_status error = USB_OK;
cdc_device_struct_t * cdc_obj_ptr;
cdc_obj_ptr = (cdc_device_struct_t *)handle;
if (NULL == cdc_obj_ptr)
return USBERR_ERROR;
usb_class_use_buffer_free(cdc_obj_ptr->class_handle);
return error;
}
----------------------------------------------------------------------------------------------------
・・・\KSDK_1.0.0\usb\usb_core\device\sources\classes\common\
usb_class.c
[以下を最後の「/* EOF */」の前に追加]
394 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* @name usb_class_use_buffer_free <external application call module>*/
/* @param None */
/* @return usb_status */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
usb_status usb_class_use_buffer_free(class_handle_t handle)
{
usb_status error = USB_OK;
usb_class_object_struct_t* class_object_ptr = (usb_class_object_struct_t*)handle;
if (NULL == class_object_ptr)
return USBERR_ERROR;
usb_dev_use_buffer_free(class_object_ptr->controller_handle);
return error;
}
----------------------------------------------------------------------------------------------------
・・・\KSDK_1.0.0\usb\usb_core\device\sources\classes\common\
usb_class_cdc.h
[以下を最後の行に追加]
237 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* @name usb_class_use_buffer_free <external application call module>*/
/* @param None */
/* @return usb_status */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
usb_status usb_class_use_buffer_free(class_handle_t handle);
244 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* @name usb_cdc_use_buffer_free <external application call module> */
/* @param None */
/* @return usb_status */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
usb_status usb_cdc_use_buffer_free(cdc_handle_t handle);
/* * * * * * * < external application call module end > * * * * * */
----------------------------------------------------------------------------------------------------
・・・\KSDK_1.0.0\usb\usb_core\device\sources\controller\
usb_dev.c
[以下を最後の行に追加]
1585 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* @name usb_dev_use_buffer_free <external application call module>*/
/* @param None */
/* @return usb_status */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
usb_status usb_dev_use_buffer_free(usb_device_handle handle)
{
usb_status error = USB_OK;
// xd_struct_t* xd_ptr;
usb_dev_state_struct_t* usb_dev_ptr;
if (handle == NULL)
{
#if _DEBUG
printf("usb_device_send_data: handle is NULL\n");
#endif
return USBERR_ERROR;
}
usb_dev_ptr = (usb_dev_state_struct_t*)handle;
error = usb_khci_use_buffer_free(usb_dev_ptr->controller_handle);
return error;
}
----------------------------------------------------------------------------------------------------
・・・\KSDK_1.0.0\usb\usb_core\device\sources\controller\
usb_dev.h
[以下を最後の「/* EOF */」の前に追加]
160 /* * * * * * * * < external application call module > * * * * * * */
usb_status usb_dev_use_buffer_free(usb_device_handle handle);
/* * * * * * * < external application call module end > * * * * * */
----------------------------------------------------------------------------------------------------
・・・\KSDK_1.0.0\usb\usb_core\device\sources\controller\khci\
khci_dev.c
<Global Variablesの箇所>
143 static xd_struct_t* previous_xd_ptr;
< モジュール名:usb_status usb_dci_khci_send() >
1612 previous_xd_ptr = xd_ptr;
[以下を最後の行に追加]
2265 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* @name usb_khci_use_buffer_free <external application call module> */
/* @param None */
/* @return usb_status */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
usb_status usb_khci_use_buffer_free(usb_device_handle handle)
{
uint32_t i;
uint8_t ep_num;
usb_status error = USB_OK;
xd_struct_t* xd_ptr;
usb_khci_dev_state_struct_t* state_ptr = (usb_khci_dev_state_struct_t*)handle;
if (handle == NULL)
{
#if _DEBUG
printf("usb_device_send_data: handle is NULL\n");
#endif
return USBERR_ERROR;
}
xd_ptr = previous_xd_ptr;
usb_dci_khci_free_xd(state_ptr, xd_ptr);
return error;
}
----------------------------------------------------------------------------------------------------
・・・\KSDK_1.0.0\usb\usb_core\device\sources\controller\khci\
khci_dev.h
[以下を最後の行に追加]
76 /* * * * * * * * < external application call module > * * * * * * */
usb_status usb_khci_use_buffer_free(usb_device_handle handle);
/* * * * * * * < external application call module end > * * * * * */
----------------------------------------------------------------------------------------------------
また、virtual_com.c のタスク処理にて「vTaskDelay( )」を追加しました。
(無い場合タスク切替えが動作せず、正常に動作しない事が有りました。)
:
:
if((start_app==TRUE) && (start_transactions==TRUE))
{
Virtual_Com_App();
}
vTaskDelay( 10 ); // 10ms Task Delay <- ここに追加(時間は調整要)
:
:
----------------------------------------------------------------------------------------------------
─── 以上 ───