센서 초기화와 통신 연결이 모두 끝난 뒤 작업을 시작해야 하는 경우, FreeRTOS 이벤트 그룹의 각 비트로 준비 상태를 표현할 수 있습니다. 이 글은 공식 커널 책의 이벤트 그룹 장과 event_groups.h API 주석을 기준으로 xEventGroupWaitBits()의 네 가지 결과를 구분합니다. 이전에 다룬 작업 알림의 누적 횟수와 달리, 이벤트 비트는 상태 플래그입니다. 같은 비트를 여러 번 세워도 횟수는 보존되지 않습니다.
1. 대기 조건과 반환값
예를 들어 비트 0을 SENSOR_READY, 비트 1을 LINK_READY로 두고 마스크 0x03을 기다립니다. xWaitForAllBits=pdTRUE이면 두 비트가 모두 필요하고, pdFALSE이면 하나만 있어도 조건이 충족됩니다. xClearOnExit=pdTRUE는 조건이 충족되어 반환할 때 기다린 마스크의 비트를 지웁니다. 반환값은 지우기 전의 비트 상태이므로 반환값을 먼저 검사하세요. 타임아웃이면 기다린 비트가 자동으로 지워지지 않습니다. 다른 비트는 지우지 않습니다.
| 현재 비트 | 대기 마스크 | 조건 | clear-on-exit | 즉시 반환값 | 반환 뒤 비트 |
|---|---|---|---|---|---|
0x03 |
0x03 |
ALL | 켬 | 0x03 |
0x00 |
0x01 |
0x03 |
ALL | 켬 | 0x01 (즉시 대기에서는 조건 미달) |
0x01 |
0x05 |
0x03 |
ANY | 켬 | 0x05 |
0x04 |
두 번째 행은 아래 PC 모델에서 대기 시간이 0인 상황입니다. 실제 API에서는 지정한 틱 동안 기다릴 수 있고, 그 사이에 다른 작업이 비트를 세우면 결과가 달라질 수 있습니다. xEventGroupWaitBits()의 반환값에 0x03이 모두 들어 있는지 검사해야 ALL 성공 여부를 판단할 수 있습니다. ANY는 (returned & mask) != 0으로 판단합니다.
2. FreeRTOS 작업에 적용하기
FreeRTOSConfig.h에서 configUSE_EVENT_GROUPS=1을 설정하고 커널의 event_groups.c를 빌드에 포함합니다. 이벤트 그룹 생성 결과가 유효한지 확인한 다음, 센서 초기화 작업에서 xEventGroupSetBits(group, SENSOR_READY), 연결 작업에서 xEventGroupSetBits(group, LINK_READY)를 호출합니다. 소비 작업은 아래처럼 두 준비 상태를 함께 기다립니다.
EventBits_t seen = xEventGroupWaitBits(group, SENSOR_READY | LINK_READY, pdFALSE, pdTRUE, pdMS_TO_TICKS(500));
이 코드는 준비 상태를 유지하려고 xClearOnExit=pdFALSE를 선택했습니다. (seen & (SENSOR_READY | LINK_READY)) == (SENSOR_READY | LINK_READY)가 거짓이면 타임아웃 또는 미완료로 처리하세요. 500 ms가 실제로 몇 틱인지 확인하고, 보드의 틱 해상도와 최악의 초기화 시간을 고려해 대기 시간을 정합니다. 준비 상태를 다음 사이클마다 새로 받아야 한다면 pdTRUE로 지우는 설계를 고려하되, 여러 작업이 같은 비트를 기다리는지 먼저 점검하세요.
ISR에서 비트를 세워야 한다면 xEventGroupSetBitsFromISR() 공식 설명을 따르세요. 이 함수는 비트 설정을 데몬 작업으로 이관하므로 즉시 반영된다고 가정하면 안 됩니다. ISR에서 이벤트 발생 횟수 또는 샘플마다의 데이터를 보존해야 한다면 큐나 카운팅 알림을 사용합니다.
3. PC에서 비트 규칙 검증하기
아래 코드는 FreeRTOS 커널과 스케줄러가 없는 단일 스레드 상태 모델입니다. 대기 시간 0인 경우의 조건 검사·지우기 규칙만 확인합니다. event_bits_model.c로 저장하고 gcc -std=c11 -Wall -Wextra -Werror event_bits_model.c -o event_bits_model로 빌드해 실행하세요.
예상 출력:
모델의 all unmet은 실제 대기 호출의 타임아웃 경로에 대응합니다. 마지막 줄은 동일 비트를 두 번 세워도 0x01이라는 점을 보여줍니다. 실기에서는 두 작업의 깨움 순서, ISR 데몬 작업 지연, 타임아웃 경계와 이벤트가 동시에 일어나는 경합을 별도 계측해야 합니다.
공식 근거: FreeRTOS 커널 책 9장, event_groups.h, xEventGroupSetBitsFromISR().
댓글
첫 댓글을 남겨 보세요.