工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Industrial Internet of Things >> 埋め込み

組み込みファームウェアのヒント:信号波形やその他のファイルデータを使用してCでアレイを初期化する方法

この記事では、Cプログラムの配列をテキストファイルの値で初期化する方法を示します。

この記事では、テキストファイルの値を使用してCプログラムの配列を初期化する方法を示します。データはソースファイルに保存されません。プログラムのコンパイル時にファイルが読み込まれます。一次元および多次元配列が考慮されます。例では、RAMまたは不揮発性メモリへのアレイの配置と初期化に使用するデータファイルの選択を制御する方法も示しています。

例で使用されているコンパイラは、ターゲットとして32ビットマイクロコントローラを備えたARM用GCCです。すべての例で標準Cを使用し、このコンパイラで動作しました。

配列の初期化の基本

配列は、「宣言」されたときに値で初期化できます。典型的な宣言をここに示します。中括弧内の値は「初期化子」と呼ばれます。


配列のサイズが括弧内に指定されていない場合、サイズは初期化子の数になります。配列のサイズよりも初期化子の数が少ない場合、余分な要素は0に設定されます。配列のサイズよりも初期化子の数が多いとエラーになります。

ホワイトスペース

イニシャライザーはコンマで区切る必要があります。 「空白」を追加しても問題ありません。この場合、空白は「空白」またはスペースです。空白文字のセットには、空白(またはスペース)、タブ、改行、キャリッジリターン、垂直タブ、およびフォームフィードが含まれます。改行と復帰は、Cソースコードの行の終わりを示すために使用されます。フォームフィードは知っていますが、垂直タブは知っていますか?

一般に、Cは、ステートメントに空白が含まれているか、別の行に続いているかを気にしません。ここでのステ​​ートメントは、上記のステートメントと同等です。大規模な配列の初期化子の行が非常に多く見られるのはよくあることです。多分ページさえ。ある時点で、「もっと良い方法はありますか?」と言うかもしれません。


ファイルからの配列の初期化

Cソースコードは、コンパイル前にプリプロセッサを介して実行されます。 Cプリプロセッサの一般的に使用される機能は「ファイルインクルード」です。これは、カーニハンとリッチーによる有名な本「TheCProgrammingLanguage」からの引用です。

「ファイルインクルードにより、 #defines のコレクションを簡単に処理できます および宣言(とりわけ )。」

「とりわけ」のイタリックを追加しました。通常、「。c」ファイルと「.h」ファイルを含めますが、プリプロセッサはファイルの名前拡張子を気にしません。どのテキストファイルでもOKです。したがって、次の構文は配列を初期化するために機能します。


ファイルには、ドキュメントのフォーマットのために非表示になることがある特殊文字を含めることはできません。単純にする。リッチテキスト形式はありません。列ヘッダーはありません。数字、コンマ、空白のみ。これがWindowsのメモ帳で作成されたファイルです。


これは、デバッガーで表示されるメモリ内の配列です。この場合、[場所]列の上位アドレスで示されているように、アレイはRAMにあります。


非揮発性メモリへの配列の保存とデータファイルの選択

上記の例では、配列はグローバル変数であり、配列を配置する場所を指定するものはありません。コンパイラとリンカは、配列がプログラムによって変更される可能性があることを前提としており、RAMに配置されます。初期値は不揮発性メモリ(「NVM」、通常はフラッシュメモリ)にあり、RAMの配列は、メインプログラムの前に実行されるコードによってこのデータから初期化されます。 NVMのこのデータは、プログラムによってアクセスされません。配列が変更されない場合(「定数」)、配列はNVMにのみ配置され、プログラムから直接アクセスされます。これにより、不足しがちなRAMを節約できます。配列が変更されないことをコンパイラとリンカに通知し、NVMで配列を見つけるには、通常、「 const 」を使用します。 」修飾子。これが例であり、結果を見てみましょう。 [場所]列には、このマイクロコントローラーのフラッシュメモリであるメモリマップの下位に表示されます。


#define および #if 前処理ステートメントを使用して、配列を検索し、初期化に使用するデータファイルを選択するためのオプションを提供できます。これは、RAMまたはNVMにアレイを配置する選択肢を提供する例です。


#if 構成は「条件付き包含」の例です。この場合、「 const 」修飾子は、配列を宣言するときに使用されます。これは、宣言が複数行にある可能性があるため、または言い換えると空白が問題ないために機能します。

条件付きインクルージョンを使用して初期化するファイルを選択する例を次に示します。


大規模アレイでのテスト

ノイズ波形を表すランダムデータの大きなファイルがあり、それを使用してNVMの大きなアレイの初期化をテストしました。これがデータと宣言のプロットです。



これがファイルの始まりです。


元のcsvファイルには、値の後にコンマがありませんでした。これらは、検索/置換操作で式を使用できるエディターを使用して簡単に追加できました。この場合、行区切り文字「\ R」の式を使用しました。検索は「\ R」で、置換は「、\ R」でした。 1回の検索/置換操作で、10,000個の値のすべてのコンマが追加されました。

すべてがうまく機能し、非常に高速にコンパイルされました!これがメモリ内の配列の始まりです。デバッガーは、表示をそれぞれ100個の要素のグループにうまく分割しました。


多次元配列

データが2つ以上の次元で編成されている場合はどうなりますか? uint16_t test [2] [3] として宣言された2次元配列を見てみましょう。 。 Cでは、右の添え字(3)は、メモリ内で要素が連続している1次元配列です。左の添え字(2)は、これらの3要素配列が2つあることを意味します。これは、6つの要素のメモリ配置です:

[0,0] [0,1] [0,2] [1,0] [1,1] [1,2]

右の添え字をインクリメントしてメモリ内の連続する要素にアクセスする方が、メモリを介した「ホップ」を必要とする左の添え字をインクリメントして要素にアクセスするよりも高速であるため、メモリ内の順序は重要です。配列が1,000要素の2つのベクトルを保持している場合、組織は test [2] [1000] である必要があります。 最速のアクセスのために。

2次元配列を初期化する例を次に示します。初期化子は、右下付き文字の1次元配列の初期化子をグループ化する追加の中括弧でグループ化されていることに注意してください。


この形式では、数字、コンマ、および空白しか含めることができないデータファイルで問題が発生します。追加の中括弧を省略するとどうなりますか?


コンパイラーは、最初に右の添え字を埋めてイニシャライザーを左から右に移動することにより、配列を埋めます。私が使用しているコンパイラは警告を出します:「初期化子の周りに中括弧がありません 」。初期化子の数が配列内の要素の数とまったく同じであれば問題はありません。ただし、等しくない場合、ガイドとして機能する中括弧がない場合に配列を埋める方法が明確ではありません。

配列は、複数の #include を使用して複数のファイルから埋めることができます ステートメント。これは、初期化が中括弧のペアで完全に囲まれている例です。前の例で示した詳細は省略します。


ユニオンでの配列の初期化

ユニオンは、同じメモリを共有するさまざまなタイプのオブジェクトを保持できる変数であり、コンパイラは、オブジェクトが別のものであるかのように追跡します。この配置は、メモリが不足している組み込みアプリケーションに役立つ可能性があります。 vector [6] の例を次に示します。 1次元と matrix [2] [3] 二次元で。これらは、メモリ内の同じ場所を占める2つのアレイです。


ユニオンを初期化するためのルールは、ユニオンの最初のものです( vector [6] )は初期化子で埋められます。配列の順序が逆になっている場合、初期化子が中括弧で完全に囲まれていないため、コンパイラは警告を出します。 #include の周りの中括弧に注意してください 倍増します。外側のセットはユニオンの初期化子を囲み、内側のセットは配列型用だと思います。

これがファイルです。私は2行ありますが、それは問題ではありません。余白が増えました。


これがメモリ内の配列です。 vector [] の開始位置に注意してください および matrix [] [] 同じです。


数字、コンマ、空白のみを含む単一のファイルから多次元配列を初期化する他の方法はありますか?コメントを追加して教えてください。

ボーナスのヒント:文字列

文字列はどうですか?文字列を初期化する例を次に示します。


#include 引用符内は機能しません。 C構文を認識している私のエディターは、たくさんの疑問符と波線のある下線を付けてくれます。新しい行と #include の文字 それ自体が初期化子です!かわいそうな編集者は混乱しています。この混乱はコンパイルされますが、文字列はファイルからではなく、ここに表示される文字で埋められます。


解決策は、ファイルに引用符を付けることです。


次に、このようなステートメントを使用します。


ファイル名を囲む引用符は #include の一部であることに注意してください 構文であり、初期化子を制御しません。これがRAMの結果です。


例はすべて理論的には機能するはずであることに注意することが重要です。 任意のコンパイラで。ただし、一部の例は一般的ではなく、一部のコンパイラで問題をくすぐる可能性があります。問題が発生した場合は、コメントでお知らせください。


埋め込み

  1. クラウドとそれがITの世界をどのように変えているか
  2. STは、STM32ニューラルネットワーク開発者ツールボックスを使用して、AIをエッジおよびノー​​ド組み込みデバイスに駆動します
  3. データモジュール:高輝度でeasyTouch機能を備えた大型オープンフレームモニター
  4. マイクロチップ:最大153.6kSPSのデータレートを備えた24ビットおよび16ビットADC
  5. Contrinex:Bluetoothインターフェースを備えたクラウド対応のスマートセンサーとセーフティライトカーテン
  6. C++ の配列 |宣言する |初期化 |配列へのポインタの例
  7. 例による配列の C++ 動的割り当て
  8. Java BufferedReader:例を使用して Java でファイルを読み取る方法
  9. TechDataとIBMPart2を使用してIOTを現実のものにする方法
  10. TechDataとIBMPart1を使用してIoTを現実のものにする方法
  11. NexusIntegraと他のIoTおよびビッグデータプラットフォームとの違い