Spresense에서 NuttX의 pthreads를 사용하여 다중 루틴 학습 #2 ~ 정음 시스템을 통해 배타적 제어 프로그램의 실행 ~

15811 단어 spresensepthreadstech
이거 뭐야?
이어서저번 Spresense에서 pthreads 인터페이스를 사용하여 동작을 확인합니다.
이번 주제.
이번에는 정음 제어 프로그램의 실행을 사용합니다.
이번에 사용한 pthreads의 함수는 다음과 같다.
  • pthread_mutex_init: 음소거 초기화
  • pthread_mutex_lock: 음소거 록
  • pthread_mutex_unlock: 음소거 해제
  • pthread_mutex_destroy: 음소거 제거
  • 환경을 확인하다
    저번와 같습니다.
    테스트 코드 설명
    이번 테스트 코드는 GiitHub[1]입니다.
    디렉토리, 실행 파일 이름 pthread무텍스입니다.
    지난번 [대기 스레드 시작/종료]의 샘플 코드를 바탕으로 정음 제어를 추가했습니다.
    음소거 정의
    음소거를 정의합니다.
    pthread_mutex_main.c//해당 부분 추출 및 기재
    pthread_mutex_t using_blink_led;
    
    음소거 초기화
    정음 시스템을 이용하다mutex_init로 초기화합니다.
    pthread_mutex_main.cmain 함수//해당 부분 추출 및 기재
    int main(int argc, FAR char *argv[])
    {
    
      if (pthread_mutex_init(&using_blink_led, NULL) != 0) {
          printf("Error; pthread_mutex_init.\n");
          exit(1);
      }
      
    }
    
    음소거 록
    뮤직록은 pthread.mutex_lock입니다.
    무음 록은 pthread. -mutex_unlock입니다.
    pthread_mutex_lock 및 pthreadmutex_unlock으로 묶은 코드가 실행될 것이라고 가정하십시오.
    pthread_mutex_main.cmain 함수//해당 부분 추출 및 기재
    void* blink_led_mutex(void* arg) {
      uint32_t led_index = (uint32_t)arg;
      uint32_t switch_index = (uint32_t)arg;
      unsigned int sleep_sec = 1 + (uint32_t)arg; // sleepする秒数
      int led_value = 1;
    
      volatile int switch_status = board_gpio_read(aps_board_switch_pin_2[switch_index]);
    
      printf("start blink_led[%ld] thread ID = %d switch_status = %d.\n", led_index, pthread_self(), switch_status);
    
      while (switch_status == 1) {  // スイッチ押下されたらループから抜ける
        pthread_mutex_lock(&using_blink_led);
    
        board_gpio_write(aps_board_led_pin_2[led_index], led_value);
        sleep(sleep_sec);
        led_value ^= 1;
        switch_status = board_gpio_read(aps_board_switch_pin_2[switch_index]);
        printf("blink_led[%ld] thread ID = %d led_value = %d switch_status = %d.\n", led_index, pthread_self(), led_value, switch_status);
    
        pthread_mutex_unlock(&using_blink_led);
      }
    
      printf("end blink_led[%ld] thread ID = %d.\n", led_index, pthread_self());
    
      return (void*)led_index;
    }
    
    음소거 제거
    음소거 필요 없으면 pthread.mutex_destroy를 사용하여 제거합니다.
    pthread_mutex_main.cmain 함수//해당 부분 추출 및 기재
    int main(int argc, FAR char *argv[])
    {
    
    
      if (pthread_mutex_destroy(&using_blink_led) != 0) {
          printf("Error; pthread_mutex_destroy.\n");
          exit(1);
      }
    
      printf("Bye.\n");
    
      return 0;  
    }
    
    동작 확인 결과
    이번 프로그램은 지난번 [대기 라인의 시작과 끝]의 샘플 코드를 바탕으로 정음 제어를 추가했습니다.
    printf의 출력을 비교하여 정음 기반 프로그램이 배타 제어를 실행했는지 확인하십시오.
    이번 (정음판) 의 printf는 다음과 같다.
    nsh> pthread_mutex
    start blink_led[0] thread ID = 12 switch_status = 1.               
    start blink_led[1] thread ID = 13 switch_status = 1.               
    blink_led[0] thread ID = 12 led_value = 0 switch_status = 1.
    blink_led[1] thread ID = 13 led_value = 0 switch_status = 1.
    blink_led[0] thread ID = 12 led_value = 1 switch_status = 1.
    blink_led[1] thread ID = 13 led_value = 1 switch_status = 1.
    blink_led[0] thread ID = 12 led_value = 0 switch_status = 1.
    blink_led[1] thread ID = 13 led_value = 0 switch_status = 1.
    blink_led[0] thread ID = 12 led_value = 1 switch_status = 1.
    blink_led[1] thread ID = 13 led_value = 1 switch_status = 1.
    blink_led[0] thread ID = 12 led_value = 0 switch_status = 1.
    blink_led[1] thread ID = 13 led_value = 0 switch_status = 1.
    blink_led[0] thread ID = 12 led_value = 1 switch_status = 1.
    blink_led[1] thread ID = 13 led_value = 1 switch_status = 1.
    blink_led[0] thread ID = 12 led_value = 0 switch_status = 1.
    blink_led[1] thread ID = 13 led_value = 0 switch_status = 1.
    blink_led[0] thread ID = 12 led_value = 1 switch_status = 1.
    blink_led[1] thread ID = 13 led_value = 1 switch_status = 1.
    blink_led[0] thread ID = 12 led_value = 0 switch_status = 1.
    blink_led[1] thread ID = 13 led_value = 0 switch_status = 1.
    blink_led[0] thread ID = 12 led_value = 1 switch_status = 1.
    blink_led[1] thread ID = 13 led_value = 1 switch_status = 1.
    blink_led[0] thread ID = 12 led_value = 0 switch_status = 1.
    blink_led[1] thread ID = 13 led_value = 0 switch_status = 1.
    blink_led[0] thread ID = 12 led_value = 1 switch_status = 1.
    blink_led[1] thread ID = 13 led_value = 1 switch_status = 1.
    blink_led[0] thread ID = 12 led_value = 0 switch_status = 1.
    blink_led[1] thread ID = 13 led_value = 0 switch_status = 1.
    blink_led[0] thread ID = 12 led_value = 1 switch_status = 1.
    blink_led[1] thread ID = 13 led_value = 1 switch_status = 1.
    blink_led[0] thread ID = 12 led_value = 0 switch_status = 1.
    blink_led[1] thread ID = 13 led_value = 0 switch_status = 1.
    blink_led[0] thread ID = 12 led_value = 1 switch_status = 1.
    blink_led[1] thread ID = 13 led_value = 1 switch_status = 1.
    blink_led[0] thread ID = 12 led_value = 0 switch_status = 1.
    blink_led[1] thread ID = 13 led_value = 0 switch_status = 1.
    blink_led[0] thread ID = 12 led_value = 1 switch_status = 0.
    end blink_led[0] thread ID = 12.                                            
    exit thread[0] thread ID = 11 return value = 0                       
    blink_led[1] thread ID = 13 led_value = 1 switch_status = 1.
    blink_led[1] thread ID = 13 led_value = 0 switch_status = 0.
    end blink_led[1] thread ID = 13.                                            
    exit thread[1] thread ID = 11 return value = 1                       
    Bye.
    
    지난번(비정음판)의 printf는 다음과 같다.
    nsh> pthread_first_test_app
    start blink_led[0] thread ID = 9 switch_status = 1.
    start blink_led[1] thread ID = 10 switch_status = 1.
    blink_led[0] thread ID = 9 led_value = 0 switch_status = 1.
    blink_led[1] thread ID = 10 led_value = 0 switch_status = 1.
    blink_led[0] thread ID = 9 led_value = 1 switch_status = 1.
    blink_led[0] thread ID = 9 led_value = 0 switch_status = 1.
    blink_led[1] thread ID = 10 led_value = 1 switch_status = 1.
    blink_led[0] thread ID = 9 led_value = 1 switch_status = 1.
    blink_led[0] thread ID = 9 led_value = 0 switch_status = 1.
    blink_led[1] thread ID = 10 led_value = 0 switch_status = 1.
    blink_led[0] thread ID = 9 led_value = 1 switch_status = 1.
    blink_led[0] thread ID = 9 led_value = 0 switch_status = 1.
    blink_led[1] thread ID = 10 led_value = 1 switch_status = 1.
    end blink_led[0] thread ID = 9.
    exit thread[0] thread ID = 8 return value = 0
    blink_led[1] thread ID = 10 led_value = 1 switch_status = 1.
    blink_led[1] thread ID = 10 led_value = 0 switch_status = 1.
    blink_led[1] thread ID = 10 led_value = 1 switch_status = 1.
    blink_led[1] thread ID = 10 led_value = 0 switch_status = 1.
    blink_led[1] thread ID = 10 led_value = 1 switch_status = 1.
    blink_led[1] thread ID = 10 led_value = 0 switch_status = 1.
    blink_led[1] thread ID = 10 led_value = 1 switch_status = 1.
    blink_led[1] thread ID = 10 led_value = 0 switch_status = 1.
    blink_led[1] thread ID = 10 led_value = 1 switch_status = 1.
    blink_led[1] thread ID = 10 led_value = 0 switch_status = 0.
    end blink_led[1] thread ID = 10.
    exit thread[1] thread ID = 8 return value = 1
    Bye.
    
    스레드 0(blink led[0])은 1초 간격, 스레드 1(blink led[1])은 2초 간격으로 LED가 깜빡이는 작업이다.
    지난번과 이번 printf를 비교하면 다음과 같다.
  • 지난번에 라인 1의 printf 사이에서 두 라인 0의 printf를 확인할 수 있었다.
  • 이번에는 지난번 printf 출력 모드가 없고 라인 0 라인 1의 printf가 교체되어 출력됩니다.
  • 음소거 록과 잠금 해제 코드를 추가하면 루틴 0이 루틴 1의 2초 동안sleep에서 실행되지 않았음을 알 수 있습니다.
    단서 사이의 프로그램이 실행하는 배타 제어를 확인했다.
    동작 확인 방법
    저번와 같습니다.
    지난번과 프로그램 이름이 다릅니다.이번 프로그램 이름은 pthread입니다.무텍스입니다.
    이번 소감.
    Spresense에서 NuttX의 pthreads 음소거 동작을 확인할 수 있습니다.
    이번에도 지난번과 마찬가지로 호스트 PC의 pthreads 인터페이스에서 구현됐다.
    앞으로도 다선정 동시 처리를 배우고 실험하고 싶습니다.
    끝까지 읽어주셔서 감사합니다.
    각주
    GiitHub 링크 ↩︎

    좋은 웹페이지 즐겨찾기