Flipper Zero Firmware
Loading...
Searching...
No Matches
check.h File Reference

Furi crash and assert functions. More...

#include <m-core.h>
#include "common_defines.h"

Go to the source code of this file.

Macros

#define __FURI_ASSERT_MESSAGE_FLAG   (0x01)
 
#define __FURI_CHECK_MESSAGE_FLAG   (0x02)
 
#define __furi_crash(message)
 Crash system with message.
 
#define furi_crash(...)   M_APPLY(__furi_crash, M_IF_EMPTY(__VA_ARGS__)((NULL), (__VA_ARGS__)))
 Crash system.
 
#define __furi_halt(message)
 Halt system with message.
 
#define furi_halt(...)   M_APPLY(__furi_halt, M_IF_EMPTY(__VA_ARGS__)((NULL), (__VA_ARGS__)))
 Halt system.
 
#define __furi_check(__e, __m)
 Check condition and crash if check failed.
 
#define furi_check(...)    M_APPLY(__furi_check, M_DEFAULT_ARGS(2, (__FURI_CHECK_MESSAGE_FLAG), __VA_ARGS__))
 Check condition and crash if failed.
 
#define __furi_assert(__e, __m)
 Only in debug build: Assert condition and crash if assert failed

 
#define furi_assert(...)    M_APPLY(__furi_assert, M_DEFAULT_ARGS(2, (__FURI_ASSERT_MESSAGE_FLAG), __VA_ARGS__))
 Assert condition and crash if failed.
 
#define furi_break(__e)
 

Functions

FURI_NORETURN void __furi_crash_implementation (void)
 Crash system.
 
FURI_NORETURN void __furi_halt_implementation (void)
 Halt system.
 

Detailed Description

Furi crash and assert functions.

The main problem with crashing is that you can't do anything without disturbing registers, and if you disturb registers, you won't be able to see the correct register values in the debugger.

Current solution works around it by passing the message through r12 and doing some magic with registers in crash function. r0-r10 are stored in the ram2 on crash routine start and restored at the end. The only register that is going to be lost is r11.

Macro Definition Documentation

◆ __furi_assert

#define __furi_assert ( __e,
__m )
Value:
do { \
((void)(__e)); \
((void)(__m)); \
} while(0)

Only in debug build: Assert condition and crash if assert failed

◆ __furi_check

#define __furi_check ( __e,
__m )
Value:
do { \
if(!(__e)) { \
__furi_crash(__m); \
} \
} while(0)

Check condition and crash if check failed.

◆ __furi_crash

#define __furi_crash ( message)
Value:
do { \
register const void* r12 asm("r12") = (void*)message; \
asm volatile("sukima%=:" : : "r"(r12)); \
__furi_crash_implementation(); \
} while(0)

Crash system with message.

Show message after reboot.

◆ __furi_halt

#define __furi_halt ( message)
Value:
do { \
register const void* r12 asm("r12") = (void*)message; \
asm volatile("sukima%=:" : : "r"(r12)); \
__furi_halt_implementation(); \
} while(0)

Halt system with message.

◆ furi_assert

#define furi_assert ( ...)     M_APPLY(__furi_assert, M_DEFAULT_ARGS(2, (__FURI_ASSERT_MESSAGE_FLAG), __VA_ARGS__))

Assert condition and crash if failed.

Warning
only will do check if firmware compiled in debug mode
Parameters
...condition to check and optional message (const char*)

◆ furi_break

#define furi_break ( __e)
Value:
do { \
if(!(__e)) { \
asm volatile("bkpt 0"); \
} \
} while(0)

◆ furi_check

#define furi_check ( ...)     M_APPLY(__furi_check, M_DEFAULT_ARGS(2, (__FURI_CHECK_MESSAGE_FLAG), __VA_ARGS__))

Check condition and crash if failed.

Parameters
...condition to check and optional message (const char*)

◆ furi_crash

#define furi_crash ( ...)    M_APPLY(__furi_crash, M_IF_EMPTY(__VA_ARGS__)((NULL), (__VA_ARGS__)))

Crash system.

Parameters
...optional message (const char*)

◆ furi_halt

#define furi_halt ( ...)    M_APPLY(__furi_halt, M_IF_EMPTY(__VA_ARGS__)((NULL), (__VA_ARGS__)))

Halt system.

Parameters
...optional message (const char*)