LoginSignup
0
0

ビルドやデバッグのメモ(組込みC言語)

Posted at

ビルドの流れをおさらい

ソースファイル(.cや.h)→コンパイル実行→オブジェクトファイル(.o)、
ライブラリやモジュール(.aや.ld)→リンク実行→実行可能ファイル(.motや.run)
※拡張子は適当

デバッグ時の心構え

・プログラムを詳細に理解する(フローチャートを用意しておくといい)
・特に非効率なのはプログラムコードを理解しない状態で
 修正してみてはコンパイル実行の繰り返し

Q1:ビルド実行時、何らかのシンボルが定義されていない系のエラー

→どこの段階でのエラーかをまずは確認する

☆コンパイル段階でのエラーの場合
・タイプミスないか(セミコロン抜け、文字コード、タブ、全角など)
・定義されてないシンボルを参照していないか
・ヘッダーファイルのインクルードが正しくできてるか
・実際のエラーを示す行と問題の行が一致しているとは限らない

☆リンク段階でのエラーの場合
・必要なライブラリやモジュールをリンクできているか
・古いプリコンパイル済みのヘッダーファイルを参照していないか、
 疑わしければリビルド(再コンパイル)する

Q2:ビルド実行時、ヘッダーファイルが見つからないエラー

・環境変数INCLUDEは適切に設定できているか
・コンパイルオプションの指定は正しいか
・IDE利用中であれば、IDEのプロジェクトの設定は正しいか

Q3:処理速度が要求を満たしていないとき

・コンパイラの最適化機能で速度優先にする
・配列のループ格納処理をポインタにする
・関数をマクロにできないか検討する
・Cからアセンブラにする(インラインアセンブラもしくはソースファイルごとアセンブラ)
・メモリ定義をレジスタ(register)にする。現場では見たことない
・サイズの小さなデータ型を使う
・シフトを使って計算を速く行う
・短絡評価(演算子の左側の数を評価した段階で式全体の値が
 定まらない時のみ右側を評価)を使う

例:if(func()>3 || x>3) ではなく 、
  if(x>3 || func()>3) こう書いておけば、
   x>3の時はfuncが呼ばれなくて無駄な処理時間を省ける。

Q4:どこかでリセットが掛かっているが原因不明のとき

・リセット要因レジスタに条件付きwriteブレークを張り、リセット要因を特定する
☆ハードウェアリセットの場合
・ウォッチドッグがリセットしてるかも(外部、内部どちらかも判別しておく)
・電源ICの仕様を確認する

☆ソフトウェアリセットの場合
・Resetで飛んでくる処理の先頭にブレークを張って、
 止まったときのコールスタック(関数の呼び出し履歴)を確認すると分かることもある
・二分法などを用いてリセット発生させてる処理を特定する
・無限ループに入る→ウォッチドッグがリセットのパターンはよくある
・想定と全然違うところで問題発生してる場合はスタックオーバーフローも疑う

Q5:デバッガ操作前に事前に知っておきたいこと

・ステップ実行、ステップオーバー実行の違い
・ソフトウェアブレークとハードウェアブレークの違い
・コールスタックの見方
・レジスタの見方
・pc(プログラムカウンタ)で現在番地を操作する

Q6:デバッガ接続時は問題ないが、デバッガ未接続時のみ問題が発生する

・デバッガではRAMなどのメモリを事前にクリアしており、問題ない挙動になることがある。
・デバッガではウォッチドッグが無効になっており、問題発生しないことも

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0