コンソールデバイスとしてのサウンドカード

freebsd-archメーリングリストのPoul-Henning Kampは、サウンドカードを介したコンソールI / Oを許可するコード例を示しています。 彼の手紙の原本はここにあり、原本にできるだけ近い翻訳を提供します。 私はいくつかの単語を翻訳できなかったので、オリジナルに残し、括弧内に私の仮定を与えます。



昨日、新しいラップトップで作業中にゴミに苦しみ、ACPIを一時停止/再開する機能に悩まされたとき、再びラップトップからシリアルポートを取り外したクレイジーな男を呪いました。



少し考えてみると、突然思いつきました。最新のデバイスにはすべて、AC97オーディオ機器のサポートが組み込まれているため、帯域幅がかなり良好です。



今朝、私は簡単な実験を始めました。 結果は、アイデアが機能していることを明確にしますが、ユーザーランドから機能するかもしれません(おそらくユーザー空間で ?Googleの定義はまさにそのような答えを与えます-およそTransl。)。



伝送には次の形式を使用しました:短期的なネガティブエッジを文字の先頭に送信し、次にN個の離散、そしてポジティブエッジを送信。 N-文字のASCII値+小さな定数。



差動ペアで2つのステレオチャンネルを使用する概念(オリジナルの概念実証 -およそTransl。)を確認するコードを添付しています(これが良いアイデアかどうかはわかりません)。



最初の試みでは、1%のエラーで毎秒約320文字を送信することができました。



まだやるべきこと:



*送信スキームを最適化します。



これは、ジャックインジャックケーブルとCコードの2台のコンピューターで実行できます。



2台のコンピューターのサンプリングレートの違いにより、1台ずつ過小評価または過大評価のエラーが発生します。 補間機能を備えたピーク検出器がこの問題を解決できるかどうか、またはレシーバーで周波数サンプリング( オーバーサンプリング -約Transl。)の使用を強制されるかどうかはわかりません。



2つのパルスは異なる極性を持つことができます。 同期を適切に実行する方法が見つかれば、2ビットを送信できます。これにより、4 (おそらく4倍は正確にこれ-およそのトランスを意味します)で伝送速度を上げることができます。



2つのステレオチャネルを個別に使用して、速度を2倍にすることができます。



*割り込みを使用せずにオーディオ機器で動作するカーネルレベルのコンソールドライバーを作成します。



サウンドカードのインターフェイスがどのように見えるかはわかりませんが、非常にシンプルだと思います。



接続が単方向であっても、私のようなカーネルハッカーは、この作業を終えた人を尊敬します。



飛び込め!



悪戯



/* proof of concept transmission code */ #include <stdio.h> #include <assert.h> #include <fcntl.h> #include <sys/soundcard.h> #define OFF 5 static short int buf[2*128 + 2 * OFF]; int main(int argc __unused, char **argv __unused) { int fd_dsp; int i, j, k, c; fd_dsp = open("/dev/dsp0.1", O_RDWR); if (fd_dsp < 0) err(1, "open /dev/dsp"); i = ioctl(fd_dsp, SNDCTL_DSP_RESET, &j); assert(i == 0); j = 2; i = ioctl(fd_dsp, SNDCTL_DSP_CHANNELS, &j); assert(i == 0); j = 44100; i = ioctl(fd_dsp, SNDCTL_DSP_SPEED, &j); assert(i == 0); j = 16; i = ioctl(fd_dsp, SNDCTL_DSP_SETFMT, &j); assert(i == 0); while (1) { c = getchar(); if (c == EOF) break; buf[OFF] = 32000; buf[OFF + 1] = -32000; buf[OFF + 2 * c] = -32000; buf[OFF + 2 * c + 1] = 32000; i = write(fd_dsp, buf, sizeof buf); assert(i == sizeof buf); buf[OFF + 2 * c] = 0; buf[OFF + 1 + 2 * c] = 0; } exit (0); }
      
      







 /* proof of concept reception code */ #include <assert.h> #include <stdio.h> static int sample(FILE *f, const char *p) { short l, r; int i, s; i = fread(&l, sizeof l, 1, stdin); assert(i == 1); i = fread(&r, sizeof l, 1, stdin); assert(i == 1); s = l; s -= r; if (0 && p != NULL) printf("%6d %s\n", s, p); return (s); } static void find_neg_peak(FILE *f) { int s, sl; while (1) { s = sample(stdin, "v"); if (s < -10000) break; } sl = s; while (1) { s = sample(stdin, "N"); if (s > sl) return; sl = s; } } static int find_pos_peak(FILE *f) { int s, sl, k; k = 0; while (1) { k++; s = sample(stdin, "^"); if (s > 10000) break; } sl = s; while (1) { k++; s = sample(stdin, "P"); if (s < sl) return (k); sl = s; } } int main(int argc __unused, char **argv) { short l, r; int i, k, p, s, sl; k = 0; p = 0; while (1) { find_neg_peak(stdin); k = find_pos_peak(stdin); if (k == 10) printf("\\n\n"); else if (k >= ' ' && k <= '~') printf("%c", k); else printf("\\x%02x", k); } exit (0); }
      
      








All Articles