おはようございます。YIと申します。
下記について、何かご存じでしたら教えてください。
T4 + FreeRTOSで tcp_rcv_dat 関数呼び出しと実際の受信が重なった時なのですが
tcp_rcv_dat 関数 処理が始まって vTaskSuspend (t4_driver.c内)でサスペンドになる前に
xTaskResumeFromISR (t4_driver.c内)が実行されて、その後 tcp_rcv_dat がサスペンドになり
復帰しなくなります。(レジュームがサスペンドを追い越してしまった)
xTaskResumeFromISR は lan_inthdr(t4_driver.c内) からの実行と思われます。
これは、tcp_rcv_dat を実行するタスクと lan_inthdr 割り込みの優先順位の設定に問題があるの
でしょうか。(e2studioのコンフィギュレータ設定を間違えている?)
以上、よろしくお願いいたします。
YIさん
シェルティです、こんにちは。T4の設計者です。
これ不具合かもしれないです。申し訳ありません。少し調べてみます。
以下T4のコードです。
https://github.com/renesas/rx-driver-package/blob/master/source/r_t4_rx/r_t4_rx_vx.xx/r_t4_rx/make_lib/make_lib.zip
以下作りになっています…
シェルティ様
YIです。こんにちは。
お手数をお掛けして申し訳ございませんが、よろしくお願いいたします。
以下作りになっています。
1: tcp_api.c 690行目でtcp_rcv_dat()
2: tcp_rcv_dat()内で754行目でdis_int()で割込み禁止 -> 続く処理にてAPIリクエストを受け付ける(TCB構造体にリクエスト情報を書き残す)
3: tcp_rcv_dat()内で771行目でena_int()で割込み許可
4: tcp_rcv_dat()内で773行目でAPI完了待ちの為_tcp_api_req()が呼ばれる
4a: _tcp_api_req() 内で850行目で_tcp_api_slp()が呼ばれる -> APIリクエストの完了待ちに入る
3のときに何らか受信イベントが発生すると確かに「APIリクエストの完了待ち」に入る前に「APIの完了報告があがる」ことが起きてしまい、4aでデッドロックしそうです。3を消せば治りそうですがコードの作り(関数内でopen/closeが対にならない)がおかしくなるので、治し方は要検討ですね。また、送信側も同様な問題がありそうです。
少しさらに深堀してみます。
以上です
t4_driver.c内のSuspendとResumeを下記のように置き換えてみました。
tcpの関数が動作しているタスクが1つなのでtid未使用で固定値としました。
(tidを更新するタイミングがありませんでした)
とりあえず動作していると思います。
このような修正でも良いでしょうか。
/* * sleep current task */static ER rtos_slp_tsk(void){#if BSP_CFG_RTOS_USED == 1 // FreeRTOS#if 0 // Sunpend置き換え vTaskSuspend(NULL);#else ulTaskNotifyTake( pdFALSE , portMAX_DELAY);#endif return E_OK;
#elif BSP_CFG_RTOS_USED == 4 // Renesas RI600V4 & RI600PX return slp_tsk();#else return E_OK; /* nothing to do */#endif}
/* * wake-up task by id/handle */static ER rtos_wup_tsk(uint32_t tid){#if BSP_CFG_RTOS_USED == 1 // FreeRTOS if(0 == tid) { return E_ID; }
#if 0 // Resume置き換え if(0 == (get_psw() & 0x20000)) */ { xTaskResumeFromISR((TaskHandle_t) tid); } else { vTaskResume((TaskHandle_t) tid); }#else if(0 == (get_psw() & 0x20000)) */ { BaseType_t xHigherPriorityTaskWoken; xHigherPriorityTaskWoken = pdFALSE; vTaskNotifyGiveFromISR( xTaskEther, &xHigherPriorityTaskWoken ); portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); } else { xTaskNotifyGive( xTaskEther ) ; }#endif return E_OK;
・ ・ ・ ・