ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • mutex freeRTOS with STM32
    Share/STM32 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

     

     

    댓글

실험중인 삶, Life is not a race