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_init,void, | ||||||
| Function,+,furi_hal_vibro_on,void,_Bool | Function,+,furi_hal_vibro_on,void,_Bool | ||||||
| Function,-,furi_init,void, | Function,-,furi_init,void, | ||||||
|  | Function,+,furi_kernel_is_irq_or_masked,_Bool, | ||||||
| Function,+,furi_kernel_get_tick_frequency,uint32_t, | Function,+,furi_kernel_get_tick_frequency,uint32_t, | ||||||
| Function,+,furi_kernel_lock,int32_t, | Function,+,furi_kernel_lock,int32_t, | ||||||
| Function,+,furi_kernel_restore_lock,int32_t,int32_t | Function,+,furi_kernel_restore_lock,int32_t,int32_t | ||||||
|  | |||||||
| 
 | 
| @ -52,30 +52,6 @@ extern "C" { | |||||||
|     } |     } | ||||||
| #endif | #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 | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -7,8 +7,32 @@ | |||||||
| 
 | 
 | ||||||
| #include CMSIS_device_header | #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() { | int32_t furi_kernel_lock() { | ||||||
|     furi_assert(!furi_is_irq_context()); |     furi_assert(!furi_kernel_is_irq_or_masked()); | ||||||
| 
 | 
 | ||||||
|     int32_t lock; |     int32_t lock; | ||||||
| 
 | 
 | ||||||
| @ -33,7 +57,7 @@ int32_t furi_kernel_lock() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int32_t furi_kernel_unlock() { | int32_t furi_kernel_unlock() { | ||||||
|     furi_assert(!furi_is_irq_context()); |     furi_assert(!furi_kernel_is_irq_or_masked()); | ||||||
| 
 | 
 | ||||||
|     int32_t lock; |     int32_t lock; | ||||||
| 
 | 
 | ||||||
| @ -63,7 +87,7 @@ int32_t furi_kernel_unlock() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int32_t furi_kernel_restore_lock(int32_t lock) { | 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()) { |     switch(xTaskGetSchedulerState()) { | ||||||
|     case taskSCHEDULER_SUSPENDED: |     case taskSCHEDULER_SUSPENDED: | ||||||
| @ -99,7 +123,7 @@ uint32_t furi_kernel_get_tick_frequency() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void furi_delay_tick(uint32_t ticks) { | void furi_delay_tick(uint32_t ticks) { | ||||||
|     furi_assert(!furi_is_irq_context()); |     furi_assert(!furi_kernel_is_irq_or_masked()); | ||||||
|     if(ticks == 0U) { |     if(ticks == 0U) { | ||||||
|         taskYIELD(); |         taskYIELD(); | ||||||
|     } else { |     } else { | ||||||
| @ -108,7 +132,7 @@ void furi_delay_tick(uint32_t ticks) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| FuriStatus furi_delay_until_tick(uint32_t tick) { | 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; |     TickType_t tcnt, delay; | ||||||
|     FuriStatus stat; |     FuriStatus stat; | ||||||
| @ -137,7 +161,7 @@ FuriStatus furi_delay_until_tick(uint32_t tick) { | |||||||
| uint32_t furi_get_tick() { | uint32_t furi_get_tick() { | ||||||
|     TickType_t ticks; |     TickType_t ticks; | ||||||
| 
 | 
 | ||||||
|     if(furi_is_irq_context() != 0U) { |     if(furi_kernel_is_irq_or_masked() != 0U) { | ||||||
|         ticks = xTaskGetTickCountFromISR(); |         ticks = xTaskGetTickCountFromISR(); | ||||||
|     } else { |     } else { | ||||||
|         ticks = xTaskGetTickCount(); |         ticks = xTaskGetTickCount(); | ||||||
|  | |||||||
| @ -10,19 +10,42 @@ | |||||||
| extern "C" { | extern "C" { | ||||||
| #endif | #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
 | /** Lock kernel, pause process scheduling
 | ||||||
|  |  * | ||||||
|  |  * @warning This should never be called in interrupt request context. | ||||||
|  * |  * | ||||||
|  * @return     previous lock state(0 - unlocked, 1 - locked) |  * @return     previous lock state(0 - unlocked, 1 - locked) | ||||||
|  */ |  */ | ||||||
| int32_t furi_kernel_lock(); | int32_t furi_kernel_lock(); | ||||||
| 
 | 
 | ||||||
| /** Unlock kernel, resume process scheduling
 | /** Unlock kernel, resume process scheduling
 | ||||||
|  |  * | ||||||
|  |  * @warning This should never be called in interrupt request context. | ||||||
|  * |  * | ||||||
|  * @return     previous lock state(0 - unlocked, 1 - locked) |  * @return     previous lock state(0 - unlocked, 1 - locked) | ||||||
|  */ |  */ | ||||||
| int32_t furi_kernel_unlock(); | int32_t furi_kernel_unlock(); | ||||||
| 
 | 
 | ||||||
| /** Restore kernel lock state
 | /** Restore kernel lock state
 | ||||||
|  |  * | ||||||
|  |  * @warning This should never be called in interrupt request context. | ||||||
|  * |  * | ||||||
|  * @param[in]  lock  The lock state |  * @param[in]  lock  The lock state | ||||||
|  * |  * | ||||||
| @ -37,6 +60,8 @@ int32_t furi_kernel_restore_lock(int32_t lock); | |||||||
| uint32_t furi_kernel_get_tick_frequency(); | uint32_t furi_kernel_get_tick_frequency(); | ||||||
| 
 | 
 | ||||||
| /** Delay execution
 | /** Delay execution
 | ||||||
|  |  * | ||||||
|  |  * @warning This should never be called in interrupt request context. | ||||||
|  * |  * | ||||||
|  * Also keep in mind delay is aliased to scheduler timer intervals. |  * Also keep in mind delay is aliased to scheduler timer intervals. | ||||||
|  * |  * | ||||||
| @ -45,6 +70,8 @@ uint32_t furi_kernel_get_tick_frequency(); | |||||||
| void furi_delay_tick(uint32_t ticks); | void furi_delay_tick(uint32_t ticks); | ||||||
| 
 | 
 | ||||||
| /** Delay until tick
 | /** 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 |  * @param[in]  ticks  The tick until which kerel should delay task execution | ||||||
|  * |  * | ||||||
|  | |||||||
| @ -1,11 +1,11 @@ | |||||||
|  | #include "kernel.h" | ||||||
| #include "message_queue.h" | #include "message_queue.h" | ||||||
| #include "core/common_defines.h" |  | ||||||
| #include <FreeRTOS.h> | #include <FreeRTOS.h> | ||||||
| #include <queue.h> | #include <queue.h> | ||||||
| #include "check.h" | #include "check.h" | ||||||
| 
 | 
 | ||||||
| FuriMessageQueue* furi_message_queue_alloc(uint32_t msg_count, uint32_t msg_size) { | 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); |     QueueHandle_t handle = xQueueCreate(msg_count, msg_size); | ||||||
|     furi_check(handle); |     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) { | 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); |     furi_assert(instance); | ||||||
| 
 | 
 | ||||||
|     vQueueDelete((QueueHandle_t)instance); |     vQueueDelete((QueueHandle_t)instance); | ||||||
| @ -28,7 +28,7 @@ FuriStatus | |||||||
| 
 | 
 | ||||||
|     stat = FuriStatusOk; |     stat = FuriStatusOk; | ||||||
| 
 | 
 | ||||||
|     if(furi_is_irq_context() != 0U) { |     if(furi_kernel_is_irq_or_masked() != 0U) { | ||||||
|         if((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) { |         if((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) { | ||||||
|             stat = FuriStatusErrorParameter; |             stat = FuriStatusErrorParameter; | ||||||
|         } else { |         } else { | ||||||
| @ -65,7 +65,7 @@ FuriStatus furi_message_queue_get(FuriMessageQueue* instance, void* msg_ptr, uin | |||||||
| 
 | 
 | ||||||
|     stat = FuriStatusOk; |     stat = FuriStatusOk; | ||||||
| 
 | 
 | ||||||
|     if(furi_is_irq_context() != 0U) { |     if(furi_kernel_is_irq_or_masked() != 0U) { | ||||||
|         if((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) { |         if((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) { | ||||||
|             stat = FuriStatusErrorParameter; |             stat = FuriStatusErrorParameter; | ||||||
|         } else { |         } else { | ||||||
| @ -131,7 +131,7 @@ uint32_t furi_message_queue_get_count(FuriMessageQueue* instance) { | |||||||
| 
 | 
 | ||||||
|     if(hQueue == NULL) { |     if(hQueue == NULL) { | ||||||
|         count = 0U; |         count = 0U; | ||||||
|     } else if(furi_is_irq_context() != 0U) { |     } else if(furi_kernel_is_irq_or_masked() != 0U) { | ||||||
|         count = uxQueueMessagesWaitingFromISR(hQueue); |         count = uxQueueMessagesWaitingFromISR(hQueue); | ||||||
|     } else { |     } else { | ||||||
|         count = uxQueueMessagesWaiting(hQueue); |         count = uxQueueMessagesWaiting(hQueue); | ||||||
| @ -148,7 +148,7 @@ uint32_t furi_message_queue_get_space(FuriMessageQueue* instance) { | |||||||
| 
 | 
 | ||||||
|     if(mq == NULL) { |     if(mq == NULL) { | ||||||
|         space = 0U; |         space = 0U; | ||||||
|     } else if(furi_is_irq_context() != 0U) { |     } else if(furi_kernel_is_irq_or_masked() != 0U) { | ||||||
|         isrm = taskENTER_CRITICAL_FROM_ISR(); |         isrm = taskENTER_CRITICAL_FROM_ISR(); | ||||||
| 
 | 
 | ||||||
|         /* space = pxQueue->uxLength - pxQueue->uxMessagesWaiting; */ |         /* space = pxQueue->uxLength - pxQueue->uxMessagesWaiting; */ | ||||||
| @ -167,7 +167,7 @@ FuriStatus furi_message_queue_reset(FuriMessageQueue* instance) { | |||||||
|     QueueHandle_t hQueue = (QueueHandle_t)instance; |     QueueHandle_t hQueue = (QueueHandle_t)instance; | ||||||
|     FuriStatus stat; |     FuriStatus stat; | ||||||
| 
 | 
 | ||||||
|     if(furi_is_irq_context() != 0U) { |     if(furi_kernel_is_irq_or_masked() != 0U) { | ||||||
|         stat = FuriStatusErrorISR; |         stat = FuriStatusErrorISR; | ||||||
|     } else if(hQueue == NULL) { |     } else if(hQueue == NULL) { | ||||||
|         stat = FuriStatusErrorParameter; |         stat = FuriStatusErrorParameter; | ||||||
|  | |||||||
| @ -3,7 +3,6 @@ | |||||||
| #include "memmgr.h" | #include "memmgr.h" | ||||||
| #include "kernel.h" | #include "kernel.h" | ||||||
| 
 | 
 | ||||||
| #include "core/common_defines.h" |  | ||||||
| #include <FreeRTOS.h> | #include <FreeRTOS.h> | ||||||
| #include <timers.h> | #include <timers.h> | ||||||
| 
 | 
 | ||||||
| @ -27,7 +26,7 @@ static void TimerCallback(TimerHandle_t hTimer) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| FuriTimer* furi_timer_alloc(FuriTimerCallback func, FuriTimerType type, void* context) { | 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; |     TimerHandle_t hTimer; | ||||||
|     TimerCallback_t* callb; |     TimerCallback_t* callb; | ||||||
| @ -60,7 +59,7 @@ FuriTimer* furi_timer_alloc(FuriTimerCallback func, FuriTimerType type, void* co | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void furi_timer_free(FuriTimer* instance) { | void furi_timer_free(FuriTimer* instance) { | ||||||
|     furi_assert(!furi_is_irq_context()); |     furi_assert(!furi_kernel_is_irq_or_masked()); | ||||||
|     furi_assert(instance); |     furi_assert(instance); | ||||||
| 
 | 
 | ||||||
|     TimerHandle_t hTimer = (TimerHandle_t)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) { | 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); |     furi_assert(instance); | ||||||
| 
 | 
 | ||||||
|     TimerHandle_t hTimer = (TimerHandle_t)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) { | FuriStatus furi_timer_stop(FuriTimer* instance) { | ||||||
|     furi_assert(!furi_is_irq_context()); |     furi_assert(!furi_kernel_is_irq_or_masked()); | ||||||
|     furi_assert(instance); |     furi_assert(instance); | ||||||
| 
 | 
 | ||||||
|     TimerHandle_t hTimer = (TimerHandle_t)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) { | 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); |     furi_assert(instance); | ||||||
| 
 | 
 | ||||||
|     TimerHandle_t hTimer = (TimerHandle_t)instance; |     TimerHandle_t hTimer = (TimerHandle_t)instance; | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ | |||||||
| #include "queue.h" | #include "queue.h" | ||||||
| 
 | 
 | ||||||
| void furi_init() { | void furi_init() { | ||||||
|     furi_assert(!furi_is_irq_context()); |     furi_assert(!furi_kernel_is_irq_or_masked()); | ||||||
|     furi_assert(xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED); |     furi_assert(xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED); | ||||||
| 
 | 
 | ||||||
|     furi_log_init(); |     furi_log_init(); | ||||||
| @ -11,7 +11,7 @@ void furi_init() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void furi_run() { | void furi_run() { | ||||||
|     furi_assert(!furi_is_irq_context()); |     furi_assert(!furi_kernel_is_irq_or_masked()); | ||||||
|     furi_assert(xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED); |     furi_assert(xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED); | ||||||
| 
 | 
 | ||||||
| #if(__ARM_ARCH_7A__ == 0U) | #if(__ARM_ARCH_7A__ == 0U) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Petr Portnov | PROgrm_JARvis
						Petr Portnov | PROgrm_JARvis