From 8215ce19ce88c01a581989395b0c2ca93d75ac42 Mon Sep 17 00:00:00 2001 From: Benjamin Walsh Date: Wed, 9 Nov 2016 19:45:19 -0500 Subject: [PATCH] kernel: fix k_msgq_get/put() from ISR There was no check to see if the current context was running an ISR when taking a decision whether to do a context switch or not. Change-Id: Ib9c426de8c0893b3d9383290bb59f6e0e41e9f52 Signed-off-by: Benjamin Walsh --- include/kernel.h | 4 ++++ kernel/unified/msg_q.c | 8 ++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/kernel.h b/include/kernel.h index ad8d76d1a4f..652c3c31788 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -1602,6 +1602,8 @@ extern void k_msgq_init(struct k_msgq *q, char *buffer, * * This routine sends a message to message queue @a q. * + * @note Can be called by ISRs. + * * @param q Address of the message queue. * @param data Pointer to the message. * @param timeout Waiting period to add the message (in milliseconds), @@ -1619,6 +1621,8 @@ extern int k_msgq_put(struct k_msgq *q, void *data, int32_t timeout); * This routine receives a message from message queue @a q in a "first in, * first out" manner. * + * @note Can be called by ISRs. + * * @param q Address of the message queue. * @param data Address of area to hold the received message. * @param timeout Waiting period to receive the message (in milliseconds), diff --git a/kernel/unified/msg_q.c b/kernel/unified/msg_q.c index 7536872c38b..374a8faaecd 100644 --- a/kernel/unified/msg_q.c +++ b/kernel/unified/msg_q.c @@ -72,6 +72,8 @@ void k_msgq_init(struct k_msgq *q, char *buffer, int k_msgq_put(struct k_msgq *q, void *data, int32_t timeout) { + __ASSERT(!_is_in_isr() || timeout == K_NO_WAIT, ""); + unsigned int key = irq_lock(); struct k_thread *pending_thread; int result; @@ -86,7 +88,7 @@ int k_msgq_put(struct k_msgq *q, void *data, int32_t timeout) _set_thread_return_value(pending_thread, 0); _abort_thread_timeout(pending_thread); _ready_thread(pending_thread); - if (_must_switch_threads()) { + if (!_is_in_isr() && _must_switch_threads()) { _Swap(key); return 0; } @@ -117,6 +119,8 @@ int k_msgq_put(struct k_msgq *q, void *data, int32_t timeout) int k_msgq_get(struct k_msgq *q, void *data, int32_t timeout) { + __ASSERT(!_is_in_isr() || timeout == K_NO_WAIT, ""); + unsigned int key = irq_lock(); struct k_thread *pending_thread; int result; @@ -146,7 +150,7 @@ int k_msgq_get(struct k_msgq *q, void *data, int32_t timeout) _set_thread_return_value(pending_thread, 0); _abort_thread_timeout(pending_thread); _ready_thread(pending_thread); - if (_must_switch_threads()) { + if (!_is_in_isr() && _must_switch_threads()) { _Swap(key); return 0; }