提问人:Gambanishu Habbeba 提问时间:11/17/2023 更新时间:11/17/2023 访问量:11
Zephyr 消息队列,带或不带信号量 + 奖励产生问题
Zephyr message queue with or without semaphore + bonus yielding question
问:
请考虑以下方案:从 UART 读取消息,然后在优先级较低的线程中解释它们。一种方法是创建一个包含 n 个项目的消息队列并添加传入行。同时给出一个信号量(最大值为 n)。优先级较低的线程将信号量和消息从队列中取出以对其进行处理:
K_MSGQ_DEFINE(uartRxMsgQ, uartFrameSize, uartMsgQSize, 4);
K_SEM_DEFINE(messageSemaphore, 0, uartMsgQSize);
static void uart_isr_handler(const struct device *dev, struct uart_event *event, void *user_data) {
switch (event->type) {
case UART_RX_RDY:
for (size_t n = event->data.rx.offset; n < event->data.rx.offset + event->data.rx.len; n++) {
if (*(event->data.rx.buf + n) == '\n' || *(event->data.rx.buf + n) == '\r') {
if (uartFramePos > 0) {
uartFrameBuff[uartFramePos] = 0;
if (k_msgq_put(&uartRxMsgQ, &uartFrameBuff, K_NO_WAIT) == 0)
k_sem_give(&messageSemaphore);
else
LOG_ERR("Uart RX message queue full");
uartFramePos = 0;
}
} else if (uartFramePos < uartFrameSize - 1) uartFrameBuff[uartFramePos++] = event->data.rx.buf[n];
}
break;
}
}
void msg_processor_thread() {
static uint8_t incomingMsg[uartFrameSize];
while (1) {
k_sem_take(&messageSemaphore, K_FOREVER);
k_msgq_get(&uartRxMsgQ, &incomingMsg, K_FOREVER);
LOG_INF("RX: %s", incomingMsg);
}
}
因此,如果信号量指示队列中的消息数。如果队列是空的,take will block,线程是快乐的。uartMsgQSize = 10;
但是呢?对于这个具体的例子,它不会像尝试获取信号量一样阻塞吗?在这种情况下,使用信号量有什么好处吗?除了管理信号量的开销之外,还有区别吗?k_msgq_get(&uartRxMsgQ, &incomingMsg, K_FOREVER);
奖励问题:while 循环是否需要让步?我对这种情况的解释是,如果没有产量,这个线程可能会使所有其他线程挨饿,直到它处理完队列中的所有消息。一旦它变得活跃,它将处理所有消息,直到它不能再接受信号量。甚至更高优先级的线程也会受到影响,对吗?在循环中产生产量时,它只会发生在优先级较低的线程上,对吗?所以如果我写:msg_processor_thread()
while (1) {
k_sem_take(&messageSemaphore, K_FOREVER);
k_msgq_get(&uartRxMsgQ, &incomingMsg, K_FOREVER);
LOG_INF("RX: %s", incomingMsg);
k_yield();
}
在每条消息之后,调度程序将有机会切换到更重要的事情。所以我的猜测是,收益率更有意义。我看对了吗?
答: 暂无答案
评论