So-net無料ブログ作成

"Broken Breakpoint"って何だ? [MPLABXとXC8]

(2014.01.24)
MPLABXでタッチ・スイッチのプログラムをデバッグしていて、ブレーク・ポイントが上手く設定できない箇所があることに気付きました。設定は受け付けるのですが実際に走らせるとブレークが掛かりません。
2014_0124_1.png設定操作は受け付ける

最初は自分のプログラムを疑いましたが、そうでは無いことが判りました。直前のif文ではブレークするのですが、STEP実行するとifブロックの下の(ブレーク・ポイントを設定した)行には行かず、別のcase文の中に入るのです。
2014_0124_2.png白い帯に変わりBroken Breakpointと表示される
<Cプログラム(抜粋)>
    switch( sw->sw_state )
    {
        case OFF_STATE:
            if( sw_condition == SW_ON )
            {
              sw->sw_state = T_ON_STATE;
              sw->prev_sw_state = OFF_STATE;
            }
            sw->delay_count = 0;   <== ここに来る(3)
            break;
        case ON_STATE:
            if( sw_condition == SW_OFF ) <== ここでBraek (1)
            {
              sw->sw_state = T_OFF_STATE;
              sw->prev_sw_state = ON_STATE;
            }
            sw->delay_count = 0;   <== STEP実行するとここに来ないで (2)
            break;
    }

アセンブル・リストを見ると、こんなコードになっていました。
<アセンブル・リスト(抜粋)>
  2759  00121E                     l9245:      <== ここに来る(4)
  2762                           ;sw_operation.c: 158: }
  2763                           ;sw_operation.c: 159: sw->delay_count = 0;
  2764  00121E  C1B6  FFD9         	movff	update_sw_common@sw,fsr2l
  2765  001222  C1B7  FFDA         	movff	update_sw_common@sw+1,fsr2h
  2766  001226  0E00               	movlw	0
  2767  001228  6EDF               	movwf	indf2,c
  2769                           ;sw_operation.c: 160: break;
  2770  00122A  D137               	goto	l9311

  2780  001236                     L9:       <==ここを経由して(3)
  2781  001236  6EDF               	movwf	indf2,c
  2782  001238  D7F2               	goto	l9245  

  3089                           ;sw_operation.c: 248: if( sw_condition == 0 )
  3094  00141A  67B5               	tstfsz	update_sw_common@sw_condition& (0+255),b
  3095  00141C  D700        goto	l9245  <== ifブロックに入らない時(1)
  3098                           ;sw_operation.c: 249: {
  3099                           ;sw_operation.c: 250: sw->sw_state = 1;
  3111                           ;sw_operation.c: 251: sw->prev_sw_state = 5;
  3120  001446  0E05               	movlw	5
  3121  001448  D6F6       goto	L9     <== ifブロックを抜ける時(2)
  3122  00144A                     l9305:


”Broken Breakpoint”というのは、ライン・ブレークに対応するアセンブラ行が見つからないときに発生するようです。それにしても不思議なコード展開です。Cプログラム通りにアセンブルしてくれれば良いんだけどなぁ~
2014_0124_3.pngOptimizeのチェックを外しても変わらない
この処理を止めさせる方法はあるんでしょうか?

にほんブログ村 IT技術ブログへ
にほんブログ村 ネットブログ コミュニティサイトへ
にほんブログ村 IT技術ブログ オープンソースへ


nice!(0)  コメント(2)  トラックバック(0) 
共通テーマ:日記・雑感

nice! 0

コメント 2

おおき

インラインアセンブラかマクロでNOPを加え、そこにブレークポイントを
設定すれば動作するはずです。
症状が改善しない場合はソースファイルのパスに全角文字がはいっていないか確認してください。すべて半角文字である必要があります。
by おおき (2016-04-05 20:31) 

broadbeans

御免なさい。コメントの承認を忘れていました。
ご指摘の通りですね。

二か所ある以下のコードを少し変えてやれば別のパスになって期待した通りのbreakが掛けられるようです。
sw->delay_count = 0;
break;

例えば下の部分にだけnopを加える
sw->delay_count = 0;
asm("nop");
break;

ただ、デバッグのためだけにコードを追加するのも煩わしいので、コンパイラに最適化を止めさせたいのですが、Optimizeを外しても駄目ってところが腑に落ちません。
by broadbeans (2016-12-01 14:04) 

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

※ブログオーナーが承認したコメントのみ表示されます。

トラックバック 0