簡単な背景
ASODUグループのエンジニアとして現地の工場に到着してから、さまざまな種類の記録装置からデータを収集するメカニズムに付随することが私の仕事の1つでした。 私は、植物がこの種の機器の良い「動物園」を持っていることに注意します。 ご存知のように、録音デバイスには、設定とポーリングを可能にする専用のソフトウェアが常にあります。 しかし、あらゆる種類のデバイスとはほど遠い、デバイスからデータを取得し、さらに処理およびアーカイブするために共通環境に配置するために使用できるソフトウェアがあります。 そのため、この問題は、利用可能なすべてのデバイスを照会する1つのプログラムを作成し、収集したデータを単一のデータベースにアップロードすることで解決しました。 しかし、問題は、新しいタイプのデバイスが登場したときに、このプログラムを再コンパイルする必要が常にあり、さらに特定のDBMSにしっかりと結び付けられていたことでした。 コンフィギュレーターもテスターも手元に持っていなかったため、このすべてが追跡プロセスを絶え間なく苦しめました。 そして、データ収集メカニズムを可能な限り維持する作業を簡素化する特定のシステムを実装するというアイデアが浮上しました。 このようなシステムのために、次の要件を提示しました。
- あらゆるタイプ/タイプの楽器にインタビューします。 これは、モジュールを介してプログラムを拡張することにより実現する必要があります。
- 好きなように、いつでもデータをアップロードします。 このアプローチは、モジュールによっても達成される必要があります。
- 調査プロセス全体を簡単に構成できるツールの存在。
- ポーリングモジュールとデータアップロードモジュールの両方をテストおよびデバッグできるツールの存在。
- 調査のタスクはサービスとして機能する必要がありますが、同時に、調査の進行状況を視覚的に監視し、データをアップロードする機能も必要です。
道具
ベンチャーを実装するために、次のツールを使用しました。
コンパイラ:gcc-3.4.2、gcc-4.6.1、tinyc-0.9.25
グラフィックライブラリ:wxWidgets-1.8.10 + wxFormBuilder-3.2
データベース:SQLite-3.7.6.2
実装
実装では、プログラムの主要部分であるデータ収集についてのみ簡単に説明します。 私の意見では、ソフトウェアパッケージの残りの部分は、実装の面でこれほど興味深いものではありません。
クリップボード
私にとって最も重要な仕事は、システムにデータを保存することでした。 私が実装したバッファは次の形式を取りました。
各ポーリングストリームは、バッファの独自のブランチにアクセスし、すべての開始(初期化)設定を取得し、そのステータスを書き込み、受信したデータを入力します。 データアップロードストリームは、ポーリングブランチ(読み取り専用アクセス)とエクスポートブランチの両方にアクセスできます。 図で赤でマークされたオブジェクトへのアクセスは、クリティカルセクションを使用して同期されます。
コア
プログラムの中核を次の図に示します。 次のように機能します。 構成ファイルを読み込むと、ローダーは最終バッファー(上図を参照)、ダウンロードされたポーリングプラグインのリスト、およびデータアップロードプラグインのリストを形成します。 生成されたバッファとプラグインリストの両方がカーネルに渡されます。 次に、カーネルは各com-portへのストリームを初期化すると同時に、バッファブランチとデバイスプラグインのリストを渡します。 ポーリングストリームがすべて作成されると、カーネルは同じ方法でデータエクスポートストリームの初期化を開始します。 しかし、上記のリストに加えて、投票ブランチへの一定のリンクを全員に渡します。 したがって、エクスポートフローは、調査プロセスの進行状況に関するすべての情報をいつでも受信でき、調査の最終結果を取得できます。
ポーリングプログラムには2つのタイプ(サービスとして、およびカスタムグラフィカルアプリケーションとして)があるため、カーネルは両方のアプリケーションが使用する動的ライブラリに配置されます。
カーネルによって生成されたすべてのスレッドは、とりわけ、カーネル自体への一定の参照を取得します。 したがって、各スレッドはカーネルの状態(RUN、STOP)を監視できます。 カーネルがSTOPモードに入ると、すべてのスレッドが自動的にシャットダウンし始めます。 RUNモードに切り替えると、カーネルは上記のスレッドを再作成します。
デバイスポーリングプラグインインターフェイス
デバイスに問い合わせるには、デバイスに送信される最終パケットを形成する機能と、デバイスから受信した応答を処理する機能の2つの機能が必要です。 したがって、プラグインインターフェイスは、パッケージを形成および処理する2つの関数と、パッケージに関する情報を返す別の関数で構成されます。 この情報は、生成および送信されたパケットの長さに関する情報がコンテンツに含まれているため、ユーザーとプログラムの両方に必要です。 その結果、次の機能があります。
- GetInfo-プラグイン情報。
- GetPackage-パッケージの形成。
- GetData-受信パケットの処理。
これらの機能を操作する構造は、システムの一般原則を説明することが私の目標なので、説明する必要はないと思います。 しかし、それが面白くなった人は、 ドキュメントを調べることができます。
エクスポートプラグインインターフェイス
エクスポートプラグインインターフェイスは、4つの機能で構成されています。
- About-プラグインに関する情報。
- 開始-カーネルがRUNモードに入った後、関数が1回実行されます。 データウェアハウスへの接続の作成に重点が置かれています。 関数がエラーを返した場合、スレッドはエラーをバッファに書き込み、終了します。
- エクスポート-データを直接エクスポートします。
- 終了-カーネルがSTOPモードに入った後、関数が1回実行されます。 Begin関数がエラーを返さなかった場合にのみ実行されます。 この機能は、データウェアハウスから切断するように設計されています。
これらの機能を操作する構造についても、上記の理由から説明しません。
結果
現時点では、複合体には次のソフトウェアが含まれています。
- エディター-ポーリング構成エディター。
- ReaderGUI-ユーザーアプリケーションの形式のポーリングプログラム。
- ReaderSvc-Windowsサービス形式のポーリングプログラム。
- ReaderSvcCtrl-ポーリングサービス管理。
- TestExport-エクスポートプラグインのテスト。
- TestRequest-調査プラグインのテスト。
この複合体はWindowsに焦点を当てていますが、WinAPIへの緊密なバインディングは、COMポートで動作するクラスでのみ使用できます。 もちろん、デバイスポーリングサービスです。 それ以外はすべて、wxWidgetsライブラリのクラスと機能に基づいています。
作業例
rmt-59とecograph-tタイプの 2つのデバイスがあるとします 。 それらはそれぞれ、インターフェイスコンバーター「RS-485-イーサネット」への個別のポートに接続されます。 ポーリングするコンピューターには、「Ethernet-RS232」を変換するドライバーがあります。 したがって、2つのcom-port(たとえば、com-10とcom-11)があり、その上に1つのデバイスがあります。 両方のデバイスについて、アドレス1を想定します。両方のデバイスは、19,200 bpsのデータレートに設定されています。
最初に、既存のプラグインがこれらのデバイスを操作するのに適していることを確認する必要があります。 これを行うには、TestRequestプログラムを実行し、これらのデバイスに問い合わせます
その後、調査構成を作成する必要があります。 Editorプログラムを実行し、調査をセットアップします。
新しいデータベースを作成した場合は、Reader.iniファイルでそのデータベースへのパスを指定する必要があります。 調査の動作をテストするには、プログラムReaderGUIを実行します
次に、データのエクスポートを処理する必要があります。 特別なプラグインは作成しませんでした。 エクスポート作業のテストのために、1つのテストプラグインがパッケージに含まれており、データをテキストファイルにエクスポートします。 最初に、TestExportプログラムを使用してその動作を確認する必要があります。
プラグインが正しく機能していることを確認したので、調査構成に追加できます。
すべて、構成、およびテストが完了しました。 これで、サービスをインストールして開始できます。 ReaderSvcCtrlプログラムを使用してサービスを管理します。
あとがき
もちろん、もっと書くこともできますが、読者を飽きさせないために、これはしません。 これが私のプロジェクトへのリンクです。 コメントにあるすべての質問にお答えいたします。
システムの多くの欠点は、動作中に発見されました。 これらの欠点には次のものがあります。
- ポーリングされたチャネルのタイプの欠如。 このタイプの必要性は、さまざまなタイプの値(アナログチャネル、数学チャネル、整数値)の多くのデバイスが特別に形成された要求を必要とするという事実によるものです。
- 乗数の概念の欠如。 つまり 一部のデバイスは、ポーリング時に値を整数として送信します。 また、このようなデバイスの場合、番号内のコンマの位置は個別に調べられます。 また、このような乗数を使用すると、ユーザーはコンマの位置を変更できます。 たとえば、特定のチャネルで整数と小数値の間の区切り文字が最初の数値の後に配置される場合、係数0.1を使用すると、数値を適切な形式にすることができます。 値123を受け取ったシステムは、この数値に対応する係数を掛けると、結果が12.3になります。