Keil uVision 5: Не работает пошаговая отладка в исходном коде!

Как это часто бывает, многие из нас очень любят настраивать workflow под себя, в каждом приложении. И зачастую не вдаёмся в подробности, а так же не запоминаем что и где изменили. Так и в данном случае, решив поиграться с настройками проекта и отладки, «настроил» я Keil под себя… и внезапно у меня перестал шагать отладчик по исходному коду. Работать работает, но шагает и брэйкпоинты ставить даёт только в дизассемблинг области. «Ну да ладно.....» — подумал я, и поначалу забил на это дело. Но через пару дней работы над заказом мне надоело постоянно переключаться в режим симуляции и обратно. К тому же всё что работает в симуляторе не всегда работает в железе, думаю многие об этом знаю уже не понаслышке.

Так вот вдоволь намучившись, я решил разобраться в чём проблема. Причём это проблема сопровождала только один проект. Все остальные работали в режиме отладке без нареканий. После долгих поисков решения в сети, я наткнулся на комментарии на форуме Keil-а. Который и помог мне в решении этого вопроса. Но так, как я достаточно долго искал решение, и за это время прочитал очень много рекомендаций, то решил их все собрать в одном месте. Итак начнём…

В первую очередь в свойствах проекта(Alt+F7), на вкладке «Debug», проверить наличие галок в пунктах «Load Application at Statup» и «Run to main()». Они нужны чтобы отладчик при старте проходил до функции main(). Это сделано для удобства отладки и быстрого перехода к пользовательскому коду.



далее переходим в настройки отладчика/программатора:



на первой же вкладке(Debug) проверяем отсутствие галок «Verify Code Download» и «Download to Flash» в области «Download Options». Эти функции отвечают за использование встроенного загрузчика кода в J-Link-ах(https://www.segger.com/products/debug-probes/j-link/technology/ides/keil-mdk/). К слову, у меня эти функции были включены мной по не знанию. Как оказалось встроенный загрузчик Segger не умеет запускать код из flash-памяти устройства.



ну и последнее, проверить галку «Update Target before Debugging», во вкладке «Utilities», свойств проекта. Насколько я понял, он отвечает за загрузку прошивки в МК. Но не смотря на это, я всё равно перед отладкой всегда нажимаю F8, чтобы прошить скомпилированный файл в устройство.



На этом всё. Успешных разработок!

Передача данных по протоколу i2c

Ведомый в режиме передатчика

После приема адреса и очистки ADDR, ведомый отправляет байты из регистра DR в линию SDA через внутренний регистр сдвига.

Ведомый держит линию SCL до тех пор, пока ADDR не будет очищен, а регистр DR не будет заполнен данными, которые необходимо отправить (см. Рис. 270).

Когда принимается импульс подтверждения (acknowledge):
• бит TxE устанавливается аппаратным обеспечением и вызывается прерывание, если биты ITEVFEN и ITBUFEN установлены.

Если бит TxE установлен, и часть данных не была записана в регистре I2C_DR до окончания следующей передачи данных, то устанавливается бит BTF, и интерфейс ожидает, пока бит BTF не будет очищен чтением регистра I2C_SR1, за которым следует запись в регистр I2C_DR, SCL держится в низком уровне.



Ведомый в режиме приемника

После приема адреса и сброса ADDR ведомое устройство принимает байты из линии SDA в регистр DR через внутренний сдвиговый регистр. После каждого байта интерфейс последовательно генерирует:
• Импульс подтверждения (acknowledge), если бит ACK установлен
• Устанавливается бит RxNE аппаратным обеспечением и генерируется прерывание, если биты ITEVFEN и ITBUFEN установлены.

Если бит RxNE установлен, и данные в регистре DR не считываются до конца следующего приема данных, устанавливается бит BTF и интерфейс ожидает, пока BTF не будет очищен чтением регистра I2C_SR1, за которым следует чтение из регистра I2C_DR, SCL держится в низком уровне. (см. Рисунок 271).



1. Событие EV1 удерживает SCL до обработки программным обеспечением.
2. Последовательность программного обеспечения EV2 должна быть завершена до окончания текущей передачи байта
3. После проверки содержимого регистра SR1 пользователь должен выполнить полную последовательность очистки для каждого установленного флага.
Таким образом, для флагов ADDR и STOPF в процедуре прерывания I2C требуется следующая последовательность:
READ SR1
If (ADDR == 1) {READ SR1; READ SR2}
If (STOPF == 1) {READ SR1; WRITE CR1}
Цель состоит в том, чтобы обе флаги ADDR и STOPF были очищены, если оба установлены.