Software Breakpoints in the IDE
From Texas Instruments Embedded Processors Wiki
How convenient would it be to do something like this:
if (some_assertion_failure) { halt_the_target_in_a_spin_loop_so_i_can_see_the_processor_state() }
Typically we think of breakpoints as IDE-only i.e. we manually have to set BPs at certain locations. However it would be neat to programmatically trigger a breakpoint. Naturally we can do this with AET but not every chip has AET capabilities.
The good news is we can do this with the software breakpoint opcode - each TI Instruction Set Architecture has one. Here is some code we use to apply programmatic software breakpoints
/* * ======== UTL_assert ======== * Assert macro for exceptions * * If an assertion fails, we interrupt the execution flow and preserve * the state of the system. * If the application is being debugged with Code Composer Studio, we place * a word in program memory that has the effect of a breakpoint -- it halts * the execution and CCS shows the line of code where the failed assertion * occurred. The special word that causes the breakpoint effect is different * for every DSP family. * Otherwise, if CCS is not used, we disable interrupts and run into an * infinite loop, waiting for the user to halt the target manually. * To do so, define UTL_ASSERTCCS macro flag externally to be 0. */ #if UTL_ASSERT == 1 /* first check if UTL_ASSERT() is enabled at all */ /* * First we define the special word for each platform: * On 55x we add a NOP to guard against small possibility that * long instruction pipeline causes debugger to stop at next C src line * instead of currently executing C src statement. We also ensure this * works on both 55x mnemonic (default) and algebraic 55x assembler. * Note that asm statement is a single execution context to maintain * pre-processor consistency. */ #if defined( _54_ ) #define UTL_STOPWORD asm( " ESTOP" ) #elif defined( _55_ ) #define UTL_STOPWORD asm(" ;\n .if (.MNEMONIC)\n ESTOP_1\n .else\n ESTOP_1()\n .endif\n NOP") #elif defined(_64P_) /* Joule */ #define UTL_STOPWORD asm( " SWBP 0") #elif defined( _6x_ ) #define UTL_STOPWORD asm( " NOP\n .word 0x10000000" ) #else #define UTL_ASSERTCCS 0 /* unknown platform => no CCS breakpoint */ #endif #if !defined( UTL_ASSERTCCS ) #define UTL_ASSERTCCS 1 #endif /* check if it's OK with the user to use CCS breakpoints for asserts() */ #if UTL_ASSERTCCS == 1 /* it is; define the UTL_assert macro */ #define UTL_assert( expr ) \ for (; !( expr ); ) \ UTL_STOPWORD #else /* UTL_ASSERTCCS == 0 */ /* no Code Composer Studio here */ #define UTL_assert( expr ) do { \ if ( !(expr) ) { /* use UTL_error() to halt, prototyped below */ \ UTL_error( "Assertion Violation: " __FILE__ ", line " \ UTL_stringify(__LINE__) " (" UTL_stringify(expr) ")", 0 ); \ } \ } while (0) #endif /* UTL_ASSERTCCS */ /* * UTL_assertFunc() is meant for testing expressions with side effects, * i.e. mostly for checking function calls. If enabled, behaves exactly * the same as UTL_assert. If disabled, it is not expanded to nothing * but to actual expression. E.g., * UTL_assertFunc( someFunc() == TRUE ); * If asserts are disabled, expands to * (someFunc() == TRUE); */ #define UTL_assertFunc UTL_assert #else /* UTL_ASSERT */ #define UTL_assert( expr ) #define UTL_assertFunc( expr ) (expr) #endif /* UTL_ASSERT */
This code shows the mnemonic / opcode for the different ISAs. You can use the UTL_assert() macro or just the UTL_STOPWORD definition.
mbxProcess = MBX_create(sizeof(CtrlMsg), THRPROCESS_MBXLENGTH, NULL); UTL_assert( mbxProcess != NULL ); // halt the target and debug if we fail
For the C28x devices, the software breakpoint instruction is: asm( "ESTOP0")
This capability is also being considered for the simulator - the enhancement number is SDSCM00025430.
Another topic to look at is Simulator Data Breakpoints and Watchpoints. However this feature is not available on all ISAs.
Leave a Comment
