Как решить: не удалось вставить все аппаратные точки останова; возможно, вы запросили слишком много аппаратных точек останова/наблюдательных точек

Я использую STM32 Cube IDE и часто получаю диалоговое окно с сообщением об ошибке:

failed to insert all hardware breakpoints; 
you may have requested too many hardware breakpoints/watchpoints

Я знаю, что ARM Cortex M0+, который я использую, поддерживает только 4 аппаратных точки останова, отсюда и ошибка, но этого часто недостаточно. Как обойти это и установить более 4 точек останова?

Примечание. Раньше я работал с STM8 (с IAR EWB), гораздо более ограниченным микроконтроллером, но я мог использовать столько точек останова, сколько хотел.


person user103185    schedule 04.01.2021    source источник


Ответы (2)


Помимо аппаратных точек останова, программные точки останова могут использоваться для взлома отладчика. Отладчик поддерживает это, только если код находится в оперативной памяти. Часто это совсем не практично.

В качестве лайфхака вместо этого можно сделать функцию breakpoint(), содержащую аппаратную точку останова. Теперь везде, где вызывается эта функция, активируется точка останова:

void __attribute__ ((noinline)) breakpoint()
{
    __asm("NOP");     // <---- set a hardware breakpoint here!
    // hello, please Step Out to go to caller location (ex: press Shift-F11)
}

void main()
{
    int x = 1;
breakpoint();             // break into the debugger
    printf("%d\n", x);
    x += 2;
breakpoint();             // break into the debugger, again
    printf("%d\n", x);
}

Теперь отладчик остановится в пределах breakpoint(). Чтобы увидеть фактическое расположение точки останова, нужно выйти.

Этот метод освобождает аппаратные точки останова для таких взаимодействий, как пошаговое выполнение, и 4 доступных точек останова часто бывает достаточно.

Заметки:

  • альтернативой функции breakpoint() может быть использование функции __asm("BKPT #0") , которая входит в отладчик. К сожалению, нет способа перешагнуть эту инструкцию (проверено на STM32/GDB), поэтому она фактически действует как инструкция HALT. Его можно использовать для размещения точек останова внутри условий отказа или неиспользуемых прерываний.
  • функция breakpoint(), кажется, работает только один раз, когда __asm("NOP"); опущен
  • Что касается STM8, то он исключительно имеет флэш-память, которая поддерживает обновление байтов, поэтому он может действовать очень похоже на ОЗУ. Отладчик может использовать это для вставки программных точек останова и столько раз, сколько необходимо.
  • Однако STM8 имеет только 2 регистра точек останова, которые, вероятно, используются исключительно для одиночного шага.
  • другие, более мощные микроконтроллеры ARM Cortex могут иметь 6 или 8 аппаратных точек останова.
  • GDB (и другие отладчики), вероятно, могли бы быть немного умнее в том, как они работают с точками останова. Например, если у вас есть несколько точек останова в функции, часто бывает невозможно достичь какой-либо точки останова до достижения точки останова над ней. Это может иметь большое значение в некоторых распространенных сценариях отладки.
person user103185    schedule 04.01.2021
comment
1. Некоторое ПО для отладки достаточно умное — например, SEGGER - person 0___________; 05.01.2021
comment
2. Не вижу смысла использовать этот неудобный обходной путь, если у вас есть инструкция bkpt и __BKPT() встроенная для удобного использования в программах на C или C++. - person 0___________; 05.01.2021
comment
ваша функция void имеет неправильный прототип - person 0___________; 05.01.2021
comment
4. Использование этой функции изменяет тайминги кода, когда точка останова не установлена ​​(ветвь, сброс конвейера, недействительность кэш-памяти). А как я писал он вообще не нужен. - person 0___________; 05.01.2021

Периферийное устройство отладки ARM имеет ограниченное количество аппаратных точек останова.

Некоторые отладочные зонды (например, SEGGER J-Link) могут устанавливать программные точки останова, вставляя инструкцию bkpt и перепрограммируя FLASH-память на лету. Вы можете установить собственную точку останова программного обеспечения, используя встроенный метод __BKPT().

#ifdef DEBUG 
#define DEBUGBKPT()     __BKPT()
#else
#define DEBUGBKPT()
#endif

Если вы используете stlink-V2, вы можете преобразовать его в Segger и воспользоваться неограниченным количеством точек останова и гораздо более быстрой отладкой, используя программное обеспечение по этой ссылке: https://www.segger.com/products/debug-probes/j-link/models/other-j-links/st-link-on-board/

person 0___________    schedule 05.01.2021
comment
Я проверил это (на STM32+GDB+ST-Link), и это не работает. почему SEGGER (аппаратное обеспечение) имеет значение? GDB - свинья здесь, и я хотел бы улучшений. - person user103185; 05.01.2021
comment
@user103185 user103185 У Segger есть собственный gdbserver. Это не только железо, но и программное обеспечение. Смотрите мой измененный ответ. - person 0___________; 05.01.2021
comment
@user103185 user103185 Я занимаюсь этим (программированием stm32) в качестве своей дневной работы и в течение многих лет использую отладчики Segger, и у меня большой опыт программирования ARM uCs. - person 0___________; 05.01.2021
comment
тогда вопрос заключается в том, есть ли ошибка в GDB (и Сеггер работал над этим) или в драйвере ST-Link, и ее следует исправить. - person user103185; 05.01.2021
comment
@user103185 user103185 это не ошибка, это функция Segger - person 0___________; 05.01.2021