HI-TechのPICC PRO 9.65を使ってPIC16F877Aのプログラミングをしています。
しかし、最近マイコンの動作が不安定になり、突然プログラムが暴走したりするので、プログラムカウンタに問題があると疑っています。
昔、アセンブラでプログラムしていた頃はPCLATHに書き込んでからPCLに書き込んだり、ORG命令などで対処していましたが、今回初めてPICCを導入したので対処の仕方がわかりません。
またCコンパイラによっては自動でPCLATHを繰り上げてくれるようなのですが、PICCの場合はどうなのでしょうか。
hexを除いてみると0x0800のあたりもびっしりコードでうまっているのですが。。。
ちなみに
asm("ORG 0x0800");
などのようにC言語の中にアセンブラで記述してもうまく解決できませんでした。
PCLATH = PCLATH + 0b000?????;
とか色々やってみたのですがだめでした。
そもそもヘッダやインクルードの内容がどの番地に書き込まれているかを調べる良い方法はないでしょうか。
1.PICCはPCの操作を自動でやってくれているのか
2.もしそうでなければどのようにして解決すればよいのか
で宜しくお願い致します。
No.3ベストアンサー
- 回答日時:
1.PICC(コンパイラ)はPCの管理を行いません。
2.暴走の原因を最近プログラミングしてしまったものと見受けられます。
PIC16Fxxxのアーキテクチャの問題ですが、内部にPC用の専用スタック(LIFO)が存在します。
アセンブラ上でCALL(関数呼び出し)が発生した場合、現状のPCカウント値を専用スタックへPUSHし、return命令時に自動でPOPします。
但し、このスタックはデバイスに拠りますがリングバッファとして大概8層程度しかありませんので、PICCを使って関数コールを8層以上掛けた場合容易に上書きされてしまいます。
C言語上で確認が可能です。関数コールを連続してスタック数以上呼んでいませんか?
正確なPCスタック数はMicrochipのサイトからデータシート内の記述で確認が可能です。
問題部の記述が無いので憶測ですが、知らずに使うと簡単に暴走する部分ですので。たぶんココじゃないかなぁ?
この回答への補足
アセンブルリストで何層スタックしているかを数えてみましたが、0x0000番地に急に飛んでしまう問題の箇所ではスタックは全くオーバーフローしていませんでした。
そのかわり、0x0000番地に飛んだときにスタックはリセットされないままですので、プログラムの2周目か3周目でオーバーフローしていることがわかりました。
つまりなぜ”CALL 0”という変な命令が生成されてしまったかを解決しないといけないようです。
遅くなりました、ありがとうございます。
PIC16F877Aのスタックは物理的に8層までです。アセンブラのときは8層も使わなかったためスタックのことはすっかり忘れていました。ありがとうございます。
本日シミュレーターで1ステップずつ確認してみましたが、0x0000番地に急に飛んでしまうという問題の箇所に差し掛かるまでに、”C言語の関数は”3~5層しか呼んでいませんでした。
ですがコンパイルされたアセンブラリストを見ると、どうもひとつの関数のために何度かcall命令が生成されているので、C言語としては3層でもアセンブラ上では8層を超えている可能性がありそうです。。。正確に何層かは簡単には数えられなさそうです。
ちなみにMPLAB-IDEでは、C言語としてのスタック数はメニューからView-HardwareStackでみれたのですが、アセンブラのスタック数を見られるはずのView-CallStackのとこはなぜか灰色でクリックできません。なので明日かあさってにはなんとか手動で数えてみます。
これで数えてみてもし9層目をcallしていたらbug_bugさんには非常に感謝しなければいけないですね。。。ありがとうございます。調べるので少々お待ちください。
あと参考程度なのですが、0x0000番地に急に飛んでしまうという問題の箇所が、アセンブラリスト上では実は
2000 (CALL 0)
となっていることがわかりました。そのまますぎて笑えるのですが、「call 0」とかいうこんな明らかに間違っているコンパイルをするというのは、無理に9層目をcallしようとして起きたという理解でいいんでしょうか。?
このようなことを何か経験された方がいらっしゃったら引き続き教えてください>< もう表題と関係ないのでスタック数のことが正式に解決しましたら質問し直します。
bug_bugさんありがとうございました。
No.4
- 回答日時:
call 0 がコンパイラによって生成されるとは考えにくいので、MPLAB上の逆アセンブルリストを参照しているのであればconst値などのデータセクションにPCが飛んでしまっているのかもしれません。
逆アセンブルリストでプログラムROM上のアドレスさえ確認できれば、.mapファイルを参照し何が格納されているのか確認できますね。
仕様が不明なのでちょっと解答は難しいですが、割り込み発生時や、割り込み処理での要因別ブランチの関数コールなどでもPCスタックは行われるので注意が必要です。
とりあえず思いつくトコだけ・・・。
No.2
- 回答日時:
C18やC30は、PIC16Fでは使えません。
他のコンパイラだと「SDCC」とか「CCS C/PCM」とか「FED-C」とかでしょうか。
c2cと言うのもあるみたいですが、Linux版のみ無料のようです。
http://ww2.tiki.ne.jp/~maro/old/PIC/C2C/
と思ったらc2cは入手不能になってました。
私は16F84しか書いたことないのでPCLATH対応については未知ですが、上記のc2cのアセンブルリストを見る限りは他のコンパイラでも対応している可能性が有ります。
No.1
- 回答日時:
PICCには詳しくないんですが、とりあえずPC系の誤動作を疑うならアセンブルリストを取ってコードを確認してみてはどうでしょうか。
PICC-LITEと同じなら-ASMLISTで取れると思います。
実際上のメモリの配置アドレスは、リンカでマップファイルを作成する必要があります。調べてみてください。
なんにしても無理やりPCLATHを変更するのはC言語として矛盾が生まれるで無理があると思います。
ありがとうございます。
アセンブルリストというものを知りませんでした。。。
いい忘れてましたがPICCはMPLABIDEと統合して使っていましたので、探してみたところMPLABのViewメニューのDisassemblyListingで見れました。
これでどの番地にどの関数が書いてあるか一目でわかりました、ありがとうございます。
で早速問題を調べてみましたが、シミュレータで見てみてもやはりreturn命令などの後にいきなり0x0003番地に戻されたりしているのでPC関連の問題な気がします。しかしどう対策するのかわかりません。。。
マップファイルやらでメモリの配置を触ったところで解決できる自信がありませんが一応今調べてみています。一応それぞれの関数はページをまたがない様に配置してくれていました。
あきらめてC18やC30に移行してみたくなっていますがこれらはPCの問題はないのでしょうか。。。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) プログラムの勉強のおすすめは 7 2022/12/09 20:09
- その他(コンピューター・テクノロジー) 量子コンピュータの動作原理がわかりません。同じビットが、1でも0でも有って良いだろうか? 3 2023/02/04 03:20
- 仕事術・業務効率化 効率的な勉強方法(分野問わず)を教えてください 1 2023/08/16 01:33
- C言語・C++・C# exeファイルが作れない(windows10) 6 2022/08/13 08:47
- C言語・C++・C# 参考にいろいろとc言語、c++言語プログラミングでレジストリーを操作したいのですが、無料配布のc++ 3 2022/12/22 01:49
- 工学 1つのタクトスイッチで複数の並列回路を閉じ、アースにつなげることができるスイッチはありますか。 2 2022/08/06 10:38
- その他(自然科学) 科学技術計算の仕事について 2 2023/02/04 18:09
- その他(プログラミング・Web制作) Windows上のプログラム。「予め決められた時刻に自分で起動して処理して自分で終了する」って可能? 3 2023/01/04 14:29
- デスクトップパソコン 「自動修復でPCを修復できませんでした」と表示されPCが起動しないのですが対処法はありますか? 5 2022/05/13 09:16
- C言語・C++・C# C言語 3 2022/10/04 15:07
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
unsigned long long 型のフォー...
-
ソフトの開発言語を調べる方法
-
printfなど、標準関数のソース...
-
昔のgraph.hというファイル
-
C++でデスクトップGUIアプリ開...
-
COBOLのALPHABET...
-
C言語のフリーソフト。
-
main() 関数は、int を返値とす...
-
組み込みソフト。ROM領域にデータ
-
サイクルカウントの方法
-
組込みC開発
-
リリースモードとデバッグモー...
-
オープン系とか、組込み系とか...
-
COBOL計算式の中間ワーク桁数に...
-
Type name expected エラーがで...
-
プログラミングって右脳よりの...
-
ALGOL・PL/Iのフリーのコンパイ...
-
cc と gcc の違い
-
C言語 main関数とsum関数の記...
-
C++Builder → Visual C++ 移植...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
unsigned long long 型のフォー...
-
ソフトの開発言語を調べる方法
-
C++でデスクトップGUIアプリ開...
-
printfなど、標準関数のソース...
-
組み込みソフト。ROM領域にデータ
-
リリースモードとデバッグモー...
-
変数の内容がコロコロ変わる、...
-
cc と gcc の違い
-
COBOLの論理演算子について質問...
-
Visual Studio でmakefileを使...
-
PICでのI2C通信でのマスタ、ス...
-
COBOLのALPHABET...
-
<conio.h>?
-
VB6のコンパイラ
-
COBOL計算式の中間ワーク桁数に...
-
パーサとコンパイラの違いって?
-
関数形式マクロ dtaは戻り値が...
-
プログラミングって右脳よりの...
-
C++Builder → Visual C++ 移植...
-
24bit サイズの変数
おすすめ情報