2020年8月23日日曜日

STM32でDCC/DDCを作る方向で (36) HARD FAULTって調べづらい

告知です.
コミケ99にて当社のDDC/DACを頒布いたします.
  日付   2021年12月31日(金) 東地区 テ-40b  東5ホール
  サークル名    bangflat
コミケにお越しの際はお立ち寄りいただけますとありがたいです.
商品紹介ページを作りました.
ーーーー

STM32でDDC/DCCを作ろう!         INDEXページへ

前回かくかくしかじかと説明した事情でSTM32F405でHARD FAULT発生中.

STM32F405のdatasheetを読んでいて、Memory protection unit(MPU)というのが在ります.205にはMPUは無いようです.
405のdatasheetによると、
  1)保護領域へのアクセスを監視する
  2)メモリ空間を8つの領域に分割し、さらにそれらを8分割して保護領域となす
てなことのようです.
405で出ているHARD FAULTはMPUのせいじゃないかと疑りの目を向けているところ.

MPUはさておき、今回はHARD FAULTが出ちまった時の追求方法を書きます.

1)debuggerでrunさせる

2)HardFault_Handler()で止まる.でも何処が原因なのかは不明

3)フォルトアナライザを開く

4)フォルトアナライザから情報を読み取る
変な場所を触らないでよとお怒りです.変な場所とは0x200c1100である.

5)フォルトアナライザの右上にこのようなボタンが!
ぴこぴこと押してみましょう.

fault発生個所がsource codeで示されます.あら便利.

それだけでなく逆アセンブリリストでも表示されます.あら便利.
しかし、場所が判ってもなぁ、、、とつぶやくしかありません.

ともあれこのケースでは、adr->DIEPTSIZがアドレス0x200c1100を指しており、そこを触ったのでSTM32F405がお怒りになっていると判ります.悪いのは0x200c1100です.

一方でDIEPTSIZとはUSBのレジスタであり、USB BASE ADDRESSは0x40040000です.0x200c1100とはかけ離れています.怪しい.

--------
0x200c1100は何者なのか?

Cortex-M4のdatasheetに解説がありました. それによると、SRAMにbitアクセスするための特殊領域のようです.だけどそれでhard faultが生じるものかしら? それは不明です.

Memory protection unit(MPU)が例外検知したとき

これもCortex-M4のdatasheetに解説がありました.MPUが例外検出したらメモリマネジメントfaultが生じると書かれています.
すなわちMemManage_Handler()でhangupするはずです.ところが現状はHardFault_Handler()でhangupしているのですからMPUは無関係と思われます.


今宵はここまでにしとうございます.

かしこ

8 件のコメント:

  1. >Memory protection unit(MPU)というのが在ります
    組み込みマイクロコントローラのくせに、仮想記憶でもやるのか?
    ・・・と思ってたんですが、よく考えると、アーキテクチャは「ARM」でしたね。
    ※ハイエンドだと、linuxとか動くし・・・

    この辺になると、マルチタスク・マルチスレッドのデバッグになるので、難儀しますね。
    私も、こういうののデバッグはイヤですね。ホント「魔法のように」メモリ値が書き換わってたりしますからね。
    (まぁ、勿論、必ず「何処かで誰かが」書き換えてるわけですが・・・)

    返信削除
    返信
    1. MPUの存在を知って、リンカがアドレス空間をぐねぐねするのかい?ってわたしも思いました.
      CoreTexM4はそこまでは器用ではないらしいのでLinuxは動かないと思いますが、RTOSを載せるとマルチタスク処理はしてくれるらしく、進化の中間的なCPUなのかなと.

      スレッドをたくさん走らせるハイブローなsoft屋さんは雲の上の人々です.

      削除
    2. "DIEPTSIZ = adr->DIEPTSIZ;" の行番号が、この値だからエラーが出たんだったりして・・・

      なワケないか、さすがにw

      削除
    3. クルマのナンバーが4274だったらどうしよう的なww

      削除
    4. っていうか、
      DIEPTSIZ = adr->DIEPTSIZ;
      って、なんかおかしくないですか? C言語的に。
      ※全部大文字って、普通「定数値」ですよね?それに代入って・・・
      (まぁ、意図的にやればできないことはないですが・・・)
      ※これ、コンパイラのバグだったりして。
      全部大文字の変数に代入すると、おかしくなるとか?

      削除
    5. ヘッダファイルを見ると、レジスタ名は大文字で定義されていますね.
      具体的には構造体のメンバ変数名がDIEPTSIZってことになってます.

      実は、Hard Faultは謎の展開で解決しつつありんす.

      削除
    6. >レジスタ名は大文字で定義
      ああ、そういうことですか。組み込み系だと、ありがち。
      (確かに、ある意味「固定」だし)

      削除
    7. レジスタ名大文字は見かけますね.他にはマクロも大文字でしょうか.

      わたしはsoftware code書いて給料もらった経験がほとんどないので表記作法とか知らないんですねぇ.勝手流です. (verilogはhardwareなので除くとして)

      削除