Cortex-M0+ не отвечает на PendSV

Я работаю на Raspberry Pi Pico (RP2040, ядро ​​Cortex-M0+, отладка через VSCode cortex-debug с использованием JLink SWD) и наблюдаю странное поведение в отношении PendSV.

Непосредственно перед этим обработчик исключений SVCall запросил PendSV через регистр ICSR. Но при возврате исключения, а не в хвостовой цепочке PendSV, выполнение вместо этого возвращается к вызывающему коду и продолжается выполнение без исключения.

Все это время регистр ICSR показывает ожидающий PendSV, даже если инструкции кода потока многократно повторяются. Приоритеты системных обработчиков равны нулю, приоритеты IRQ ниже.

введите здесь описание изображения

Согласно справочному руководству ARMv6-M, PendSV нельзя отключить.

Итак, что мне не хватает, что может вызвать такое поведение?

Отредактировано, чтобы добавить:

Возможно, это взаимодействие с отладчиком? Программное обеспечение JLink (v4.95d) все еще находится в стадии бета-тестирования...

Я вижу, что отладчик может фактически отключить PendSV и Systick — C1.5.1 Пошаговая отладка: Дополнительно отладчик может установить для DHCSR.C_MASKINTS значение 1, чтобы предотвратить возникновение PendSV, SysTick и внешних настраиваемых прерываний. Это описывается как маскирование этих прерываний. Таблица C1-7 на странице C1-326 обобщает пошаговое управление инструкциями.


person Jeremy    schedule 17.02.2021    source источник
comment
Вы упоминаете пошаговое выполнение — вы также видите такое поведение, когда код работает нормально? Имейте в виду, что прерывания отключены во время пошагового выполнения. Это логично для обычных асинхронных аппаратных прерываний, но такое же поведение распространяется и на полусинхронные прерывания, инициируемые программным обеспечением, такие как PendSV и SVC.   -  person cooperised    schedule 17.02.2021
comment
@cooperised - я подозреваю, что вы можете быть правы. Согласно справочному руководству, пошаговое выполнение может происходить с отключенными прерываниями или без них. Я почти уверен, что успешно прошел идентичный код на другой платформе Cortex-M0+ (Atmel SAMD21), но, возможно, я ошибаюсь, поэтому я обязательно перепроверю на обеих платформах.   -  person Jeremy    schedule 17.02.2021
comment
Пошаговое выполнение с включенными прерываниями редко бывает полезным, потому что (по своей природе) запросы на прерывание обычно выстраиваются в очередь между шагами, и вы обнаружите, что больше ничего не происходит последовательно — или, по крайней мере, запускаются ISR и меняют материал между одной строкой и следующей. Таким образом, отключение прерываний во время пошагового выполнения используется по умолчанию в каждом отладчике, который я когда-либо использовал. Тем не менее, часто было бы полезно исключить из этого SVC и PendSV, потому что они запускаются программно.   -  person cooperised    schedule 17.02.2021


Ответы (1)


Оказывается, проблема вызвана пошаговым выполнением инструкции, которая записывает бит PENDSVSET в ICSR: бит установлен, а поле VECTPENDING показывает 0xe, но PendSV никогда не срабатывает.

Свободный запуск этой инструкции до более поздней точки останова показывает, что PendSV срабатывает правильно.

Так что это действительно взаимодействие с отладчиком.

Неясно, связано ли это с запретом прерываний, как предполагает @cooperised - бит DHCSR C_MASKINTS везде читается как ноль, но то, как этот бит манипулируется во время фактической операции шага, на этом уровне не видно.

Что заставляет меня задаться вопросом, вызывает ли то, как JLink выполняет этот шаг, непредсказуемое/неопределенное поведение - например. согласно предупреждению в описании C_MASKINTS. Или, возможно, это просто то, что происходит в M0+ при таких обстоятельствах, и я никогда раньше не выполнял эту инструкцию пошагово.

В любом случае обходной путь заключается в том, чтобы просто не выполнять пошагово инструкцию, устанавливающую PENDSVSET.

Отредактировано, чтобы добавить:

Наконец, @cooperised был прав.

Если уделять больше внимания точному различению пошагового выполнения (включая переход по вызовам функций) и выполнения (включая переход к самой следующей инструкции), становится ясно, что пошаговое выполнение отключает прерывания, включая PendSV.

person Jeremy    schedule 17.02.2021
comment
Не совсем таким образом (мне не нужны ни одиночные шаги, ни точки останова), но я видел какое-то странное поведение с pico и openocd, которого я никогда раньше не видел с openocd и cortex-m, поэтому, если они не выполнили эту работу или есть какие-то дыры или если это какая-то вещь безопасности, то это также объясняет то, что я вижу. Я думаю, нам нужно подождать, пока они закончат реализацию openocd, или это связано с безопасностью, тогда мы не можем делать все, что хотим (есть некоторые новые чипы stm32, которые вы не можете делать из отладчика и должны выполнить код, чтобы получить его бывает например) - person old_timer; 18.02.2021
comment
Я уже видел такие вещи с пико, когда пытался выяснить загрузчик второго этапа, я предполагаю, что отладчик проходит через другую шину ahb, чем код примера подключается к флэш-памяти spi, поэтому должен был выполнить код не просто читайте/пишите через openocd. - person old_timer; 18.02.2021