Прерывание SysTick не срабатывает, если GDB подключен до его включения.
У меня есть микро ATSAMD21E18A, который я использую с полу-хостингом. Для того чтобы полу-хостинг работал, GDB необходимо "подключить" перед первой инструкцией bkpt. С другой стороны, я необъяснимым образом обнаружил, что прерывание SysTick не сработает, если GDB уже был подключен, когда я его настраивал. Если я хочу, чтобы прерывание SysTick сработало, я должен выполнить сброс (отключение питания с помощью кнопки) и сказать GDB продолжить, когда он еще не настроил микро (то есть он не отправил точки останова или что-нибудь еще), а затем нажмите Ctrl-C, чтобы инициализировать режим отладки после настройки SysTick, но прежде чем мы доберемся до initialise_monitor_handles
,
Я проверил, что функция запуска копирует только перемещаемый сегмент данных, обнуляет нулевой сегмент и устанавливает правильное начальное значение указателя стека. Мы пишем наш код без библиотек, таких как CMSIS.
Кроме того, я могу подтвердить, что у меня нет проблем, когда отладчик не подключен (JLinkGDBServer через Atmel SAM-ICE), кроме необходимости удалять вещи с полу-хостингом.
Кроме того, SysTick COUNT все еще правильно считает, даже если сами прерывания не срабатывают. Кроме того, бит ожидания PysSTSET SysTick в ICSR фактически устанавливается, когда это происходит.
Мой код выглядит следующим образом:
int main()
{
// enable system timer interrupt
SYS_TICK->STATUS = 0; // (CSR)
SYS_TICK->PERIOD = 48000; // (RVR) fire at 1khz for 48mhz clock
SYS_TICK->STATUS = 0b111; // use processor clock, w/ interrupt, and enabled
SYS_TICK->COUNT = 1; // (CVR) avoid high unknown value
// dumb busy loop
util_idle_ms(2000); // <<< I hit Ctrl-C to break here!
initialise_monitor_handles();
// ... more system initialization and everything else
}
Я видел подобные похожие вопросы здесь, на Stackru, но они казались слишком расплывчатыми, чтобы получить хорошие ответы.
Редактирование: Здесь, возможно, приведены соответствующие значения регистров, взятые во время цикла занятости для цикла, который не вызывает обработчик SysTick (без аппаратного сброса, GDB подключен до настройки SysTick):
SYS_TICK_CSR/STATUS: 0x10007
SYS_TICK_RVR/PERIOD: 48000
SYS_TICK_CVR/COUNT: 5245 (varies of course)
NVC_ISER: 0 (and we expect this since SysTick is considered an exception, and not an interrupt)
DHCSR: 0x30003/0x1030003 (C_MASKINTS is not set; I've seen both values show up)
ICSR: 0x400f00f (it really wants to run the SysTick handler)
PRIMASK: 0
xPSR: 0x2100000f (IPSR is 0x0f/SysTick)
И для прогона, который вызывает обработчик SysTick просто отлично (полный сброс с подключением GDB после конфигурации SysTick):
SYS_TICK_CSR/STATUS: 0x10007
SYS_TICK_RVR/PERIOD: 48000
SYS_TICK_CVR/COUNT: 16892 (varies of course)
NVC_ISER: 0
DHCSR: 0x10003/0x1030003 (I've seen both values show up)
ICSR: 0 (SysTick handler already run)
PRIMASK: 0
xPSR: 0x2100000f
Так что значения регистров здесь, кажется, еще не открывают мне ничего нового... Пожалуйста, помогите сообщить мне о других потенциально важных регистрах, которые нужно проверить!
Просто для интереса, причина, по которой это важно для меня, заключается в том, что я получил gprof для работы с этим чипом на основе https://mcuoneclipse.com/2015/08/23/tutorial-using-gnu-profiling-gprof-with-arm-cortex-m/ И хотя мне нужно нажать Ctrl-C как раз в нужное время после полной перезагрузки, это работает так!
Изменить Я обнаружил, что у меня было недоразумение, где я думал, что работает load
в ГБД выполнен мягкий сброс. С тех пор я обнаружил, что хотя он возвращает выполнение для сброса вектора, различные периферийные устройства и другие регистры фактически не сбрасываются. Если я выполняю мягкий сброс в GDB с monitor reset
тогда мне не нужно Ctrl-C во время задержки, чтобы подключить GDB, и SysTick и SemiHosting будут работать.
Проблема возникает, когда SysTick настроен, а затем load
запускается в GDB без явного жесткого или программного сброса. В этом случае SysTick не запускает прерывания. Большая часть моей отладки прошла так: загрузка нового кода и немедленное ожидание его работы, чтобы я мог оценить его. Просто работает monitor reset
это лучший обходной путь, чем раньше, но я все же предпочел бы знать причину неправильного поведения SysTick!
1 ответ
Я бы посетил Справочное руководство по архитектуре ARM® v6-M и посмотрю, сможете ли вы получить от этого какие-то указания. https://static.docs.arm.com/ddi0419/d/DDI0419D_armv6m_arm.pdf
Обратите внимание на то состояние регистров, связанных с Systick, которое вы не включили в свой вопрос. Если вы не можете выяснить проблему на основе этих регистров, отредактируйте свой вопрос и опубликуйте здесь значения регистров (NVIC ISER, все регистры, связанные с конфигурацией systick, DHCSR и любые другие, которые, по вашему мнению, связаны). Они будут ключом к получению большего количества отзывов.
Регистр контроля и остановки состояния отладки (DHCSR) имеет возможность маскировать прерывания, включая пометку. Может быть, это устанавливается отладчиком?
Бит 3 DHCSR выглядит актуально
Я бы также проверил, что SYST_RVR (регистр значений перезагрузки Systick) установлен на что-то вменяемое.
У меня нет представителя, чтобы комментировать ваш вопрос, но я надеюсь, что это поможет вам продвинуться в продуктивном направлении:)