2026年3月の投稿[2件]
2026年3月5日 この範囲を時系列順で読む この範囲をファイルに出力する
C言語の共用体(union)ですが、教科書やら動画を見ますと「あまり使い道が無い」的な解説が多いような気がします。
されど、今回のArt-Net系の装置では便利です。Art-Net のポート番号 0x1936(6454) の受信値をとりあえず突っ込むだけで要素毎に取り出すことも出来るからです。例えば ArtDMX は530バイトのパケットですが、受信値を uint8_t[530] (または unsigned char[530]) の配列として保存するだけで ArtDMX の構造体としても扱えます。パディングに注意は必要ですが、便利に使えると思うのです。ID、OpCode、ProVer をまとめて評価するのに先頭12バイトを uint8_t[12] としておいて memcmp で判別することも出来ます。AertDMX と別種の Art-Net パケットもシームレスに扱えそうです。
天才を超越した神たちが何故 union を作ったのかを考えるとワクワクします。
とまぁ、最近C言語の理解が進んで一人笑いが止まらないアホの戯言でした。
オレメモです。
gccで構造体のパディングを回避する書き方。struct に続いて「__attribute__((__packed__))」を入れるそうな。gcc独特の書式らしいので、コンパイラに合わせた書式を使ってください。
typedef struct __attribute__((__packed__)) ad_struct {
uint8_t ad_ID[8];
uint8_t ad_OpCode[2];
uint8_t ad_ProVerHi;
uint8_t ad_ProVerLow;
uint8_t ad_Sequence;
uint8_t ad_Physical;
uint8_t ad_SubUni;
uint8_t ad_Net;
uint8_t ad_LengthHi;
uint8_t ad_Length;
uint8_t ad_Data[512];
};
ad_struct ad_data;
ArtDMXを保存する構造体はこんな感じに書けばよいのでしょう。たぶん。
この型を sizeof で見て530バイトならヨシです。
ついでに共用体の定義(案)です。
// Art-Netの受信値を収める構造体
typedef struct __attribute__((__packed__)) an_struct {
uint8_t resv[530];
};
// ArtDMXを取り出す構造体
typedef struct __attribute__((__packed__)) ad_struct {
uint8_t ID[8];
uint8_t OpCode[2];
uint8_t ProVerHi;
uint8_t ProVerLow;
uint8_t Sequence;
uint8_t Physical;
uint8_t SubUni;
uint8_t Net;
uint8_t LengthHi;
uint8_t Length;
uint8_t Data[512];
};
// Art-Netの受信値を保存する共用体ループバッファ
union an_stack {
an_struct an_resv;
ad_struct ad_data;
} an_loopbuffer[8192];
こういうことでいいのかな?
共用体の書き方はまだよくわかってないのですけど。
共用体の配列を作って Art-Net のポートで受信したパケットを延々と保存します。8191番まで記録したら0に折り返すループバッファです。
8192個あれば44fps、8センダー、各16ユニバースで最短でも1.45秒分の保存が出来るハズです。十進数で8192なのは2進数(16進数)でキリの良い数値のため折り返し評価が少ない処理で出来るからです。十進数8192は16進数0x2000でキリがよく処理しやすいのです。このあたりはアセンブリ言語だけでPICマイコンと会話をしてきた者にとって自然な着想です。10進数は人が日常的に使い慣れているだけで特筆するほど合理的な数体系ではありませんし、今どきのコンピュータ(論理回路)に合わせた方が便利です。
ヘッダーチェックは当該の配列要素(例えば an_loopbuffer[1024] )を示すポインタからmemcmpで12バイトをチェックすれば済みますので共用体には定義しません。
ArtDMX以外のパケットにも使えるチェック方法です。
#C言語
されど、今回のArt-Net系の装置では便利です。Art-Net のポート番号 0x1936(6454) の受信値をとりあえず突っ込むだけで要素毎に取り出すことも出来るからです。例えば ArtDMX は530バイトのパケットですが、受信値を uint8_t[530] (または unsigned char[530]) の配列として保存するだけで ArtDMX の構造体としても扱えます。パディングに注意は必要ですが、便利に使えると思うのです。ID、OpCode、ProVer をまとめて評価するのに先頭12バイトを uint8_t[12] としておいて memcmp で判別することも出来ます。AertDMX と別種の Art-Net パケットもシームレスに扱えそうです。
天才を超越した神たちが何故 union を作ったのかを考えるとワクワクします。
とまぁ、最近C言語の理解が進んで一人笑いが止まらないアホの戯言でした。
オレメモです。
gccで構造体のパディングを回避する書き方。struct に続いて「__attribute__((__packed__))」を入れるそうな。gcc独特の書式らしいので、コンパイラに合わせた書式を使ってください。
typedef struct __attribute__((__packed__)) ad_struct {
uint8_t ad_ID[8];
uint8_t ad_OpCode[2];
uint8_t ad_ProVerHi;
uint8_t ad_ProVerLow;
uint8_t ad_Sequence;
uint8_t ad_Physical;
uint8_t ad_SubUni;
uint8_t ad_Net;
uint8_t ad_LengthHi;
uint8_t ad_Length;
uint8_t ad_Data[512];
};
ad_struct ad_data;
ArtDMXを保存する構造体はこんな感じに書けばよいのでしょう。たぶん。
この型を sizeof で見て530バイトならヨシです。
ついでに共用体の定義(案)です。
// Art-Netの受信値を収める構造体
typedef struct __attribute__((__packed__)) an_struct {
uint8_t resv[530];
};
// ArtDMXを取り出す構造体
typedef struct __attribute__((__packed__)) ad_struct {
uint8_t ID[8];
uint8_t OpCode[2];
uint8_t ProVerHi;
uint8_t ProVerLow;
uint8_t Sequence;
uint8_t Physical;
uint8_t SubUni;
uint8_t Net;
uint8_t LengthHi;
uint8_t Length;
uint8_t Data[512];
};
// Art-Netの受信値を保存する共用体ループバッファ
union an_stack {
an_struct an_resv;
ad_struct ad_data;
} an_loopbuffer[8192];
こういうことでいいのかな?
共用体の書き方はまだよくわかってないのですけど。
共用体の配列を作って Art-Net のポートで受信したパケットを延々と保存します。8191番まで記録したら0に折り返すループバッファです。
8192個あれば44fps、8センダー、各16ユニバースで最短でも1.45秒分の保存が出来るハズです。十進数で8192なのは2進数(16進数)でキリの良い数値のため折り返し評価が少ない処理で出来るからです。十進数8192は16進数0x2000でキリがよく処理しやすいのです。このあたりはアセンブリ言語だけでPICマイコンと会話をしてきた者にとって自然な着想です。10進数は人が日常的に使い慣れているだけで特筆するほど合理的な数体系ではありませんし、今どきのコンピュータ(論理回路)に合わせた方が便利です。
ヘッダーチェックは当該の配列要素(例えば an_loopbuffer[1024] )を示すポインタからmemcmpで12バイトをチェックすれば済みますので共用体には定義しません。
ArtDMX以外のパケットにも使えるチェック方法です。
#C言語
2026年3月2日 この範囲を時系列順で読む この範囲をファイルに出力する
先日の現場はヒマな時間が長かったのでC言語の教科書を読みまくってみましたがかなり整理出来ました。
昨今の教科書はポインタの説明が丁寧です。ハードウェアとしてのメモリの動作がアタマに入っていないと分かり難いことですが、私はPICのアセンブラで普通に扱ってきたことなので改めてではありますが素直に理解出来ました。わかってしまえばむしろ便利だなと。変数の読み書き方法が何種類もあることになるので混乱すると思いますが、どれもメモリへのアクセス手段だと捉え直せばいいだけでした。このあたりが整理できるとmmapも自然に理解出来ます。
ヘッダーファイルはコピペでテキトウに書いていましたが、意味と書き方が整理できました。後はmakefileが整理出来れば良さそうです。
#C言語
昨今の教科書はポインタの説明が丁寧です。ハードウェアとしてのメモリの動作がアタマに入っていないと分かり難いことですが、私はPICのアセンブラで普通に扱ってきたことなので改めてではありますが素直に理解出来ました。わかってしまえばむしろ便利だなと。変数の読み書き方法が何種類もあることになるので混乱すると思いますが、どれもメモリへのアクセス手段だと捉え直せばいいだけでした。このあたりが整理できるとmmapも自然に理解出来ます。
ヘッダーファイルはコピペでテキトウに書いていましたが、意味と書き方が整理できました。後はmakefileが整理出来れば良さそうです。
#C言語