2014/10/19

[nrf51]softdevice_sys_evt_handler_set()は、何だ? - (3)

ちょっと追った。

softdevice_sys_evt_handler_set()は、sd_common/softdevice_handler.cにある。
これは、m_sys_evt_handlerという変数に覚えるだけ。

使っているのは、intern_softdevice_events_execute()だけ。
これの呼び出し元は、SWI2_IRQHandler()。
名前からすると、ソフトウェア割り込みのハンドラだろう。
スケジューラの関数が登録されていればそちらを呼び、登録されていなければintern_softdevice_events_execute()を呼ぶ。

ここでいうスケジューラの関数は、SOFTDEVICE_HANDLER_INIT()でスケジューラを使うと指定すると、自動的に割り当てている。
softdevice_evt_schedule()という関数で、やっているのはapp_sched_event_put()でスケジューラに登録するだけ。
登録するのは関数呼び出しで、結局はintern_softdevice_events_execute()を呼ぶようにしている。
私のイメージだと、とりあえず発生したイベントだけは吸い上げて、それをスケジューラに登録するんだろうと思ったんだけど、そうではないんだな。

intern_softdevice_events_execute()では、SoftDeviceからのイベントとBLEスタックからのイベントの両方をさばいている。
SoftDeviceの方は必ず処理するが、BLEスタックはBLE_STACK_SUPPORT_REQDが定義されているときだけだ。
softdevice_sys_evt_handler_set()は引数がNULLの場合には処理されないので、それが"Once the application has registered for the events, it is not possible to possible to cancel the registration"と説明している意味だろう。

 

さて、最初の疑問に戻ろう。
「なんでBLEスタック初期化の中で呼び出しているの?」だ。
関数コメントを信じるなら、SWI2_IRQHandler()はBLEスタックイベントの割込ハンドラらしい。
だから、ble_stack_init()でしか呼び出さないということか。

じゃあ、なんでBLEスタックイベントの割込とSoftDeviceのイベントが一緒になってるんだ?
また、SoftDeviceイベントというのは、sd_evt_get()で取得しているので、enum NRF_SOC_EVTSみたいなのだ。
これはNRF_EVT_FLASH_OPERATION_SUCCESSみたいな定義があることから、必ずしも異常発生だけとは限っていない。

あまり考えても仕方ないから、こんな感じになるだろうか。

  • BLEを使うなら、softdevice_sys_evt_handler_set()でコールバック関数を設定した方がよい。
  • FLASH操作するなら、その処理結果がコールバックされるようである。
  • なので、必ずエラー処理にするのではなく、内容によりけり。

 

現在までで整理した内容を、githubにプッシュした。
残るは、main.cのBLE周りですな。
https://github.com/hirokuma/nrf51822_templete

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。