Прерывание SysTick не срабатывает, если GDB подключен до его включения - PullRequest
0 голосов
/ 30 января 2019

У меня есть микро ATSAMD21E18A, который я использую с полу-хостингом.Для того чтобы полу-хостинг работал, GDB необходимо «подключить» перед первой инструкцией bkpt.С другой стороны, я необъяснимым образом обнаружил, что прерывание SysTick не сработает, если GDB уже был подключен, когда я его настраивал.Если я хочу, чтобы прерывание SysTick сработало, я должен выполнить сброс (отключение питания с помощью кнопки) и сказать GDB продолжить, когда он еще не настроил микро (то есть он не отправил точки останова иличто-нибудь еще), а затем нажмите Ctrl-C, чтобы инициализировать режим отладки после конфигурации SysTick, но прежде чем мы доберемся до initialise_monitor_handles.

Я убедился, что функция запуска only копирование поверхперемещаемый сегмент данных, обнуление нулевого сегмента и установка правильного начального значения указателя стека.Мы пишем наш код без библиотек, таких как CMSIS.

Также я могу подтвердить, что у меня нет проблем, когда отладчик не подключен (JLinkGDBServer через Atmel SAM-ICE), кроме необходимости удалять вещи с полу-хостингом..

Кроме того, СЧЕТЧИК SysTick по-прежнему правильно считает, даже если сами прерывания не срабатывают.Кроме того, бит ожидания 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
}

Я видел некоторые похожие кажущиеся вопросы здесь в StackOverflow, но ониказалось, слишком расплывчатым, чтобы получить хорошие ответы.

Редактировать: Здесь, возможно, соответствующие значения регистров, взятых во время цикла занятости для цикла, который не вызывает обработчик 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 в нужное время после полной перезагрузки, он работает какs!

Edit Я обнаружил, что у меня возникло недоразумение, когда я подумал, что выполнение load в GDB произвело программный сброс.С тех пор я обнаружил, что хотя он возвращает выполнение для сброса вектора, различные периферийные устройства и другие регистры фактически не сбрасываются.Если я выполняю программный сброс в GDB с помощью monitor reset, тогда мне не нужно нажимать Ctrl-C для задержки GDB, и будут работать и SysTick, и SemiHosting.

Проблема возникает, когда SysTick настроен изатем load запускается в GDB без явного жесткого или программного сброса.В этом случае SysTick не запускает прерывания.Большая часть моей отладки прошла так: загрузка нового кода и немедленное ожидание его работы, чтобы я мог оценить его.Просто запустить monitor reset - лучший обходной путь, чем раньше, но я все же предпочел бы знать причину неправильного поведения SysTick!

1 Ответ

0 голосов
/ 30 января 2019

Я бы посетил Справочное руководство по архитектуре 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) установленчто-то вменяемое.

У меня нет представителя, чтобы комментировать ваш вопрос, но я надеюсь, что это поможет вам продвинуться в продуктивном направлении:)

...