🗐 電装工芸日記 - 舞台照明機器の製作とか -

今年は開発案件を進めたい

or 管理画面へ

タグ「C言語」を含む投稿[64件](5ページ目)

Icon of admin
 ダンプ表示のライブラリは出来ました。何の変哲もない16進数のカラム表示です。
 データ配列のポインタ、表示データ数、列数、行数、最上行値のポインタなどを引数にして関数を呼ぶと表示します。
 地味ですが、こういったライブラリがあると開発の効率が良くなるのでは?という想いで作ってみました。後でDMXデータを表示する画面を作る際にも同様のことをするので習作でもあります。

 以下オレメモです。
 ANSIエスケープシーケンスにおいてパラメータに変数を用いたい場合。

 // カーソルをx=10,y=5にして文字列を表示する
#define ESC 0x1B
int main(void) {
 int x = 10 ;
 int y = 5 ;
 printf("%c[%d:%dHカーソルを指定の位置に", ESC, x, y ) ;
 return 0 ;
}

 ※ このブログシステムでは#や[が機能文字扱いなので、上記ではこれらを全角文字で書いています。

 などとします。大昔のN-BASICの「LOCATE + PRINT」みたいなことをしています。
 printfの文字列中のエスケープを\eと直で書くと後に続く%dが機能しませんが、#defineで定義したESC(0x1B)を%cで読み込めば機能します。
 もちろん、printfのESCの位置に0x1Bと直書きしてもいいのですが、#defineした方が読みやすいと思います。

 C言語ではこういった不思議な記述が多いです。正規表現的でもありますが、バイナリ的な指向が各所に出てきます。
 アセンブラに慣れた身に違和感はありませんが、理解に苦しむ要素かもしれません。

#C言語
Icon of admin
 本業では社内のサーバーやパソコンのメンテをしていますが、処理の待ち時間でC言語のお勉強。
 時間についてです。
 DMXを扱うには無受信1秒でタイムアウトしなければなりませんし、Delayを構成するには1/30~1/50秒程度のインターバルタイムで受信値をスタックしなければなりません。
 ですので、msec(1/1000)クラスの時間評価が必要です。

 システムが持つ時間情報を扱うには<time.h>を用い、エポック秒やPOSIX時間などと呼ばれる基準日時(1970年1月1日0時0分0秒(UTC))からの経過時間(secとnsec)を使うのがよいと思います。有効な精度は10usec程度の様ですが、今現在書いている処理では十分です。これを処理の節目でスタックして経過時間を評価するのですが、年月日時でパラメータが分かれているよりもトータル秒数の方が扱いが簡単です。23時59分59秒の1秒後に0時0分0秒にならないタイマで継続した時間評価をしたいのでこの方がいいと思います。
 ただ、スタックする変数のバイト長には気を付けないといけません。secもnsecもそれぞれ4バイト数なので評価をするには8バイト数で考えないといけないからです。64bitOSならint型でも8バイト数なことが多いので問題ありませんが、私はRaspberryPiで32bitOSを使っているのでint型は4バイト数になります。対策には8バイト数である「(unsigned) long long int」型を使います。ちょっとクセがある型なので計算やprintfで注意しないといけませんケドね。

#C言語
Icon of admin
 オレメモであります。
 参考になりそうな先達のページ

● UDP/IP通信全体の参考
UDP / IP でパケットの送受信を行う
● broadcast通信の参考
UDPブロードキャスト送信サンプル
● ネットワークデバイスを指定した通信の参考
Ethernetインターフェース(eth0, eth1)を指定してソケットを作成する (Linux, C, Raspberry Pi)
● 受信タイムアウトの参考
selectを使用してタイムアウト付き受信を実現する <= recvもrecvfromも受信があるまでひたすら待ち続けるので、タイムアウトさせることは必須。
UDP通信におけるselectの使い方。 <= recvの例が多い中、recvfromの書式を確認出来る。recvfromを使う理由は送信元アドレスを取得したいから。
● 時間の扱い方
時間情報の取得方法と扱い方 <= これの5ページ目の「POSIX環境」が結構大事。DelayをするにもDMXのタイムアウトをするにもこれが必要。
● ターミナルの行長と行数を取得する
ターミナルのサイズを取得する
ターミナルの幅と高さを得る
● ANSIエスケープシーケンス
ANSIエスケープシーケンス チートシート

 この辺りを参考にすれば「ネットワークデバイスを指定してbroadcastで通信する」が出来そうな気がします。
 ただし、1行々々読み込んで使われている構造体をよく把握することが大切です。構造体の中に必要な情報が隠れていることが多いからです。構造体の中に構造体があったりもするので、十分に読み込まないといけません。

 実験は受信が当面の課題となり、
1)ネットワークデバイスを指定せずArt-Netを受信する。<= とにかく受信する
2)ネットワークデバイスを指定してArt-Netを受信する。<= ネットワークデバイスを制限して受信する。
3)送信元IPアドレスを取得し、IPアドレスをもとに受信値を振り分ける。<= 複数の送信元(卓)がある場合の不確実性排除とミックス処理のためには不可欠。
 といった手順で進めることになろうかと思います。
 受信値を確認するため、習作を兼ね、バイナリをダンプ表示をするライブラリも作ってみましょう。

#C言語 #[Art-Net]
Icon of admin
 RTCを装着したRaspberryPiは正常のようです。
 今後製作する装置にもRTCを装着したいのですが、電池切れをどうやって拾うか思案中です。

 socketの実験は連休中に時間が取れず未対応です。
 Art-Netの受信と送信を1台でこなすにはIPアドレス的には同じゾーンで装置は別という変な構成になります。その上、broadcastで受けてbroadcastで送るというこれもまた変な構成です。ですので、コピペで使える先例がありそうでありません。
 RaspberryPiのPythonでは成功していることですから可能だと思いますが、C言語のsocketの方が設定すべきパラメータが多いため、Pythonには無かった設定をどうするかが難問なのです。難しいというより、「ネットワークデバイスを指定してbroadcastで通信する」という前提の先例が少なく、沢山のデータシートを継ぎハギしないと見えないことが多いために苦心しているところです。

#RaspberryPi #C言語 #[Art-Net]
Icon of admin
 Art-Netを受信する準備を進めています。
 思った以上に面倒だったのはデータの比較です。受信値と期待値を比較して処理を分岐する処理は重要です。文字列ならstrcmp、バイナリならmemcmpを使います。どちらもstring.hの関数です。
 どちらにしてもバイナリな感覚を持ち合わせていないと使えませんが、アセンブラに慣れた体にとって違和感はありませんし、ある意味とても明確な処理になるので悪い気はしません。Pythonが如何に簡単に書けるかを感じたりはしましたけどね。
 あとはエンディアンの処理です。RaspberryPiはARM系なのでリトルエンディアンです。受信したArt-Netを仕分けて情報にするには2-4バイトのバイナリを数値化しないといけませんが、エンディアンを気にしながらバイナリを並べて処理します。並べたバイナリを数値化するにはカッコとアンパサンドを使った不思議な記述をしますが、理解不能なので定型句と思って使っています。
 こんな底辺処理が整理出来たら受信テストですが、これらを先にやっておかないと受信値を人が読める形で表示することが出来ないのです。

#[Art-Net] #C言語
Icon of admin
 ここ数日は本業で手一杯でした。ライトアップの施工があったのですが、建物の窓を光らせたいとのことで専用の行燈を製作してました。
 簡単な作りではあったのですが思った以上に時間がかかり、徹夜して間に合わせたのはいいですが、その余波で心身共にキツイここ数日。
 8月のお盆明けからの大連チャンでしたが、この後3月中旬までは緩い日程なので、各種製作や開発を進めて行けそうです。

 同時にイロイロ進めますが、とにかくArt-Netエンジンを完成させたい。
 Art-Netエンジンとは、Art-Netを受信し、Merge、In-Delay、Patch、Out-Curve、Out-Delayを施し、Art-Netとして送信するデバイスドライバの様なモジュールです。ユーザーインターフェースなどは別途製作ですが、これが完成すれば求めることの半分は完成です。
 そのためにC言語を学習しているワケですが、ポインタ、構造体、共有メモリ、マルチプロセスの基本が見えてきましたので、これからしばらくはArt-Netの要であるscoketを試そうと思います。C言語でscoketを扱う情報は高位者による高位者向けの高度な物ばかりですが、幸いPythonでの前例がありますので、これをC言語に置き換える方向で読み解いていこうと思います。
 学習を進めれば進める程「ライブラリの使い方はmanとヘッダーファイルを読めば分かるだろ!」という圧を強く感じますが、この感覚が自分にとっても当たり前になるように精進したいものです。

#C言語 #本業 #[Art-Net]
Icon of admin
 C言語の教科書を幾つか読んでいます。
 熟知した人でないと書けないことですが、熟知した人は初心者の気持ちを忘れた人たちです。どんなに優しく書こうとしても初心者向けの説明など書けません。部分的に初心者の理解を助けてくれる文章があるので複数読んだ方がいいのです。
 お勧めというか、理解しやすかった教科書を2つご紹介します。

「新・明解C言語 入門編」
 初心者が挫折しやすい変数の型、ポインタ、構造体を後回しにして書いているのでC言語の全体像が見えやすい。変数の型、ポインタ、構造体で悩みたくないなら他の言語を使うべきですが、冒頭から「変数の型がぁ~」「ポインタがぁ~」と書かれた解説書は挫折率が高い(俺評価)のでよろしくありません。簡単とは言いませんが、これは挫折し難い内容です。

「苦しんで覚えるC言語」
 書籍にもなっていますが、webでも読める解説書です。途中息切れを感じるところはありますが、これはこれでわかりやすい。

 あと、以前ご紹介した「改訂第3版(5版) ANSI C 対応 はじめてのC」は和文規格書かもしれません。わかりやすい記述も多いのですが、誰もが悩むポインタは触るだけだったりと、誰もが躓くところほど流している傾向があります。すでに習得している人の参考書としてなら悪くありませんケド。

 ただ、総じて言えることですが、C言語はこの時代に初めてプログラムを書く人が使う言語ではありません。画面とキーボード、マウスで完結するシステムならPythonなどの高度にマネージされた言語を使うべきです。なぜなら、CPUのレジスタとかフラグ、メモリの概念が体に染み込んでいないと書式の意味を理解することが難しいからです。私の課題は対象がハードウェアですからPythonよりもC言語の方が適切ってだけです。

#C言語
Icon of admin
 ランチャーに行く前にscoketの基本動作の確認かな?
 受信したArt-Netパケットをそのまま送信する実験。
 これが求める機能の基本ですから確認せんといかん。

#[Art-Net] #C言語
Icon of admin
 共有メモリの衝突回避ですが、共有メモリの中にハンドシェイク表すフラグを入れたらそれでいいんじゃないかと。
 そのフラグが立っていれば極々わずかな時間sleepを繰り返す処理です。

while(flag1 == 1)
{
 sleep(0.001);
}
flag2 = 1;
/* 共有メモリ処理 */
flag2 = 0;


 みたいなものです。
 別プロセスがフラグを0にすればwhileを抜けます。
 簡易的なモノですが、フラグを書き換えられるプロセスを一つにしておけばイイんじゃないかと。最も簡単なセマフォはこういうことですし。

 子プロセスの停止制御も同様の考え方が使えます。
 動作し続けるってことは繰り返し処理です。単なる繰り返しはwhile(1)とかで無限ループすることが多いので、while(flag==1)とかにすればいい。共有メモリ上のフラグが1ならwhileでループし0になったら抜ければいいのです。抜けたら終了処理をしてプロセスを落とすと。子プロセスが完全に終わったことはスタックしておいたプロセスIDを見ればわかります。

 この辺りまで決まれば次はランチャーです。

#C言語
Icon of admin
 共有メモリに構造体を配置してみましたが、割と簡単でした。
 構造体のタグ(ひな形)をヘッダーファイルに作り、親プロセスと子プロセスにinclude。共有メモリのサイズは構造体のタグから得て設定。共有メモリ上に置く変数を独立したポインタにするとオフセットをそれぞれ計算して与えないといけませんが、構造体なら一括設定出来て便利です。
 構造体をポインタにすると表記が独特になりますが、意味合いが明示的となって読みやすいかもしれません。
 この辺りには、本文中に出来るだけ定数を直書きしないという方針にも繋がってきます。

 次は共有メモリの衝突回避を調べないといけません。

#C言語

■思ってみた

春ですねぇ~。
花粉症の部下は死にそうですが、暖かいってのはいいことです。

編集

■全文検索:

複合検索窓に切り替える

■複合検索:

  • 投稿者名:
  • 投稿年月:
  • #タグ:
  • カテゴリ:
  • 出力順序:

■日付検索:

■カレンダー:

2023年1月
1234567
891011121314
15161718192021
22232425262728
293031

■カテゴリ:

■最近の投稿:

最終更新日時:
2025年4月29日(火) 20時16分48秒