質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.00%

C言語 長いプログラムのスマートなプログラムリセット(終了)方法について教えて下さい。

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,223

Guamstreet

score 29

MPLAB_X IDEと、XC8コンパイラの組み合わせ環境です。

PIC16F1938を使用し、普段はスリープさせておいて、外部割り込み(RB0)を意図的に発生させる事でスリープから復帰。
そして割り込みプログラムにて、希望の動作をさせると言ったフローでプログラムを製作したいです。

その割り込みプログラムの最初で、条件分岐をさせ、①次のプログラムに進むか、もしくは、②プログラムを終了させて、また、改めてスリープに戻り、外部割り込みの発生を待機させると言った事をさせたいです。

この希望を実現させる為に、普段は『goto』を使用しています。
条件YESなら、次のプログラム。noなら『goto END_PROGRAM;』と言う風にして、プログラムの最後に、一気に飛ばします。
そうすれば、また、sleepに戻り、外部割り込み発生するまで待機してくれます。

しかしながら、今回製作しているプログラムが、異常に長く、どうやら許容範囲を超えてしまったみたいで、XC8コンパイラエラーが発生。
『error~fixup overflow string~』と言うエラー文が表示されてしまいます。

そこで、プログラムのスリム化や、効率化をして、なんとか、プログラムを短くする様に努力したのですが、それでも長いみたいで、コンパイルエラーが発生し、同じエラー文が表示されます。

以上を踏まえた上で、今のプログラムの内容は変えずに、私の希望を実現させる為のスマートな方法は、どのような方法がありますか?
そこの所を、ご教示頂けると嬉しいです。

自分でも色々と考えました。

(1)exit(0);を採用する。
最初の条件に置いてnoの場合、exit(0);// 強制終了。
これで、私の希望は実現できますか?
また、exit関数利用の為の実装(stdlib.h)がなされていれば、この1命令だけで、他は何もしなくて大丈夫でしょうか?
更に、プログラムを終了して元に戻るみたいな、今回の使用の仕方としてなら、exit(0);関数は、プログラム中に2つ以上使用しても問題はないでしょうか?

(2)return(0);を採用する。
最初の条件に置いてnoの場合、return(0);// 強制終了。
これで私の希望は実現できますか?
また、return関数利用の為の実装がなされていれば、この1命令だけで、他は何もしなくて大丈夫でしょうか?
更に、私の希望するプログラム製作においては、exit、returnのどちらを採用するのが適切でしょうか?
それと、プログラムを終了して元に戻るみたいな、今回の使用の仕方としてなら、return(0);関数は、プログラム中に2つ以上使用しても問題はないでしょうか?

(3)WDTを採用する。
条件noの場合、while(1){}で永久ループを意図的に発生させ、WDTでリセットをかける事で、改めてsleepから始める。
この方法はインターネットを探して見つけました。
これをやる場合は、コンフィグも合わせて、どの様な設定をすれば宜しいでしょうか?

(4)RESET();を採用する。
これもインターネットで探しました。
データシートで、ざっと調べてみましたが、どこに記載されているのか、わかりませんでした。
もし、これを採用する場合は、具体的にどの様なソースを記述する事で希望する動作をしてくれるプログラムが作れますか?

以上4点について、この中に、今回の、私が製作している様な、長いプログラムに最適な、スマートな方法がありますでしょうか?

それとも、上記以外で、一般的に採用されているスマートな方法がありますか?

XC8コンパイラについては、現在、free版を使用してプログラミングしています。
元々、長いプログラムが原因で、許容範囲を超えてしまった為、『goto』が採用できないと言う事で、有償版に変更して最適化させ、そして『goto』で飛ばした方が、すっきりしてよろしいのでしょうか?

色々と、申し訳ありませんが、ご教示の方、どうぞよろしくお願い申し上げます。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

+5

XC8の関数はソースファイルがインストールされているので閲覧することができます。それを参照すると、exit関数は次のようになっています。

void
exit(int v)
{
    for(;;)
        continue;
}


一目瞭然で、ただの無限ループです。もちろんこんなのはC言語規格から言えばあり得ない実装なのですが、他のマイコン専用コンパイラーでもこうした実装はしばしば見かけますし、むしろ一般的とも言えます。

今まで回答やコメントは、こうしたマイコンプログラミング固有の特殊事情を踏まえていないものがほとんどのように思えます。

ということを昨日書きかけてやめたのですが、やっぱり書かないとまずそうな雰囲気なので。

で、それを踏まえた上なんですが、私も適切な答えはちょっと出しづらいなあ。そもそも事の発端になっているエラーメッセージが、本当に想像されている「プログラムが長くて許容範囲を超えた」通りなのかなと思うのですが、私もPICでは長らく他のコンパイラーを使っていたので、XC8のエラーメッセージの詳しい内容まではちょっとわかりかねます。

率直に言って、この質問はYahoo知恵袋の方がいいかもね。あちらにはマイコンにもPICにも通じている回答者がおられますので。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/23 21:26

    keicha_hrsさん、いつも、色々すいません、ありがとうございます。
    おかげさまで、また、ひとつ、知識を習得する術を、教えて頂きました。
    ホントに感謝の気持ちでいっぱいです。
    今回は、取り敢えず、suyamaさんという方が教えて下さった"return"でプログラムを実際に動かしてみることにします。
    それでダメなら、keicha_hrsさんにアドバイス頂きましたyahooで質問してみようと思います。
    ほんとに色々ありがとうございます。
    実験した結果を、また、ご報告させて頂きます。
    今回も、お付き合い頂きありがとうございました。

    キャンセル

  • 2017/11/23 21:31

    やっぱりか!!!!
    うん、そんな気はしてたんだ。だから
    >お使いの処理系が正しくC規格に沿ってexitを実装していれば
    と釘を指していたんですが。

    keicha_hrs氏指摘の通り、Yahoo!知恵袋のほうが詳しい回答者がいるのでそちらへ質問するか英語で本家のStackOverflowに質問されることをおすすめします。

    キャンセル

  • 2017/12/04 22:21

    keicha_hrsさん、ご連絡が遅くなりました。
    return;でプログラム製作し、実際にPICにて動作させたところ、見事、return;で、元のSleep状態に戻る事が出来ました!
    return;は、プログラム内で、いくつ使っても大丈夫みたいでした。
    色々とありがとうございました!
    (yahoo質問の方にも、質問を投げてみたのですが、return;でと仰ってくれる方がいらっしゃいませんでした)
    これで、私の問題は解決いたしましたので、本質問を終了させて頂きます。
    ご報告とお礼まで!

    キャンセル

checkベストアンサー

+1

exitとreturnの結果が同じような動作となるのは、main関数内だけかと思います。
通常はexitにてプログラムを終了すれば事足りるかと思います。

exit
http://pubs.opengroup.org/onlinepubs/009695399/functions/_exit.html

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/23 19:03 編集

    exitはプログラムの終了ですので、プログラムの終了コードを返却することに問題はありません。
    main関数の定義がint mainであっても、void mainであってもです。
    実際にはその終了コードを受け取って次に実行されるものが何もないため、keicha_hrsさんのご回答のように実装上は無限ループとなって何も処理を行わなくなるといった挙動となるようですね。

    キャンセル

  • 2017/11/23 19:51

    suyamaさん、ここまで色々とありがとうございました。
    suyamaさん含め、色々な方の、ご回答により、今回は、予想以上の知識を習得できたように思います。
    これ以降は、実際に、プログラムを走らせてみて実験してみたいと思います。
    ご教示頂いた"return;"を強制終了の所と、プログラムの最後の2箇所に採用してやってみたいと思います。
    少し、時間が掛かるかもしれませんが、結果は、また、ご報告させて頂きます。
    ほんとに、どうもありがとうございました。

    キャンセル

  • 2017/12/04 22:26

    suyamaさん、ご連絡遅くなりました。
    return;でプログラム作成し、実際にPICで動作確認をしました所、見事、return;で、私の希望を実現させる事ができました。
    return;にすると、そこで強制終了させる事が出来、かつ、一番最初のSleep状態に戻ってくれました。
    exit;ですと、PICの供給電源を一度落とすとか、物理的なリセットを掛けないと、最初のSleepに戻りませんでした。
    今回は、return;と言う、問題解決の為の重要なトリガーを下さって、本当にありがとうございました!
    これで、私の問題は解決されましたので、私の質問を終了させて頂きます。
    遅くなりましたが、ご報告とお礼まで!

    キャンセル

+1

お使いの処理系が正しくC規格に沿ってexitを実装していれば、単にそれを呼び出すだけでいいです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/23 17:38

    Taro Toyotomiさん、早速のご回答、どうもありがとうございます。
    なるほど、そういう事なのですね。
    ありがとうございます。
    これを踏まえた上で、私の希望を実現させるのは、exit(0);一択と考えても宜しいでしょうか?
    すいませんが、ご回答くださいますと、幸いです。

    キャンセル

  • 2017/11/23 18:03

    お使いの環境の仕様を知らないので何とも言えませんが、
    本当の意味でプログラムを終了させるのならexit(0)で問題ないと思います。
    その場合、次にプログラムを実行するのは電源を入れなおした時になると思います。

    キャンセル

  • 2017/11/23 18:10

    TaroToyotomiさん、ご返信、ありがとうございます。
    TaroToyotomiさん含め、皆様、色々、アドバイスして下さり、少しずつではありますが、見えてきたところがあります。
    今回の質問で、ある程度、知識が蓄えられたので、そろそろ、実際に、プログラムを走らせて実験をしてみようと思います。
    TaroToyotomiさん、ご助言頂き、ほんとうにどうもありがとうございます。
    感謝致します。

    キャンセル

+1

XC8自体使った事がないのでなんとも言えませんが、通常はreturnなりexitなりで抜ければよいはずです。
エラーになるのはそういう問題ではなく、単純にプログラムが大き過ぎてスタックが足りてないからかと思います。

もし、割込みではなくてワンショットなら動くということであれば、処理が長過ぎて多重割り込みになっているということもありえなくはないですが・・・・。(普通は先頭で割込み禁止にして、終了時に割込み再開にしますが)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/23 20:33

    CodeLabさん、ご回答くださりありがとうございます。
    他の回答者の方も、"return;"を試してみてはと仰って下さっているので、今回は、"return;"で、実際に実験してみようと思っています。
    ご回答くださり、どうもありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.00%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる
  • トップ
  • Cに関する質問
  • C言語 長いプログラムのスマートなプログラムリセット(終了)方法について教えて下さい。