Furi: make furi_is_irq_context
public (#2276)
* Furi: make `furi_is_irq_context` public * Furi: proper name and documentation for furi_kernel_is_irq_or_masked. * Target: bump symbol table version * Furi: proper doxygen context for warnings Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
parent
d93ed003fe
commit
f5fe0ff694
@ -1389,6 +1389,7 @@ Function,+,furi_hal_version_uid_size,size_t,
|
||||
Function,-,furi_hal_vibro_init,void,
|
||||
Function,+,furi_hal_vibro_on,void,_Bool
|
||||
Function,-,furi_init,void,
|
||||
Function,+,furi_kernel_is_irq_or_masked,_Bool,
|
||||
Function,+,furi_kernel_get_tick_frequency,uint32_t,
|
||||
Function,+,furi_kernel_lock,int32_t,
|
||||
Function,+,furi_kernel_restore_lock,int32_t,int32_t
|
||||
|
|
@ -52,30 +52,6 @@ extern "C" {
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline bool furi_is_irq_context() {
|
||||
bool irq = false;
|
||||
BaseType_t state;
|
||||
|
||||
if(FURI_IS_IRQ_MODE()) {
|
||||
/* Called from interrupt context */
|
||||
irq = true;
|
||||
} else {
|
||||
/* Get FreeRTOS scheduler state */
|
||||
state = xTaskGetSchedulerState();
|
||||
|
||||
if(state != taskSCHEDULER_NOT_STARTED) {
|
||||
/* Scheduler was started */
|
||||
if(FURI_IS_IRQ_MASKED()) {
|
||||
/* Interrupts are masked */
|
||||
irq = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return context, 0: thread context, 1: IRQ context */
|
||||
return (irq);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -7,8 +7,32 @@
|
||||
|
||||
#include CMSIS_device_header
|
||||
|
||||
bool furi_kernel_is_irq_or_masked() {
|
||||
bool irq = false;
|
||||
BaseType_t state;
|
||||
|
||||
if(FURI_IS_IRQ_MODE()) {
|
||||
/* Called from interrupt context */
|
||||
irq = true;
|
||||
} else {
|
||||
/* Get FreeRTOS scheduler state */
|
||||
state = xTaskGetSchedulerState();
|
||||
|
||||
if(state != taskSCHEDULER_NOT_STARTED) {
|
||||
/* Scheduler was started */
|
||||
if(FURI_IS_IRQ_MASKED()) {
|
||||
/* Interrupts are masked */
|
||||
irq = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return context, 0: thread context, 1: IRQ context */
|
||||
return (irq);
|
||||
}
|
||||
|
||||
int32_t furi_kernel_lock() {
|
||||
furi_assert(!furi_is_irq_context());
|
||||
furi_assert(!furi_kernel_is_irq_or_masked());
|
||||
|
||||
int32_t lock;
|
||||
|
||||
@ -33,7 +57,7 @@ int32_t furi_kernel_lock() {
|
||||
}
|
||||
|
||||
int32_t furi_kernel_unlock() {
|
||||
furi_assert(!furi_is_irq_context());
|
||||
furi_assert(!furi_kernel_is_irq_or_masked());
|
||||
|
||||
int32_t lock;
|
||||
|
||||
@ -63,7 +87,7 @@ int32_t furi_kernel_unlock() {
|
||||
}
|
||||
|
||||
int32_t furi_kernel_restore_lock(int32_t lock) {
|
||||
furi_assert(!furi_is_irq_context());
|
||||
furi_assert(!furi_kernel_is_irq_or_masked());
|
||||
|
||||
switch(xTaskGetSchedulerState()) {
|
||||
case taskSCHEDULER_SUSPENDED:
|
||||
@ -99,7 +123,7 @@ uint32_t furi_kernel_get_tick_frequency() {
|
||||
}
|
||||
|
||||
void furi_delay_tick(uint32_t ticks) {
|
||||
furi_assert(!furi_is_irq_context());
|
||||
furi_assert(!furi_kernel_is_irq_or_masked());
|
||||
if(ticks == 0U) {
|
||||
taskYIELD();
|
||||
} else {
|
||||
@ -108,7 +132,7 @@ void furi_delay_tick(uint32_t ticks) {
|
||||
}
|
||||
|
||||
FuriStatus furi_delay_until_tick(uint32_t tick) {
|
||||
furi_assert(!furi_is_irq_context());
|
||||
furi_assert(!furi_kernel_is_irq_or_masked());
|
||||
|
||||
TickType_t tcnt, delay;
|
||||
FuriStatus stat;
|
||||
@ -137,7 +161,7 @@ FuriStatus furi_delay_until_tick(uint32_t tick) {
|
||||
uint32_t furi_get_tick() {
|
||||
TickType_t ticks;
|
||||
|
||||
if(furi_is_irq_context() != 0U) {
|
||||
if(furi_kernel_is_irq_or_masked() != 0U) {
|
||||
ticks = xTaskGetTickCountFromISR();
|
||||
} else {
|
||||
ticks = xTaskGetTickCount();
|
||||
|
@ -10,19 +10,42 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Check if CPU is in IRQ or kernel running and IRQ is masked
|
||||
*
|
||||
* Originally this primitive was born as a workaround for FreeRTOS kernel primitives shenanigans with PRIMASK.
|
||||
*
|
||||
* Meaningful use cases are:
|
||||
*
|
||||
* - When kernel is started and you want to ensure that you are not in IRQ or IRQ is not masked(like in critical section)
|
||||
* - When kernel is not started and you want to make sure that you are not in IRQ mode, ignoring PRIMASK.
|
||||
*
|
||||
* As you can see there will be edge case when kernel is not started and PRIMASK is not 0 that may cause some funky behavior.
|
||||
* Most likely it will happen after kernel primitives being used, but control not yet passed to kernel.
|
||||
* It's up to you to figure out if it is safe for your code or not.
|
||||
*
|
||||
* @return true if CPU is in IRQ or kernel running and IRQ is masked
|
||||
*/
|
||||
bool furi_kernel_is_irq_or_masked();
|
||||
|
||||
/** Lock kernel, pause process scheduling
|
||||
*
|
||||
* @warning This should never be called in interrupt request context.
|
||||
*
|
||||
* @return previous lock state(0 - unlocked, 1 - locked)
|
||||
*/
|
||||
int32_t furi_kernel_lock();
|
||||
|
||||
/** Unlock kernel, resume process scheduling
|
||||
*
|
||||
* @warning This should never be called in interrupt request context.
|
||||
*
|
||||
* @return previous lock state(0 - unlocked, 1 - locked)
|
||||
*/
|
||||
int32_t furi_kernel_unlock();
|
||||
|
||||
/** Restore kernel lock state
|
||||
*
|
||||
* @warning This should never be called in interrupt request context.
|
||||
*
|
||||
* @param[in] lock The lock state
|
||||
*
|
||||
@ -37,7 +60,9 @@ int32_t furi_kernel_restore_lock(int32_t lock);
|
||||
uint32_t furi_kernel_get_tick_frequency();
|
||||
|
||||
/** Delay execution
|
||||
*
|
||||
*
|
||||
* @warning This should never be called in interrupt request context.
|
||||
*
|
||||
* Also keep in mind delay is aliased to scheduler timer intervals.
|
||||
*
|
||||
* @param[in] ticks The ticks count to pause
|
||||
@ -45,6 +70,8 @@ uint32_t furi_kernel_get_tick_frequency();
|
||||
void furi_delay_tick(uint32_t ticks);
|
||||
|
||||
/** Delay until tick
|
||||
*
|
||||
* @warning This should never be called in interrupt request context.
|
||||
*
|
||||
* @param[in] ticks The tick until which kerel should delay task execution
|
||||
*
|
||||
|
@ -1,11 +1,11 @@
|
||||
#include "kernel.h"
|
||||
#include "message_queue.h"
|
||||
#include "core/common_defines.h"
|
||||
#include <FreeRTOS.h>
|
||||
#include <queue.h>
|
||||
#include "check.h"
|
||||
|
||||
FuriMessageQueue* furi_message_queue_alloc(uint32_t msg_count, uint32_t msg_size) {
|
||||
furi_assert((furi_is_irq_context() == 0U) && (msg_count > 0U) && (msg_size > 0U));
|
||||
furi_assert((furi_kernel_is_irq_or_masked() == 0U) && (msg_count > 0U) && (msg_size > 0U));
|
||||
|
||||
QueueHandle_t handle = xQueueCreate(msg_count, msg_size);
|
||||
furi_check(handle);
|
||||
@ -14,7 +14,7 @@ FuriMessageQueue* furi_message_queue_alloc(uint32_t msg_count, uint32_t msg_size
|
||||
}
|
||||
|
||||
void furi_message_queue_free(FuriMessageQueue* instance) {
|
||||
furi_assert(furi_is_irq_context() == 0U);
|
||||
furi_assert(furi_kernel_is_irq_or_masked() == 0U);
|
||||
furi_assert(instance);
|
||||
|
||||
vQueueDelete((QueueHandle_t)instance);
|
||||
@ -28,7 +28,7 @@ FuriStatus
|
||||
|
||||
stat = FuriStatusOk;
|
||||
|
||||
if(furi_is_irq_context() != 0U) {
|
||||
if(furi_kernel_is_irq_or_masked() != 0U) {
|
||||
if((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) {
|
||||
stat = FuriStatusErrorParameter;
|
||||
} else {
|
||||
@ -65,7 +65,7 @@ FuriStatus furi_message_queue_get(FuriMessageQueue* instance, void* msg_ptr, uin
|
||||
|
||||
stat = FuriStatusOk;
|
||||
|
||||
if(furi_is_irq_context() != 0U) {
|
||||
if(furi_kernel_is_irq_or_masked() != 0U) {
|
||||
if((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) {
|
||||
stat = FuriStatusErrorParameter;
|
||||
} else {
|
||||
@ -131,7 +131,7 @@ uint32_t furi_message_queue_get_count(FuriMessageQueue* instance) {
|
||||
|
||||
if(hQueue == NULL) {
|
||||
count = 0U;
|
||||
} else if(furi_is_irq_context() != 0U) {
|
||||
} else if(furi_kernel_is_irq_or_masked() != 0U) {
|
||||
count = uxQueueMessagesWaitingFromISR(hQueue);
|
||||
} else {
|
||||
count = uxQueueMessagesWaiting(hQueue);
|
||||
@ -148,7 +148,7 @@ uint32_t furi_message_queue_get_space(FuriMessageQueue* instance) {
|
||||
|
||||
if(mq == NULL) {
|
||||
space = 0U;
|
||||
} else if(furi_is_irq_context() != 0U) {
|
||||
} else if(furi_kernel_is_irq_or_masked() != 0U) {
|
||||
isrm = taskENTER_CRITICAL_FROM_ISR();
|
||||
|
||||
/* space = pxQueue->uxLength - pxQueue->uxMessagesWaiting; */
|
||||
@ -167,7 +167,7 @@ FuriStatus furi_message_queue_reset(FuriMessageQueue* instance) {
|
||||
QueueHandle_t hQueue = (QueueHandle_t)instance;
|
||||
FuriStatus stat;
|
||||
|
||||
if(furi_is_irq_context() != 0U) {
|
||||
if(furi_kernel_is_irq_or_masked() != 0U) {
|
||||
stat = FuriStatusErrorISR;
|
||||
} else if(hQueue == NULL) {
|
||||
stat = FuriStatusErrorParameter;
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include "memmgr.h"
|
||||
#include "kernel.h"
|
||||
|
||||
#include "core/common_defines.h"
|
||||
#include <FreeRTOS.h>
|
||||
#include <timers.h>
|
||||
|
||||
@ -27,7 +26,7 @@ static void TimerCallback(TimerHandle_t hTimer) {
|
||||
}
|
||||
|
||||
FuriTimer* furi_timer_alloc(FuriTimerCallback func, FuriTimerType type, void* context) {
|
||||
furi_assert((furi_is_irq_context() == 0U) && (func != NULL));
|
||||
furi_assert((furi_kernel_is_irq_or_masked() == 0U) && (func != NULL));
|
||||
|
||||
TimerHandle_t hTimer;
|
||||
TimerCallback_t* callb;
|
||||
@ -60,7 +59,7 @@ FuriTimer* furi_timer_alloc(FuriTimerCallback func, FuriTimerType type, void* co
|
||||
}
|
||||
|
||||
void furi_timer_free(FuriTimer* instance) {
|
||||
furi_assert(!furi_is_irq_context());
|
||||
furi_assert(!furi_kernel_is_irq_or_masked());
|
||||
furi_assert(instance);
|
||||
|
||||
TimerHandle_t hTimer = (TimerHandle_t)instance;
|
||||
@ -82,7 +81,7 @@ void furi_timer_free(FuriTimer* instance) {
|
||||
}
|
||||
|
||||
FuriStatus furi_timer_start(FuriTimer* instance, uint32_t ticks) {
|
||||
furi_assert(!furi_is_irq_context());
|
||||
furi_assert(!furi_kernel_is_irq_or_masked());
|
||||
furi_assert(instance);
|
||||
|
||||
TimerHandle_t hTimer = (TimerHandle_t)instance;
|
||||
@ -99,7 +98,7 @@ FuriStatus furi_timer_start(FuriTimer* instance, uint32_t ticks) {
|
||||
}
|
||||
|
||||
FuriStatus furi_timer_stop(FuriTimer* instance) {
|
||||
furi_assert(!furi_is_irq_context());
|
||||
furi_assert(!furi_kernel_is_irq_or_masked());
|
||||
furi_assert(instance);
|
||||
|
||||
TimerHandle_t hTimer = (TimerHandle_t)instance;
|
||||
@ -117,7 +116,7 @@ FuriStatus furi_timer_stop(FuriTimer* instance) {
|
||||
}
|
||||
|
||||
uint32_t furi_timer_is_running(FuriTimer* instance) {
|
||||
furi_assert(!furi_is_irq_context());
|
||||
furi_assert(!furi_kernel_is_irq_or_masked());
|
||||
furi_assert(instance);
|
||||
|
||||
TimerHandle_t hTimer = (TimerHandle_t)instance;
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "queue.h"
|
||||
|
||||
void furi_init() {
|
||||
furi_assert(!furi_is_irq_context());
|
||||
furi_assert(!furi_kernel_is_irq_or_masked());
|
||||
furi_assert(xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED);
|
||||
|
||||
furi_log_init();
|
||||
@ -11,7 +11,7 @@ void furi_init() {
|
||||
}
|
||||
|
||||
void furi_run() {
|
||||
furi_assert(!furi_is_irq_context());
|
||||
furi_assert(!furi_kernel_is_irq_or_masked());
|
||||
furi_assert(xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED);
|
||||
|
||||
#if(__ARM_ARCH_7A__ == 0U)
|
||||
|
Loading…
Reference in New Issue
Block a user