Share/STM32

mutex freeRTOS with STM32

Jimmy.B 2020. 10. 12. 19:55

 

 

 

mutex 개념 및 필요성 

실전으로 먼저가보자 

 

- stm32F7 

- cubeMX/cubeIDE 

- FreeRTOS 10.2.0 

실험환경

1. task2개 구성 

2. shared Memory 하나로 문자열을 읽고 print out 했을때, 섞이거나 혼선없이 출력하는지 확인 

 

Tip) 표준출력 변경 --> printf 사용 

 

소스코드 

 

1. task 생성

 

/* USER CODE BEGIN 2 */

   xTaskCreate(myTask1, "task1", 200, (void*) 0, tskIDLE_PRIORITY, &myTask1Handle);
   xTaskCreate(myTask2, "task2", 200, (void*) 0, tskIDLE_PRIORITY, &myTask2Handle);
   

 

 

2. task 함수 구현  

 

void myTask1(void *p){
	char Task1Msg[]="pomatoes";

	while(1){

		int i;
		for(i=0;i<9;i++){
			mySharedResource[i] = Task1Msg[i];
			vTaskDelay(50);
		}
		mySharedResource[i] =0 ;

		//HAL_UART_Transmit(huart3, mySharedResource, 10, 2000);

		printf("T1 : %s\r\n", mySharedResource);
	}
}

void myTask2(void *p){
	char Task2Msg[]="tomatoes";

	while(1){

		int i;
		for(i=0;i<9;i++){
			mySharedResource[i] = Task2Msg[i];
			vTaskDelay(50);
		}
		mySharedResource[i] =0 ;

		printf("T2 : %s\r\n", mySharedResource);
	}
}

 

3. PV(private variable) 선언

TaskHandle_t myTask1Handle = NULL;
TaskHandle_t myTask2Handle = NULL;

 

 

 

구현결과 

 

분석 

태스크 코드를 보면, 논리적으로는 T1에는 pomatoes 가 , T2에는 tomatoes 가 출력되어야 될 것 같지만,

실제로는 반대로 되는 현상을 보인다.

 

이유는 task1 이 다 완료되어 sharedMemory를 출력하는 그 시간에 이미 task2에 남아있는 sharedMemory를 출력 해버리는 현상. 

 

즉, task1이 완전히 끝나서 데이터를 저장하고 불러올때까지 다른 task가 잠깐 멈추어 주었으면... 

하는 아이디어에서 적용 

 


문제해결  

 

void myTask1(void *p){
	char Task1Msg[]="pomatoes";

	while(1){

		if(xSemaphoreTake(xMutex, (TickType_t) 0xFFFFFFFF )==1 )
		{
			int i;
			for(i=0;i<9;i++){
				mySharedResource[i] = Task1Msg[i];
				vTaskDelay(50);
			}
			mySharedResource[i] =0 ;

			//HAL_UART_Transmit(huart3, mySharedResource, 10, 2000);

			printf("T1 : %s\r\n", mySharedResource);

			xSemaphoreGive(xMutex);

	 	}
		vTaskDelay(100);
	}
}

void myTask2(void *p){
	char Task2Msg[]="tomatoes";

	while(1){
		if(xSemaphoreTake(xMutex, (TickType_t) 0xFFFFFFFF ) == 1 )
		{
			int i;
			for(i=0;i<9;i++){
				mySharedResource[i] = Task2Msg[i];
				vTaskDelay(50);
			}
			mySharedResource[i] =0 ;

			printf("T2 : %s\r\n", mySharedResource);

			xSemaphoreGive(xMutex);
		}
		vTaskDelay(100);
	}
}

 

분석 

 

xSemaphoreTake : 세마포어를 획득하기 위한 매크로.

xSemaphoreGive :  획득한 세마포어를 놓아주기 위한 매크로. 

 

즉, 세마포어를 활용하여 take와 give를 task별로 번갈아 수행한다. 

추가로, 만약 vTaskDelay를 동일하게 해주지않으면 100초동안 다른 task가 끝날 수 가 없기때문에 한쪽 task만 수행하게된다. 

 

 

결과

 

 

 

참고자료  

 

www.youtube.com/watch?v=rqpbQlzgws0