AnsweredAssumed Answered

KSDK_1.0.0 の「vertual_com.c」の動作で「usb_dev.c」にて HardFault する。

Question asked by 山崎 直己 on Feb 14, 2015

「usb_dev.c」での HardFault の回避方法を教えてください。

よろしくお願いします。

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    KSDK_1.0.0 インストール   => インストール後再起動

        インストール先

            D:\Temp\Freescale\ksdk_1.0.0

 

        カスタム設定で以下をチェック

            KSDK_1.0.0

            FreeRTOS_V8.0.0

 

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    IAR Embedded Workbench IDE を起動。

   

        以下のワークスペースを開く

 

            D:\Temp\Freescale\KSDK_1.0.0\usb\example\device\cdc\

            virtual_com\sdk\iar\dev_cdc_virtual_com_frdmk64f120m_freertos

            dev_cdc_virtual_com_frdmk64f120m_freertos.eww

 

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    Make    (DebugモードでMakeする。(とりあえず))

 

        ksdk_freertos_lib - Debug                           エラー: 0, ワーニング: 0

            以下のオプション設定を変更する。

                一般オプション

                    「MISRA-C2004」タブ

                        MISRA-Cを有効にする(E): チェック有り -> チェックを外す。

 

        usbd_sdk_frdmk64f120m_freertos - Debug              エラー: 0, ワーニング: 29

            オプションの変更は無し。

        dev_cdc_virtual_com_frdmk64f120_freertos - Debug    エラー: 0, ワーニング: 0

            オプションの変更は無し。

            右クリックして「アクティブに設定」を選択する。

 

          <Source code「virtual_com.c」の変更>

             1. sources配下の virtual_com.c の 392行目からの「void Virtual_Com_App(void)」

                に以下(001)または(002)を追加する。(追加のパターンは(001)=正常と(002)=異常の 2種類)

             2. sources配下の virtual_com.c の最後尾に

                「int str_copy(uint8_t dst_str[], uint8_t src_str[])」と

                「int strlen(uint8_t char_count[])」

                を追加する。

             3. 「Virtual_Com_App(void)」より前に以下を定義する。

                「int str_copy(uint8_t dst_str[], uint8_t src_str[]);」

                「int strlen(uint8_t char_count[]);」

 

        をそれぞれMakeする。

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    デバッガの設定

     1. dev_cdc_virtual_com_frdmk64f120_freertos - Debug を右クリックしてオプションを開く

     2. カテゴリのデバッガを選択して、設定タブの ドライバ(D):で「I-jet/JTAGjet」を選択する。

     3. カテゴリのデバッガ配下の「I-jet/JTAGjet」を選択を選択して設定タブのリセット(R):を

        ハードウェアに設定する。

     4. 同じく「I-jet/JTAGjet」の設定タブの ターゲット電源の「プローブから供給(F)」

        のチェックを外す。

     5. 「JTAG/SWD」の設定タブの インタフエースで「SWD(S)」を選択する。

     6. OKを押してオプション設定を終了する。

 

     7. コンパイル後、デバッガを起動させ、mainで停止後、一度ハードリセットを実行する。、

        再度mainで停止した箇所からプログラムを「実行」させる。(この時点ではまだ

        TeraTermは起動しない。)

     8. TeraTermを起動させてUSB-Serialドライバで指定したCOMポート番号に接続。

        (PCにはあらかじめ「mchpcdc.inf」にてドライバを設定しておく。)

        ☆ ハードリセットは、TeraTermを終了させてから実施する。

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

    確認

     1. 001 の場合は、Enterをキーボートから押下すると改行後に「Prompt> 」が表示される。

        回数に制限が無く正常に応答する。(表示は正常)

        ┌──────────────────

        │

        │Prompt>

        │Prompt>

        │Prompt>

        │Prompt>

        │   :

        │

 

    2. 002 の場合は、Enterをキーボートから押下すると、以下のように表示され、

        11回目に以下の場所で止まる。(表示も異常)

        ┌──────────────────

        │

        │Prompt> PrPrompt> PrPrompt>

        │Prompt> PrPrompt>

        │Prompt>

        │Prompt>

        │Prompt>

        │Prompt> PrPrompt>

        │

 

     3.停止位置

         1. 以下の「HardFault_Handler」の下の「B .」でカーソルが止まっている。

 

            startup_MK64F12.s の385行目

 

                    :

                    PUBWEAK NMI_Handler

                    SECTION .text:CODE:REORDER:NOROOT(1)

            NMI_Handler

                    B .

 

                    PUBWEAK HardFault_Handler

                    SECTION .text:CODE:REORDER:NOROOT(1)

            HardFault_Handler

                    B .                                      <= 385 行目

 

                    PUBWEAK MemManage_Handler

                    SECTION .text:CODE:REORDER:NOROOT(1)

            MemManage_Handler

                    B .

                    :

 

         2. 逆アセンブリのウインドウでは、以下の「0x5bc6: 0xe7fe」でカーソルが止まっている。

 

                    :

            HardFault_Handller:

                0x5bc6: 0xe7fe      B.N     HardFault_Handller      ; 0x5bc6

                    :

 

     4. 停止直前の実行箇所

        以下のコード実行時に停止する。

        ファイル名: usb_dev.c

        実行命令:

                OS_dcache_flush_mlines((void*)buff_ptr,size); 内の

                            :

                    /* Initialize the new transfer descriptor */

                    xd_ptr->ep_num = ep_num;

                    xd_ptr->bdirection = USB_SEND;                   <= 2回目の実行後停止(ステップ実行)   1118行目

                    xd_ptr->wtotallength = size;

                    xd_ptr->wstartaddress = buff_ptr;

                    xd_ptr->wsofar = 0;

                    xd_ptr->bstatus = USB_STATUS_TRANSFER_ACCEPTED;

                            :

 

☆ Hard_Faultの回避方法について教えてください。

    よろしくお願いします。

 

/*(001)***************************************************************************/

void Virtual_Com_App(void)

{

    /* User Code */

    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;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <ここから追加> */

        str_copy(g_curr_send_buf, "\r\nPrompt> ");

        g_send_size = 10;

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <追加はここまで> */

    }

 

    if(g_send_size)

    {

        uint8_t error;

        uint8_t size = g_send_size;

        g_send_size = 0;

 

        error = USB_Class_CDC_Send_Data(g_app_handle, DIC_BULK_IN_ENDPOINT,

            g_curr_send_buf, size);

 

        if(error != USB_OK)

        {

            /* Failure to send Data Handling code here */

        }

    }

    return;

}

 

/*(002)***************************************************************************/

void Virtual_Com_App(void)

{

    /* User Code */

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <ここから追加> */

     static int CmdSendRequest;

 

     if (CmdSendRequest == 1) {

        CmdSendRequest = 0;

        str_copy(g_curr_send_buf, "Prompt> ");

        g_send_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; /* - - - - - - - - - - - - - - - <ここを追加> */

    }

 

    if(g_send_size)

    {

        uint8_t error;

        uint8_t size = g_send_size;

        g_send_size = 0;

 

        error = USB_Class_CDC_Send_Data(g_app_handle, DIC_BULK_IN_ENDPOINT,

            g_curr_send_buf, size);

 

        if(error != USB_OK)

        {

            /* Failure to send Data Handling code here */

        }

    }

    return;

}

 

/*****************************************************************************/

int str_copy(uint8_t dst_str[], uint8_t src_str[]);

int strlen(uint8_t char_count[]);

 

int str_copy(uint8_t dst_str[], uint8_t src_str[])

{

    int i;

    int n;

 

    n = strlen(src_str);

    for (i = 0; i < n; i++) {

        dst_str[i] = src_str[i];

    }

    dst_str[i] = 0x00;

    return n;

}

 

/*****************************************************************************/

int strlen(uint8_t char_count[])

{

    int i;

    int c;

 

    c = 0;

    for (i = 0; i < 255 ; i++) {

        if (char_count[i] == 0x00) {

            c = i;

            i = 255;

        }

    }

    return c;

}

 

/*****************************************************************************/

Outcomes