임베디드/임베디드 레시피

ATOMIC

twoweeks-within 2025. 1. 7. 15:02

int curr_temp[2];

//  전역변수로 배열 선언하면

// 함수 내부에서 각 요소 값을 지정해주더라도

// 값들이 사라지지 않음
 
void read_temperature_isr(void)
{
      curr_temp [0] = read_temp_door();  /* 문가의 온도계를 읽어 옴 */
      curr_temp [1] = read_temp_indoor();  /* 실내의 온도계를 읽어 옴 */
}

 

온도차가 크면 수리공에게 전화하는 시스템

 

void waiter_task()
{
     int temp_door;
     int temp_indoor;
    
     waiter_task_init();   
                                   
     while (1)
     {
            temp_door = curr_temp [0];  /* ISR의 Data */
            temp_indoor = curr_temp [1];  /* ISR의 Data */
 
            if (temp_door != temp_indoor)
               {
                     call_repair();  /* 수리공에게 전화를! */
                }
      } /* while (1) */
}

 

if)

            temp_door = curr_temp [0];
            → 요기에서 curr_temerature_isr()이 발생! 한다면?
            temp_indoor = curr_temp [1];

 

평소) [0], [1] 이 30도로 저장되어있고 외부온도가 31도로 바뀌더라도 괜찮음

but isr발생) isr에 의해 31도로바뀐게 [1]에 값 변경이됨 >> 문제가 없는데도 call_repair()

> 공유데이터문제

  > isr 과 일반 code가 data 공유할때 발생

>>

Interrupt_Lock() , isLcok =1 , =0 과 같은걸로 보호해줌

 >> Atomic 영역 // critical section 

 

ex)

RTOS : Kernel Service 로 task 끼리 발생하는 문제 해결

   > semaphore, Mutex 사용

// Mutex : semaphore 의 변종

Semaphore : 철로가 하나있는 구간 , 여러개의 기차가 공유

    > 신호를 켰다 컸다 하며 기차가 지나가게함

 

 

void read_temperature_task(void)
{
     while (1)
     {
         task_sleep (1000);      /* 1초에 한번 씩 다시 자기 자신을 호출해서 실행 함 */    
            ObtainSemaphore();
           curr_temp [0] = read_temp_door();  /* 문가의 온도계를 읽어 옴 */
           curr_temp [1] = read_temp_indoor();  /* 실내의 온도계를 읽어 옴 */
            ReleaseSemaphore();
     }
}
 
 
void waiter_task(void)
{
     int temp_door;
     int temp_indoor;
    
     waiter_task_init();   
                                   
     while (1)
     {
         task_sleep (1500); /* 1.5초에 한번씩 다시 자기 자신을 호출해서 실행 함 */
            ObtainSemaphore();
            temp_door = curr_temp [0];
            temp_indoor = curr_temp [1];
            ReleaseSemaphore();
 
            if (temp_door != temp_indoor)
               {
                     call_repair();  /* 수리공에게 전화를! */
                }
      } /* while (1) */
}

>>

task_sleep (ms) > 그 시간만큼 task 를 잠시 쉬게해줌

쉬는중에

다른 task 에서 ObtainSemaphore() 가 불린다면..

그 task 가 ReleaseSemaphore();  될때까지 기다림

 

 

SpinLock : 여러개의 CPU> 여러개의 kernel로 한개의 Resource에 접근할때

   > 한개의 CPU가 resource를 spinlock > 다른 cpu는 삥삥돌면서 기다림

 

'임베디드 > 임베디드 레시피' 카테고리의 다른 글

Queue , Inter Task Communication  (0) 2025.01.10
Interrupt, Polling  (0) 2025.01.10
Clock Tick ISR  (0) 2025.01.07
선점형 kernel  (0) 2025.01.07
ISR구현  (0) 2025.01.07