(19)【発行国】日本国特許庁(JP)
(12)【公報種別】特許公報(B2)
(11)【特許番号】
(24)【登録日】2024-11-11
(45)【発行日】2024-11-19
(54)【発明の名称】制御装置および処理方法
(51)【国際特許分類】
G06F 9/48 20060101AFI20241112BHJP
【FI】
G06F9/48 350Z
G06F9/48 350B
(21)【出願番号】P 2020194423
(22)【出願日】2020-11-24
【審査請求日】2023-10-16
(73)【特許権者】
【識別番号】000005234
【氏名又は名称】富士電機株式会社
(74)【代理人】
【識別番号】100104433
【氏名又は名称】宮園 博一
(74)【代理人】
【識別番号】100202728
【氏名又は名称】三森 智裕
(72)【発明者】
【氏名】中島 信一
(72)【発明者】
【氏名】宮崎 剛
(72)【発明者】
【氏名】高松 英治
【審査官】坂庭 剛史
(56)【参考文献】
【文献】米国特許出願公開第2020/0073711(US,A1)
【文献】米国特許出願公開第2020/0183671(US,A1)
【文献】米国特許出願公開第2011/0167248(US,A1)
【文献】米国特許出願公開第2013/0227254(US,A1)
【文献】米国特許出願公開第2016/0321045(US,A1)
【文献】多田好克、寺田 実,移植性・拡張性に優れたCのコルーチンライブラリー実現法,電子情報通信学会論文誌,日本,社団法人電子情報通信学会,1990年12月25日,Vol.J73-D-I, No.12,pp.961-970,ISSN 0915-1915
(58)【調査した分野】(Int.Cl.,DB名)
G06F 9/48
(57)【特許請求の範囲】
【請求項1】
処理を中断させた後、中断させた処理の続きから処理を再開させるコルーチン関数を実行する制御装置であって、
前記コルーチン関数を含むプログラムが保存されるメモリと、
前記プログラムを実行する制御部、とを備え、
前記制御部が前記プログラムを実行することにより行われる処理は、
前記コルーチン関数が呼び出された後、前記メモリのグローバル領域に前記コルーチン関数の情報を退避させる退避領域を確保するステップと、
前記コルーチン関数が呼び出された後、前記コルーチン関数の処理が中断される前に、前記メモリのスタック領域に保存されている前記コルーチン関数の情報に含まれる自動変数を、前記退避領域に退避させるステップと、
前記中断された処理を再開する前に、前記退避領域に退避された前記自動変数を、前記メモリの前記スタック領域に復元するステップと、
前記コルーチン関数を呼び出した後に、前記メモリの前記スタック領域における前記自動変数のアドレスリストを前記メモリの前記グローバル領域に作成するステップと、を含む、制御装置。
【請求項2】
前記コルーチン関数の情報は、前記コルーチン関数のポインタ情報、前記コルーチン関数の中断位置、引数、および、戻り値をさらに含む、請求項1に記載の制御装置。
【請求項3】
前記自動変数、前記引数、および、前記戻り値の各々の情報は、前記メモリ上の領域情報またはポインタ情報である、請求項2に記載の制御装置。
【請求項4】
前記退避領域を確保するステップは、前記コルーチン関数の情報の大きさに応じて、前記退避領域を確保するステップを含む、請求項1~3のいずれか1項に記載の制御装置。
【請求項5】
前記制御部が前記プログラムを実行することにより行われる処理は、前記自動変数を前記メモリの前記スタック領域に復元した後、前記自動変数が保存されていた領域を解放するステップをさらに含む、請求項1~4のいずれか1項に記載の制御装置。
【請求項6】
前記自動変数を前記退避領域に退避させるステップは、作成された前記アドレスリストに基づいて、前記自動変数を前記退避領域に退避させるステップを含み、
前記自動変数を前記スタック領域に復元するステップは、作成された前記アドレスリストに基づいて、前記自動変数を、前記メモリの前記スタック領域に復元するステップを含む、請求項1~5のいずれか1項に記載の制御装置。
【請求項7】
前記制御部が前記プログラムを実行することにより行われる処理は、前記自動変数を前記退避領域に退避させた後、前記自動変数の前記アドレスリストが保存されていた領域を解放するステップをさらに含む、請求項6に記載の制御装置。
【請求項8】
処理を中断させた後、中断させた処理の続きから処理を再開させるコルーチン関数を実行する処理方法であって、
前記コルーチン関数を呼び出すステップと、
前記コルーチン関数が呼び出された後、メモリのグローバル領域に前記コルーチン関数の情報を退避させる退避領域を確保するステップと、
前記コルーチン関数が呼び出された後、前記コルーチン関数の処理が中断される前に、前記メモリのスタック領域に保存されている前記コルーチン関数の情報に含まれる自動変数を、前記退避領域に退避させるステップと、
前記中断された処理を再開する前に、前記退避領域に退避された前記自動変数を、前記メモリの前記スタック領域に復元するステップと、
前記コルーチン関数を呼び出した後に、前記メモリの前記スタック領域における前記自動変数のアドレスリストを前記メモリの前記グローバル領域に作成するステップと、を含む、処理方法。
【発明の詳細な説明】
【技術分野】
【0001】
この発明は、制御装置および処理方法に関し、特に、コルーチン関数を実行する制御装置および処理方法に関する。
【背景技術】
【0002】
従来、コルーチン関数を実行する処理方法が知られている(たとえば、特許文献1参照)。
【0003】
上記特許文献1には、コルーチン関数のプロセスが開示されている。通常の関数(サブルーチン関数など、関数Bとする)では、呼び出し元の関数(関数Aとする)から関数Bを呼び出した場合、呼び出された関数Bの処理が完了した後、処理は、呼び出し元の関数Aに復帰する。一方、コルーチン関数では、呼び出し元の関数Aからコルーチン関数(コルーチン関数Cとする)を呼び出した場合、コルーチン関数Cは、処理を実行した後に処理を中断する。これにより、処理は、呼び出し元の関数Aに復帰する。そして、呼び出し元の関数Aが、再びコルーチン関数Cを呼び出した場合、呼び出されたコルーチン関数Cは、処理を中断した時点から処理を再開する。
【0004】
ここで、従来、C言語などのように、標準ライブラリとして、コルーチン関数が提供されていない言語がある。この場合、たとえばC言語では、switch-case文を用いて疑似的にコルーチン関数を実装する方法が知られている。この方法では、コルーチン関数内の複数の処理が、case節の単位に分割される。そして、1つのcase節内の処理が実行され、次回に処理されるcase節のラベルがメモリに保存された後、コルーチン関数が終了される。これにより、疑似的にコルーチン関数の処理の中断が実現されている。なお、コルーチン関数の自動変数などは、メモリのスタック領域に保存されている。そして、処理の再開時には、コルーチン関数の先頭から処理が実行される。そして、switch-case文の条件判断によって、処理の中断の前に保存されたラベルのcase節の処理が実行される。
【先行技術文献】
【特許文献】
【0005】
【発明の概要】
【発明が解決しようとする課題】
【0006】
しかしながら、C言語のswitch-case文を用いて疑似的なコルーチン関数を実装した場合において、中断した処理を再開するためにコルーチン関数が呼び出された際、コルーチン関数の自動変数が保存されているメモリのスタック領域が初期化されるか、または、スタック領域に不定値が保存される。このため、中断した処理の再開時には、コルーチン関数の自動変数の値が、処理の中断前の値と異なっており、中断した処理を正常に再開できない場合があるという問題点がある。
【0007】
この発明は、上記のような課題を解決するためになされたものであり、この発明の1つの目的は、コルーチン関数を実行する際に、中断した処理を正常に再開することが可能な制御装置および処理方法を提供することである。
【課題を解決するための手段】
【0008】
上記目的を達成するために、この発明の第1の局面による制御装置は、処理を中断させた後、中断させた処理の続きから処理を再開させるコルーチン関数を実行する制御装置であって、コルーチン関数を含むプログラムが保存されるメモリと、プログラムを実行する制御部、とを備え、制御部がプログラムを実行することにより行われる処理は、コルーチン関数が呼び出された後、メモリのグローバル領域にコルーチン関数の情報を退避させる退避領域を確保するステップと、コルーチン関数が呼び出された後、コルーチン関数の処理が中断される前に、メモリのスタック領域に保存されているコルーチン関数の情報に含まれる自動変数を、退避領域に退避させるステップと、中断された処理を再開する前に、退避領域に退避された自動変数を、メモリのスタック領域に復元するステップと、コルーチン関数を呼び出した後に、メモリのスタック領域における自動変数のアドレスリストをメモリのグローバル領域に作成するステップと、を含む。なお、「コルーチン関数」とは、標準ライブラリとして提供されるコルーチン関数に加えて、C言語のswitch-case文などを用いて実装された疑似的なコルーチン関数を含む概念である。
【0009】
この発明の第1の局面による制御装置では、上記のように、プログラムは、コルーチン関数が呼び出された後、コルーチン関数の処理が中断される前に、メモリのスタック領域に保存されているコルーチン関数の情報に含まれる自動変数を、退避領域に退避させるステップと、中断された処理を再開する前に、退避領域に退避された自動変数を、メモリのスタック領域に復元するステップと、を含む。これにより、メモリのスタック領域に保存されている自動変数がメモリのグローバル領域の退避領域に退避されるので、中断した処理を再開するためにコルーチン関数が呼び出された際、メモリのスタック領域が初期化されるかまたはスタック領域に不定値が保存されていても、メモリのグローバル領域の退避領域に退避された自動変数がメモリのスタック領域に復元される。その結果、コルーチン関数の中断した処理の再開時に、正確な自動変数に基づいて、処理を再開することができる。これにより、コルーチン関数を実行する際に、中断した処理を正常に再開することができる。
【0010】
上記第1の局面による制御装置において、好ましくは、コルーチン関数の情報は、コルーチン関数のポインタ情報、コルーチン関数の中断位置、引数、および、戻り値をさらに含む。このように構成すれば、中断した処理の再開に必要なコルーチン関数のポインタ情報、コルーチン関数の中断位置、自動変数、引数、および、戻り値が、メモリのグローバル領域の退避領域に退避されるので、中断した処理を正常かつ確実に再開することができる。
【0011】
この場合、好ましくは、自動変数、引数、および、戻り値の各々の情報は、メモリ上の領域情報またはポインタ情報である。ここで、メモリのグローバル領域は、メモリのスタック領域と異なり自由に書き込みが可能であるので、自動変数、引数、および、戻り値の各々の情報を、メモリ上の領域情報またはポインタ情報のいずれでも書き込むことができる。
【0012】
上記第1の局面による制御装置において、好ましくは、退避領域を確保するステップは、コルーチン関数の情報の大きさに応じて、退避領域を確保するステップを含む。ここで、コルーチン関数の情報を、コルーチン関数を呼び出す呼び出し元の関数のスタック領域に保存する場合、コルーチン関数の情報のための領域が固定サイズで確保される場合がある。この場合、コルーチン関数の構成(引数、自動変数および戻り値のそれぞれの個数)によっては、コルーチン関数の情報のために適切に領域を確保できない(過不足する)場合がある。そこで、上記のように構成することによって、メモリのグローバル領域では、退避領域を可変長により確保することができる(グローバル領域は、スタック領域に比べて領域のサイズの指定が容易である)ので、退避領域を適切に確保することができる。
【0013】
上記第1の局面による制御装置において、好ましくは、制御部がプログラムを実行することにより行われる処理は、自動変数をメモリのスタック領域に復元した後、自動変数が保存されていた領域を解放するステップをさらに含む。このように構成すれば、自動変数をメモリのスタック領域に復元した後にメモリの自動変数が保存されていた領域が解放されるので、コルーチン関数が複数設けられる場合において、解放後のメモリのグローバル領域を他のコルーチン関数の自動変数などを保存する領域として利用することができる。つまり、コルーチン関数の数が比較的多い場合でも、コルーチン関数を適切に実行することができる。
【0014】
上記第1の局面による制御装置において、好ましくは、自動変数を退避領域に退避させるステップは、作成されたアドレスリストに基づいて、自動変数を退避領域に退避させるステップを含み、自動変数をスタック領域に復元するステップは、作成されたアドレスリストに基づいて、自動変数を、メモリのスタック領域に復元するステップを含む。このように構成すれば、アドレスリストに基づいて自動変数の退避および復元が行われるので、自動変数を間違えることなく退避領域に退避させるとともにスタック領域に復元することができる。
【0015】
この場合、好ましくは、制御部がプログラムを実行することにより行われる処理は、自動変数を退避領域に退避させた後、自動変数のアドレスリストが保存されていた領域を解放するステップをさらに含む。このように構成すれば、自動変数を退避領域に退避させた後、自動変数のアドレスリストが保存されていた領域が解放されるので、コルーチン関数が複数設けられる場合において、解放後のメモリのグローバル領域を他のコルーチン関数のアドレスリストなどを保存する領域として利用することができる。つまり、コルーチン関数の数が比較的多い場合でも、コルーチン関数を適切に実行することができる。
【0016】
この発明の第2の局面による処理方法は、処理を中断させた後、中断させた処理の続きから処理を再開させるコルーチン関数を実行する処理方法であって、コルーチン関数を呼び出すステップと、コルーチン関数が呼び出された後、メモリのグローバル領域にコルーチン関数の情報を退避させる退避領域を確保するステップと、コルーチン関数が呼び出された後、コルーチン関数の処理が中断される前に、メモリのスタック領域に保存されているコルーチン関数の情報に含まれる自動変数を、退避領域に退避させるステップと、中断された処理を再開する前に、退避領域に退避された自動変数を、メモリのスタック領域に復元するステップと、コルーチン関数を呼び出した後に、メモリのスタック領域における自動変数のアドレスリストをメモリのグローバル領域に作成するステップと、を含む。
【0017】
この発明の第2の局面による処理方法では、上記のように、コルーチン関数が呼び出された後、コルーチン関数の処理が中断される前に、メモリのスタック領域に保存されているコルーチン関数の情報に含まれる自動変数を、退避領域に退避させるステップと、中断された処理を再開する前に、退避領域に退避された自動変数を、メモリのスタック領域に復元するステップと、を含む。これにより、メモリのスタック領域に保存されている自動変数がメモリのグローバル領域の退避領域に退避されるので、中断した処理を再開するためにコルーチン関数が呼び出された際、メモリのスタック領域が初期化されるかまたはスタック領域に不定値が保存されていても、メモリのグローバル領域の退避領域に退避された自動変数がメモリのスタック領域に復元される。その結果、コルーチン関数の中断した処理の再開時に、正確な自動変数に基づいて、処理を再開することができる。これにより、コルーチン関数を実行する際に、中断した処理を正常に再開することが可能な処理方法を提供することができる。
【発明の効果】
【0018】
本発明によれば、上記のように、コルーチン関数を実行する際に、中断した処理を正常に再開することができる。
【図面の簡単な説明】
【0019】
【
図1】本実施形態による制御装置のブロック図である。
【
図2】本実施形態による制御装置のメモリの構成を示す図である。
【
図3】一般的なサブルーチン関数の処理を説明するためのシーケンス図である。
【
図4】一般的なコルーチン関数の処理を説明するためのシーケンス図である。
【
図5】本実施形態によるコルーチン関数の処理とメモリとの関係を説明するための図である。
【
図6】本実施形態による制御装置のメモリのブロックを説明するための図である。
【
図7】本実施形態によるコルーチン関数の処理を例示した図である。
【
図8】本実施形態による自動変数のアドレスリスト(スタックフレーム定義)を説明するための図である。
【
図9】本実施形態によるコルーチン関数の処理を説明するためのフロー図である。
【
図10】本実施形態によるコルーチン関数の記述例および実際のコード例を説明するための図である。
【
図11】本実施形態によるコルーチン関数の処理を説明するためのシーケンス図である。
【
図12】本実施形態によるコルーチン関数の処理を説明するためのメモリ遷移図である。
【
図13】本実施形態による2つのコルーチン関数の処理を説明するためのシーケンス図である。
【
図14】本実施形態による2つのコルーチン関数の処理を説明するためのメモリ遷移図である。
【
図15】本実施形態によるコルーチン関数およびサブコルーチン関数の処理を説明するためのシーケンス図である。
【
図16】本実施形態によるコルーチン関数およびサブコルーチン関数の処理を説明するためのメモリ遷移図である。
【発明を実施するための形態】
【0020】
以下、本発明を具体化した実施形態を図面に基づいて説明する。
【0021】
図1~
図16を参照して、本実施形態による制御装置100の構成について説明する。なお、制御装置100は、たとえば、組み込み機器に用いられる制御装置100である。
【0022】
図1に示すように、制御装置100は、プリント基板1に設けられたマイコン2と、メモリ3とを備えている。メモリ3は、ROM(Read Only Memory)およびRAM(Random Access Memory)などから構成されている。また、メモリ3には、コルーチン関数を含むプログラム4が保存されている。マイコン2は、メモリ3に保存されたプログラム4を実行する。プログラム4は、C言語により記載されている。なお、マイコン2は、特許請求の範囲の「制御部」の一例である。
【0023】
図2に示すように、C言語によって取り扱われるメモリ3は、テキスト領域3aと、グローバル領域3b(静的領域)と、ヒープ領域3cと、スタック領域3dとを含む。そして、テキスト領域3aには、機械語に翻訳されたプログラム4が格納される。グローバル領域3bには、グローバル変数などの静的変数が格納される。ヒープ領域3cは、メモリ3の管理のために使用される。スタック領域3dは、C言語の自動変数(ローカル変数など)が格納される。また、ヒープ領域3cおよびスタック領域3dのサイズは、プログラム4中に変化する。
【0024】
本実施形態では、制御装置100は、処理を中断させた後、中断させた処理の続きから処理を再開させる、C言語により実装された疑似的なコルーチン関数を実行するように構成されている。
【0025】
図3および
図4を参照して、サブルーチン関数とコルーチン関数との差異について説明する。
【0026】
図3に示すように、サブルーチン関数は、func1関数からサブルーチン関数であるfunc2関数を呼び出すと(call)、func2関数は、func2関数に含まれるreturn文までの処理を実行する。一方、
図4に示すように、コルーチン関数では、func1関数からコルーチン関数であるfunc2関数を呼び出すと(resume)、func2関数の途中まで処理を実行するとともに中断する(yield)。そして、再び、func1関数からfunc2関数を呼び出すと(resume)、前回の処理において中断された部分の続きから、処理が再開される。
【0027】
なお、C言語では、コルーチン関数が標準ライブラリとして提供されていない。そこで、本実施形態では、C言語のSwitch-case文を用いて、疑似的なコルーチン関数を実装する(
図10参照)。具体的には、Switch-case文により実装された疑似的なコルーチン関数において、コルーチン関数の処理がcase節単位に分割される。そして、1つのcase節の処理が実行され、次回に処理するcase節のラベル(中断位置)がメモリ3に保存された後、処理は、コルーチン関数から復帰(離脱)する。これにより、C言語のSwitch-case文を用いて、疑似的なコルーチン関数が実装される。コルーチン関数の処理の再開時には、コルーチン関数が呼び出され、コルーチン関数の先頭から処理が開始される。そして、Switch文の条件判定に基づいて、前回の処理の中断時に保存されたcase節のラベル(中断位置)に対応するcase節から処理が実行される。
【0028】
(プログラムの構成)
次に、本実施形態によるC言語で疑似的に実装されたコルーチン関数の構成(プログラム4の構成)について説明する。
【0029】
本実施形態では、
図5に示すように、C言語で疑似的に実装されたコルーチン関数の処理(プログラム4)は、コルーチン関数が呼び出された後、メモリ3のグローバル領域3bにコルーチン関数の情報を退避させる退避領域3eを確保するステップを含む。退避領域3eは、可変長のブロック単位で管理される。また、
図6に示すように、ブロックの先頭には、使用情報フラグと、ブロックサイズとを含むブロック情報が保存されている。使用情報フラグは、未使用または使用中を示す。ブロックサイズは、ブロック情報と、割り当てられたメモリ領域のサイズの情報とを含む。
【0030】
退避領域3eを確保する処理では、退避領域3eの先頭から、ブロック情報が参照され、使用状況フラグが未使用であるブロックが検索される。そして、使用状況フラグが未使用であるブロックが見つかった場合、このブロックの使用状況フラグを使用中にするとともに、割り当てられたメモリ3の領域(ブロック)の先頭のアドレスを返す。また、使用状況フラグが未使用であるブロックが見つからなかった場合、ブロック情報において使用状況フラグが未使用であるブロックが再検索(順次検索)される。
【0031】
また、本実施形態では、コルーチン関数の情報は、自動変数に加えて、コルーチン関数のポインタ情報、コルーチン関数の中断位置、引数、および、戻り値をさらに含む。また、自動変数、引数、および、戻り値の各々の情報は、メモリ3上の領域情報またはポインタ情報である。なお、自動変数の領域情報、引数の領域情報、および、戻り値の領域情報は、退避領域3eの範囲内でサイズを変更することが可能である。また、自動変数のポインタ情報、引数のポインタ情報、および、戻り値のポインタ情報の参照先は、退避領域3eにおいて確保された、各々に必要なサイズを有する領域である。
【0032】
また、本実施形態では、
図5に示すように、退避領域3eを確保するステップは、コルーチン関数の情報の大きさに応じて、メモリ3のグローバル領域3bに退避領域3eを確保するステップを含む。ここで、コルーチン関数の情報を、コルーチン関数を呼び出す呼出元関数のスタック領域3dに確保した場合、スタック領域3dのサイズ(最大値)は、プログラム4のコンパイル時に決定される。このため、コルーチン関数の情報を保存するためのスタック領域3dのサイズは、コンパイル時に決定されたスタック領域3dの最大値未満となるので、同時に実行可能なコルーチン関数の数が制限される。一方、本実施形態では、コルーチン関数の情報がグローバル領域3bの退避領域3eに保存される。スタック領域3dに比べてグローバル領域3bのサイズの指定が容易であるので、本実施形態では、同時に実行可能なコルーチン関数の数が制限されるのを抑制することが可能になる。
【0033】
また、本実施形態では、プログラム4は、コルーチン関数が呼び出された後、コルーチン関数の処理が中断される前に、メモリ3のスタック領域3dに保存されているコルーチン関数の情報に含まれる自動変数を、退避領域3eに退避させるステップを含む。なお、自動変数は、コルーチン関数の情報(以下、Co情報と言う場合がある)の内部の自動変数領域に退避されてもよいし、Co情報とは別個に確保された領域に退避されてもよい。
【0034】
また、本実施形態では、プログラム4は、中断された処理を再開する前に、退避領域3eに退避された自動変数を、メモリ3のスタック領域3dに復元するステップを含む。
【0035】
図7に示す例では、コルーチン関数1とコルーチン関数2とが実行される。コルーチン関数1の実行時には、コルーチン関数1の自動変数1-1および自動変数1-2が、メモリ3のスタック領域3dに保存されている。コルーチン関数1の処理が中断される前に、スタック領域3dに保存されている自動変数1-1および自動変数1-2は、退避領域3eに退避される。なお、
図7の例では、自動変数1-1および自動変数1-2は、コルーチン関数1の情報であるCo情報1(ポインタ情報、コルーチン関数の中断位置、引数、および、戻り値など)が保存される領域とは異なる領域に退避されている。
【0036】
次に、コルーチン関数2の実行時には、コルーチン関数2の自動変数2-1および自動変数2-2が、メモリ3のスタック領域3dに保存されている。コルーチン関数2の処理が中断される前に、スタック領域3dに保存されている自動変数2-1および自動変数2-2は、退避領域3eに退避される。
【0037】
コルーチン関数1の再開時には、スタック領域3dに保存されている自動変数1-1および自動変数1-2が、メモリ3のスタック領域3dに復元される。コルーチン関数2の再開時も、同様である。
【0038】
また、本実施形態では、プログラム4は、自動変数をメモリ3のスタック領域3dに復元した後、自動変数が保存されていた領域(退避領域3e)を解放するステップをさらに含む。具体的には、
図6に示すように、退避領域3eの先頭アドレスから、開放する領域が含まれるブロックのブロック情報を参照して、このブロックの使用状況フラグを未使用にする。
【0039】
また、本実施形態では、
図8に示すように、プログラム4は、コルーチン関数を呼び出した後に、メモリ3のスタック領域3dにおける自動変数のアドレスリストAL(スタックフレーム定義)を作成するステップをさらに含む。具体的には、メモリ3のグローバル領域3bに、アドレスリストALの情報を保存するために必要な定義領域3fが確保される。そして、退避する自動変数のスタック領域3d上のアドレス値(ポインタ)がアドレスリストAL(スタックフレーム定義)としてグローバル領域3bに保存される。
【0040】
たとえば、
図8(a)に示す例では、スタック領域3dに、自動変数A、自動変数Bおよび自動変数C(
図8では、各々、A、BおよびCと記載する)が保存されている。そして、グローバル領域3bに、アドレスリストALとして、自動変数Aのポインタ、自動変数Bのポインタおよび自動変数Cのポインタが保存されている。なお、自動変数Aのポインタ、自動変数Bのポインタおよび自動変数Cのポインタは、
図8に示される順に限られず、任意の順に保存される。
【0041】
そして、本実施形態では、
図8(c)に示すように、自動変数をグローバル領域3bに退避させるステップは、作成されたアドレスリストALに基づいて、自動変数を退避領域3eに退避させるステップを含む。具体的には、メモリ3のグローバル領域3bにコルーチン関数の情報(自動変数)を退避させる退避領域3eを確保する。そして、アドレスリストALで定義された順に、ポインタが参照した自動変数の値を、退避領域3eに保存する。
【0042】
たとえば、
図8(c)に示す例では、スタック領域3dに自動変数A、自動変数Bおよび自動変数Cが保存されている。そして、ポインタが参照した自動変数Aの値が、退避領域3eに保存される。これにより、グローバル領域3bに、自動変数Aの値が退避される。自動変数Bおよび自動変数Cについても同様である。
【0043】
そして、本実施形態では、プログラム4は、自動変数(の値)を、退避領域3eに退避させるステップの後、アドレスリストALが保存されていた領域を解放するステップをさらに含む。
【0044】
また、本実施形態では、
図8(b)に示すように、自動変数をスタック領域3dに復元するステップは、作成されたアドレスリストALに基づいて、自動変数を、メモリ3のスタック領域3dに復元するステップを含む。具体的には、退避領域3eから、処理の中断前に退避した自動変数の値を取得する。そして、自動変数を、アドレスリストALに定義された順に、ポインタが示すスタック領域3dの部分に保存する。
【0045】
たとえば、
図8(b)に示す例では、退避領域3eに中断前の自動変数Aの値、自動変数Bの値および自動変数Cの値が保存されている。そして、自動変数Aの値を、アドレスリストALの自動変数Aのポインタが示すスタック領域3dの部分に保存する。これにより、スタック領域3dに、自動変数Aの値が復元される。自動変数Bおよび自動変数Cについても同様である。自動変数A~Cがメモリ3のスタック領域3dに復元された後、自動変数A~Cが保存されていた領域(グローバル領域3bの部分)が解放される。
【0046】
次に、本実施形態のコルーチン関数の処理方法について説明する。なお、以下の処理は、マイコン2によって行われる。
【0047】
まず、
図9、
図11および
図12に示すように、ステップS1(
図10のco_begin)において、コルーチン関数が呼び出される。
【0048】
次に、ステップS2(
図10のdefine_frame)において、コルーチン関数が呼び出された後、メモリ3のグローバル領域3bに、メモリ3のスタック領域3dにおける自動変数のアドレスリストALを保存するための領域を確保する。そして、コルーチン関数を呼び出した後に、アドレスリストALをこの領域に作成する。
【0049】
次に、ステップS3(
図10のSwitch)において、Switch文によって、コルーチン関数の処理の中断位置が判定される。
【0050】
ステップS3において、初めてコルーチン関数が実行される(
図10のcase0)と判定された場合、ステップS4において、
図10のcase()節の処理が実行される。つまり、「hello world!!」が図示しないディスプレイに表示される。
【0051】
次に、
図10(コルーチン関数の記述例)に示すように、「co_yield()」によって、コルーチン関数の処理の中断が指令される。具体的には、ステップS5(
図10のsave_value)において、コルーチン関数のためのスタック領域3dに保存された自動変数がグローバル領域3bの退避領域3eに退避される。詳細には、メモリ3のグローバル領域3bにコルーチン関数の情報(自動変数、コルーチン関数のポインタ情報、コルーチン関数の中断位置、引数、および、戻り値)を退避させる退避領域3eを確保した後、スタック領域3dの自動変数がグローバル領域3bの退避領域3eに退避される。
【0052】
次に、ステップS6(
図10の_state=_LINE_)において、中断位置(コルーチン関数が中断した位置)が、メモリ3の退避領域3eに退避(保存)される。
【0053】
次に、ステップS7(
図10のreturn)において、コルーチン関数が中断(終了)される。
【0054】
ステップS3において、コルーチン関数が再開(1回目の再開)されたと判定された場合(
図10のcase_LINE_)、ステップS8において、メモリ3のグローバル領域3bに退避されていた自動変数が、スタック領域3dに復元される(
図10のload_value())。その後、メモリ3のグローバル領域3bにおいて、自動変数が保存されていた領域が解放される。
【0055】
次に、ステップS9において、
図10のcase_LINE_節の処理が実行される。つまり、「hi world!」が図示しないディスプレイに表示される。
【0056】
次に、
図10に示すように、「co_yield()」によって、コルーチン関数の処理の中断が指令される。具体的には、ステップS10(
図10のsave_value)において、コルーチン関数のためのスタック領域3dに保存された自動変数がグローバル領域3bの退避領域3eに退避される。詳細には、メモリ3のグローバル領域3bにコルーチン関数の情報(自動変数、コルーチン関数のポインタ情報、コルーチン関数の中断位置、引数、および、戻り値)を退避させる退避領域3eを確保した後、スタック領域3dの自動変数がグローバル領域3bの退避領域3eに退避される。
【0057】
次に、ステップS11(
図10の_state=_LINE_)において、中断位置(コルーチン関数が中断した位置)が、メモリ3の退避領域3eに退避される。
【0058】
次に、ステップS12(
図10のreturn)において、コルーチン関数が中断(終了)される。
【0059】
ステップS3において、コルーチン関数が再開(2回目の再開)されたと判定された場合(
図10のcase_LINE_)、ステップS13において、メモリ3のグローバル領域3bに退避されていた自動変数が、スタック領域3dに復元される(
図10のload_value())。その後、メモリ3のグローバル領域3bにおいて、自動変数が保存されていた領域が解放される。
【0060】
次に、ステップS14において、
図10のcase_LINE_節の処理が実行される。つまり、「:)」が図示しないディスプレイに表示される。
【0061】
次に、
図10に示すように、「co_end」によって、コルーチン関数の処理の終了が指令される。具体的には、ステップS15(
図10の_state=_LINE_)において、中断位置(コルーチン関数が終了した位置)が、メモリ3の退避領域3eに退避される。
【0062】
次に、ステップS16(
図10のreturn)において、コルーチン関数が終了される。また、自動変数が保存されていた領域(グローバル領域3bの部分)が解放される。
【0063】
なお、ステップS16におけるコルーチン関数の終了後、ステップS3において、コルーチン関数が再開されたと判定された場合、ステップS16において、コルーチン関数が終了した位置がメモリ3の退避領域3eに退避されているため、コルーチン関数の処理が実行されずにコルーチン関数が終了する。
【0064】
(複数のコルーチン関数)
次に、
図13および
図14を参照して、複数のコルーチン関数を実行する場合の動作について説明する。以下では、コルーチン関数1およびコルーチン関数2が実行される場合について説明する。
【0065】
まず、コルーチン関数1が呼び出される(ステップS21)。そして、コルーチン関数1が呼び出された後、メモリ3のグローバル領域3bに、アドレスリストALを保存するための領域を確保するとともに、アドレスリストAL(Co情報1)をこの領域に作成する。
【0066】
次に、コルーチン関数1の処理が実行される(ステップS22)。コルーチン関数1の処理の実行中において、自動変数1-1は、スタック領域3dに保存されている。なお、
図14では、グローバル領域3b(退避領域3e)に自動変数1-1が保存され、スタック領域3dに自動変数1-1が復元される図が示されているが、初回のコルーチン関数1の処理の実行時には、自動変数1-1の復元および自動変数1-1が保存されていた領域の解放は、不要である。
【0067】
次に、コルーチン関数1の処理が中断(ステップS23)される。これにより、スタック領域3dに保存された自動変数1-1が、グローバル領域3bの退避領域3eに退避される。また、中断位置(コルーチン関数が中断した位置)が、メモリ3の退避領域3e(Co情報1)に退避される。
【0068】
次に、コルーチン関数2が呼び出される(ステップS24)。そして、コルーチン関数2が呼び出された後、メモリ3のグローバル領域3bに、アドレスリストALを保存するための領域を確保するとともに、アドレスリストAL(Co情報2)をこの領域に作成する。
【0069】
次に、コルーチン関数2の処理が実行される(ステップS25)。コルーチン関数2の処理の実行中において、自動変数2-1は、スタック領域3dに保存されている。なお、
図14では、グローバル領域3b(退避領域3e)に自動変数2-1が保存され、スタック領域3dに自動変数2-1が復元される図が示されているが、初回のコルーチン関数2の処理の実行時には、自動変数2-1の復元および自動変数2-1が保存されていた領域の解放は、不要である。
【0070】
次に、コルーチン関数2の処理が中断(ステップS26)される。これにより、スタック領域3dに保存された自動変数2-1が、グローバル領域3bの退避領域3eに退避される。また、中断位置(コルーチン関数が中断した位置)が、メモリ3の退避領域3e(Co情報2)に退避される。
【0071】
次に、コルーチン関数1が再び呼び出されて、コルーチン関数1の処理が再開される(ステップS27)。これにより、メモリ3のグローバル領域3bに退避されていた自動変数1-1が、スタック領域3dに復元される。その後、メモリ3のグローバル領域3bにおいて、自動変数1-1が保存されていた領域が解放される。なお、その後の、コルーチン関数1の中断の処理は、上記と同様である。
【0072】
次に、コルーチン関数2が再び呼び出されて、コルーチン関数2の処理が再開される(ステップS28)。これにより、メモリ3のグローバル領域3bに退避されていた自動変数2-1が、スタック領域3dに復元される。その後、メモリ3のグローバル領域3bにおいて、自動変数2-1が保存されていた領域が解放される。なお、その後の、コルーチン関数2の中断の処理は、上記と同様である。
【0073】
(サブコルーチン関数)
次に、
図15および
図16を参照して、コルーチン関数からサブコルーチン関数を呼び出す場合の動作について説明する。以下では、コルーチン関数1およびサブコルーチン関数であるコルーチン関数1-1が実行される場合について説明する。
【0074】
まず、コルーチン関数1が呼び出される(ステップS31)。そして、コルーチン関数1が呼び出された後、メモリ3のグローバル領域3bに、アドレスリストALを保存するための領域を確保するとともに、アドレスリストAL(Co情報1)をこの領域に作成する。
【0075】
次に、コルーチン関数1-1が呼び出される(ステップS32)される。
【0076】
次に、コルーチン関数1-1が起動され(ステップS33)、メモリ3のグローバル領域3bに、アドレスリストALを保存するための領域を確保するとともに、アドレスリストAL(Co情報1-1)をこの領域に作成する。
【0077】
次に、コルーチン関数1-1の処理が実行される(ステップS34)。コルーチン関数1-1の処理の実行中において、自動変数1-1-1は、スタック領域3dに保存されている。なお、
図16では、退避領域3eに自動変数1-1-1が保存され、スタック領域3dに自動変数1-1-1が復元される図が示されているが、初回のコルーチン関数1-1-1の処理の実行時には、自動変数1-1-1の復元および自動変数1-1-1が保存されていた領域の解放は、不要である。
【0078】
次に、コルーチン関数1-1の処理が中断(ステップS35)される。これにより、スタック領域3dに保存された自動変数1-1が、グローバル領域3bの退避領域3eに退避される。また、中断位置(コルーチン関数が中断した位置)が、メモリ3の退避領域3e(Co情報1-1)に退避される。
【0079】
次に、コルーチン関数1の処理が再開(ステップS36)される。具体的には、グローバル領域3bの退避領域3eに保存されている自動変数1-1をスタック領域3dに復元(保存)し、スタック領域3dに保存されていた自動変数1-1を用いて、処理を実行する。また、自動変数1-1が保存されていた、退避領域3eを解放する。そして、コルーチン関数1の処理の中断時には、スタック領域3dに保存された自動変数1-1が、グローバル領域3bの退避領域3eに退避される。また、中断位置(コルーチン関数が中断した位置)が、メモリ3の退避領域3e(Co情報1)に退避される。
【0080】
[本実施形態の効果]
本実施形態では、以下のような効果を得ることができる。
【0081】
本実施形態では、上記のように、プログラム4は、コルーチン関数が呼び出された後、コルーチン関数の処理が中断される前に、メモリ3のスタック領域3dに保存されているコルーチン関数の情報に含まれる自動変数を、退避領域3eに退避させるステップと、中断された処理を再開する前に、退避領域3eに退避された自動変数を、メモリ3のスタック領域3dに復元するステップと、を含む。これにより、メモリ3のスタック領域3dに保存されている自動変数がメモリ3のグローバル領域3bの退避領域3eに退避されるので、中断した処理を再開するためにコルーチン関数が呼び出された際、メモリ3のスタック領域3dが初期化されるかまたはスタック領域3dに不定値が保存されていても、メモリ3のグローバル領域3bの退避領域3eに退避された自動変数がメモリ3のスタック領域3dに復元される。その結果、コルーチン関数の中断した処理の再開時に、正確な自動変数に基づいて、処理を再開することができる。これにより、コルーチン関数を実行する際に、中断した処理を正常に再開することができる。
【0082】
また、本実施形態では、上記のように、コルーチン関数の情報は、コルーチン関数のポインタ情報、コルーチン関数の中断位置、引数、および、戻り値をさらに含む。これにより、中断した処理の再開に必要なコルーチン関数のポインタ情報、コルーチン関数の中断位置、自動変数、引数、および、戻り値が、メモリ3のグローバル領域3bの退避領域3eに退避されるので、中断した処理を正常かつ確実に再開することができる。
【0083】
また、本実施形態では、上記のように、自動変数、引数、および、戻り値の各々の情報は、メモリ3上の領域情報またはポインタ情報である。ここで、メモリ3のグローバル領域3bは、メモリ3のスタック領域3dと異なり自由に書き込みが可能であるので、自動変数、引数、および、戻り値の各々の情報を、メモリ3上の領域情報またはポインタ情報のいずれでも書き込むことができる。
【0084】
また、本実施形態では、上記のように、退避領域3eを確保するステップは、コルーチン関数の情報の大きさに応じて、退避領域3eを確保するステップを含む。ここで、コルーチン関数の情報を、コルーチン関数を呼び出す呼び出し元の関数のスタック領域3dに保存する場合、コルーチン関数の情報のための領域が固定サイズで確保される場合がある。この場合、コルーチン関数の構成(引数、自動変数および戻り値のそれぞれの個数)によっては、コルーチン関数の情報のために適切に領域を確保できない(過不足する)場合がある。そこで、上記のように構成することによって、メモリ3のグローバル領域3bでは、退避領域3eを可変長により確保することができる(グローバル領域3bは、スタック領域3dに比べて領域のサイズの指定が容易である)ので、退避領域3eを適切に確保することができる。
【0085】
また、本実施形態では、上記のように、プログラム4は、自動変数をメモリ3のスタック領域3dに復元した後、自動変数が保存されていた領域を解放するステップをさらに含む。これにより、自動変数をメモリ3のスタック領域3dに復元した後にメモリ3の自動変数が保存されていた領域が解放されるので、コルーチン関数が複数設けられる場合において、解放後のメモリ3のグローバル領域3bを他のコルーチン関数の自動変数などを保存する領域として利用することができる。つまり、コルーチン関数の数が比較的多い場合でも、コルーチン関数を適切に実行することができる。
【0086】
また、本実施形態では、上記のように、プログラム4は、コルーチン関数を呼び出した後に、メモリ3のスタック領域3dにおける自動変数のアドレスリストALをメモリ3のグローバル領域3bに作成するステップをさらに含む。そして、自動変数を退避領域3eに退避させるステップは、作成されたアドレスリストALに基づいて、自動変数を退避領域3eに退避させるステップを含む。また、自動変数をスタック領域3dに復元するステップは、作成されたアドレスリストALに基づいて、自動変数を、メモリ3のスタック領域3dに復元するステップを含む。これにより、アドレスリストALに基づいて自動変数の退避および復元が行われるので、自動変数を間違えることなく退避領域3eに退避させるとともにスタック領域3dに復元することができる。
【0087】
また、本実施形態では、上記のように、プログラム4は、自動変数を退避領域3eに退避させた後、自動変数のアドレスリストALが保存されていた領域を解放するステップをさらに含む。これにより、自動変数を退避領域3eに退避させた後、自動変数のアドレスリストALが保存されていた領域が解放されるので、コルーチン関数が複数設けられる場合において、解放後のメモリ3のグローバル領域3bを他のコルーチン関数のアドレスリストALなどを保存する領域として利用することができる。つまり、コルーチン関数の数が比較的多い場合でも、コルーチン関数を適切に実行することができる。
【0088】
[変形例]
なお、今回開示された実施形態は、すべての点で例示であって制限的なものではないと考えられるべきである。本発明の範囲は、上記した実施形態の説明ではなく特許請求の範囲によって示され、さらに特許請求の範囲と均等の意味および範囲内でのすべての変更(変形例)が含まれる。
【0089】
たとえば、上記実施形態では、コルーチン関数が、C言語によって疑似的に実装されている例を示したが、本発明はこれに限られない。たとえば、コルーチン関数をC言語以外の言語によって実装してもよい。
【0090】
また、上記実施形態では、コルーチン関数が、C言語のSwitch-case文によって疑似的に実装されている例を示したが、本発明はこれに限られない。たとえば、コルーチン関数をC言語のSwitch-case文以外の文(命令文)を用いて実装してもよい。
【0091】
また、上記実施形態では、コルーチン関数の情報が、自動変数、コルーチン関数のポインタ情報、コルーチン関数の中断位置、引数、および、戻り値を含む例を示したが、本発明はこれに限られない。本発明では、コルーチン関数の情報として、上記の情報以外の情報を含んでいてもよい。
【0092】
また、上記実施形態の
図12などでは、メモリ3のグローバル領域3b上において、自動変数が、Co情報が保存される領域以外の領域に保存される例を示したが、本発明はこれに限られない。たとえば、自動変数を、Co情報内の自動変数のための領域に保存してもよい。
【符号の説明】
【0093】
2 マイコン(制御部)
3 メモリ
3b グローバル領域
3d スタック領域
3e 退避領域
4 プログラム
100 制御装置
AL アドレスリスト