【実施例1】
【0054】
典型的なフレキシブルメッセージングアルゴリズム
下記に、本発明のフレキシブルメッセージングを実行するための、Cプログラミング言語で記述されたアルゴリズムの典型例が示される。本アルゴリズムは特に、各行20文字の、2行のディスプレイスクリーンに使用される。このアルゴリズムでは、2行のメッセージが同時に提示され、現行のディスプレイスクリーン、1つ前のディスプレイスクリーン、次のディスプレイスクリーンを格納する記憶アレイが設けられ、各々の記憶アレイは2行のメッセージを持つことができる。このアルゴリズムは最小限のメモリを使用し、あらゆるプロセッサで効率的に実行することができる。例えば、8ビットのST72F321プロセッサにおいて、このアルゴリズムが要求するメモリの量は134バイトのみで、各42ビットの3つ(現行のメッセージ、次のメッセージ及び1つ前のメッセージ)の表示情報を格納し、適切な変数及びポインタを維持し、両方向の移動を可能とするためのものである。この典型的なアルゴリズムには、一方向(例えば下方または順方向)のみの動作を行う機能性も含まれており、その場合、2つのみの表示情報が格納される。以下、典型的なアルゴリズムに定義される様々な関数の概要を説明する。
【0055】
関数:FlxScrnCircle
この関数は、ユーザが順方向または下方に移動する際に、物理メモリの正しい領域の位置にポインタを操作するものである。より詳しくは、この関数はポインタを操作し、1つ前の表示を示すポインタ(pPrevScrn)を、以前「現行の提示情報」を格納していたメモリ位置とし、現行の表示を示すポインタ(pCurrScrn)は、以前「次の表示情報」を格納しているメモリ位置の位置を示し、次の提示を示すポインタ(pCurrLine)は、以前「1つ前の表示情報」のメモリ領域の1番目のメッセージラインを示す。
【0056】
関数:FlxScrnCircle
この関数は、FlxScrnCircleとは正反対の振る舞いをし、ユーザが逆方向または上方に移動する際に、物理メモリの正しい領域の位置にポインタを操作するものである。より詳しくは、この関数はポインタを操作し、1つ前の表示を示すポインタ(pPrevScrn)を、以前「現行の提示情報」を格納していたメモリ位置とし、現行の表示を示すポインタ(pCurrScrn)は、以前「次の表示情報」を格納しているメモリ位置の位置を示し、次の提示を示すポインタ(pCurrLine)は、以前「1つ前の表示情報」のメモリ領域の2番目のメッセージラインを示す。
【0057】
関数:Flx_IsItEndLoop
この関数は、「次の表示情報」を格納するメモリ位置を示すポインタ(pCurrLine)を操作し、移動の方向(順方向または逆方向)に基づき、正しい行(メッセージ)を指すようにする。従って、順方向に移動している場合には、ポインタは第1の行(メッセージ)sTextを指し、一方、逆方向に移動している場合には、ポインタは第2の行(メッセージ)sText2を指す。ポインタを操作した後、この関数は、フレキシブルメッセージのターミネータを、受け取っているかをチェックする。フレキシブルメッセージのターミネータを受け取ると、関数FlxEndLoopProcessが呼び出され、ポインタをNULL状態に設定する。
【0058】
関数:FlexStartFirstLine
この関数は、ルーチンが最初のフレキシブルメッセージから開始された場合に、メッセージ提供システムから、最初のフレキシブルメッセージ(フレキシブルメッセージ1)を取得する。すなわち、静的メッセージのブロックを順方向に抜け出ることにより、このルーチンが開始された場合である。
【0059】
関数:FlexStartFromLastLine
この関数は、ルーチンが最後のフレキシブルメッセージNから開始された場合に、メッセージ提供システムから、最後のフレキシブルメッセージ(フレキシブルメッセージN)を取得する。すなわち、静的メッセージのブロックを逆方向に抜け出ることにより、このルーチンが開始された場合である。
【0060】
関数:DefaultStatusPrevFlexible
この関数は、ユーザが静的メッセージングに移行する際に、静的メッセージを扱うために従来のレガシーコードを使用できるようにする。この関数は、関数InitialTheLastFlexibleMessageによってシステムの電源投入後一度だけ呼び出されて、フレキシブルメッセージングに使用される変数を初期化する。従って、静的メッセージを扱うために従来のレガシーコードが使用され、一方、フレキシブルメッセージに対してはフレキシブルメッセージングのアルゴリズムが用いられる。
【0061】
関数:InitialTheLastFlexibleMessage
この関数の目的は、システムの起動を円滑にすることである。システムの電源投入後、
この関数は予め設定された期間待ち、それから、変数の初期化を開始し、その後関数DefaultStatusPrevFlexibleを呼び出し、フレキシブルメッセージの提示が、最初のフレキシブルメッセージと最後のフレキシブルメッセージのいずれから開始されているかを判断する。
【0062】
関数:FlexiblelnnerLoopNormal
この関数は、関数FlexibleStringlnnerLoopによって呼び出され、標準的な内部ループの条件をプロセスし、すなわち、ユーザがフレキシブルメッセージループの中間にいる場合に、順方向に移動している場合及び逆方向に移動している場合に関わらずフレキシブルメッセージループから抜け出し、静的メッセージループに入る。この関数は、移動の方向に基づき、INC_RIGHT_CMDコマンドまたはDEC_LEFT_CMDコマンドを送信し、メッセージ提供システムに次のメッセージを要求する。またこの関数は、関数FlexibleStringlnnerLoopによって呼び出される。
【0063】
関数:FlexibleStringlnnerLoop
この関数は、必要に応じて他のすべてのコードセグメントを呼び出す、主要なコードセグメントである。この関数は、ユーザが「上」ボタンを押した場合にはIncFxnPtr、「下」ボタンを押し場合にはDecFxnPtrが呼び出す別セクションのコードによって、呼び出される。
【0064】
//=============================================================
//=============================================================
#define FLEXIBLE_BUFFERS 1 // フレキシブル表示機能
// フレキシブル表示機能の無効時には
//0とする
#if FLEXIBLE_BUFFERS
#define FULL_LINE_SIZE_BUFF 21 // ディスプレイの物理的サイズに1を加えて
//決定される
#define BOTH_UPDOWN_DIRECTION 1 // 両方向の移動を可能とする
// 下方/右方のみの移動を行う場合は0を設定する
// 構造体内のバッファsText_nの数は、提示されるメッセージラインの数で決定される。
// FULL_LINE_SIZE_BUFFは、1つのメッセーシ゛の最大サイズに1を加えた値とすべきである。
//
// 下記の構造体は、ディスプレイに2行提示する構造体FLEXBUFFの定義の典型例である。
typedef struct FLEX_BUFF {
char sText[FULL_LINE_SIZE_BUFF]; // 第1の表示メッセージラインを格納する
char sText2[FULL_LINE_SIZE_BUFF]; // 第2の表示メッセージラインを格納する
} FLEXBUFF;
// 構造体FLEXSCNを定義する
typedef struct FLEXIBLE_SCREEN {
char *pCurrLine; // 次に来るメッセージを格納するバッファのポインタ
FLEXBUFF *pCurrScrn; // 現行のディスプレイ表示のポインタ
FLEXBUFF *pPrevScrn; // 1つ前のディスプレイ表示のポインタ
FLEXBUFF sLine[3]; // 本機能を扱うためには3つのFLEXBUFFが必要となる。
char bScreenIndex; // 表示制御パラメータ
// 0、1、2のいずれかの値を持つ、配列sLine[]のインデックスである
// メッセージ制御用の、メッセージ及び表示の状態変数
UBYTE bLoopCnt;
UBYTE bStatus;
// メッセージ要求のトラッキングの記録
UBYTE bIncMsgReq; // メッセージのインクリメント要求をカウントする
#if BOTH_UPDOWN_DIRECTION
UBYTE bDecMsgReq; // メッセージのデクリメント要求をカウントする
#endif
} FLEXSCN;
// ************ bStatus用の定義 ***************
#define fBackEndLoop 0x80 // 第7ビット 1: セットされている場合、逆方向に移動してループの端部に到達したことを示す
#define fAcknowledged 0x40 //第6ビット 1: ACKキャラクタの受信、0:未受信
#define fNotInitialState 0x20 //第5ビット 1: 初期状態でない, 0: 初期状態
#define fEndLoop 0x10 //第4ビット 1: フレキシブル内部ループの端部 (EOMSG)
#define fScrnReady 0x08 //第3ビット 1: 次のメッセージを表示する準備ができている
#define f1stLine 0x04 //第2ビット 1: 1行目, 0: 2行目; 下記の備考を参照
#define fDefaultScrn 0x02 //第1ビット 1: 負/デクリメント/逆方向
#define fIncfunc 0x01 //第0ビット 1: IncFxn, 0: DecFxn;
// 備考:1ビットの代わりに1バイトが使用された場合、256行を収容できる。
FLEXSCN FlxScn; // 物理メモリをここに割り当てる
//=============================================================
//
// 関数: FlxScrnCircle ( )
//
// 説明: 表示のインクリメント/右回りの移動
//
// 入力:
// char bScrnIndex - 表示インデックス番号 ( 0, 1, 2 )
//
//=============================================================
//
void FlxScrnCircle ( char bScrnIndex )
{
FlxScn.pCurrScrn = &(FlxScn.sLine[ bScrnIndex ]);
FlxScn.pPrevScrn = FlxScn.pCurrScrn++;
if ( bScrnIndex == 2 ) // この条件が満たされたときのみ、次の命令文を実行する
FlxScn.pCurrScrn = &(FlxScn.sLine[0]);
// 新しいメッセージを受け取るバッファのポインタ
FlxScn.pCurrLine =
FlxScn.pCurrScrn->sText;
}
//=============================================================
//
// 関数: FlxScrnCounterCircle ( )
//
// 説明: 表示のデクリメント/左回りの移動
//
// 入力:
// char bScrnIndex - 表示インデックス番号 ( 0, 1, 2 )
//
//=============================================================
//
void FlxScrnCounterCircle ( char bScrnIndex )
{
FlxScn.pCurrScrn = &( FlxScn.sLine[ (2 - bScrnIndex) ] );
FlxScn.pPrevScrn = FlxScn.pCurrScrn--;
if ( bScrnIndex >= 2 ) // この条件が満たされたときのみ、次の命令文を実行する
FlxScn.pCurrScrn = &(FlxScn.sLine[2]);
//新しいメッセージを受け取るバッファのポインタ
FlxScn.pCurrLine = FlxScn.pCurrScrn->sText2;
}
//=============================================================
//
// 関数: Flx_IsItEndLoop ( )
//
// 説明: フレキシブルメッセージループの端部かどうか確かめる
//
// 入力:
// char bScrnIndex - 表示インデックス番号 ( 0, 1, 2 )
// UBYTE fIncFxn - 0の場合は上(左)に移動し、その他の場合は下(右)に動かす
//
//=============================================================
//
void Flx_IsItEndLoop ( char bScrnIndex, UBYTE fIncFxn )
{
FLEXBUFF *pScrn; // 適切な表示ポインタ
char *pStr;
if ( !fIncFxn ) //上(左)に移動している場合
{
pScrn = &( FlxScn.sLine[ (2 - bScrnIndex) ] );
pStr = pScrn->sText2; }
else //下(右)に移動している場合
{
pScrn = &( FlxScn.sLine[ bScrnIndex ] );
pStr = pScrn->sText;
}
if ( !*pStr || !strcmp( pStr, "APC" ) )
FlxEndLoopProcess ( );
}
//====================================================
//
// 関数: FlxEndLoopProcess ( )
//
// 説明: フレキシブルメッセージループの端部のプロセス
//
// 入力:なし
//
//====================================================
//
void FlxEndLoopProcess ( void )
{
if ( ValTheBit(FlxScn.bStatus, f1stLine) )
{
if ( FlxScn.pCurrLine == FlxScn.pCurrScrn->sText )
FlxScn.pCurrScrn->sText2[0] = 0;
else
FlxScn.pCurrScrn->sText[0] = 0;
}
#if NO_TERMINATER_DISPLAY
*FlxScn.pCurrLine = 0;
#endif
// 端部を表す文字列を受け取る
SetTheBit( FlxScn.bStatus, (fEndLoop | fScrnReady) );
}
//=============================================================
//
// 関数: FlexStartFirstLine ( )
//
// 説明: 最初のフレキシブルメッセージラインの要求を設定する
//
// 入力: なし
//
//=============================================================
//
void FlexStartFirstLine ( void )
{
ClrTheBit( FlxScn.bStatus, fScrnReady );
FlxScrnCircle ( FlxScn.bScreenIndex );
#if BOTH_UPDOWN_DIRECTION
SetTheBit(FlxScn.bStatus, (fIncfunc | f1stLine | fBackEndLoop) );
#else
SetTheBit(FlxScn.bStatus, f1stLine );
#endif
SendInsertCmd ( INC_MSG_1_CMD );
}
//=============================================================
//
// 関数: FlexStartFromLastLine ( )
//
// 説明: 最後のフレキシブルメッセージラインの要求を設定する
//
// 入力: なし
//
//=============================================================
//
void FlexStartFromLastLine ( void )
{
FlxScrnCounterCircle ( FlxScn.bScreenIndex );
#if BOTH_UPDOWN_DIRECTION
SetTheBit( FlxScn.bStatus, (f1stLine | fBackEndLoop) );
ClrTheBit(FlxScn.bStatus, fIncfunc);
#else
SetTheBit( FlxScn.bStatus, f1stLine );
#endif
SendInsertCmd ( DEC_MSG_N_CMD );
}
//=============================================================
//
// 関数: DefaultStatusPrevFlexible ( )
//
// 説明: 最後のフレキシブルメッセージラインを、既定状態に設定する
//
// 入力:なし
//
//=============================================================
//
void DefaultStatusPrevFlexible ( void )
{
if ( !ValTheBit( FlxScn.bStatus, fDefaultScrn ) )
{
if ( !ValTheBit( bbmCommFlags, fUI_uLinkMode ) ) // レガシーコードの条件
//が満たされる場合、
//付加的な作業を行う
{
#if BOTH_UPDOWN_DIRECTION
if ( EE_default_screen < 4 )
FlexStartFromLastLine ( );
else
#endif
FlexStartFirstLine ( );
}
SetTheBit( FlxScn.bStatus, fDefaultScrn );
}
}
//=============================================================
//
// 関数: InitialTheLastFlexibleMessage ( )
//
// 説明: 最後のフレキシブルメッセージ用の初期化
//
// 入力:なし
//
//=============================================================
// void InitialTheLastFlexibleMessage ( void )
{
if ( !ValTheBit( FlxScn.bStatus, fNotInitialState ) )
{
if ( FlxScn.bLoopCnt++ >= 126 ) // 下記のプロセスを遅延させ、最小化させる
//タイミング制御文
{
SetTheBit( FlxScn.bStatus, fNotInitialState );
ClrTheBit( FlxScn.bStatus, fDefaultScrn ); DefaultStatusPrevFlexible ( );
}
}
}
//=============================================================
//
// 関数: FlexibleInnerLoopNormal ( )
//
// 説明: 標準の内部ループの条件プロセス
//
// 入力:
// UBYTE max_funcs - 関数メニューの項目数
// UBYTE fIncFxn -1の場合、IncFxnPtr( )から呼び出されている
// その他の場合、DecFxnPtr( )から呼び出されている
// char bScrnIndex - 表示インデックス番号( 0, 1, 2 )
//
//=============================================================
//
void FlexibleInnerLoopNormal ( UBYTE max_funcs,
UBYTE fIncFxn,
char bScrnIndex )
{
SetTheBit( FlxScn.bStatus, f1stLine ); // 第一の表示ラインを満たす処理の開始
#if BOTH_UPDOWN_DIRECTION
if ( fIncFxn )
{
SetTheBit( FlxScn.bStatus, fIncfunc );
FlxScrnCircle ( bScrnIndex );
bFuncIndex = (max_funcs-4) + (bScrnIndex << 1);
SendInsertCmd ( INC_RIGHT_CMD );
}
else
{
ClrTheBit( FlxScn.bStatus, fIncfunc );
FlxScrnCounterCircle ( bScrnIndex );
bFuncIndex = max_funcs - (bScrnIndex << 1);
SendInsertCmd ( DEC_LEFT_CMD );
}
// 即座に静的メッセージの状況を返答するように制御する
if ( ValTheBit( FlxScn.bStatus, fDefaultScrn ) )
ClrTheBit( FlxScn.bStatus, fDefaultScrn );
#else
FlxScrnCircle ( bScrnIndex );
bFuncIndex = (max_funcs-4) + (bScrnIndex << 1);
SendInsertCmd ( INC_RIGHT_CMD );
#endif // BOTH_UPDOWN_DIRECTIONのブロック
}
//=============================================================
//
// 関数: FlexibleStringInnerLoop ( )
//
// 説明: インクリメントまたはデクリメントのファンクションキーが押された場合に、
// 終了シグナルまで、ループ中のフレキシブルメッセージをプロセスする
//
// Input:
// UBYTE max_funcs - 機能メニューの項目数
// UBYTE fIncFxn - 1の場合、IncFxnPtr( )から呼び出されている
// その他の場合、DecFxnPtr( )から呼び出されている
//
//=============================================================
void FlexibleStringInnerLoop ( UBYTE max_funcs, UBYTE fIncFxn )
{
char bScrnIndex; // より柔軟にするため、ローカル変数を使用する
// 新しいスクリーンメッセージを更新するため、フラグをクリアする
ClrTheBit( FlxScn.bStatus, fScrnReady );
bScrnIndex = FlxScn.bScreenIndex + 1;
if ( bScrnIndex > 2 )
bScrnIndex = 0;
#if BOTH_UPDOWN_DIRECTION
// 内部ループの中にいる場合、方向転換のプロセスを行う
if ( fIncFxn != ValTheBit( FlxScn.bStatus, fIncfunc ) )
{
if ( bScrnIndex < 2 )
bScrnIndex {circumflex over ( )}= 0x01; // 高速に切り替える技術を使用している
// ここでは、押されるキーの方向が変更されたかチェックし、
// 現在の表示にはターミネータが含まれるかをチェックする
if ( ValTheBit( FlxScn.bStatus, fBackEndLoop ) )
{
SetTheBit( FlxScn.bStatus, fEndLoop );
}
else
{
// 方向が変更されたため、以前のEndLoopはもはや有効でない
if ( ValTheBit( FlxScn.bStatus, fEndLoop ) )
{
ClrTheBit( FlxScn.bStatus, fEndLoop );
}
if ( ( !fIncFxn && (FlxScn.bIncMsgReq == 5) )
|| ( fIncFxn && (FlxScn.bDecMsgReq == 5) ) )
Flx_IsItEndLoop ( bScrnIndex, fIncFxn );
}
}
#endif // BOTH_UPDOWN_DIRECTIONのブロック
FlxScn.bScreenIndex = bScrnIndex; // 現行の表示を更新する
if ( !ValTheBit( FlxScn.bStatus, fEndLoop ) )
{
FlexibleInnerLoopNormal ( max_funcs, fIncFxn, bScrnIndex );
}
else // if ( ValTheBit( FlxScn.bStatus, fEndLoop ) )
{
// フレキシブルメッセージループから静的メッセージに移動した場合、
// フレキシブルメッセージを開始する準備をする必要はなく、
// 固定メニューからフレキシブルメニューに移動するキーが押されたときに、
//表示の準備はできている
ClrTheBit( FlxScn.bStatus, fEndLoop );
#if BOTH_UPDOWN_DIRECTION
if ( !fIncFxn )
{
bFuncIndex = max_funcs - 6;
ClrTheBit( FlxScn.bStatus, fIncfunc );
}
else
{
bFuncIndex = 0;
SetTheBit( FlxScn.bStatus, fIncfunc );
}
#else
bFuncIndex = 0;
#endif // BOTH_UPDOWN_DIRECTIONのブロック
if ( FlxScn.bIncMsgReq & 1 )
SetTheBit( FlxScn.bStatus, fScrnReady );
}
}
#endif // FLEXIBLE_BUFFERSのブロック
【0065】
上記のアルゴリズムは、メッセージ提供システムに次のフレキシブルメッセージ(例えばメッセージi)を要求し、該メッセージを次のディスプレイスクリーンを示すメモリ位置に設定し、ポインタ*pCurrLineを設定する。例示する実施形態では、各々のディスプレイスクリーンは2つのメッセージを含むことができるため、現在の移動方向の次のメッセージ(例えばメッセージi+1または例えばメッセージi−1)も要求される。一実施形態では、この次のメッセージは下記のコードを含むProcess_FlexibleStringUpdateと呼ばれる関数により要求される。
【0066】
#if BOTH_UPDOWN_DIRECTION
if ( ValTheBit(FlxScn.bStatus, fIncfunc) )
{
FlxScn.pCurrLine = FlxScn.pCurrScrn->sText2;
SendInsertCmd ( INC_RIGHT_CMD ); // メッセージ提供システムからの
// フレキシブル文字列の更新要求
else
{
FlxScn.pCurrLine = FlxScn.pCurrScrn->sText;
SendInsertCmd ( DEC_LEFT_CMD ); // メッセージ提供システムからの
// フレキシブル文字列の更新要求
}
#else
FlxScn.pCurrLine = FlxScn.pCurrScrn->sText2;
SendInsertCmd ( INC_RIGHT_CMD ); // メッセージ提供システムからの
// フレキシブル文字列の更新要求
#endif
【0067】
この例示的な実施形態では、下記のコードのセグメントにより、DEC_LEFT_CMDまたはINC_RIGHT_CMDが通信インタフェースに提供され、メッセージ提供システムに送信される際に、関数Process_FlexibleStringUpdateが呼び出される。
【0068】
#if FLEXIBLE_BUFFERS
case DEC_LEFT_CMD:
case INC_RIGHT_CMD:
case DEC_MSG_N_CMD:
case INC_MSG_1_CMD:
Process_FlexibleStringUpdate ( bRxChar );
break;
#endif
【0069】
本発明の少なくとも1つの実施形態の各々の態様を記載したが、当業者は様々な置換、変更及び改善をたやすく行うことができることは明らかである。そのような置換、変更及び改善は本開示の一部と解釈され、本発明の範囲に含まれることは明らかである。従って、上述の記載は単なる例示のみを目的とするものである。