큐는 이전 기사에서 소개되었습니다. 메일박스보다 단순 메시지 태스크 간 전달에 더 유연한 수단을 제공합니다.
큐 사용하기
Nucleus SE에서 큐는 빌드 타임에 구성됩니다. 애플리케이션당 최대 16개 큐 정의 가능. 큐 구성하지 않으면 RTOS가 모든 큐 관련 데이터 구조와 API 코드 생략해 바이너리 경량화.
큐는 단순히 저장 슬롯 배열로, 각 슬롯은 단일 ADDR 데이터 항목을 담을 수 있을 만큼 큽니다. 접근은 동기화되어 여러 태스크가 안전하게 인큐/디큐 가능. 태스크는 모든 슬롯이 찰 때까지 큐에 쓰고, 선입선출(FIFO) 순서로 읽습니다. 꽉 찬 큐에 보내기나 빈 큐에서 읽기 시도는 API 옵션과 Nucleus SE 구성에 따라 에러 또는 태스크 일시 중단 발생.
큐 vs 파이프
Nucleus SE는 파이프도 지원하며, 주로 메시지 크기에서 차이. 큐가 단일 ADDR(일반적으로 포인터) 전송인 반면, 파이프는 가변 길이 바이트 블록 전송; 블록 크기는 구성 시 고정. 파이프는 향후 기사에서 심층 다룰 예정.
큐 구성
큐 개수
큐 구성은 nuse_config.h의 #define 문으로 제어. 핵심 설정은 NUSE_QUEUE_NUMBER로 큐 활성화 개수 결정. 기본값 0(큐 없음). 0~16 사이 값 설정 가능; 범위 초과 시 nuse_config_check.h가 컴파일 타임 #error 발생.
NUSE_QUEUE_NUMBER를 0이 아닌 값으로 설정하면 큐 서브시스템 활성화, 필요 데이터 구조 할당, 연관 API 콜 활성화.
기본적으로 모두 FALSE로 해당 서비스 콜 비활성화. 특정 API 사용 위해 심볼 TRUE 설정. 큐 구성 없이 API 인에이블 시(NUSE_Queue_Count()는 항상 허용) 컴파일 타임 에러. 코드에서 비활성화된 API 호출 시 구현 생략으로 링크 타임 에러.
#define NUSE_QUEUE_NUMBER 0 /* 시스템 내 큐 수 – 0‑16 */ /* 서비스 콜 인에이블러 */ #define NUSE_QUEUE_SEND FALSE #define NUSE_QUEUE_RECEIVE FALSE #define NUSE_QUEUE_JAM FALSE #define NUSE_QUEUE_RESET FALSE #define NUSE_QUEUE_INFORMATION FALSE #define NUSE_QUEUE_COUNT FALSE
큐 서비스 콜
Nucleus RTOS는 10개 큐 관련 서비스 콜 제공, 그중 6개 Nucleus SE 구현. 기능:
메시지 보내기 – NUSE_Queue_Send()
메시지 받기 – NUSE_Queue_Receive()
메시지를 앞쪽에 넣기(잼) – NUSE_Queue_Jam()
큐 리셋 – NUSE_Queue_Reset()
큐 정보 조회 – NUSE_Queue_Information()
구성된 큐 수 얻기 – NUSE_Queue_Count()
나머지 콜(생성, 삭제, 열거, 브로드캐스트) Nucleus SE 미제공.
각 API 구현은 다음 섹션에서 자세히 다룹니다.
쓰기 및 읽기 서비스
큐 핵심 연산은 쓰기(보내기)와 읽기(받기). 큐 앞쪽에 쓰기는 잼이라 부름. Nucleus RTOS와 Nucleus SE 각각 이 액션용 3개 기본 API 콜 노출.
큐에 쓰기
RTOS API NU_Send_To_Queue()는 큐 꽉 차면 무기한 일시 중단 또는 타임아웃 허용로 유연. Nucleus SE는 동일 함수 제공하지만 일시 중단은 선택 사항, 타임아웃 미지원. RTOS는 브로드캐스트 연산도 지원하나 SE 미제공.
RTOS API: NU_Send_To_Queue()
프로토타입:
STATUS NU_Send_To_Queue(NU_QUEUE *queue, VOID *message, UNSIGNED size, UNSIGNED suspend);
매개변수:
queue – 사용자 제공 큐 컨트롤 블록 포인터
message – 보낼 데이터 포인터
size – UNSIGNED 요소 수; 큐 메시지 크기와 일치해야 함
suspend – NU_NO_SUSPEND, NU_SUSPEND, 또는 타임아웃 값
반환 코드: NU_SUCCESS, NU_QUEUE_FULL, NU_TIMEOUT, 유효하지 않은 포인터나 큐 상태 에러 코드 등.
SE API: NUSE_Queue_Send()
프로토타입:
STATUS NUSE_Queue_Send(NUSE_QUEUE queue, ADDR *message, U8 suspend);
매개변수:
queue – 큐 인덱스(ID)
message – 인큐할 ADDR 값 포인터
suspend – NUSE_NO_SUSPEND 또는 NUSE_SUSPEND
반환 값은 RTOS 함수 반영하나 SE 제한적 블로킹 동작 반영.
구현 개요
블로킹 비활성화 시 루틴은 공간 확인 후 값 쓰거나 NUSE_QUEUE_FULL 반환. 블로킹 활성화 시 함수 루프 돌며 큐 꽉 차면 공간 생기거나 리셋될 때까지 태스크 일시 중단. 구현은 NUSE_Queue_Blocking_Count로 블로킹된 태스크 추적, NUSE_Task_Blocking_Return으로 슬롯 열리면 재개.