« 2012年11月25日 - 2012年12月1日 | トップページ | 2012年12月16日 - 2012年12月22日 »

2012年12月9日 - 2012年12月15日の1件の記事

2012年12月 9日 (日)

STM8Sの開発環境を整備する

STマイクロ純正の開発環境に移行するのに苦労する(12/1/2012)
 販促基板のUSBローダーの部分だけが脚光を浴び、本体は見捨てられて不遇な境遇にあるSTM8Sプロセッサーに少しでも日を当ててやろうと、このところSTM8S-Discovery基板の開発環境を整備している。

 前回の記事ではフラッシュ32KBまで無償のRaisonanceのCコンパイラーと一緒にIDE(統合開発環境)であるRide7をインストールしたことをご報告した。しかし、どうもRide7だけではSTM8Sにプログラムを書き込めないようだ。プラグインのような形で別のプログラマーを組み込む必要がある。面倒なことになってきた。

 あらためて、いくつかのSTM8S関連のサイトを見渡す。みなさん素直にSTマイクロの純正の開発環境をインストールされている。こちらの開発環境はSTVDとSTVPという2つの系に分かれており、使いにくそうなので敬遠していたのだが、Ride7のプラグインを探すより、正規の環境でやる方が安全だ。あまりこだわるのはやめて、みんなの方法に従うことにした。

 ところがいざプログラムをダウンロードしようとしたら、開発用ソフトのzipファイルsttoolset.exeが見つからない。サイトの情報が古くなっていて所定のURLにはもうファイルがない。みなさんが使っているCosmicのCコンパイラーも無償提供が終わっている。考えてみれば、話題になってからもう3年近く経っているのだ。

 STマイクロのサイトは、STM32の頃、欲しいものが見つからないと散々悪態をついていたが、今度も大苦戦だ。色んなところを探し回って、やっと見つけた。実は、一番最近のこのサイトにはちゃんとダウンロードの仕方が書いてあったのだが見落としていた。

 サイトのネストが深いのである。いくつかリンクしてSTVDの紹介ページに辿りつくのだが、ここでも更にDesign Supportのタグを押さないとリンクが出てこないようになっていた。やれやれ慌て者だから、こういうミスが多い。

 さらに混乱したのは、必要なファームウエアライブラリの名前が参考にしていたな主なサイト(さっきの平坂氏のサイトとここ)で変わっていて、最初は2つあるのかと勘違いしていた。旧の名前は、_fwlibで、新は_StdPeriph_Libになっており中身は同じである。

 こういう開発環境の整備は、余り好きではない(人の言う通りに素直に動くのが嫌い)。しかし、ここを通らなければ何も進まないので仕方がない。AVRにしておけば何も苦労することはないのだが、乗りかかった船だ。降りるわけには行かない。黙々とディレクトリチェーンを作る。

Ws000000 STVD(ST Visual Develop)は、AVRStudioと開発したところが同じと見えて外観が似ており、アイコンなどは全く同じなのが面白い。ファームウエアライブラリを少し見てみる。8ビットマシンだけれど、生意気に結構、大層なライブラリー構成だ。

 ほどなく、最初のサイトから頂いたLEDチカチカプログラムは一つのエラーをコメント化して(full_assertのチェックルーチンのエラー、stm8s_conf.sで#define USE_FULL_ASSERTをコメントにしてソースから削除。とりあえず不必要)無事に稼動した。

 STM8S-Discoveryのボードは、デモ用にタッチパッドでLEDを制御するプログラムが元々焼かれている。開発環境のテストを兼ねて、このプログラムへの復元をやってみた。これは、もっと楽だった。落としてきたUM0834アプリケーションノートをそっくりプロジェクトにしてコンパイルし直したら、そのまま簡単に動いた。

 さて、とりあえず、STM8Sは動いたようだ。次はUARTに行こう。

UARTを作り替えようとしてはまる(12/3/2012)
 UARTはこうした組み込み系の開発にはモニター機能として欠かせない機能で、当研究所ではどんなチップでも、まずこれを動かすことを開発の基本にしている。UARTを使わないアプリケーションでも、フラッシュがある限り必ずつけて、本番のときとりはずす(メモリがあればデバッグ用に残す)。

 STM8Sでも当然のように、UARTの組み込みを始めた。LEDチカチカのソースを頂いたサイトにはもちろんUARTのサンプルソースもある。ありがたく参考にさせてもらう。ソースコードをコピー&ペーストで簡単に取り込んだ。割り込みを使った本格的なUARTだ。

S_pc095488 ハードは定番の秋月のUSB-UARTモジュールを使ってPCとつなぐ。モジュールはブレッドボードに差し、ジャンパーで接続する。ハードの準備はあっという間である。早速テストする。苦もなく動いた。

 次にやることは、このUARTプログラムを、PCからUARTを経由してコマンドを受け入れ、色々なことをさせるモニターに仕立てることである。デバッグの強力なツールになる。ソースを本格的に読み始めた。

 ふーむ、このUARTのソースは、割り込みルーチンに、殆どのアプリケーション処理が入っている。どうも馴染めない。まあ、この程度の規模のソースでは目くじらたてることでもないし、参考にさせて貰ってこういうことを言うのも少し気が引けるが、普通はこういう書き方はしない。

 速度の速くない、メモリの少ない組み込み系プログラムでは、割り込みルーチンはなるべく身軽にしておき、メインルーチンに処理を集めるのが鉄則である。そういう習慣をつけておくとあとあとの開発が楽になる。

 なぜ、割り込みルーチンに処理を入れてはいけないかと言うと、普通、割り込み中は別の割り込みを禁止しているので、余り長い間ひとつの割り込みルーチンに居ると、別の割り込みを待たせることになり、同時性が失われたり、動作がおかしくなる可能性がある(多重割り込みは処理がはるかに複雑になるので余程の時以外は使わない)。

 さらに、割り込みとは現在の処理を強引に中断して別の処理を始めることなので、そのときのレジスターを全てどこかに保存してから、帰るときに元へ戻す余分なコードを必要とする。割り込みルーチンにはなるべく処理(たくさんのレジスターを使う処理)を入れないほうが良い。

 フラッシュの少ないマイコンではプログラムが(無駄に)大きくなるだけでなく、C言語を使うと、このレジスターのsave/restoreだけで(無駄な)数十ステップを使い、このオーバーヘッドは無視できない性能の低下をきたす。

 それならどうするかと言うと、一番簡便な方法は、割り込みルーチンにはフラグを立てるだけの処理などにしてなるべく身軽に作る。そしてメインルーチンのループで、このフラグをキーに割り込みでやりたかった処理を行う。こうすることで様々なメリットが生まれる。

 まず、フラグを立てるだけなので、セイブすべきレジスターを最小限にでき、オーバーヘッドを減らせる(Cコンパイラーの最適化も効く)。さらに、フラグをテストする順番を工夫(短いウェイトやsleepを入れるなど)すれば、メインルーチンで複数の割り込みの優先順位をつけることも出来る。別々の割り込みルーチンだとこういう芸当はできない。

 それにメインルーチンの中にアプリケーションがすべて入ってくるので、何をやっているのか一望できるメリットも大きい。ソースコードの一覧性というのは、みんなが思っているより重要な要素で、メンテナンスしやすいプログラムの大きな条件のひとつである。

 もちろん、良いことばかりではない。フラグでメインに処理を持ち込む方法は、時間にシビアな処理(いわゆるリアルタイム処理)には使えない。音声のデコードや、周波数の測定などに、これを使うことは無意味である。また、メインの中での処理は結局は順序処理になるので厳密な同時処理は難しい。OSを使った多重割り込み機能が必要になってくる。

 てな、うんちくを垂れながら、鼻歌まじりでソースコードを入れ替えた。ついでにUARTからのコマンドで、タイマーを使ったLEDの点滅の入り切りが出来るようにする。STM8Sのペリフェラルライブラリーの書式は、STM32にそっくりなので進行が早い。タイマーや、GPIOの制御も簡単に書けた。

 テストする。これが動かないのである。送信は問題ない(変えてないのだから当然だ)が、UARTの受信が出来ない。STVDは、単にプログラムを走らせることは出来なくて、必ずデバッガーを経由するのだが、このステップ実行では、受信割り込みルーチンを抜けてメインに来てもフラグが立っておらず、受信データがないことになっている。

 サンプルソースにある割り込みルーチンの書式が良くわからない。このあたりはコンパイラーの独自仕様なので、Raisonanceのコンパイラー仕様をネットで探すが見つからない。この割り込みは何を契機に起きているのか資料が見つからないのである。

 オリジナルのソースコードを見ると割り込みルーチンに来てから、さらにUARTのレジスターの受信フラグを調べている。それなら、この割り込みは何なのだ。他の割り込みというのはあるのか。ここは受信割り込みだけのルーチンのはずだが。

またお粗末な勘違いだった。UART動く(12/5/2012)
 少しづつステートメントをメイン側から割り込み側に戻して様子を見る。デバッガーにもう少し慣れれば、もっと楽に原因究明ができるのだろうが、こういうタイムディペンダント(UARTのキー入力)な処理のデバッグは容易ではない。

Ws000001  UARTの受信関数を割り込みルーチンに入れれば、動くことは確認できた。とりあえず受信だけさせておいて、フラグを立てて受信バッファーをメインで処理すれば、正常に動く。コマンドも受け付ける。しかし、何かやっていることが重複している感じで美しくない。

 フラグだけにすると、全く動かなくなる。フラグが換わらなくなる。おかしい。色々なところにテスト出力をUARTにさせて原因を探る。一文字出力関数で'*'を割り込み関数の頭に入れてみる。おおー、画面一杯に*が埋め尽くされる。ふーむ、受信割り込み以外にも、何か割り込みが起きているのか。

 一文字出力を、受信割り込みを特定してからのプロセスにも入れてみる。ありゃりゃー、変わらない、同じように画面が*で一杯になった。わかった、わかったぞー、このSTM8Sの割り込みルーチンは、割り込みフラグは明示的にクリアしないと、割り込みルーチンに飛んできただけでは解除されないのだ。

 このままでは、割り込みから抜ける度に、また割り込みが入って延々とループを続ける。割り込みルーチンの中で、データ受信をすれば、このとき割り込みフラグがクリアされるので問題ない。全くの基本的なミスだ。情けない。

 デバッガーではわからなかった。本来なら割り込みルーチンにへばりつくべきだが、実際には、メインルーチンの一定の場所(割り込みが起きたところ)に止まったままだった。まあ、これもデバッガーの指定で換えられるのかもしれないので、使えないと結論するのは早いかもしれない。

 AVRのUART受信割り込みは、割り込みルーチンに来た時に自動的に割り込みフラグはクリアされるので他のマイコンもそうだとばかり思っていた。STM8Sのデータシートには、「受信割り込みフラグは明示的にクリアするか、受信データレジスターをアクセスするとクリアされる」とちゃんと書いてあった。はい、はい、悪いのは私でした。

 原因がわかれば、対処は簡単だ。割り込みルーチンで、受信割り込みなら受信割り込みフラグをクリアするステートメントUART2_ClearFlag(UART2_FLAG_RXNE); を追加するだけである。

 これで割り込みをフラグだけにしたUARTプログラムは、無事、正常に動作した。これは今後のプロジェクトでモニタープログラムとして活躍してくれるコアプログラムである。

 こちらにソースコードの中身の参考のため、このUARTモニタープログラムのmain.cを置きます。ただし、これだけではライブラリをincludeしていないのでコンパイルエラーになります。リンクしたサイトを参考にライブラリを所定のディレクトリに配置してビルドしてください。

「main.c」をダウンロード

 余裕が出来たので、STマイクロの開発環境のもう一つの系STVP(ST Visual Programmer)を試してみる。これは、単なるSTLinkを介した独立のプログラムローダーだ。STVDにもプログラミング環境があるのだが、立ち上がりが遅い上、やたらとハングする。STVPの方が少し早そうだ。

焦電型人感センサーの修理に成功。基本的な間違いだった(12/7/2012)
 階段の照明制御に使っている人感センサーの誤動作がまた目立ってきた。人も居ないのに頻繁に作動し、役に立たない。修理しようと電源を切って工作机に置いていたら、家族から「あら、もう壊れたの」と言われてしまった。

S_pc065478 へー、頼りにしていたんだ(階段の照明は別にあるのだが、便利なようだ)。今までに何も言われなかったが、こういう反応は予想外である。ちょっと嬉しい。でも復旧へのプレッシャーは強くなったように思う。早く直さなきゃ。

 STM8Sが予想外に早く進展したので、ちょっとお休みし、こちらの方の修理に入る。症状は、オペアンプの無入力の時の電圧がマイコンの入力ピンの閾値に近いので、オペアンプのドリフトで感知してしまうというものである。

 以前も同様な状態になり、入力ピンにプルアップ抵抗をつけて電圧を閾値以上に引き上げた経緯がある。ケースをはずして抵抗値を確かめると22KΩだった。これを半分の10KΩにしてみる。心配したとおり、今度はセンサーが反応した(->0V)ときでも2V以下に下がらず、失敗である。

 そのうち見るともなしに配線図を見ていて、2段目のオペアンプの入力の一方が、同じ抵抗2本でVccの半分の電圧であることに気づいた。あーっ、わかったぞ。センサーがドリフトしているのではない。このオペアンプは交流増幅なのだ。2.5Vの中位電圧にしてセンサーの出力を上下に振っているだけなのだ。

 完全に勘違いをしていた。この部分は、秋月の回路のアナログコンパレーターの部分をマイコンにしたところで、HighのVccが無入力、Lowの0Vがセンサー感知というTTL出力だとばかり頭から信じ込んでいた。2.5Vになるのはドリフトではなくもともとの仕様だったのである。

S_pc065475 理屈がわかれば解決法は早い。この中位電圧をマイコンの閾値に近い2.5Vより、もう少し高い3V近辺にしておけばオペアンプのドリフトくらいで反応することはない。人が近づいた時の反応は、0VからVccまで派手に振れるので中位電圧は高い方が安定する。

 制御部からプルアップ抵抗を外し、焦電センサーのオペアンプの分圧抵抗を、4.7k×4.7kの組み合わせから、2.7k×3.9kに換えた。オシロで確かめる。オペアンプの定常出力は、3.1Vになった。これにより焦電センサーは完全に安定した。このあいだの電源のふらつきによるディップも、こうしておけば何の問題もなかったのだ。

 ついでに、センサー基板の固定部分の一部を改善する。何回か前のブログ記事で、基板をアクリルケースに固定する簡便な方法をみなさんにお聞きしたところ、何人かの方がコメントでアイデアを提供してくださった。

 このうち、そら。さんから頂いたアイデアを実行する。やることは非常に簡単で、切片つまりストッパーをアクリル板に固定してしまう方法である。とりはずしは、ケースの剛性で行う。

S_pc065477 ケースは2つに分かれており、組みあがっているときはたわみが少ないので、この方法はとれないが、アクリルは剛性に富んでいるので、パーツに分解した時は楽にミゾに基板は入り込む。実にコロンブスの卵的解決である。

 切片に接着剤をつけ、完全に乾くのを待つ(慌てて付けてとれなくなると悲劇)。基板をはめてみる。問題なく入った。いやあ、あれこれ迷って、ガイドを切って切片を削ったり、色々苦労したことがうそのような解決だ。そら。さん、ありがとう。

 いくつもの課題が一気に解決して、すこぶる気分が良い。記事の量は少ないが気分の良いうちにブログに報告しておこう。

| | コメント (3) | トラックバック (0)

« 2012年11月25日 - 2012年12月1日 | トップページ | 2012年12月16日 - 2012年12月22日 »