2

割り込みにより、スケジューラがコンテキストを RTOS の特定のタスクに切り替えることができるかどうかを知りたいです。私はmicroCOS OSで作業しています

これは、キースキャンを実行して文字をメールボックスに投稿するタスクです。デバウンスや自動リピートなどの機能をこのコードに追加する必要がありますが、適切に機能させるにはトリガー メカニズムを整理する必要があります。

これを達成するためにポーリングまたは割り込みを使用する方法がわかりません

        static  void  AppTaskKeyscan (void *p_arg)
    {
        CPU_INT08U debouncing = 1;
        CPU_INT16U key;
        key_t button={0,0,0};

        (void)p_arg;

         while (DEF_TRUE) 
         {
            static CPU_INT08U pattern;
            key=P10;

            OSTimeDlyHMSM(0, 0, 0, 50);
            P10=0x0E;
            if ((pattern=P10)==0xee)
                {button.data='1', button.live=1;}       
            else if (pattern==0xde)
                {button.data='4', button.live=1;}
            else if (pattern==0xbe)
                {button.data='7', button.live=1;}
            else if (pattern==0x7e)
                {button.data='*', button.live=1;}
            else
            {
                P10=0x0d;
                if ((pattern=P10)==0xed)
                    {button.data='2', button.live=1;}
                else if (pattern==0xdd)
                    {button.data='5', button.live=1;}
                else if (pattern==0xbd)
                    {button.data='8', button.live=1;}
                else if (pattern==0x7d)
                    {button.data='0', button.live=1;}
                else
                {
                    P10=0x0b;
                    if ((pattern=P10)==0xeb)
                        {button.data='3', button.live=1;}
                    else if (pattern==0xdb)
                        {button.data='6', button.live=1;}
                    else if (pattern==0xbb)
                        {button.data='9', button.live=1;}
                    else if (pattern==0x7b)
                        {button.data='#', button.live=1;}
                    else
                    {
                        P10=0x07;
                        if ((pattern=P10)==0xe7)
                            {button.data='A', button.live=1;}
                        else if (pattern==0xd7)
                            {button.data='B', button.live=1;}
                        else if (pattern==0xb7)
                            {button.data='C', button.live=1;}
                        else if (pattern==0x77)
                            {button.data='D', button.live=1;}
                        else
                            button.live=0;
                    }
                }
            }

            P10=pattern; 

            if (button.live==0)
                OSTimeDlyHMSM(0, 0, 0, 50);
            else
            {
                if (P10==pattern)
                OSTimeDlyHMSM(0, 0, 0, 50);
                else
                button.live=0;
            }

            P10=0x00;              
            if (button.live)        //if button live, set unread flag to 1 and start count down
            {
                button.unread=1;
            }

            if(button.unread&&button.data!='X')
            {
                key=button.data;
                OSMboxPost(KeyMbox, (void *) &key);
                button.live=0;
                button.unread=0;
            }

             OSTimeDlyHMSM(0, 0, 0, 200); 
         } // End of While
    }
4

3 に答える 3

2

これを行う典型的な方法は、セマフォでペンディングするループを持つキーボード処理タスクを持つことです。キーボード割り込みハンドラーがセマフォを送信すると、処理タスクが準備完了して実行されます。

于 2012-01-05T17:25:20.207 に答える
0

通常、スケジューラはこれを行います。プロセス/スレッドの優先度に基づいてコンテキストスイッチをいつ実行するかを知るのがその仕事です(スレッド/プロセス対応スケジューラが与えられた場合)

編集:

これが行われない理由

侵入者が優先度の低いタスクを生成し、CPU に (たとえば優先度の高いタスクから) コンテキスト スイッチを強制して、悪意のあるペイロードを実行させることを想像してみてください。

于 2012-01-05T16:59:18.300 に答える
0

利用可能な割り込み互換 (つまり、非ブロッキング) IPC メカニズムを使用して、タスクにシグナルを送る必要があります。キーボードを保守する最も簡単な方法は、ISR がキー コードをキューに入れることです。ユーザー入力が必要なタスクは、このキューから読み取ります。

あるいは、単に ISR にカウント セマフォをインクリメントさせ、キーボード デコードをタスクに延期させることもできます。これにより、ユーザー入力を読み取る任意のタスクによって読み取られるキューに文字が配置される可能性があります。これは、デコードが長い場合や実行時間が変動する場合に適しています。

特に uC/OS-II では、スケジューラの実行を必要とする ISR は、OSIntEnter() および OSIntExit() 呼び出しを使用する必要があります。最後のネストされた割り込みが完了したときにスケジューラを実行させるのは、OSIntExit() です。その後、スケジュール ポリシーに従ってタスクがスケジュールされます。スケジューリング ポリシーに対して特定のタスクを強制的に実行するために、ポリシーを回避することはできません。特定のタスクを実行する必要がある場合は、それを最高の優先度にします。

通常、ISR プロローグ/エピローグ関数は、OS 呼び出しを行う ISR にのみ必要です。これは、OS 呼び出しを行わない ISR ではスケジューラを実行する必要がないためです。

于 2012-01-07T21:08:35.877 に答える