Super Sylphide 進捗状況(28) -- DSPのROMブートでmain()前にPLLを有効に

オートパイロットシステム Super Sylphideですが、ちょっとした佳境を迎えつつあります。そのデバック作業中において遭遇した問題について、今回は記事にしてみようと思います。内容はタイトルのとおり、ブートコードでPLLの設定を完了しなければせならなかったという話です。

Super Sylphideで利用しているDSPはTIのTMS320C6713Bという浮動小数点DSPです。このDSPはROMからブートする場合、以下の2段階の過程を経て行われます。

  1. まず、ROMの先頭1K Bytesが内蔵RAMに自動的にコピーされます。その1KBには、基本的なレジスタの設定、例えば外部に接続されたSDRAMのバス幅やリフレッシュレートなどを書くとともに、プログラムコードやデータを適切な配置となるようコピーするコード、そしてmainに飛ぶコードを埋め込んでおきます。
  2. その1KBのコードが実行されます。つまり基本的なレジスタ設定が完了するとともに、コードやデータが適切なメモリ番地に配置されます。最後にmain()が実行され、晴れてブートプロセスが完了します。

この1KBのブートコードは、なんといってもレジスタ設定やコード配置に関することですから非常に重要です。ということでTIのDSKに付属していたブートコードをベースに、RAMのリフレッシュレートの定数などを少し変更しただけのブートコードをこれまで使ってきました。

しかしながら時たまブートしなくなるという、不安定な症状が発生しました。原因を色々と探ってみたのですが、コードのサイズが少しばかり大きくなると問題が発生するということがわかりました。どうやら外部RAMであるSDRAM上に配置したプログラムコードが時たま予期しないものに書き換わってしまっているようでした。

色々考えてみた結果、タイトルの通りのこと、つまりPLLの初期化をmain()ではなくブートコード上で行うと不安定な状態が解消されることがわかりました。SDRAMのリフレッシュが不足し、データの一部が改変されていたようです。
これまではDSKのサンプルコードに従って、ブートコードが終了しmain()に飛んだ時点でPLLの初期化を行っていたのですが、この状態では本来の速度よりも遅い速度で外部バスが駆動されているので、main()でPLLが設定されるまでリフレッシュのタイミングが予期したものよりも遅くなります。一方、main()が呼ばれる前にブートコードでPLLの初期化を行うと、CPUや外部バスのクロックがコードを配置する以前に本来の速度となり、main()が呼ばれる前のコード配置中においても適切なタイミングでSDRAMのリフレッシュがかかるようになりました。

元にしたDSKのサンプルコードですが、これはこれで正当な方法でブートが行われている、と見ることができることもわかりました。というのも、DSPは高速な演算をさせるために、プログラムコードは外部RAMにおかず、内部RAMにおくというのが有る意味作法となっているからです。内蔵RAMはSRAMでありリフレッシュは必要ないので、PLLによってクロックが変化しようが問題ない、つまりPLLの設定はどこで行っても問題がないということなのでしょう。

最後に現在のブートコード(boot6713.asm)と、PLL初期化がない古いブートコード(boot6713.asm.r3660)を置いておきます。直接参考になるコードがなかった(C672xのブートに関する資料(jaja100.pdf)は参考になった)ので、ニーモニックを調べたりCコンパイラが吐くアセンブラを見ながら、なんとかハンドコーディングできました。

※進捗状況とはちょっと異なりますが、新たな関連文章をリリースしたのでお知らせします。『システム同定による小型無人航空機の飛行特性の取得』。Super Sylphideが計測装置として活躍しています。

※※新システム Tiny Featherを開発しはじめました。

February 03, 2010 00:07 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク

コメント

コメントする