[FreeRTOS] 임계영역과 상호배제

seopppio·2024년 11월 1일

FreeRTOS

목록 보기
3/14

어떤 함수를 동시에 여러 테스크에서 부른다면? (레지스터를 동시에 접근)
"동시성 문제가 발생할 수 있다."

이러한 현상은 공유자원이 있고, 비원자적인 연산일 때

  • 비원자적인 연산은 어셈블리코드로 보았을 때, x = x+1에서 일어날 수 있다
    x값을 메모리에서 읽어오고
    메모리에 1을 더하고
    그 값을 다시 메모리에 적는데 이 과정에서 누가 x를 수정하면 값이 이상해질 수 있다

임계 영역

공유 자원을 사용중인 함수내의 일부 혹은 전체 영역
임계 영역 보호 방법
1. 인터럽트 중단(틱 인터럽트를 발생하지 않아 문맥전환이 일어나지 않는다)
2. 스케줄링 중단
3. 세마포어

재진입

멀티태스킹 환경에서 다수 태스크에서 호출하여 사용할 수 있는 해당 함수는 재 진입 가능하도록 작성 되어야 한다. 단일 태스크가 독점하여 사용할 것으로 확신되는 경우는 재진입 안 해도 됨

  • 재진입 함수가 아닌 경우(공유하고 있는 자원이 있는 경우)

  • 재진입 함수(전역 변수를 없애버린다)

    전역변수를 꼭 서야하면,

  1. 세마포어같은 커널 리소스로 전역 변수 보호
  2. 전역 변수 사용 동안 인터럽트 사용 중지

SYSTICK(타이머 인터럽트)의 의미, 인터럽트 중단

SYSTICK은 인터럽트를 시스템에서 계속 작동 시키는 것이다
이 이유는 문맥전환을 할 수 있는 기회, 즉 선점을 할 수 있는 기회를 지속해서 제공해주기 위함
(ex. Hz가 1000이면 1초에 1000번 Tick이 발생하는데, 1초에 1000번 문맥전환이 가능한 기회를 주기 위함이라고 해석해도 된다)

얘를 비활성화하면, 선점도 하지 않고 문맥전환도 일어나지 않으며 바로 멀티태스킹이 일어나지 않는다는 것이다

taskENTER_CRITICAL(), taskEXIT_CRITICAL()로 인터럽트 중지 및 활성화
저 사이 크리티컬 섹션 시간이 길면 안 좋다

!!! ENTER가 인터럽트 중지 상태로 진입이다, EXIT가 인터럽트 중지 상태 퇴장이다

이런식으로 전역변수(공유자원) 위 아래로 인터럽트 중지 및 활성화 걸어둔다 -> 문맥전환 안 일어나게 원천 차단

하지만 이런 방식은, 하드 리얼 타임을 적용하는데 결격 사유가 있다
이러한 인터럽트 중단 순간이 존재하니까, 선점을 꼭 해야하는 순간에 선점이 안 일어난다 -> 하드리얼타임이 아니다

스케줄러 중단

FreeRTOS에서 지원 X

세마포어

가장 안전한 방법

  • 세마포어, 뮤택스 커널 서비스를 이용
    but 오버헤드 발생(부차적인 시간이 많이 발생)

이상적인 방법. 공유 자원을 아예 만들지 않고, 각 테스크가 공유 자원을 독점하도록 만든다

ex LCD 태스크와 LCD H/W가 있다면, 어떤 태스크에서만 LCD 하드웨어를 사용하도록 만들자. 그리고 다른 함수를 통해서 LCD H/W를 접근하지 못하게 하면 된다.

FreeRTOS 우선순위

0개의 댓글