• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:グローバル変数を別Cファイルで使用すると暴走)

グローバル変数を別Cファイルで使用すると暴走

このQ&Aのポイント
  • 現在ATMELのATxmega128A1でプログラミングを行っています。ブザーを鳴らす機能で、必ずならしたらすぐに消すというコードを作成したつもりなのですが、ずっとなり続けてしまうという動作が出てしまいます。
  • グローバル変数を使用してブザーを制御し、5秒間ブザーが鳴り続けた場合に強制停止するようにしたいです。そのために、u32型のグローバル変数BuzzerTimeLimit_GetTimeを作成し、ブザーを鳴らしたタイミングで現在時刻に5秒を足して代入しています。
  • しかし、このグローバル変数を別のCファイルでも使用するためにextern宣言を行ったところ、プログラムが暴走してしまいます。原因やチェックすべき箇所について教えていただきたいです。

質問者が選んだベストアンサー

  • ベストアンサー
  • wormhole
  • ベストアンサー率28% (1626/5665)
回答No.2

>バッファオーバーランについてですが、これを見つける方法などご教示頂けると幸いです。Debugフォルダの中にあるmapファイルなどで見つけ出すことなど可能でしょうか? バッファオーバランというのは例えば10バイトの領域しか確保していないのに、11バイトや12バイトなどそれより多く読み書きしようとすることですのでmapファイルなどではわかりませんよ。 基本的にはソースコードを詳細に読んで、そのような処理になっているところがないかを調べていくしかないです。

techhouse
質問者

お礼

回答頂きありがとうございます。返事が遅くなり申し訳ありません。 その後、この問題が解決できました。 原因が完全に判明したわけではないのですが、システム起動時にEEPROM領域に保存されているシステムの各機能の使用有無の設定データの領域を必ずグローバル変数領域に読み込む動作を行っているのですが、EEPROM領域に今後追加されるであろう機能のためにリザーブ領域としてすべて確保していたのですが、それ以外のグローバル変数領域も合わせるとData Memory Usage :8121 bytes 99.1 % Full もうギリギリまで使用していて起こっていた現象のようで、EEPROM領域のグローバル変数への確保を30byte程度減らすコードに修正したところ u32 BuzzerTimeLimit_GetTime この変数を宣言しても暴走する現象は起きなくなりました。 ”99.1%だったので、あと0.9%残ってる”という考えは甘かったようです。Data memory領域は限界に近いということのようでした。他に影響がないかを調べる予定です。 助かります。

その他の回答 (1)

  • wormhole
  • ベストアンサー率28% (1626/5665)
回答No.1

バッファオーバーランなどが起こるようになっていないかソースをしらみつぶしに調べてくしかないかと思います。 http://okwave.jp/qa/q9212502.html で書かれていたソースもNUL文字終端の文字列を扱う関数にNUL文字終端になっていない文字列を渡すなどされていましたし。 また sprintf((char *)str,"%04dZ",pass16); を sprintf((char *)str,"%04d\x5a",pass16); で直ったように思われてるようですけど、実際にはこれで直るはずはありませんから(たぶんほかの要因も絡んで見かけ上直ったように思えるだけかと)。 補足 文字列"%04d\x5a"の解釈はコンパイル時に行われ"%04dZ"に変換されます。 sprintfの書式の解釈はsprintf実行時なのでコンパイル時に変換された"%04dZ"が渡されます。 リテラル文字列のエスケープ文字の解釈はコンパイル時です。 printfやscanfなどの書式の解釈はその関数実行時です。

techhouse
質問者

お礼

回答頂きありがとうございます。助かります。 バッファオーバーランについてですが、これを見つける方法などご教示頂けると幸いです。Debugフォルダの中にあるmapファイルなどで見つけ出すことなど可能でしょうか? 今まで正常に動作できていた際のビルド結果と今回のビルド結果を比較すると、 (前回の正常に動作するさビルド結果のリポート) ------ Build started: Project: MainUnit, Configuration: Debug AVR ------ Build started. Project "MainUnit.cproj" (default targets): Target "PreBuildEvent" skipped, due to false condition; ('$(PreBuildEvent)'!='') was evaluated as (''!=''). Target "CoreBuild" in file "C:\Program Files (x86)\Atmel\Atmel Studio 6.2\Vs\Compiler.targets" from project "C:\mywork\source\TestWatch\branches\TestWatch_20160607\MainUnit\MainUnit.cproj" (target "Build" depends on it): Task "RunCompilerTask" Shell Utils Path C:\Program Files (x86)\Atmel\Atmel Studio 6.2\shellUtils C:\Program Files (x86)\Atmel\Atmel Studio 6.2\shellUtils\make.exe all make: Nothing to be done for `all'. Done executing task "RunCompilerTask". Task "RunOutputFileVerifyTask" Program Memory Usage : 51546 bytes 37.0 % Full Data Memory Usage : 8079 bytes 98.6 % Full Done executing task "RunOutputFileVerifyTask". Done building target "CoreBuild" in project "MainUnit.cproj". Target "PostBuildEvent" skipped, due to false condition; ('$(PostBuildEvent)' != '') was evaluated as ('' != ''). Target "Build" in file "C:\Program Files (x86)\Atmel\Atmel Studio 6.2\Vs\Avr.common.targets" from project "C:\mywork\source\TestWatch\branches\TestWatch_20160607\MainUnit\MainUnit.cproj" (entry point): Done building target "Build" in project "MainUnit.cproj". Done building project "MainUnit.cproj". Build succeeded. ========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ========== (今回の暴走してしまうファームのビルド結果のリポート) ------ Build started: Project: MainUnit, Configuration: Debug AVR ------ Build started. Project "MainUnit.cproj" (default targets): Target "PreBuildEvent" skipped, due to false condition; ('$(PreBuildEvent)'!='') was evaluated as (''!=''). Target "CoreBuild" in file "C:\Program Files (x86)\Atmel\Atmel Studio 6.2\Vs\Compiler.targets" from project "C:\mywork\source\TestWatch\branches\TestWatch_20160804\MainUnit\MainUnit.cproj" (target "Build" depends on it): Using "RunCompilerTask" task from assembly "C:\Program Files (x86)\Atmel\Atmel Studio 6.2\Extensions\Application\AvrGCC.dll". Task "RunCompilerTask" Shell Utils Path C:\Program Files (x86)\Atmel\Atmel Studio 6.2\shellUtils C:\Program Files (x86)\Atmel\Atmel Studio 6.2\shellUtils\make.exe all make: Nothing to be done for `all'. Done executing task "RunCompilerTask". Using "RunOutputFileVerifyTask" task from assembly "C:\Program Files (x86)\Atmel\Atmel Studio 6.2\Extensions\Application\AvrGCC.dll". Task "RunOutputFileVerifyTask" Program Memory Usage : 52564 bytes 37.7 % Full Data Memory Usage : 8121 bytes 99.1 % Full Done executing task "RunOutputFileVerifyTask". Done building target "CoreBuild" in project "MainUnit.cproj". Target "PostBuildEvent" skipped, due to false condition; ('$(PostBuildEvent)' != '') was evaluated as ('' != ''). Target "Build" in file "C:\Program Files (x86)\Atmel\Atmel Studio 6.2\Vs\Avr.common.targets" from project "C:\mywork\source\TestWatch\branches\TestWatch_20160804\MainUnit\MainUnit.cproj" (entry point): Done building target "Build" in project "MainUnit.cproj". Done building project "MainUnit.cproj". Build succeeded. ========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ========== 前回と今回のビルド結果の違いは、 前回はData Memory Usageは98.6%だったのですが、今回 u32 BuzzerTimeLimit_GetTime このグローバル変数を加えてからは Data Memory Usage : 8121 bytes 99.1 % Full になっていることぐらいだと思うのですが、気づいた点など教えていただけると助かります。

techhouse
質問者

補足

http://okwave.jp/qa/q9212502.html こちらの件でもお世話になっております。 この件に関しましては、 sprintf((char *)str,"%04d%s",pass16,"M1#"); sprintf((char *)str,"%04d%s",pass16,"Z"); と書いて解決しました。 助かりました。

関連するQ&A