日記帳だ! with Tux on Libserver

二度目の大改造!! 日記帳…か?を継承し、より柔軟でパワフルなBlogに変身しました。

RSSに対応しています。リンク・コメント・トラックバックは自由にしていただいてほぼ問題ありません。
RSS購読方法、僕のリンク・コメント・トラックバックについての考えを読むことをおすすめします。

JavaScriptを有効にし、Cookieを受け入れ、以下のブラウザを使うことで完全なコンテンツが楽しめます。
Mozilla Firefox 3.0(Get Firefox)・Opera 9.6・Safari 3.2・Lunascape 4/5(Gecko)・Lunascape 5(WebKit)
Internet Explorer 7/8とそれを使うIEコンポーネントブラウザ(Lunascape・Sleipnirなど)

<< 過去

エミュレータからデバッグ情報を吐き出す

マイコンのデバッグ用に使っているツールがある。

プログラムの中に自動的にデバッグ用のコードを埋め込んで、そのコードによりデバッグ情報をシリアル通信で出力する。

このシリアル通信を受信して、プログラムの内部動作を解析するというもの。

デバッグ用のコードを埋め込む必要があるのは難点だが、他のツールではできない解析ができるのが長所だ。

なかなか使い所が難しいという話もあるが、僕はデバッグの効果を高められるツールだと思っている。


このツールをエミュレーターでのユニットテストと組み合わせて使うことができないかということを考えていた。

うちでもユニットテストできるの?

エミュレータを使ってのユニットテストでハードウェアに依存しない機能のテストをしようと考えている。

このときの内部動作を実機でのデバッグで使っているのと同じツールで解析しようと考えたわけだ。


というのも、このツールはデバッグ用のコードを埋め込む都合、全機能の内部動作を一気に解析するのは難しい。

過去には何度かに分けて解析を行ったこともあるが、同じような操作を何度か繰り返す必要があるなど不都合も多かった。

そこで、ハードウェアに依存しない部分の詳細はエミュレータで詳しく内部動作を調べて、

実機ではハードウェア依存の部分の内部動作と、結合しての動作の解析と役割分担するとよいと考えた。

同じツールを使うことで、エミュレータでの解析結果と実機での解析結果との結合ができるというメリットもある。


とはいえ、1つ問題があって、それはエミュレータではシリアル通信でデバッグ情報を出力することができないということ。

そこで代替策がないか調べたところ、このツールはデバッグ情報をファイル出力する方法も持っていると書いてある。

ファイルシステムを持っているシステムでデバッグ情報を自分のファイルシステムに保存するようなのを想定しているらしいが、

エミュレータならメモリダンプをファイルに保存することはできそうだし、なんとでもなるでしょう。

というわけで方法を調べてみた。


具体的な方法だが、データブレイクポイントを使うとできるようだ。

書き込み用バッファをプログラム内で用意しておいて、そのバッファの最終バイトへの書き込みにブレークポイントを仕掛ける。

一般的にブレイクポイントはコード上に仕掛けるものだが、データの読み書きに対して仕掛けることもできる。

特にマイコンのエミュレータでは、ペリフェラルを模擬するのにデータブレイクポイントが使われることがあると。

ブレークポイントでコードを停止するのではなく、ここでエミュレータのマクロを呼び出すように設定する。

このマクロに書き込みバッファのダンプをファイルに出力するというように書いておく。

するとプログラム中ではバッファに書き込むだけで、そのバッファの内容がファイルに出力される仕組みが作れる。

出力されたデータをツールに食わせれば、見事に内部動作の解析ができるというわけ。


このファイルにはタイムスタンプを埋め込むことができる。タイムスタンプを埋め込むことで実行時間の解析などができる。

シリアル通信でデバッグ情報を出力する方式では、受信側でタイムスタンプを付けることができるが、

ファイルに出力する方式ではタイムスタンプは出力する側で付ける必要がある。

必須ではないものの、できることならエミュレータでもそれらしいタイムスタンプを付けたいものである。


それでエミュレータのマニュアルを見ていたら、エミュレータ内のサイクル数をカウントするレジスタがあることがわかった。

ファイル出力時にこの値を持ってきて、実機のクロック周波数でわり算した値をタイムスタンプとして埋め込む。

すると、解析結果にそれらしい実行時間が表示されるようになった。

エミュレータはマイコンのサイクル数も模擬しているはずなので、それなりの見積もりにはなっているはず。

厳密に実機での実行時間と一致するということはないだろうが、感覚的にはそんなもんだよねという数字になっていた。


このツールを使って解析することで、ユニットテストの妥当性の確認が容易になる。

こういう内部動作を期待して、こういう入力を用意したけど、本当にその通りになっているか。

ブレークポイントを差し込んで内部変数の値を調べて妥当性を確認することもできるが、

ツールをうまく使えば、収集したデバッグ情報を一括解析して、妥当性が確認できる。

すでに実機で使っているのと同じツールなので納得感も高い。

そこまでしてエミュレータで使うかという話もあるが、完成したものを見てみるとなかなかよいと思う。


Author : hidemaro
Date : 2018/06/20(Wed) 21:48
電気・数学・物理 | Comment | trackback (0)

ヒステリシスがないがために

とある製品に搭載されているファンの回転数を監視するシステムの調査をしていた。

というのも、これと同じ機能を持ったものを新しく作る必要があったので、既存のはどうなってるのか調べたかったと。

ファンユニットに組み込まれたロータリーエンコーダーのパルスをカウントして回転数を監視しているのだが、

このロータリーエンコーダー出力をファンクションジェネレータで模擬するのにいろいろ治具が必要で、

それで後回しになってたんだけど、治具を作ったり、集めたりして、実験環境を整えられた。


それで実験していたら、ファン回転数異常状態と正常状態を行ったり来たりする周波数があることがわかった。

って、その前に設計資料を確認していた時点でこうなることは知ってたんだけどね。

というのも、このシステムでは一定時間内のパルスの回数を数えることで回転数を測定して、異常か正常か判定している。

1秒間に60回以上のパルスが入れば正常と判定するようになっていたとする。

ここで、65.5Hzのパルスを入れれば1秒間に65回か66回かパルスが入るので、必ず正常と判定される。

55.5Hzのパルスを入れると1秒間に55回か56回かパルスが入るので、これは60回未満だから必ず異常と判定される。

一方、59.5Hzのパルスを入れたときを考えてみると、1秒間に59回か60回となり、59回のときは異常、60回のときは正常になってしまう。

こういうことが原理的に起きてしまうことは設計から明らかだった。


この問題の解決策はいくつかあるけど、一番簡単なのがヒステリシスを用意すればいいんですね。

1秒間60回未満で異常と判定、62回以上で正常に復帰とすれば、

1秒間で59回か60回の場合は、59回を測定した時点で異常と判定、その後62回以上にならないから復帰しない。

判定値にヒステリシスを持たせているものはけっこう多いが、境界値付近で厄介な挙動を起こさないようにと考えられたものだ。

簡単な仕組みだが、うまい解決になっているように見える。

というか、このシステム、本来ならばヒステリシスを持っていてもよさそうなところに全くヒステリシスがない。


もっとも新しく作るシステムでは、ファン回転数の測定方式が変わる予定で、

同じ周波数を入れ続けている限りにおいては回転数が揺らぐことはごく少なくなる。

原理的には境界値付近のごく狭い周波数では発生しうるが、なかなかそこを狙うのは難しいだろう。

なので、ヒステリシスを持たせなくても、簡単に異常状態・正常状態を行き来する状態になることはなさそう。

他も状況を鑑みると、境界値付近に留まり続けるのはなかなか難しい。

というかファン回転数もファンクションジェネレーターで模擬すれば簡単に起こせるけど、実機で起こすのは難しいし。


だからヒステリシスはいらないのかというと、そういうもんではないとも思うのだが。

ただ、もともとヒステリシスがあることを想定した仕様になっていないので、注意が必要とも。

ヒステリシスの幅をごく狭くすれば許されそうな気もするけど。


Author : hidemaro
Date : 2018/06/13(Wed) 22:06
電気・数学・物理 | Comment | trackback (0)

なぜか2段構えのWDT

使っているマイコンのウォッチドックタイマ(WDT)がちょっとクセのある動作をする。

というのも設定した時間の倍の時間経たないとリセットが発生しないからだ。


そもそも、WDTというのは、こういうもの。

WDTはプログラムの暴走を検出するために使われる、いわば最後の砦である。

WDTはタイムアップするとマイコンをリセットするなどするタイマだ。

WDTを使うシステムでは、定期的にWDTをクリアするプログラムを作っておく。正常に動いているときはWDTがタイムアップすることはない。

ところが何らかの理由でプログラムが暴走するとWDTがクリアされなくなり、指定時間経過するとWDTタイムアップで検出できる……ということを期待している。

(マイコンはタイマだらけ)

WDTがタイムアップするとプログラムが暴走したと判断するわけだが、

実はWDTタイムアップ=リセットというわけでもない。


というのも、WDTタイムアップで割り込みを発生させて、エラーログの取得とかを行うシステムもあるから。

このマイコンのWDTは、1回目のタイムアップで割り込み発生、2回目のタイムアップでリセットとなっている。

1回目の割り込みでエラーログの取得などの処理を行い、これが終わらなくても2回目のタイムアップで強制的にリセットしてしまうという用途を想定しているのだろう。

こういう用途で使う分にはよくできた仕組みなのだが、このシステムってWDTでリセットさえできればいいんだよね。

すなわち1回目のタイムアップで発生する割り込みは何もせず、2回目のタイムアップのリセットだけを使うのだ。

なんかおかしくね? と思うんだけど、最終的にリセットされるという結論に差はないから、あまり気にしていないようだ。


WDTもいろいろあって、マイコンの種類によって全く異なる。

同種のARMコアを使っているマイコンでも、メーカーによって全く違うぐらい。

そもそもWDTタイムアップ=リセットというマイコンもあるし、

あるマイコンでは、タイムアップ手前の所定の値で割り込み発生、タイムアップでリセットとなっている。

調べた限りで多かったのが、割り込みかリセットか選択制になっているもの。

1つのマイコンで複数のWDTを持っていることも多いので、1つのWDTで割り込み、1つのWDTでリセットという使い分けをすることも想定しているのかも。

1つのWDTに割り込み・リセットの両方の役割を持たせるより、こっちの方がわかりやすい気がするな。


というわけで、やっぱりこのマイコンのWDTはちょっと変だなと思ったんだけど、

ペリフェラルマニュアルをよく見てみると、WDT割り込みでとある操作を行うと、即WDTリセットにできるようになっていた。

割り込み処理にこの操作を書いておけば1回目のタイムアップでWDTリセットになるってことだね。

もししくじっても、2回目のタイムアップでリセットになるので安心感があるとも言える。

いろいろ総合して考えてみると、これが正しい使い方のような気がしてきたが、その割にはサンプルプログラムとかには書かれていないのが解せないところ。


今回はマイコン内部のWDTの話をしているが、WDTというのもいろいろあって、

アナログ回路で構成されるWDTもあるし、他のロジックにWDTを持たせることもある。

とあるシステムでは、マイコンのWDTを使わず、このマイコンと通信を行うプログラムが一定時間以上の通信停止を発見したら、

マイコンをリセットさせるという仕組みになっていた。これもWDTの一種だよね。

目的が実現できればマイコン内のWDTを使う必要は必ずしもないということだね。

一番手軽なのがマイコン内のWDTを使うという方法なだけで。


Author : hidemaro
Date : 2018/05/25(Fri) 22:50
電気・数学・物理 | Comment | trackback (0)

CRC演算は時間がかかるからDMA

ところで、このプログラム、ちょっと奇妙だよね。

for(unsigned long *p=PTR_START; p<PTR_END; p++){
  CRCIN = *p;
}
crc_result = CRCOUT;

CRCINにひたすら値を代入して、CRCOUTを読んでいると。

当然のことながら、このCRCINというのは普通の変数ではなくて、マイコンの機能レジスタで、

CRCINレジスタに1回書き込むとCRC演算が1回行われ、その結果はCRCOUTから取得できるということ。


CRC演算って普通にプログラムで書くとめんどくさいが、回路で作れば比較的簡単だ。

使用しているマイコンでは、CRC16とCRC32の代表的なものが計算できるようになっている。

マイコンのペリフェラルってこういうのもあるんですよ。

普通にプログラムで書くよりも高速に計算できるのは言うまでもないが、

それでも大量のデータに対してCRC演算すると時間がかかってしまう。

しかも、最初に書いたようなプログラムでやると計算中は他の処理ができないという問題もある。


そこでDMAである。

DMAはDirect Memory Access、CPUを使わずにデータ転送を行う仕組みだ。

上の処理は、データを右から左に流しているだけだから、DMAにやらせればその間はCPUは手放しにできる。

送信元のポインタだけ進めて、送信先のポインタは固定ということもできるので、機能レジスタに書き込み続けること、

逆に送信元を固定にして、機能レジスタを読み込み続けるということもできる。

そしたら、DMAを使うと手放しにできるだけでなく、転送速度も速かった。倍速近かった。

今回の用途では、計算完了までにかかる時間はそこまで重要ではないし、CPUが手放しにならないとしても工夫すればなんとかなるのだが、

DMAを使って悪いことは何もないので、DMAを使ってCRC計算をすることにしようと思う。


さて、大量のデータを転送するならばDMAは大きなメリットがある。

他にペリフェラルからの割り込みをDMAで受けて、それに応じてデータ転送をすることもできると。

例えば、シリアル通信の送信バッファに4バイト×100回転送するとDMAに設定して、送信バッファが空のときに発生する割り込みをDMAにつなげておく。

その上で、最初の1回はプログラムからトリガをかけてやれば、

バッファに4バイト転送→4バイト送信→バッファが空になったので4バイト転送→4バイト送信……とプログラムを介さずにできる。

4バイト×100回の転送を終えたら、DMA転送完了となるので、そこで割り込みを発生させるなり、転送完了をポーリングしておけばよい。

AD変換との組み合わせで、AD変換結果からRAMに1ワード×16回転送とDMAに設定して、AD変換完了割り込みをDMAにつなげる。

それで、ADコンバータは定周期で動くようにしておけば、プログラムを介さずに定周期で16回取得したアナログ値がRAMに格納される。


ただ、DMAは単純に左から右にデータを流すことしかできない。CPUを使わないというのはそういうこと

シリアル通信の受信バッファからRAMに受信バッファが満タンになるごとにDMAに転送させるということもできるが、

DMAに設定した回数よりも、受信したデータが少ないと、DMA転送は永遠に終わらないし、

受信中にデータ転送以外の処理をしなければならないとなれば、DMAだけに任せておけない。

1回の転送量が少なくても、回数が多いのを手放しでできればメリットはあるが、どうせ1回1回は少量だしという考えもある。

やり方次第ですかね。


DMAというもの自体は知ってたけど、大量のデータ転送をすることもそんなに多くないしなぁと思ってたら、

CRC計算という意外な用途でDMAが大きな効果を発揮したので、よい発見だった。

そもそもCRC計算のプログラムを書かずに済むだけでもラッキーと思ったけど、

ハードウェアでCRC計算できるとこんなこともできちゃうんだよね。


Author : hidemaro
Date : 2018/05/21(Mon) 22:24
電気・数学・物理 | Comment | trackback (0)

シフトレジスタにシリアル通信も可

回路設計をしている人からマイコンのピン割り付け案を受け取って確認していた。

この機能はここでいいねとかいうのを確認していた。

その表でシフトレジスタの入出力にシリアル通信機能と書かれていた。

GPIOのつもりだったんだけどなぁ、と思いつつも、確かにシリアル通信でもシフトレジスタとの入出力できるんだよね。

もっとも、シリアル通信とすればピン割り付けがおかしいので、ここはここに割り付けてと指示したが。


入出力の拡張としてシフトレジスタが使われることがある。

TC74VHC165F: 8-Bit Parallel-In/Serial-Out Shift Register  (TOSHIBA)

TC74VHC595F: 8-Bit Shift Register/Latch (3-State) (TOSHIBA)

標準ロジックICの74シリーズのこのあたりがよく使われるらしい。

74165は入力用に使われる。8bitのパラレル入力をシリアル化する。

74595は出力用に使われる。8bitのシフトレジスタとラッチを持っている。

シフトレジスタにデータを格納して、全部格納できたら一括してラッチするということができる。


マイコンのピンにも限りがあるが、74165を使えばマイコンの入出力3ピンで8bitの入力を受けられる。

すなわち、これで5ピンの節約になる。

さらに複数の74165を連結して使うこともできるから、そうすると節約効果はなおさら大きい。

74595も8bitの出力をマイコンの出力を最小3ピン使えば操作出来る。(Hi-Z状態を制御したい場合は+1ピン)

これも複数の74595を連結して使うことができる。


ただし、入出力にあたってはシフトレジスタの操作が必要になる。

そこで、当初想定していたのはプログラムで信号を1つずつ操作する方法だった。

ロード信号を下げて上げて、シフトレジスタ出力を格納して、クロック信号を上げて下げて……というのを全部プログラムで書くと。

この方式のメリットは特別な機能を使わずに済むこと。GPIOさえ使えればよい。

GPIOはGeneral Purpose Input/Output、単純なデジタル入出力のことですね。マイコンのほぼ全てのピンがGPIOで使える。

ただ、欠点は信号の操作を全てプログラムで書くので、データ転送のスピードが遅くなってしまうこと。


一方でシフトレジスタとのデータ転送にクロック同期シリアル通信が使えるという話がある。

74165も74595もクロックの立ち上がり時にデータを1bit転送されるわけですからね。

クロック同期シリアル通信はSPIバスなどで使われるので、マイコンにはほぼ搭載されている機能。

この機能を使えば、プログラムで信号を1つ1つ操作するより高速に、なおかつ転送中は他のプログラムの実行ができる。

そういうわけでパフォーマンス面ではマイコンのシリアル通信機能を使う方が有利なわけである。


そのことを意識してシフトレジスタの入出力ピンをシリアル通信機能のピンに割り付けようとしていたのだろう。

その割にはピン割り付けがおかしかったから、本当はよくわかってなかったのかもしれないけど。

とりあえず、シリアル通信機能にも使えるようにピンは割り付けてもらうことにした。

GPIOはほぼ全てのピンで使える機能なので、ほとんどどこに割り付けても自由だ。

なので、シリアル通信機能が使えるように割り付けておけば、GPIOでの操作もできる。


というわけで、シフトレジスタとのデータ転送方法について シリアル通信 と GPIO の2種類の選択肢を得たわけだが……

どうしてもシリアル通信を使わないといけないほどパフォーマンスが厳しいわけではない。むしろ暇をもてあますことになりそう。

GPIOだと信号の操作を1つずつプログラムに書かないといけないが、プログラムで書いた通りの波形が出てくるという安心感はある。

どっちがいいんだろ? というわけでチームリーダーに相談してみた。

そしたら「どっちでもいいけど、通信機能の操作をあれこれ考えるぐらいなら、GPIOの方が楽なのでは」とのことだった。


そこで教えてもらったのだが、1世代前のシステムではEEPROMへのアクセスをGPIOを使って行っていたらしい。

クロック同期のシリアルバスの通信をプログラムで信号を1つずつ操作してやってたらしい。

それでもなんとかなっていたのだが、問題は通信速度が遅いこと。

8msあたり2Byteずつという遅いスピードで行っていたようで、すなわち1kByte転送するのに4秒かかるということだ。

というわけで当時はEEPROMに格納するデータサイズをできるだけ小さくする工夫をしていたようだ。

それでも128Byteのデータを転送するのに0.5秒ですからね。リード→ライトとやると2回転送するから1.0秒かかってしまう。

最新世代のシステムでは、マイコンのシリアル通信機能を使うことで、8msあたり32Byteずつ転送するようになった。

EEPROMの書き込み時間を考慮すると、書き込みでは限界に近いスピードになっているとのこと。

すると1kByteのデータを250msで転送できるようになった。1世代前のシステムで128Byte転送するよりも短時間で済む。

これにより設定情報の大容量化が実現できたということらしい。


500kbpsで128bitのデータを転送するのにかかる時間は0.256ms。

オーバーヘッドなど考慮しても通信機能を使えば1ms間隔で74165または74595 16個分のデータ転送をすることもできそう。

マイコンはたった3ピンだけで、ロジックICを16個外付けすれば、128ピンの入出力が1ms間隔でできるというのはなかなかすさまじい。

とはいえ、今回はシフトレジスタはせいぜい1個(16bit)、データ転送間隔は数百ms間隔である。

通信機能を使って本気で転送しなければならないスピードということは決してない。

じゃあGPIOでいいねって。


Author : hidemaro
Date : 2018/05/10(Thu) 22:55
電気・数学・物理 | Comment | trackback (0)

マイコンはタイマだらけ

古い製品の再設計のためにマイコンのペリフェラルを調べていた。

この機能を実現するにはこのペリフェラルをこの設定にすればいけるぞとか調べてたと。

「このマイコンだとこの設定できないのか!」ということで、代替策を考えないといけないなんてことも起きたけど。

元々あまり期待してなかった機能ではあったけど。


それはそうとして、マイコンのデータシートを見て思ったのは、タイマが大量に積まれているということ。

同種のタイマが複数個というのもあるが、何種類ものタイマがあるんだよね。

タイマと一言で言うが、それぞれ想定されている用途には違いがある。

でも、このタイマでも、このタイマでもできるという用途はそれなりにある。

例えば、定周期での割り込みはほとんどの種類のタイマでできる。


マイコンを使ってあれこれやったことがある人にとってはマイコンのタイマってどんなか分かるだろうが、

知らない人からすれば、タイマなんて時間を計るだけでしょ? とも思うかも知れない。

ところが時間が関わるものはほとんど全てタイマの世話になるわけだから、その用途はかなり多い。

何種類ものタイマがあるというのも、タイマの用途の多さを表している。


おそらく一番特殊なタイマがウォッチドックタイマ(WDT)だろう。

WDTはプログラムの暴走を検出するために使われる、いわば最後の砦である。

WDTはタイムアップするとマイコンをリセットするなどするタイマだ。

WDTを使うシステムでは、定期的にWDTをクリアするプログラムを作っておく。正常に動いているときはWDTがタイムアップすることはない。

ところが何らかの理由でプログラムが暴走するとWDTがクリアされなくなり、指定時間経過するとWDTタイムアップで検出できる……ということを期待している。

本当にプログラムが暴走するとWDTのクリアが行われなくなり、WDTタイムアップでリセットが飛ぶのか?

疑うとキリがないが、WDTはプログラムの暴走を検出する手段として広く受け入れられている。


マイコンのタイマで使う機会が多いのが、PWM出力 と タイマ割り込み だろう。

PWMはパルス幅変調、ONとOFFの時間の比で情報を伝達するということで、モーターの制御とか、その他いろいろな用途で使われる。

タイマレジスタに周期32μs、ON 4μsのように指定するだけで、以後はプログラムで操作せずともその波形が出力され続ける。

レジスタにセットさえすればプログラムで操作しなくていいから、かなり高速な出力もできる。

タイマ割り込みはタイマをスタートさせてから所定時間経過したら割り込みを発生させるということ。

割り込みは実行中のプログラムを中断して、他の処理を割り込ませるということ。割り込み処理が終わったら元のプログラムに戻る。

普段の生活でもキッチンタイマーをセットして、キッチンタイマーが鳴ったら他の作業をしにいくということがある。まさにそういうこと。

マイコンの用途からして、定周期での処理が多い。例えば2msおきに入力を読み出して処理するとか。

そういう処理は、タイマで定周期で割り込みを発生させて行うのが通常だ。マイコンの動作の基本を形作るのもタイマだ。


あと、それ自体はタイマじゃないけど、ADコンバータとかも内部にタイマを備えてるよね。

サンプリング時間とか指定してそれに応じて動くわけだから。

そんなことを考えるとマイコンのペリフェラルってタイマの塊だよなと。

そもそもタイマと言われているものも数が多いし、それ以外にもタイマ要素を備えたものは多いと。


過去のいくつかの設計を参考にしながら、これはこのタイマをこの設定にして……とか考えていたんだけど、選択肢多いよね。

今まで仕事で、どのタイマをどの機能に割り付けてということはやってこなかったけど、わりといろいろある。


Author : hidemaro
Date : 2018/04/27(Fri) 22:27
電気・数学・物理 | Comment | trackback (0)

全部DIP部品って本当?

4世代前の製品の再設計という怪しげな仕事をしているわけだが。

世代が変わっても現役であり続けた結果

その製品のマイコン周りってどうなってるのかな?

とプリント板を見てみたら……想像よりかなり大きなプリント板が出てきた。


今からすれば信じられないことに全部DIP部品だった。

全ての部品に足があって、それを穴に差し込んではんだ付けして作られているということだ。

ピン数の割に大きなマイコン、何個も並べられたロジックIC、数々のリード抵抗……といった具合。

今やほぼ全ての部品が表面実装部品で、自動的に実装してはんだ付けされるというのに。

これって自動化されてるのかな? でも手実装もありそうな感じなんだよな。

未だにこんなのを現役で作り続けてるというのがびっくりだが。


今でもDIP部品ってのは使われていて、特に大型の部品では出番があるようだ。

最近の製品でも表面実装部品とDIP部品の併用というのは見る。

でも、全部DIP部品というのはこの職場では初めて見たかも。

それだけ古いって話なんでしょうけどね。

だってマイコンの大きさ、同じピン数の今どきのマイコンの10倍ぐらいはあったし。


再設計後はできるだけ表面実装部品を使うだろうから、かなりコンパクトになりそう。

多分、プリント板はスカスカになるんだろう。

おそらく当時の水準ではできるだけ詰め込もうとしたのだろう。

片面実装ではあるが、部品が搭載されている面はほぼ全てが部品で覆い尽くされるほどだった。

今だとこの1/10以下のサイズのプリント板でできそうなもんだけど。

いや、メカリレーのように時代が移り変わってもあまり小さくならない部品もあるからそこまではいかないか。


というわけで今どきの常識とは全く違うんだなと歴史を感じた。

確かに古いなぁと思ったけど、全部DIPなんて時代のものとはまさか。


Author : hidemaro
Date : 2018/04/24(Tue) 23:56
電気・数学・物理 | Comment | trackback (0)

ロケットが肩代わりするのはなぜ?

もうだいぶ前の話だけど、H-IIAロケットの高度化ということで、新しい静止衛星の打ち上げ方法を行った。

ファン!ファン!JAXA!/基幹ロケット高度化とH-IIAロケット29号機への適用


静止衛星は地上との位置関係が見かけ上変わらない衛星で、放送・通信・気象観測などに広く活用されている。

位置関係が見かけ上変わらないというのが地面が動くのと同じ速度で地球を回っているから。

具体的には地上35786kmの高度で赤道上を飛ぶと実現できる。

非常に利用価値が高いわけだが、よくつかわれる人工衛星の軌道の中ではかなり高いところを飛ぶ。

そこで、こんな投入方法を取る。

  1. 東向きにロケットを飛ばし、低軌道に投入する
  2. 赤道上でロケットエンジンを再点火して、遠地点が35786kmになる静止トランスファー軌道(GTO)に変換する
  3. 遠地点で加速して、静止軌道に変換する (通常、衛星のエンジンで加速する)

エネルギー的にも効率がいいですからね。


この方式で静止衛星を打ち上げるのは万国共通ではあるが、日本のH-IIAロケットは不利らしい。

なぜならば打ち上げ地点が種子島だから。種子島から打ち上げたロケットで1,2 の手順を踏むと、GTOは赤道に対して28.5°傾いた軌道になる。

ここから静止軌道に変換するときには、この傾きを打ち消す必要がある。

ところが、ほぼ赤道直下にあるフランスのギアナ宇宙センターから打ち上げると、GTOはほぼ傾かないので、静止軌道への変換に必要なエネルギーが小さいと。


静止軌道を飛ぶ衛星は約3100m/s、近地点250m・遠地点35786kmのGTOの速度は1600m/s、

GTOが赤道に対して全く傾いていない場合は、単純に進行方向に加速するだけだから、およそ1500m/sの加速で済む。

ところが種子島から打ち上げるとGTOが同じ1600m/sでも、28.5°の傾きを打ち消す必要がある。

三角関数を使って計算すると、種子島発のGTOだと1860m/sの加速が必要となり、ずいぶん不利なのだ。


といっても種子島から打ち上げるなら、これは仕方のない問題とも言える。

GTO→静止軌道の変換に燃料が多く必要になるなら、その分だけ衛星に燃料を多く積んでもらえばよいだけのこと。

赤道直下から飛ばすのと、種子島から飛ばすのでは、必要なエネルギーに差がでるのは仕方ないのだから。

でも、人工衛星を作る側からしてみれば、これは不都合な話らしい。

というのも種子島から飛ばす場合と赤道直下から飛ばす場合で積む燃料の量を変える必要があるから。

当初から種子島からの打ち上げを想定している気象庁の気象衛星とかだと問題はないのだけど、

人工衛星を打ち上げる側にしてみれば、どこから打ち上げるかで人工衛星の設計を変えなければいけないのは不都合だと。


そこで、この差をロケット側で吸収して欲しいという話があるようだ。

このロケット側で吸収する方法もいくつかあるようだ。

1つ目は最初から高い軌道に投入するとか、傾きを補正しておくという方法。

最初にロケットでエネルギーを投入して、後が楽になるようにしておくと。

2つ目はGTOへの変換時に余分に加速するという方法。すると遠地点が35786kmよりも高くなる軌道に入る。

ここからうまくやると通常のGTOより少ないエネルギーで静止軌道に投入できると。この軌道をスーパーシンクロナストランスファ軌道というらしい。

複雑だが、GTOへの変換時に余分にエネルギーを投入しておけば、後が楽になるということ。

3つ目がH-IIAロケットが選択した方法で、GTOから静止軌道への変換の一部をロケットが肩代わりするという方法。


他の方式に比べればH-IIAロケットの選んだ方法はわかりやすいですよね。エネルギー効率もよいらしい。

ただ、これをやるためには、低軌道への投入、GTOへの変換、静止軌道への変換の一部 と3回ロケットエンジンを点火する必要がある。

H-IIAロケットの2段目エンジンはそのための仕込みとして、再々点火機能はあったのだが、

再点火~再々点火の間に4時間かかるので、その間に燃料が蒸発しにくくなるようにとか、バッテリーを増やしたりとかする必要はあった。

でも、その程度で対応できるように最初から仕込みはされてたのよね。


人工衛星側で積む燃料の量は減らせるけど、その分H-IIAロケットの燃料は消費するのだから、お得かというとなんとも言えない。

けど、GTO→静止軌道への変換に必要な加速は1500m/s程度というのが国際標準だから、

そこには適合させないと、H-IIAロケットは静止衛星打ち上げの選択肢にも入らないという実情があったんだろう。

なお、打ち上げ能力への影響だが、1800m/s加速のGTOへの投入能力が6tのロケットで、1500m/s加速のGTOへの投入は5.0t程度になるとのこと。

衛星側で対応するのと、ロケット側で対応するの、どっちがお得なのかこれを見てもよくわからないけど。


そういう経緯があるので、次期基幹ロケット、H3ロケットでは打ち上げ能力についてこう書かれている。

静止トランスファー軌道に6.5トン以上(ΔV=1500m/s)

ΔV=1500m/sというのが静止軌道への変換の一部を肩代わりしてという意味ですね。

おそらくH3ロケットでも同じ方式で実現するんだと思うけど。2段目の構成はあまり変わらないようだし。

というわけで今後の日本からの静止軌道打ち上げはこの方式が標準になるのかなと。

もともと種子島から打ち上げる前提なら、従来からのGTOを使ってもいいんだろうけど。


ちなみに種子島というのも、日本国内でできるだけ赤道に近いところということを考慮したらしい。

あえて不利になるところを選ぶ理由もないですからね。

ただ、地球レベルで見るとやはり不利な方という話にはなる。

不利なところから打ち上げることも考慮して設計するという考えもあるが、ほぼ赤道直下から打ち上げるアリアンスペース社が強い業界ですから。

そこに合わせざるを得なかったということですね。


Author : hidemaro
Date : 2018/04/23(Mon) 23:27
電気・数学・物理 | Comment | trackback (0)

NGから芋づる式にバグが見つかる

ここ最近は論理シミュレーションをしているのだが、

2つのテストから、大量のバグを発見して、一体なんぼほど出てくるんだと思った。

テストの難しさってこういうところにあるんだろうなぁって。


そもそもことの発端は、とあるバグが修正されたこと。

このバグに関連してNGとなっていたテストがOKになったか確認しようと思ったら、相変わらずNGだった。

ただ、NGの出る場所が変わっていたので、新しく発生したNGの原因を探ることにしたのだが……

  1. 直接のNG要因はテスト条件の誤りだが、その場合の期待値とは一致しない
  2. その前に実行していたテストでおかしな値が格納されていることが発覚
  3. 1を修正するついでに、2を洗い出せるテストに修正すると、2の要因でNG
  4. 仮修正を行い、OKとなることを確認

というわけで、テスト条件の誤りをきっかけにして詳細を調べたら、別の問題もありそうだとわかって、

その問題を顕在化させるテストに書き換えたら、予想通り発生したわけですね。


ここまでなら大した話ではなかったのだが、上記4.の修正を行ったことで別のバグも直ったのでは? と予想した。

起きている現象はやや異なるが、結果として同じ修正で直りそうだと考えたのだ。

でも、実際にはこれだけでは直らなかったし、さらなるバグがどんどん発見されたのだ。

  1. テストにかかる時間が長すぎるので、リセットを省略するよう修正
  2. その上で実行すると、当初発見したバグAは直っていないし、別の要因でも期待値とずれてNG
  3. 想定とやや異なる波形なので、調査すると 既存製品のバグA' と 新規バグBの複合で発生したことが発覚
    2.で発生したバグA’を再現するテストを作って既存製品の環境で動かすとNG
  4. 3.以外にも期待値とずれているところがあるので調査すると、エラー発生後に異常な挙動が発生するバグCを発見
    1.のリセット省略の結果、顕在化したことがわかった
  5. バグA’を修正して改めて実行すると、バグB, バグCのNGだけ残る
  6. 5.の結果を見て、エラーレジスタのビット定義に不足があることに気づく(これは保留中)
  7. バグBの原因を調べると、本プロジェクト初期に行った設計に抜けがあることが発覚
  8. 7.の解析結果よりバグBを修正
    4.の解析結果よりある種のソフトリセット処理を追加すればバグCは回避出来るので追加
    これによりバグCは棚上げしてテストOK

と、1つのテストでバグA',B,Cの3つのバグを顕在化させたのだった。

さらに6.に書いたように仕様上の懸念も発見した。実際にはこれでOKな可能性もあるのだが、要確認だなと。


実は上のテストは当初OKだったらしい。ところが後に通すとNGになってしまったのだ。

上記のバグA,B,Cはいずれも新たに埋め込まれたバグではなく、テストOKの時点から存在していたのだが顕在化しなかっただけなのだ。

実はバグBは他のバグとの組み合わせにより、顕在化してなかったらしいんだよね。

そのバグが修正されたことで、バグBが顕在化した。さらに既存製品から存在したバグA’が顕在化した。

さらにテスト時間短縮のためにリセットを省略する変更を行ったらバグCが顕在化した。

実はもともとテストごとに通電時相当のリセット処理をするという非現実的なことをやってたんだよね。

非現実的だし、通電時相当のリセットは所要時間も長いから、こんなの消してしまえと消した。その結果がこれである。

発生条件を調べたところ、実際にそういう状態に陥ったら、ソフトリセットを叩くだろうし、そのソフトリセットにより復帰出来ることもわかった。

本来はリセットなしで復帰出来るように修正すべきだが、とりあえずは現実に合わせてソフトリセットで復帰するという想定に書き直したのだった。


バグが存在していても、それを顕在化させられるかというと、これは難しい。

操作AでエラーXを発生→操作Bを行うとバグが顕在化する というのはよくあるけど、

これを再現するには、操作A→操作Bを行った上で、なおかつ操作Aでエラーを発生させなければならない。

実機でガチャガチャと動かしていて、操作AでエラーXを起こせるなら発見できる可能性もあるのだが……

実は今回、シミュレーションで起こしたエラーというのは、実機で起こすのは極めて難しい。

なので既存製品でも発見されなかったという実情がある。論理シミュレーションで顕在化させなけば発見しようもないと。


実はそういう観点で言うと、バグCはよくシミュレーションで顕在化できたなと思うのだ。

操作Aの準備→操作AでエラーXを発生→エラーレジスタの確認→(リセット操作)→操作Aの準備(リセットを消すとここでバグが顕在化)

まず、エラーXが発生して、エラーレジスタに正しく格納されることを確認するところで終わってはバグが顕在化することは決してない。

このテストでは、パラメータを変えながら操作Aを繰り返し行うテストなので、顕在化させる余地があったのだが、

通常、操作Aの準備には、エラーを顕在化させる操作はやらないんだよね。

ユースケースに従ってテストを書くと、おそらくこんなテストにはならない。

でも、この変なテストのおかげで、リセット操作を消すだけでバグが顕在化できたのだ。

ただし、エラーXの後に、エラーを顕在化させる操作を行わない保証はないので、これはバグではないと強弁することはできない。


あと、テスト条件の誤りをきっかけとして発見されるバグもけっこう多いんだよね。

期待値が不一致となる直接の原因はテスト条件の誤りだが、そうすると別の矛盾が発見され、掘っていくとバグが見つかることもある。

結論から言えば、テスト条件が不足しているということになる。

テスト条件の誤りをきっかけに追加したテストはけっこうある。

過去に作られたテストを実行してOKとなると、それで満足してしまうけど、

NGになると、何がおかしいか詳しく調べるから、矛盾や不足に気づいちゃうんだよね。

そう考えるとOKとなったテストの裏には潜在的なバグがあるのかもしれないが……まぁ優先度は落ちちゃうよね。


Author : hidemaro
Date : 2018/03/23(Fri) 22:56
電気・数学・物理 | Comment | trackback (0)

実は書き込み専用レジスタ

ここのところは論理回路の設計をやっているのだが、

古い設計のモジュールがあって、ある種のマイコンとのインターフェースになっている。

かなり奇妙な設計のモジュールなのだが、それもこれも設計が本当に古いから。

重要性が低く、古い設計のままでも機能的に問題がないということで再設計のタイミングを逸してしまったというのが実情なのかなと。


それで、古くさい設計のモジュールAに関係する新しい機能を実装することになった。

関係する機能なんだから、モジュールAに新たに組み込んだ方がよくない?と提案したのだが、

いろいろな事情があって、他のモジュールの機能として組み込むことになった。

機能の実装ができたので、シミュレーションで動作確認してみようということで、

新機能のユースケースに沿って、テストシナリオを書こうとしたのだが……


そのユースケースはこんなのだった。

  1. 新しく追加したレジスタに書き込みを行い、新機能を作動させる
  2. モジュールAからマイコンをリセットする
  3. リセット解除後、マイコンは新機能へアクセスする

ということで、1, 2と順番にやって、リセット解除時点でマイコンから新機能へのアクセスが想定通りに動くか確認すればよい。

ここで2のリセットのために、モジュールAの関連レジスタ一覧を見たのだが、リセット機能に紐付いたものがない。

でもRTL見る限りはなんらかのレジスタを叩くとリセットできそうなんだけどなぁ。

と思って詳しく見ると、枠外に「リセットは xxxxxxxx番地に0x00をライト、リセット解除は0x80をライトする」という記述があった。


この記述を見ると、レジスタに紐付いていない特定のアドレスに書き込みを行うとリセットできると読めるが、

いやいや、それって書き込み専用のレジスタって言うんじゃないの?

このモジュールを設計した人がそこまで意識していたかは知らないけど、実態はそうだと思うんだよね。

確かにこのモジュールに関連する他のレジスタはどれもリードもライトもできるもので、

それとはかなり違う構造なので、別扱いをしたんだろうなと思ったんだけど、それが不親切だと。


レジスタには読み出し専用のもの、読み書きできるもの、書き込み専用のものがある。

読み出し専用のレジスタは状態を表示するレジスタ、例えばタイマのカウント値を表示したり、外部ピンの入力値を表示したり。

読み書きどちらもできるレジスタは状態の設定に使われることが多い。設定鎮の書き込みと確認ができると。

あと、リセットだけできるレジスタというのもあって、エラーログレジスタとかがそうなんだけど、

エラー発生時に値が設定され、レジスタリードで値を確認し、確認したらレジスタライトでリセットするというような使い方をする。

任意の値を書き込める必要はないレジスタだと、こういうやり方はよく行われている気がする。


こういうのはわかりやすいのだが、書き込みしかできないレジスタというのは特殊だよね。

値を書き込んだのに、リードしても書き込んだ値が確認出来ないということで、ちょっと不思議なレジスタだ。

このシステムでの書き込み専用レジスタの代表例がリセットレジスタだ。

マジックワードを書き込むとリセットが行われるようになっている。

書き込みだけできて読み出しができないのは、現状態を確認できる必要がないからだろう。

読み出せるようにしたところで、マジックワードを書き込む→リセット発生→リセット完了後にマジックワードが自動的に消える ってなるだけでしょうから。


というわけで、この問題提起をきっかけにして、モジュールAのリセット機能は書き込み専用レジスタという形で仕様書に記載されることになりそうだ。

xxxxxxxx番地にリセットレジスタがあって、このレジスタは書き込み専用で、7bit目が0のときリセット、1のときリセット解除という形で書かれるのかなと。

もともと書き込み専用レジスタだと思って作り込まれていないのでちょっと怪しい造りなのだが、

外部仕様としてはこれがわかりやすいでしょうからね。


Author : hidemaro
Date : 2018/03/15(Thu) 23:24
電気・数学・物理 | Comment | trackback (0)

Tools