質問

現在、Friendlyarm Linux 2.6.32.2 (mini2440) 用の GPIO カーネル モジュールを開発しています。私はエレクトロニクスの出身ですが、Linux は初めてです。

起動時にロードされるカーネル モジュールと関連デバイス ファイルは次の場所にあります。 /dev として gpiofreq.

デバイス ファイルに初めて書き込むとき、GPIO ピンは 50kHz で連続的に切り替わります。2 回目の書き込みではトグルが停止します。3 回目では再び開始され、以下同様に続きます。

周波数を生成するために別のカーネルモジュールを作成しました。ただし、最初にデバイスファイルを書き込んだ後、CPUがフリーズします。ターミナルプロンプトは表示されますが、その後コマンドを実行できません。

コードの抜粋は次のとおりです。

//calling function which generates continuous freq at gpio

static int send_freq(void *arg)
{
    set_current_state(TASK_INTERRUPTIBLE);
    for(;;)
    {
        gpio_set_value(192,1);
        udelay(10);
        gpio_set_value(192,0);
        udelay(10);
    }
    return 0;
}

以下は、デバイスファイルに書き込まれたデータから起動または停止するデバイス書き込みコードです。

if(toggle==0)
{
       printk("Starting Freq.\n");
       task=kthread_run(&send_freq,(void *)freq,"START");
       toggle=1;
}
else
{
       printk("Operation Terminated.\n");
       i = kthread_stop(task);
       toggle=0;
}
役に立ちましたか?

解決

カーネルスレッドで無限のループを行っていますが、IRQや他のカーネルスレッドを除いて、他に何も発生する余地はありません。

あなたができることはどちらかです

  • ハードウェアにタイマーをプログラムし、割​​り込みでピンを切り替えます。

  • ulay を usleep_range に置き換えます

段階的に実行し、usleep_range を使用して kHz 範囲で開始し、最終的にはカスタム タイマー + ISR に移行することをお勧めします。

どちらの場合でも、おそらく多くのジッターが発生するでしょう。このような gpio 切り替えを DSP または PIC で行うことは良いアイデアかもしれませんが、pwm 対応 gpio でハードウェア支援されていない限り、ARM + Linux ではリソースの無駄になります。エンジン。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top