osPfsInitPak.htm 8.52 KB
<HTML>
<HEAD>
<TITLE>HTML 文書</TITLE>
<META NAME="GENERATOR" CONTENT="mitu">
</HEAD>

<BODY>

<P>
<B><FONT FACE="Arial">osPfsInitPak(3P)<BR>
</FONT></B>
<P>
<B>関数名<BR>
</B>
<P>
osPfsInitPak  
<P>
→ コントローラパックのファイルハンドルの初期化<BR>

<P>
<B>構文<BR>
</B>
<P>
#include &lt;ultra64.h&gt;<BR>

<P>
<B>s32 osPfsInitPak (OSMesgQueue *mq,  OSPfs *pfs,  int controller_no);<BR></B>

<P>
<B>説明<BR>
</B>
<P>
コントローラパックを扱うためのファイルハンドルであるOSPfs構造体pfsの初期化を行います。一番初めにコントローラパックを扱う場合や、新しくコントローラパックが差し込まれた場合、まず最初にこの関数を呼んでください。
<BR>

<P>
コントローラパック関数では、ファイルシステムを制御するときに、OSPfs構造体pfsをファイルハンドルのように用いてアクセスを行います。関数osPfsInitPakはこのOSpfs構造体を初期化します。controller_noはコントローラパックが挿し込まれているコントローラの番号(0〜3)を指定します。mqはOS_EVENT_SIと関連付けられた初期化されたメッセージ待ち行列です。この関連付けの方法に関しては、<A HREF="osSetEventMesg.htm">osSetEventMesg</A>,(3P)を参照してください。関数osPfsInitPakの内部では、mqでメッセージ待ちを行っていますので、このmqを共有しないようにしてください。また、OSの低レベルでの同期の初期化のため、osPfsInitPakの呼び出しを行う前に、先に<A HREF="osContInit.htm">osContInit</A>,(3P)を呼び出しておく必要があります。
<BR>

<P>
関数osPfsInitPakの内部では次のような処理を行っています。まずステータスとID領域を調べにいきます。そして、IDが認識できた場合、続いて、関数osPfsCheckerを呼んでいますので、ファイル管理領域が破壊されていた場合、自動的に修復を行っています。
<BR>

<P>
旧来のPFS初期化関数osPfsInitは、ID領域が完全に破壊されていた場合、自動修復を行っていましたが、関数osPfsInitPakでは自動修復を行いません。IDを修復するには、別途に関数osPfsRepairIdの呼び出しが必要となります。以後、通常コントローラパックを初期化する場合には、関数osPfsInitを使用せずに、関数osPfsInitPakの方をご使用ください。また、必ず、関数osPfsRepairIdと組み合わせてお使いください。
<BR>

<P>
この理由としては、次のような可能性があるからです。
<BR>
<P>
接続端子の接触不良などの理由で、一部のアドレスが不定になってしまうことがあります。関数osPfsInitでは最初ID領域を調べにいくのですが、このような場合では、ID領域を調べにいったつもりが、別のアドレスのデータを見てしまい、それがIDではないと判断されてしまいます。そして、旧来のosPfsInitでは、IDを新たに自動的に割り当てるために、その間違ったアドレスに新規IDを書き込んでしまいます。つまり、コントローラパックの内容を破壊してしまうかもしれないのです。
<BR>

<P>
このため、コントローラパックのイニシャライズでは、必ず次のような手順を踏んでください。
<BR>

<P>
まず、関数osPfsInitPakを呼び出してください。エラーコードとして0が返ってきた場合は正常終了です。
<BR>

<P>
エラーコードとして、PFS_ERR_ID_FATALが返った場合には、次のようないくつかの可能性があります。コントローラパックのID領域が破壊されている場合、コントローラパックが正しく接続されていない場合、端子が汚れており、IDを読み出せない場合、コントローラのジョイバスやコントローラパックが故障している場合などです。そのため、この場合、まず、画面上に、「コントローラ、または、コントローラパックに異常があります。きちんと挿し込まれていないか、内容が壊れています」などのメッセージと、「接続しなおす」「修復する(コントローラパックの内容が消去される可能性があります)」という2種類の選択肢を表示します。ユーザが「接続しなおす」を選んだ場合には、関数osPfsInitPakの再呼び出し、「修復する」を選んだ場合には、関数osPfsRepairIdを呼び出し、再び関数osPfsInitPakの呼び出しを行ってください。
<BR>

<P>
エラーが発生したときに返り値として返されるエラーコードには以下のものがあります。<BR>

<P>
<B>PFS_ERR_NOPACK</B>
<P>
指定したコントローラにコントローラパックが挿し込まれていません。あるいは、コントローラが挿し込まれていないなど、何らかのPIfエラーが発生しました。このどちらであるのかを調べる場合には、関数osContStartQuery&osContGetQueryなどを使用してください。
<BR>
<P>
<B>PFS_ERR_NEW_PACK</B>
<P>
コントローラパックが別のコントローラパックに挿し替わっています。このまま、このコントローラパックを使用する場合には、osPfsInitPak(3P)を呼び出して、コントローラパックを初期化してください。
<BR>
<P>
<B>PFS_ERR_CONTRFAIL</B>
<P>
コントローラとのデータ転送の失敗です。関数の内部では、転送エラーが発生した場合、最大3回転送のやり直しを行っています。そのため、このエラーが発生することはあまりありません。このエラーが返る場合、コントローラが正しく接続されていないか、あるは、コントローラパックかコントローラコネクタに異常がある可能性があります。
<BR>
<P>
<B>PFS_ERR_ID_FATAL</B>
<P>
ファイルシステムの初期化を試みましたが、ID領域が壊れていました。コントローラパックが故障しているか、きちんと接続できていないか、あるいは、SRAMを持たない周辺機器が挿し込まれています。
<BR>
<P>
このエラーコードが返ってきた場合、コントローラパックを初期化してもいいかどうか(新しくIDを割り振るか)、あるいは、もう一度コントローラパックの接続を確認してもらうかのどちかかを、まず、ユーザに尋ねてください。そして、コントローラパックを初期化してもよいとユーザが答えた場合には、関数osPfsRepairIdを呼び出してください。
<BR>
<P>
<B>PFS_ERR_DEVICE</B>
<P>
ファイルシステム初期化時に、ページ0にあるID領域中のデバイスIDをチェックしたところ、コントローラパックのデバイスIDではありませんでした。つまり、コントローラパック以外の機器がコントローラに挿さっています。
<BR>
<P>
参考
<BR>
<P>
PFS_ERR_ID_FATALとPFS_ERR_DEVICEの違いは次の通りです。
<BR>
<P>
関数osPfsInitPakで初期化する場合、まず最初に、ID管理領域を調べます。このとき、ID管理領域が壊れていた場合に発生するエラーがPFS_ERR_ID_FATALです。壊れていなかった場合、次にID管理領域中のデバイスIDをチェックします。もし、デバイスIDにコントローラパックを示すビットが立てられていなかった場合に返るのが、PFS_ERR_DEVICEです。
<BR>
<P>
ちなみに、振動パックの場合には、ID管理領域自体が存在しませんので、PFS_ID_FATALが返ります。
<BR>

<PRE WIDTH=132>
<FONT SIZE=6>
</FONT><FONT SIZE=4 FACE="MS ゴシック">
void
mainproc(void) {
  int            i;
  u8             contpat;
  OSContStatus   contstat[MAXCONTROLLERS];
  OSPfs          pfs[MAXCONTROLLERS];

  osContInit(&n_siMessageQ, &contpat, contstat);
  for (i = 0  ; i &lt; MAXCONTROLLERS ; i ++) {
    if ((contpat &gt;&gt; i) & 1) {
      if ((contstat[i].type & CONT_JOYPORT) != 0 &&
          (contstat[i].type & CONT_ABSOLUTE) != 0) {
         do {
           ret = osPfsInitPak(&n_siMessageQ, &pfs[i], i);
           switch(ret) {
           case 0:
             osSyncPrintf(&quot;PORT %dにコントローラパックがささっています\n&quot;, i);
             break;
           case PFS_ERR_NOPACK:
             osSyncPrintf(&quot;PORT %dにはコントローラパックがささっていません\n&quot;, i);
             osSyncPrintf(&quot;コントローラパックをさしてください\n&quot;);
             break;
           case PFS_ERR_NEW_PACK:
             osSyncPrintf(&quot;PORT %dのコントローラパックがさしかえられました\n&quot;, i);
             osSyncPrintf(&quot;このコントローラパックを使います\n&quot;);
             break;
           case PFS_ERR_CONTRFAIL:
             osSyncPrintf(&quot;PORT %dのコントローラの接続に異常があります\n&quot;, i);
             osSyncPrintf(&quot;コントローラが正しく差し込まれているか確認してください\n&quot;);
             break;
           case PFS_ERR_DEVICE:
             osSyncPrintf(&quot;PORT %dのコントローラパックにはセーブできません\n&quot;, i);
             osSyncPrintf(&quot;コントローラパックが正しく差し込まれているか確認してください\n&quot;);
             break;
           case PFS_ERR_ID_FATAL:
             osSyncPrintf(&quot;PORT %dのコントローラパックに異常があります\n&quot;, i);
             osSyncPrintf(&quot;   Aボタン       ...修復を試してみる\n&quot;);
             osSyncPrintf(&quot;   その他のボタン...さしなおす\n&quot;);
            if (AskQuestion(i) == A_BUTTON) {
               osPfsRepairId(&pfs[i]);
             }
             break;
           }
           WaitForPushingAnyButton(i);
         } while (ret != 0) ;
      } else {
          osSyncPrintf(&quot;PORT %dは通常のコントローラではありません\n&quot;, i);
      }
    } else {
      osSyncPrintf(&quot;PORT %dにはコントローラがささっていません\n&quot;, i);
    }
  }

</FONT></PRE>
<P>
<B>参照<BR>
</B>
<A HREF="osPfsRepairId.htm">osPfsRepairId</A>(3P),
<A HREF="osPfsAllocateFile.htm">osPfsAllocateFile</A>(3P),
<A HREF="osPfsChecker.htm">osPfsChecker</A>(3P),
<A HREF="osPfsFileState.htm">osPfsFileState</A>(3P),
<A HREF="osPfsFreeBlocks.htm">osPfsFreeBlocks</A>(3P),
<A HREF="osPfsIsPlug.htm">osPfsIsPlug</A>(3P),
<A HREF="osPfsReSizeFile.htm">osPfsReSizeFile</A>(3P),
<A HREF="osPfsReadWriteFile.htm">osPfsReadWriteFile</A>(3P),
<A HREF="osPfsSetLabel.htm">osPfsSetLabel</A>(3P),
</BODY>

</HTML>