FreeRTOS on ATmega328
Pandaの手足(予定)にI2Cの専用ICじゃなくてAVRでもぶら下げて、ある程度はそっちで処理してから送るようにした方が良いんじゃないかと思いついて、この前買ってきたATmega328を使って試してみようと思ってコードを書き始めたら、I2Cのスレーブ処理が予想以上にめんどくさく、RTOSなしで割り込みを駆使するよりも、RTOSでタスクごとに分けて書いた方がすっきりするんじゃないか?と思い立ってRTOSを探した。
汎用的で、軽いのを探していたらFreeRTOSというのがあった。複数のアーキテクチャに対応している上に、プリエンプティブ型で信頼性が高そう。
標準で入っているデモと機種依存コードはATmega323(すでに廃品種)とAVR32用しかなかったので、ツギハギで328用に変更した。
ポーティング時に書いたメモを備忘録として書いておく。
- makefileのターゲットをatmega328に変更
- ポーティングディレクトリ Source\portable\GCC\ATMega328を作成(323のコピー)
- makefileのポーティングディレクトリを変更
- serial.cのレジスタがURATが一つしかない場合も数字付きになったので変更する(UART0)
- ISRヘッダの名前も変化しているので、修正した
- SIG_UART_RECV→USART_RX_vect(/* USART, Rx Complete */)
- SIG_UART_DATA→USART_UDRE_vect(/* USART Data Register Empty */)
- タイマ関係も変更 port.c
- 323で使用しているタイマ 16Bitタイマ1→基本的に互換あり
- コンペアマッチリセットの設定は同じ
- 割り込みマスクレジスタTIMSKがタイマごとに独立になった
- TIMSK→TIMSK1(タイマ1専用マスク)
- portCOMPARE_MATCH_A_INTERRUPT_ENABLE=2
- エラー修正
- コンペアマッチA割り込み発生→リセットがかかっている=
- lssファイルを確認すると、割り込みベクタが生成されていない
- コンペアマッチのベクタを認識していない→ISR構文で記述する
- コンペアマッチA割り込み発生→リセットがかかっている=
デバッグはシミュレータのステップ実行で何とかなった。
最後の問題は、オリジナルだと
void SIG_OUTPUT_COMPARE1A( void ) __attribute__ ( ( signal, naked ) );
void SIG_OUTPUT_COMPARE1A( void )
と書いてある部分が割り込みベクタ生成部だと思われるが、割り込みベクタが作られないので、
ISR( TIMER1_COMPA_vect, ISR_NAKED )
のように、ISR()マクロで作るようにしたところうまくいった。
WinAVRの古い構文(現在は非推奨)を使っている?
とりあえず、デモがエミュレータで動いたので、テスト用基板を作って実際に動いているところを撮影した。
I2Cテスト用にI2C EEPROMも乗っけてみた。