こんばんは、ファルコンM です。
今回は、PIC でharmony ライブラリでTimer を使用するときの注意点について。
ライブラリの仕様書見てもあんまり詳しく書いてないので、かなりはまった。
harmony のデフォルトは、以下のように設定されている。
harmony で特に何設定することなく使える。
開始時は、
SYS_TMR_HANDLE SYS_TMR_ObjectCreate ( uint32_t periodMs, uintptr_t context, SYS_TMR_CALLBACK callback, SYS_TMR_FLAGS flags)
を使用する。
終了時は、
void SYS_TMR_ObjectDelete ( SYS_TMR_HANDLE handle)
を使用する。
注意点1.Object はMaximum Timer Clients の数だけ作成できる
harmony のsys_tmr.c のソースコードは以下のように書かれている。
static SYS_TMR_HANDLE _SYS_TMR_ClientCreate ( uint32_t periodMs, uintptr_t context, SYS_TMR_CALLBACK callback, SYS_TMR_FLAGS flags ) { -略- for ( index = 0; index < sizeof(sClientObjects)/sizeof(*sClientObjects); index++, timerObj++ ) { if ( timerObj -> currState == SYS_TMR_CLIENT_FREE ) { // found free object -略- timerObj->currState = SYS_TMR_CLIENT_ACTIVE; -略- } } -略- }
SYS_TMR_ObjectCreate を呼んだとき、上記の _SYS_TMR_ClientCreate 関数が呼ばれる。この関数のfor 文で、Maximum Timer Clients の数( sizeof(sClientObjects)/sizeof(*sClientObjects) ) を最大数としてループを回している。空いているオブジェクトがあれば、そのオブジェクトを使用する。
すなわち、Maximum Timer Client の数だけループして、全部使っていれば、新しいオブジェクトは生成されない。新しいタイマーを使えない。
もし、SYS_TMR_ObjectCreateを呼んで、エラーが発生するならば、オブジェクトの最大数を疑ってみるべき。
対策として、
- 使っていないタイマーオブジェクトは、SYS_TMR_ObjectDelete で削除する。
- Maximum Timer Clients の数を増やす。
といったところ。
注意点2.コールバックでObjectDelete はしてはいけない
SYS_TMR_CreateObject 関数でcallback を引数にしている。
その関数内でSYS_TMR_ObjectDelete 関数を呼んではいけない。
理由は、callback 関数を呼ぶ側の処理で、callback関数を呼んだ後、そのオブジェクトの処理を行っているから。
SYS_TMR_ObjectDelete の処理が無効になってしまう。
SYS_TMR_ObjectDelete してもタイマーオブジェクトは残ったままとなる。
この対策として、
- callback 関数を抜けた後、SYS_TMR_ObjectDeleteをする。
- SYS_TMR_ObjectCreate をする前に、SYS_TMR_ObjectDelete をする。
といったところ。
まとめ
もしharmony のTimer を使うのであれば、上記の注意点はしっかり把握しておくことをお勧めする。タイマーはharmony プロジェクトを生成すれば他に何も設定することなく使えるので非常に便利。
コメントを残す