Tag Archives: 電子工作

stm32f10x_can.c のバグについて

前回の投稿と打って変わって組込系の話題を。

最近STM32でCANとか使っているのですが、時々送信に失敗してしまうという問題がありました。

たまになので問題ないのですが、気になったので調べてみるとSTMicroが用意しているSTM32F10x standard peripheral libraryのバグでした。バージョンは04/16/2010 のV3.3.0と古いやつですが。

具体的に言うと、現在送信しようとしているメッセージの状態を確認する関数

CAN_TransmitStatus にあります。

ここでは CANxのTSRレジスタのTSS_RQCP0、TSR_TXOK0、およびTSR_TME0ビットの値を見て、

CANTXPENDING(送信中)、CANTXFAILED(失敗)、CANTXOK(成功)を返しています。

が、こんな風にレジスタにアクセスするようなコードになってます。

switch (TransmitMailbox)
  {
    case (0): state |= (uint8_t)((CANx->TSR & TSR_RQCP0) << 2);
      state |= (uint8_t)((CANx->TSR & TSR_TXOK0) >> 0);
      state |= (uint8_t)((CANx->TSR & TSR_TME0) >> 26);
      break;
    case (1): state |= (uint8_t)((CANx->TSR & TSR_RQCP1) >> 6);
      state |= (uint8_t)((CANx->TSR & TSR_TXOK1) >> 8);
      state |= (uint8_t)((CANx->TSR & TSR_TME1) >> 27);
      break;
    case (2): state |= (uint8_t)((CANx->TSR & TSR_RQCP2) >> 14);
      state |= (uint8_t)((CANx->TSR & TSR_TXOK2) >> 16);
      state |= (uint8_t)((CANx->TSR & TSR_TME2) >> 28);
      break;
    default:
      state = CANTXFAILED;
      break;
  }

これでは、レジスタに3回アクセスしてしまっており、アクセスとアクセスの間でレジスタの値が変わってしまうと変なstatusになってしまいます。その結果 default で CANTXFAILED がセットされてしまうというのが送信失敗の原因です(実際にはこの瞬間に成功しているが、失敗したと判断してしまう)。

最も修正量の少ない解決策は簡単で、CANx->TSRの値を一旦変数に入れてやればいいのです。

uint32_t _tsr =  CANx->TSR;
switch (TransmitMailbox)
  {
    case (0): state |= (uint8_t)((_tsr & TSR_RQCP0) << 2);
      state |= (uint8_t)((_tsr & TSR_TXOK0) >> 0);
      state |= (uint8_t)((_tsr & TSR_TME0) >> 26);
      break;
    case (1): state |= (uint8_t)((_tsr & TSR_RQCP1) >> 6);
      state |= (uint8_t)((_tsr & TSR_TXOK1) >> 8);
      state |= (uint8_t)((_tsr & TSR_TME1) >> 27);
      break;
    case (2): state |= (uint8_t)((_tsr & TSR_RQCP2) >> 14);
      state |= (uint8_t)((_tsr & TSR_TXOK2) >> 16);
      state |= (uint8_t)((_tsr & TSR_TME2) >> 28);
      break;
    default:
      state = CANTXFAILED;
      break;
  }

こんな風に。

で、最新のV3.5.0ではちゃんと修正されてました。

switch (TransmitMailbox)
  {
    case (CAN_TXMAILBOX_0):
      state =   CANx->TSR &  (CAN_TSR_RQCP0 | CAN_TSR_TXOK0 | CAN_TSR_TME0);
      break;
    case (CAN_TXMAILBOX_1):
      state =   CANx->TSR &  (CAN_TSR_RQCP1 | CAN_TSR_TXOK1 | CAN_TSR_TME1);
      break;
    case (CAN_TXMAILBOX_2):
      state =   CANx->TSR &  (CAN_TSR_RQCP2 | CAN_TSR_TXOK2 | CAN_TSR_TME2);
      break;
    default:
      state = CAN_TxStatus_Failed;
      break;
  }

一度でアクセスするようになってます。でも返値変わってて、最新版に置き換えるのは大変そう…

STM32の書き込み環境

Mac OSX でSTM32の開発環境を構築してきましたが、どうしてもDFUを使った書き込みだけができません…

Macでコンパイルして生成したelfバイナリをWindowsに持って行き、STMicroのツールでDFUに転送するとちゃんと実行されるのでコンパイル環境は正常に構築できたようです。

また、前回最後に触れたdfu-utilも導入できたのですが、それをつかって書き込む方法がさっぱり分かりません。


sudo dfu-util -d 0110:1001 -a 0 -R -D $(TARGET).bin

というコマンドをLeaf LabsのMakefileに見つけたので以下のようにやってみたのですがダメでした…


sudo dfu-util -d 0483:df11 -a 0 -R -D main.bin

どなたかdfu-utilを使ってSTM32に書き込みをする方法を教えてください!

NHK大学ロボコン2010 出場要項

本日クラブにNHKから当日の確認事項が載った出場要項が届きました。

NHKロボコン2010「出場要項」

NHKロボコン2010「出場要項」


大会当日まであと少しという感じがしてきましたが、できるだけ良い結果が残せるようにがんばります。

と、Robohanのブログに書きました。

あとは個人的な話を。
STM32を入手したので明日の昼休みは図書館で今まで構築してきた開発環境の動作確認ができそうです。

アルバに開発を頼まれているいくつかのセンサー情報をSDカードへの記録するロガーの方もすこしずつ実験をしていかないとなぁと。

こっちは以前に試作したGPSロガーを元にすればそんなに大変ではないと予想しています。

では。

SnowLeopardにSTM32(Cortex-M3)の開発環境を構築

図書館で二時間時間を潰さないといけない状況になったので、なにかしようと思います。

そこで、最近無性にSTM32が使いたかったのでとりあえず開発環境でもを用意してみようかということで進めていきます。

今回は以下の二段構えになっています。

  • コンパイル環境の構築
  • 書き込み環境の構築

まず、前者についてはCortex M3開発環境 on Mac OS Xというページを参考にしました。

  • ARM用gccのインストール (Targetがarm-eabiのgcc)

ARM用のgccはSHやH8の時とはちがい、コンパイル済みのdevkitARMを利用します。このページからdevkitARMのOSXバージョンの最新版をダウンロードし、インストールします。

こいつはインストーラが無いので解凍してできたdevkitARMディレクトリを /usr/local/ ディレクトリにコピーしておきます。

そして、PATHを通すために~/.bash_profileファイルに(無ければ新規作成)

export PATH=$PATH:/usr/local/devkitARM/bin

という一行を加えておきます。
  • プロジェクトテンプレートの構築
次にSTM32のプログラムをコンパイルするためのプロジェクトのテンプレート(雛形)を作成します。
このディレクトリにSTMicroが用意してくれているSTM32のためのライブラリファイルや、リンカースクリプト、Makefile等を用意しておきます。新しくプログラムを作るときにはこのディレクトリのコピーを作成し、main.c等のユーザープログラムを書くだけでmakeコマンド一発でコンパイルできるようになります。
たぶんこれは二次配布可能だと思うので、圧縮したファイルを添付しておきます。問題があればコメントください。
このディレクトリはこのファイルでなくても、Strawberry LinuxのSTM32ボードであるSTBeeのサンプルプログラムでも構いません。
ただし、この場合には付属のMakefileの“arm-none-eabi”となっている所を全て”arm-eabi”に変更する必要があります。
以上でコンパイルまではできるようになりました。
次はDFUを使ってUSB経由で書き込みをするツールを用意します。dfu-utilというのを見つけたのでインストールしたいのですが、何故かコンパイルエラー。
ここで時間が来てしまったのでまた出来次第追記します。

SnowLeopardにH8とSHのクロスコンパイル環境の準備

Mac OSX 10.6 SnowLeopardでSHとH8のためのプログラムをコンパイルするためのGCCをコンパイルしました。

なかなか最初はうまくいきませんでしたが、いくつかオプションを指定することでうまくいきました。

基本的にクロスコンパイル環境はbinutilsをコンパイルし、その後にGCCをnewlibといっしょにコンパイルすることになります。

その前に、GCCのコンパイルにはGMPとMPFR及び、MPCをインストールしておく必要があります。

今回使ったバージョンは以下の通りです。

  • GMP 5.0.1
  • MPFR 2.4.2
  • MPC 0.8.1
  • binutils 2.20
  • newlib 1.18.0
  • gcc 4.5.0

これらが~/src/以下に展開されている状態である場合のコンパイル例が以下の通りです。SHとH8の違いはTargetがsh-elfかh8300-elfかの違いだけです。

また~/.bash_profileに以下の二行を追加しておきます。

export PATH=$PATH:/usr/local/sh/bin
export PATH=$PATH:/usr/local/h8/bin
以下はコンパイルしたときに実行したコマンドです。-disable-werrorを追加しないとコンパイルできませんでした。
これで/usr/local/h8以下と/usr/local/sh以下にそれぞれgcc等がインストールされるはずです。
2010年5月14日追記:newlibのコンパイルが抜けていたのを追加
$ cd ~/src
$ cd ./gmp-5.0.1
$ ./configure
$ make
$ sudo install
$ cd ../mpfr-2.4.2
$ ./configure
$ make
$ sudo install
$ cd ../mpc-0.8.1
$ ./configure
$ make
$ sudo install
$ cd ../gcc-4.5.0
$ ln -s ~/src/newlib-1.18.0/newlib ./
$ cd ../
$ mkdir h8-binutils
$ cd ./h8-binutils
$ ../binutils-2.20/configure –prefix=/usr/local/h8 –program-prefix=h8300-elf- –target=h8300-elf –disable-nls –disable-werror
$ CC=’cc -no-cpp-precomp’ CFLAGS=”-O2 -fomit-frame-pointer” make all
$ sudo make install
$ cd ../
$ mkdir h8-gcc
$ cd ./h8-gcc
$ ../gcc-4.5.0/configure –prefix=/usr/local/h8 –program-prefix=h8300-elf- –target=h8300-elf –with-newlib –enable-languages=c
$ CC=’cc -no-cpp-precomp’ CFLAGS=”-O2 -fomit-frame-pointer” make all
$ sudo make install
$ cd ../
$ mkdir h8-newlib
$ cd ./h8-newlib
$ ../newlib-1.18.0/configure –prefix=/usr/local/h8 –program-prefix=h8300-elf- –target=h8300-elf
$ make
$ sudo make install
$ cd ../
$ mkdir sh-binutils
$ cd ./sh-binutils
$ ../binutils-2.20/configure –prefix=/usr/local/sh –program-prefix=sh-elf- –target=sh-elf –disable-werror
$ CC=’cc -no-cpp-precomp’ CFLAGS=”-O2 -fomit-frame-pointer” make all
$ sudo make install
$ cd ../
$ mkdir sh-gcc
$ cd ./sh-gcc
$ ../gcc-4.5.0/configure –prefix=/usr/local/sh –program-prefix=sh-elf- –target=sh-elf –with-newlib –enable-languages=c
$ CC=’cc -no-cpp-precomp’ CFLAGS=”-O2 -fomit-frame-pointer” make all
$ sudo make install
$ cd ../
$ mkdir sh-newlib
$ cd ./sh-newlib
$ ../newlib-1.18.0/configure –prefix=/usr/local/sh –program-prefix=sh-elf- –target=sh-elf
$ make
$ sudo make install

教育用マイコンボード

中二の時に同級生数人とロボット同好会を学校で発足させたのですが、今では中学ロボット同好会はロボット研究部に昇格し、高校にもロボット同好会ができています。

で、ロボットを作るためにはマイコンでモーターを回す回路を設計したりプログラムを作れるようにならないといけません。

がこれまで、いちから独学で回路もプログラムもとなると相当の実力をつけているころには高校生ということになってしまっていました。

なぜそんなに時間がかかるか考えると、プログラムをするためにはマイコンボードができてないと学習できない、基板設計するにはプログラムでどういうことをするのか理解していないといけない…..という無限ループになるからだということになりました。

そこで、僕らの学年の部長だったT-Engineとクラブ向けの学習用マイコンボードがついたロボットキットをつくることになりました。

完成した基板があることによりプログラムの学習が早期からできるというのが目論見です。しかもマイコンは汎用マイコンを搭載しファームウエア等もあえて搭載しないので今後1から回路設計した場合でもそのときの経験はそのまま利用することができます。また回路図を読むことによりどういう回路ならこういうことが実現できるのかという教科書にもなるため回路の学習の基礎にもなればと思っています。

これを用いて中学初期あたりから学習すれば早期にロボット作成の基本が学習できる”はず”です。

構成としてはAVRマイコンと2チャンネルのモータードライバとUSBシリアル変換&書込回路をワンボードにしたマイコンボードとタミヤのユニバーサルプレートにギアボックスをセットにしたものになると思います。

拡張性を考えてI2C、デジタル入出力、アナログ入力ポートも備えています。

で、僕はマイコンボードの設計をするので以下のような感じになっています。

教育用マイコンボード

教育用マイコンボード

あと、AVRStudioを使って1からレジスタを操作してプログラムをするまえに、NQCのように簡単にプログラミングができるような開発環境も用意することにしたのでそちらも開発しています。

Windowsだけの対応ですがC#で開発しています。といってもコンパイル時にこっそり用意しておいたヘッダファイルをインクルードし、リンク時に用意しておいたライブラリをくっつけるという作業をしているだけなのですが…

それでも1から操作するよりは容易にプログラミングに慣れることができると思います。以下は開発中の開発環境です。一番大変なのは実際の動作とは全く関係のない部分なのですが、コードの色分けを実装するとこでしたね(笑)。できればVisualStudioのInteliSenceのような入力補完機能をつけるのが目標です。

教育用開発環境

教育用開発環境

インクルードが全くないのに用意された関数がつかえます。

これはコンパイル時にこっそり用意しておいたライブラリのヘッダファイルをインクルードし、ライブラリをリンクするという作業を裏で行うのことにより実現しています。というかただそれだけなのですが…

追伸

DCCデコーダの開発用のための実験基板ができました。AVRとモータードライバとBEMF用の回路が載っています。

Engineer Award

先日「Engineer Award」事務局の小島様からコメントをいただいた技術コンテスト「Engineer Award」についてです。(小島様、コメントの許可が遅れてしまい申し訳ございません。「不適切であれば削除してください」とまでご丁寧にも追加でご連絡いただきました。もちろん不適切ではありませんし、寧ろお知らせいただき感謝しております。)

僕自身は今年は受験で制作する余裕はないのですが、学校(中学・高校)のクラブの後輩に参加を進めてみようとおもいます。
何か自分たちでアイデアを出して短期間で何かを作るのは良い経験になるでしょうし、おもしろそうだし。

僕は来年同じ企画があればエントリーしたいと思います。去年のこの時期にあったら絶対エントリーしたんですが。ちょうど文化祭のネタにもいいですしね。USBがついてるマイコンではW-SIMをUSB経由でアナログモデムとして接続するアダプターが作りたいですね。