要約
- 新機能のMCUboot image compressionを試したい!
- nRF Connect SDK v2.9.0に更新したところ、OTA(BluetoothLE経由でのDFU)がエラーで止まってしまう問題が発生した。
- System Workqueueを使っていた時間のかかる処理を、優先度を下げた別のWorkqueueに移すと正常にDFUできた。
状況
- 「自作App + SDK v2.6.x」では、正常にDFUできる。
- 「自作App + SDK v2.9.0」では、nRF Connect(iOSアプリ)でDFUオプションの「Number of buffers」を3以上にすると最初の数チャンクでDFUが止まる。
- 「自作App + SDK v2.9.0」では、nRF Connect(iOSアプリ)でDFUオプションの「Number of buffers」を2にすると正常にDFUできる。(すごく遅い)
- SDK v2.9.0付属のサンプルコードでは、「Number of buffers」が2〜6のいずれの値でも正常にDFUできる。
参考情報
SDK v2.6.1からv2.8.0へ移行して似たような問題に遭遇している方を発見
It turned out that the issue was that the
adc_read_async
call was being performed from within the timer handler. It seems that timer handlers run in ISR context. When performing theadc_read_async
from a work item submitted by the timer handler the system freeze vanishes.
推定
- 前述の方はタイマハンドラでAD変換を実施すると問題が発生している。
- SDK v2.9.0のサンプルコードは動作するが、自作Appと組み合わせると動作しない。(自作Appには時間のかかる処理があり、SystemWorkqueueで実行している(この処理をコメントアウトすると正常にOTAできる))
- OTA処理よりも優先度の高いタスクが長時間実行されると、OTA処理がタイムアウトしてしまうのでは?
対策
- Defining and Controlling a Workqueueに従って、優先度の低いスレッドで実行するWorkqueueを作って、時間のかかる処理はそのWorkqueueで実行する。
#define MY_STACK_SIZE 512 #define MY_PRIORITY 5 K_THREAD_STACK_DEFINE(my_stack_area, MY_STACK_SIZE); struct k_work_q my_work_q; k_work_queue_init(&my_work_q); k_work_queue_start(&my_work_q, my_stack_area, K_THREAD_STACK_SIZEOF(my_stack_area), MY_PRIORITY, NULL);
※時間のかかる処理をSystemWorkqueueで実行するようにしているのであればCONFIG_SYSTEM_WORKQUEUE_PRIORITY
でSystemWorkqueueの優先度を下げるだけで良いのかもしれないです。(未検証)
動作確認環境
- toolchains v2.9.0
- nRF Connect SDK v2.9.0