mutex freeRTOS with STM32
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