マイコン関連小ネタ

| コメント(0)

本ページでは、筆者が作業中にあたった問題等をメモ化して列記する。

問題と原因の関係が一対一であるとは限らないので、

あくまでも一例としてご覧いただきたい。

★ARM関連

① STM32F2でシステムクロック周波数を変更すると、動作がおかしくなる。

◆問題:
STM32F2において、25MHzのシステムクロックを内蔵PLLでてい倍し、120MHzにして使おうとした。
そうすると、システムクロックをPLL出力に切替した瞬間に動作がおかしくなった。
PLLの設定や、内蔵周辺機能に渡すクロックの分周器設定は間違っていないはずである。
PLL設定を変えてシステムクロックを下げると、正しく動作するようになる。
◆原因:
内蔵フラッシュのアクセス遅延時間の設定を正しく行っていなかった。
電源電圧とシステムクロック周波数の関係から、正しい遅延時間設定を行う必要がある。
◆解決:
システムクロックをPLLに切替する前に、
フラッシュアクセスコントロールレジスタ (FLASH__ACR) の再下位3bit LATENCY を
リファレンスマニュアルの設定表にあわせて正しく設定する。

② Cortex-M3 でlong long型の計算をするとおかしくなる。

◆問題:
STM32F2 (コアはCortex-M3) でlong long型の割り算を行ったら、なぜか処理がおかしくなる。
デバッガを使ってアセンブラの命令を追いかけると、BLXという命令にあたった時におかしくなっているよう。
BLXは、long long型の計算を行う関数に飛ぶためのジャンプ命令として使われているよう。
コンパイラはgcc。
32ビットのCortex-M3はlong longの計算ができないので、gccがlong long型の計算を行う関数を
勝手にリンクするということのよう。
◆原因:
コンパイラのオプションにはコア指定の -mcpu=cortex-m3 -mthumb 設定をつけていたが、
リンカには上記設定をしていなかった。そのため、Cortex-M3の対応しない命令が使われてしまった。
解決:
リンカのオプション設定にも -mcpu=cortex-m3 -mthumb を追加する。
参考:
以下が詳しい。

③ クロック設定等をいじっていたら、おかしくなった。
 リセットしてもJTAGのデバッガが使えない。

◆問題:
STM32F2のIOポート設定や、クロック設定をいじって試していたら、
設定がまずかったため、マイコンが動作しなくなった。
マイコンやIDEをリセットしてもJTAGデバッガが動くようにならない。
◆原因:
マイコンの起動直後にJTAGデバッガ等のICEの通信環境をつぶすような
プログラムを書くと、マイコンをリセットしても起動直後にデバッガが使えなくなるため、通信できなくなる。
JTAG経由のマイコン書き換えもできず、困った状態になる。
◆解決 その1:

① パソコンのシリアルポート経由でCPUとパソコンを接続できるようにする。
 CPUボードに、USB-シリアル変換ICが載っているのであれば、それを利用してもよい。
 なければ、USB-シリアル変換器や、RS232のレベルコンバータ等を使っての接続が必要になるかもしれない。

② "STM32 and STM8 Flash loader demonstrator"をSTマイクロのページよりダウンロードする。

http://www.st.com/stonline/stappl/resourceSelector/app?page=resourceSelectorPage&doctype=st_software_rsrc&SubClassID=1169

③ マイコンのブートモード設定端子をいじり、ブートモードを System memory に設定してマイコンをリセットする。

 STM32F2の場合、BOOT1 =0、 BOOT0 = 1にすればよい。

④ Flash loader demonstratorを使ってマイコンのFlashを全部消す。

⑤ マイコンは復活し、JTAG経由でプログラム書き込みできるようになったはず。

  ただし、同じプログラムを書き込んだら、また死んでしまう。忘れずに違うプログラムを書き込もう。

◆解決 その2:

設定ミスするたびにその1の手順を踏むのが面倒な場合は、
その1に加えて以下の手順を行えるようにしておくとよい。
(すでにマイコンがおかしくなっている場合は、その1の手順から実施しないとだめです)

⑥あらかじめ、プログラムのスタート地点にできるだけ近い場所※1に、以下のようなコードを入れる。

int main (void) {

RCC->AHB1ENR = 0x000000FF; //IOポートにクロック供給する

//バグった時の救済用。ボタンを押しながらリセットすると、ここでひっかかる。
if (((GPIOC->IDR) & 0x00002000) == 0) {
while (1);
}
・・・

つまり、IOポートを読んで、起動時点で何かボタン※2が押されていたら、
無限ループに入るようにしておく。

※1: 問題の発生箇所より手前にないと意味がない。
※2: 上記の場合は、ポートCの13番に負論理でボタンが接続されている。

⑦ ボタンを押しながらマイコンをリセットする。
  この時点で、マイコンの処理は無限ループに入るから、
  JTAGポートをつぶすような処理もしない。

⑧ ボタンはそのまま押しっぱなしにし、JTAGデバッガをつないで、
  デバッグ起動してみる。プログラムはwhile(1); で永久ループしているはず。
 JTAGデバッガが使える状態である。

⑨ JTAGポートをつぶさない、正しいプログラムを書き込む。
  ボタンをはなして、正規の処理を行わせる。

コメントする

本ページの管理人

Likipon

埼玉在住の一応エンジニア。最近はシステムエンジニア気味で回路が本業でなくなってしまった。

うなりくんのファン。

メニュー

広告