아두이노 freeRTOS 튜토리얼 15Arduino FreeRTOS2015. 1. 16. 20:51
Table of Contents
반응형
공유자원인 시리얼을 두 개의 태스크가 동시에 기록하면 아래처럼 첫번째 태스크에서 다 기록하기 전에 두번째 태스크가 선점하여 문자열을 출력하는 원치 않은 결과를 얻을 수 있다.
이를 방지하기 위해서 뮤텍스 타입의 세마포어를 사용하여 시리얼을 사용 중일 때에는 다른 태스크가 시리얼에 접근 할 수 없도록 막는다.
정상적으로 수행되는 경우의 결과…
- /* FreeRTOS.org includes. */
- #include "FreeRTOS_AVR.h"
- //#include "task.h"
- //#include "semphr.h"
- /* Compiler includes. */
- //#include <stdlib.h>
- //#include <stdio.h>
- //화면에 문자열을 출력하는 태스크를 위한 함수
- static void prvPrintTask( void *pvParameters );
- //뮤텍스 타입 세마포어를 이용하여 공유자원인 시리얼을 동시에 사용하지 못하도록한 새로운
- //문자열 출력함수
- static void prvNewPrintString( const char *pcString );
- /*-----------------------------------------------------------*/
- //SemaphoreHandle_t 타입의 변수를 여기에서는 뮤텍스 타입의 세마포어를 위해 사용된다.
- //공유자원인 시리얼로의 출력을 동시에 사용하지 않기 위해서 사용됨(상호배제 mutual exclusive)
- //예를 들어 첫번째 문자열 출력도중에 두번째 문자열을 출력하게 되는 상황이 안벌어지게 한다.
- SemaphoreHandle_t xMutex;
- void setup( void )
- {
- Serial.begin(9600);
- //뮤텍스 타입의 세마포어를 생성한다.
- xMutex = xSemaphoreCreateMutex();
- //난수를 발생시키기 위한 시드값
- //태스크가 랜덤한 시간동안 블록되게 만들때 사용할 rand함수를 사용 하위한 작업
- srand( 567 );
- if( xMutex != NULL ) //뮤텍스타입의 세마포어가 정상적으로 생성되었다면
- {
- //두 개의 문자열을 출력하는 태스크를 생성한다.
- //우선순위를 다르게 했기 때문에 하나의 태스크를 수행중 다른 태스크가 실행될수 있게 했다.
- xTaskCreate( prvPrintTask, "Print1", 200, (void*)"Task 1 ******************************************\r\n", 1, NULL );
- xTaskCreate( prvPrintTask, "Print2", 200, (void*)"Task 2 ------------------------------------------\r\n", 2, NULL );
- //스케줄러를 시작한다.
- vTaskStartScheduler();
- }
- //여기에 도달하면 아마도 메모리 부족
- for( ;; );
- // return 0;
- }
- /*-----------------------------------------------------------*/
- static void prvNewPrintString( const char *pcString )
- {
- //뮤텍스 타입 세마포어를 무한 시간동안 기다리게 된다.
- //얻지 못하면 블록상태가 되버림.얻을때에만 블록이 풀리기 떄문에 리턴값을 체크할 필요가 없음.
- xSemaphoreTake( xMutex, portMAX_DELAY );
- {
- /* The following line will only execute once the semaphore has been
- successfully obtained - so standard out can be accessed freely. */
- //printf( "%s", pcString );
- //fflush( stdout );
- Serial.print(pcString);
- Serial.flush(); //시리얼 포트에 있는 데이터가 다 기록될때 까지 대기한다.(아두이노 1.0 이전 버전에선 삭제했음)
- }
- xSemaphoreGive( xMutex );
- if( Serial.available() ) //버퍼가 비어있지 않다면 True를 반환한다.
- {
- //커널 틱을 정지시키고 모든 생성된 태스크들을 삭제한다
- //시리얼 포트에 있는 데이터가 다 기록될때 까지 위에서 기다렸는데도 버퍼가 꽉차있다는 것은
- //먼가 문제가 있는 것이므로 스케줄러를 다시 시작하는 것으로 보인다.
- vTaskEndScheduler();
- }
- }
- /*-----------------------------------------------------------*/
- static void prvPrintTask( void *pvParameters )
- {
- //파라메터로 받은 문자열을
- char *pcStringToPrint;
- pcStringToPrint = ( char * ) pvParameters;
- for( ;; )
- {
- //시리얼로 문자열을 출력하기 위해 새로 만든 함수를 이용한다.
- prvNewPrintString( pcStringToPrint );
- //rand로 생성한 임의의 시간동안 대기한다.
- //여기에서 critical section없이 사용하려면 rand함수가 reentrant해야 한다.
- //여러 쓰레드에서 코드를 동시에 수행하더라도 실행결과가 정확함을 보장한다는 것이다.
- vTaskDelay( ( rand() & 0x1FF ) );
- }
- }
- //------------------------------------------------------------------------------
- void loop() {}
반응형
'Arduino FreeRTOS' 카테고리의 다른 글
아두이노 freeRTOS 튜토리얼 17 - LED깜빡이게 하기 (0) | 2015.01.17 |
---|---|
아두이노 freeRTOS 튜토리얼 16 (0) | 2015.01.16 |
아두이노 freeRTOS 튜토리얼 14 (0) | 2015.01.16 |
아두이노 freeRTOS 튜토리얼 13 (0) | 2015.01.16 |
아두이노 freeRTOS 튜토리얼 12 (0) | 2015.01.16 |
시간날때마다 틈틈이 이것저것 해보며 블로그에 글을 남깁니다.
블로그의 문서는 종종 최신 버전으로 업데이트됩니다.
여유 시간이 날때 진행하는 거라 언제 진행될지는 알 수 없습니다.
영화,책, 생각등을 올리는 블로그도 운영하고 있습니다.
https://freewriting2024.tistory.com
제가 쓴 책도 한번 검토해보세요 ^^
@webnautes :: 멈춤보단 천천히라도
그렇게 천천히 걸으면서도 그렇게 빨리 앞으로 나갈 수 있다는 건.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!