2017-12-25 28 views
0

ボタンを押した後にブロックされたタスクに切り替えようとしています。基本的には、task_player1は、task_ctrlからセマフォを受け取るまで何もしません。私がセマフォを与える方法は、ボタンを押すことです。コードは怒鳴るです:FreeRTOS、Atmel Studio - バイナリセマフォを受信する前にタスクがブロックされていない

#define B1 PIO_PB26_IDX 

#define TASK_STACK_SIZE (2048/ sizeof(portSTACK_TYPE)) 

xTaskCreate(task_ctrl, (const signed char * const) "Control", TASK_STACK_SIZE, NULL, 1, NULL); 

xTaskCreate(task_player1, (const signed char * const) "Player1", TASK_STACK_SIZE, NULL, 1, NULL); 

void task_player1(void *pvParameters) 
{ 
    vSemaphoreCreateBinary(player1_signal); 

    while (1) 
    { 
     if(xSemaphoreTake(player1_signal, portMAX_DELAY) == pdTRUE) 
     { 
      printf("Semaphore taken\n"); 
      ioport_set_pin_level(L1, HIGH); 
     } 
    } 
} 

    void task_ctrl(void *pvParameters) 
{ 
    static signed portBASE_TYPE xHigherPriorityTaskWoken; 

    bool button1; 
    while (1) 
    { 
     xHigherPriorityTaskWoken = pdFALSE; 
     button1 = ioport_get_pin_level(B1); 
     printf("TASK_CTRL RUNNING...\n"); 
     ioport_set_pin_level(L1, LOW); 

     if (button1) 
     { 
      xSemaphoreGiveFromISR(player1_signal, &xHigherPriorityTaskWoken); 
      printf("Semaphore given\n"); 

      vTaskDelay(1); 
     } 
    } 
} 

問題は、それがportMAX_DELAYであるべきなtask_player1がブロックされることはありませんです。コードをマイクロチップにアップロードするとLEDが点灯し、ボタンを押してセマフォを入力するだけで点灯します。私はここで間違って何をしていますか?

Atmel Studioの制限により、私はFreeRTOS v7.3を使用しています。

編集:FreeRTOSで更新されたコード

+1

セマフォはどのように作成されましたか? – jwdonahue

+0

一般に、セマフォは共有リソースを保護するために使用され、フラグとしては使用されません。問題の説明に基づいて、関連するすべてのコードを表示していないようです。 [MCVE]を確認してください。 – jwdonahue

+0

なぜ、セマフォがtask_ctrl()で通知されたら、task_player1()で再度通知しますか? –

答えて

1

バイナリセマフォはすなわち、「与えられた」状態で作成されます。したがって、task_player1()がwhileループに入ると、セマフォをブロックすることなく、ピンをハイに設定します。セマフォを作成した直後にxSemaphoreTake()を呼び出してセマフォカウントを0に減らすことができます。

task_ctrl()はxSemaphoreGiveFromIsr()を使用してはいけません。

+0

これはうまくいくはずです、ありがとう!簡単な質問 - xSemaphoreHandle player1_signal = 1;同じことをする?現在、0に設定されています。 – Tisa

+0

player1_signalはセマフォハンドルですが、1に設定することはできません。vSemaphoreCreateBinaryの呼び出し後、player1_signalのxSemaphoreTakeへの呼び出しを追加するだけです。次に、ISRバージョンの関数を呼び出さないように制御タスクを修正します。 – stathisv

+0

ええ、それは働いて、私はISR機能を修正しました。再度、感謝します! – Tisa

関連する問題