Основываясь на идее @ Devolus , я получил следующее:
uint32_t status = Flash_EraseAll();
__asm volatile ("str %0, [sp, #-4]!\n\t" // Push to stack
"bkpt 0x0\n\t" // Halt CPU
"add sp, sp, #4\n\t" // Restore SP
: : "r"(status)); // status as input to __asm()
Инструкция по сборке говорит компилятору поместить переменную состояния в удобный регистр «r» и сохранить содержимое этого регистра под предварительно уменьшенным адресом указателя стека, а затем остановить выполнение ЦП с немедленным 0.
Приложение вождения будет опрашивать цель, если она будет остановлена (bkpt hit). В случае остановки, считывая 16-битные данные на текущем ПК (__asm ("bkpt 0x00") -> 0xbe00 -> #imm = 0xbe00 & 0x00ff = 0), приложение может убедиться, что выполнение остановлено справа место. Затем он считывает 32-разрядные данные по последнему адресу SP, чтобы получить информацию о состоянии выполнения встроенного кода.
Таким образом, вместо статического 8-битного кода из непосредственного bkpt, можно динамически «сообщать» больше материала во внешний мир (32-битный в данном случае).
Как подчеркивает @ PeterCordes , операторы push и bkpt должны находиться в одной и той же встроенной инструкции по сборке, в противном случае компилятор может решить вставить код между операторами. Кроме того, SP должен быть восстановлен до значения перед __asm (), так как компилятор принимает единоличное управление над SP.