Cơ chế tập hợp hàng đợi trong FreeRTOS

1. Tổng quan

Tập hợp hàng đợi (Queue set) trong FreeRTOS quản lý nhiều hàng đợi sử dụng một cơ chế đơn lẻ. Cơ chế này tương tự như các thẻ chọn đa năng trong hệ thống POSIX, cho phép tác vụ theo dõi nhiều hàng đợi đồng thời. Khi dữ liệu tới một hàng đợi, tập hợp sẽ trả lại định danh của hàng đợi khả dụng để thao tác.

2. Các giao diện công nghệ

2.1. Khởi tạo tập hợp

#if defined(configUSE_QUEUE_SETS) && defined(configSUPPORT_DYNAMIC_ALLOCATION)
QueueSetHandle_t initQueueCollection(UBaseType_t capacity) {
    QueueSetHandle_t collection = createGenericQueue(
        capacity, 
        sizeof(QueueHandle_t), 
        QUEUE_TYPE_COLLECTION
    );
    return collection;
}
#endif

Khởi tạo tập hợp chỉ yêu cầu chỉ định số lượng phần tử tối đa. Hàm sử dụng phương thức tạo hàng đợi tổng quát, chứa các định danh quản lý.

2.2. Đăng ký hàng đợi vào tập hợp

#if (configUSE_QUEUE_SETS == 1)
BaseType_t registerToCollection(
    QueueHandle target, 
    QueueSetHandle collection
) {
    BaseType_t status;
    CRITICAL_SECTION_ENTER();
    if (((Queue_t*)target)->parentCollection != NULL || 
        ((Queue_t*)target)->pendingCount != 0) {
        status = FAILURE;
    } else {
        ((Queue_t*)target)->parentCollection = collection;
        status = SUCCESS;
    }
    CRITICAL_SECTION_EXIT();
    return status;
}
#endif

Điều kiện đăng ký: hàng đợi không thuộc tập hợp nào khác và không chứa dữ liệu đang chờ. Thao tác này cập nhật con trỏ quản lý tập hợp của hàng đợi.

2.3. Hủy đăng ký khỏi tập hợp

#if (configUSE_QUEUE_SETS == 1)
BaseType_t unregisterFromCollection(
    QueueHandle target,
    QueueSetHandle collection
) {
    Queue_t* const pTarget = (Queue_t*)target;
    BaseType_t status;

    if (pTarget->parentCollection != collection) {
        status = FAILURE;
    } else if (pTarget->pendingCount != 0) {
        status = FAILURE;
    } else {
        CRITICAL_SECTION_ENTER();
        pTarget->parentCollection = NULL;
        CRITICAL_SECTION_EXIT();
        status = SUCCESS;
    }
    return status;
}
#endif

Hàng đợi chỉ được hủy đăng ký khi trống dữ liệu. Thao tác này đặt lại con trỏ quản lý tập hợp về giá trị rỗng.

2.4. Chờ nhận dữ liệu

#if (configUSE_QUEUE_SETS == 1)
QueueSetMemberHandle findAvailableMember(
    QueueSetHandle collection, 
    TickType_t timeout
) {
    QueueSetMemberHandle activeMember = NULL;
    (void) receiveFromQueue(
        (QueueHandle_t)collection, 
        &activeMember, 
        timeout, 
        false
    );
    return activeMember;
}
#endif

Khi dữ liệu được gửi tới hàng đợi, hệ thống tự động đăng ký hàng đợi con vào tập hợp cha. Có hai phiên bản hàm cho ngữ cảnh tác vụ và ngắt.

2.5. Thông báo khả dụng

#if (configUSE_QUEUE_SETS == 1)
static BaseType_t notifyParentCollection(
    const Queue_t* const pSource, 
    const BaseType_t position
) {
    Queue_t* parent = pSource->parentCollection;
    BaseType_t notificationStatus = false;

    assert(parent != NULL);
    if (parent->pendingCount < parent->capacity) {
        const int8_t lockState = parent->sendLockState;
        notificationStatus = pushQueueItem(parent, &pSource, position);

        if (lockState == UNLOCKED) {
            if (!isTaskListEmpty(&parent->receivingTaskList)) {
                if (wakeHighestPriorityTask(&parent->receivingTaskList)) {
                    notificationStatus = true;
                }
            }
        } else {
            parent->sendLockState = lockState + 1;
        }
    }
    return notificationStatus;
}
#endif

Thông báo bằng cách đưa định danh hàng đợi con vào tập hợp cha. Trạng thái khóa kiểm soát việc thông báo sự kiện và các tác vụ chờ.

Thẻ: FreeRTOS Queue-Set RTOS-Queues Task-Synchronization

Đăng vào ngày 24 tháng 8 lúc 14:22