6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SPRESENSEでセマフォを使ってみる

Posted at

前回は、Spresenseで2つのスレッドでそれぞれLEDの点滅を行いました。

今回はセマフォを使ってみました。
セマフォとは、ある資源(今回の例ではcountという変数)を複数のスレッドで使用している時に、同時にアクセスされないよう排他制御する仕組みです。
詳細はこの記事の説明がわかりやすいので、そちらをご参照ください。

イベントフラグ、セマフォ|RTOS編

準備

前回作成したtestプロジェクトに、新たにアプリを追加します。

$ tools/mkcmd.py -d test semaphore_test "My Semaphore test" # アプリ作成
$ make clean
$ tools/config.py -m # My Semaphore testにチェックを入れる
$ make

セマフォを使ってみる

今回は、

  • スレッドA: 200 ms周期でLED1を点滅
  • スレッドB: 3秒おきに、LED1を1秒間点灯
    とします。
    どちらのスレッドでもLED1を使用しているので、セマフォを使って排他制御する必要があります。
semaphore_test.c

#include <sdk/config.h>
#include <stdio.h>
#include <semaphore.h>
#include <arch/board/board.h>
#include <arch/chip/pin.h>

#define PIN_LED0  PIN_I2S1_BCK
#define PIN_LED1  PIN_I2S1_LRCK
#define PIN_LED2  PIN_I2S1_DATA_IN
#define PIN_LED3  PIN_I2S1_DATA_OUT

const int led_pin[4] = {
  PIN_LED0,
  PIN_LED1,
  PIN_LED2,
  PIN_LED3
};

sem_t sem;

void toggle_led(uint32_t pin){
  board_gpio_write(pin, board_gpio_read(pin) == 0 ? 1 : 0);
}


void* task_A(void *arg)
{
  while(1)
  { 
    // 200 ms周期でLED1を点滅
    sem_wait(&sem);
    toggle_led(led_pin[1]);
    sem_post(&sem);

    usleep(200*1000);
  }

  return NULL;
}


void* task_B(void *arg)
{
  while(1)
  {
    // 1秒間LED1を点灯
    sem_wait(&sem);   
    
    board_gpio_write(led_pin[1], 1);
    sleep(1);
    board_gpio_write(led_pin[1], 0);
    
    sem_post(&sem);
    
    // 2秒間待機
    sleep(2);

  }

  return NULL;
}




#ifdef CONFIG_BUILD_KERNEL
int main(int argc, FAR char *argv[])
#else
int semaphore_test_main(int argc, char *argv[])
#endif
{
  for(int i = 0; i < 4; i++){
    board_gpio_config(led_pin[i], 0, true, true, PIN_FLOAT); // GPIOの設定
  }

  sem_init(&sem, 0, 1);
  pthread_t thread_A, thread_B;
  
  pthread_create(&thread_A, NULL, task_A, NULL);
  pthread_create(&thread_B, NULL, task_B, NULL);

  pthread_join(thread_A, NULL);
  pthread_join(thread_B, NULL);
  
  sem_destroy(&sem);

  return 0;
}

結果

想定どおりの動きをしていることが確認できます。
試しに、task_A,task_B内のsem_wait,sem_postをコメントアウトすると、点滅し続けます。

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?