zheka 1 19 января, 2017 Опубликовано 19 января, 2017 (изменено) · Жалоба Господа, я понимаю, что причину моей проблемы вы не найдете, но может быть подскажете, как искать ошибку. А может быть и констатируете, что это не ошибка, а глюк отладчика... Суть такова. Контроллер STM32F103, в нем включен USART. В обработчике прерывания по приему заполняется буфер, объявленный как uint8_t rx_buffer[50]; Буфер кольцевой. Работаю с KEIL. Отлаживаю по SWD, в окно watch я добавил rx_buffer. Проблема в чем - в эту переменную, согласно уведомлениям отладчика, периодически в случайные позиции на мгновение вместо 0x00 записывается 0xFF или 0xAA. При этом единственное место в программе, где в эту переменную что-то пишется - это обработка прерывания по приему, я ставил брейкпоинт на эту единственную строку - не срабатывает. Потому как я для чистоты эксперимента вообще отключил источник данных. Я закомментировал практически всю программу main() { while(1) { LCD_DrawFill(0,0,30,30,BLACK); } } Выяснилось, что глюк появляется когда присутствует именно эта строка. ну и анализ и комментирование строк в этой функции привели к тому, что глюк вызывается при записи в регистр данных SPI3. Я бы обозначил эту проблему, как конфликт SPI и RAM если бы не два "но". 1. В SPI ведется запись еще несколькими функциями, но проблема возникает только в одной из них. 2. Я написал кусок кода, который в цикле проверяет каждый элемент rx_buffer на предмет отличия его от изначального 0x00 и поставил на нем брейкпоинт. Понимая, что проверка и кратковременное изменение буфера могут не совпасть по времени, я запустил программу на ночь, по моим прикидкам буфер должен был быть проверен около 3 миллионов раз. Ни разу програма не засекла вмешательство в буфер. Похожие глюки, с записыванием данных не в те переменные у меня была как-то, когда я объявил безразмерный массив ( uint8_t XXX[]; ) Но в данном случае ничего такого у меня нет. Скажите, возможно ли что отладчик брешет? Как используя средства отдладки KEIL подловить момент записи в переменную и определить кто на нее посягает? Изменено 22 ноября, 2022 пользователем haker_fox Уточнил название темы, добавил теги, переместил в нужный раздел. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 19 января, 2017 Опубликовано 19 января, 2017 · Жалоба Скажите, возможно ли что отладчик брешет? Наверное. Тут нужно в деталях разбираться, как работает отладчик. Как используя средства отдладки KEIL подловить момент записи в переменную и определить кто на нее посягает? Обычно это называют watchpoint, вроде бы. У Кейла это называется data breakpoint. Если настроить всё как надо, отладчик остановится в тот момент, когда процессор попробует записать что-то в указанный диапазон адресов. Он не остановится, если туда полезет DMA, но это не ваш случай, насколько я понял. Кстати, с тактированием всё нормально? Может быть, вы дико разогнали МК, не заметив этого, и он странно глючит? Или шум в цепи Vdda? Ещё можно поварьировать частоту SWCLK. Если наблюдается неустойчивое соединение, можно повесить на цепь SWCLK маленькую ёмкость (десятки пФ) на землю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 19 января, 2017 Опубликовано 19 января, 2017 (изменено) · Жалоба Кстати, с тактированием всё нормально? Может быть, вы дико разогнали МК, не заметив этого, и он странно глючит? Или шум в цепи Vdda? Работаю с макеткой, которая хоть и китайская, но за 5 лет меня подобным образом ни разу не подводила. У меня ничего не разогнано. Вы понимаете, в чем парадокс? За то, что это глюк отладчика говорит тот факт, что сам контроллер, его код, науськанный на непрерывное отслеживание изменений в буфере, не обнаруживает таковых. За то, что проблема в контроллере и программе говорит тот факт, что отключение записи в SPI сохраняет данные в буфере в целостности. Еще одна особенность, которую я не могу трактовать в пользу чего либо - если в буфере 0x00, то пишется FF или AA. А если какие-то данные есть, то там оказывается другое число. Понимаете, если бы туда шла запись, то писалось бы конкретное число, а тут идет порча битов. Самое интересное, что, как я уже писал, в работе программа не ощутила изменений в буфере за 3 миллиона его проверок. То есть либо изменение кратковременное, либо это брехня. Ну а если бы и ощутила, протокол, который я собираюсь использовать, предполагает проверку контрольной суммы и данные были бы запрошены повторно. То есть можно смело выпускать устройство. Но все равно меня этот глюк гложет... Скажите, а можно ли как то при объявлении переменной приказать ей разместиться в строго определенном адресе? Ну или... если я чисто по тексту программы размещу ее в самом начале, она окажется по другому адресу? Если это глюк и что-то в программе лезет по определенному адресу, где у меня случайным образом оказался rx_buffer, то проблема именно с этой переменной должна исчезнуть. Это будет свидетельствовать в пользу глюка отладчика. Изменено 19 января, 2017 пользователем zheka Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 19 января, 2017 Опубликовано 19 января, 2017 · Жалоба Господа, я понимаю, что причину моей проблемы вы не найдете, но может быть подскажете, как искать ошибку. А может быть и констатируете, что это не ошибка, а глюк отладчика... Я бы посмотрел (по карте памяти), какие переменные размещены до и после исследуемого буфера ("обрамляют" его) . Причина: не исключено, что в процедурах, работающих c "обрамляющими" переменными, нарушается некий указатель. Вторая тема: размер и размещение стэка. Третья тема: наличие, размер и размещение кучи (HEAP). Явно кто-то влазит на исследуемый буфер. Я также работаю с KEIL. Он может показывать чушь содержимого переменной, если смотреть переменную через watch (особенно при включенной оптимизации кода), но до сих пор KEIL мне всегда показывал правду, если смотреть память по адресу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 19 января, 2017 Опубликовано 19 января, 2017 · Жалоба Я бы посмотрел (по карте памяти), Это где примерно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 19 января, 2017 Опубликовано 19 января, 2017 · Жалоба Как используя средства отдладки KEIL подловить момент записи в переменную и определить кто на нее посягает? Насчёт Кейла не скажу, но у Вас же Cortex-M3? В нём есть MPU. Выносите rx_buffer в отдельную секцию памяти, выравниваете ещё положение и размер на 64 байта (например), закрываете к ней доступ по записи через MPU, приоткрывая его временно только в точке записи (в ISR) (на всякий случай запретив прерывания на это время (или назначив прерыванию rx_buffer наивысший приоритет из всех)). Если в каком-то другом месте будет попытка записи в эту область - сразу получите исключение, проанализируете его источник - найдёте виновника. Я таким образом не раз решал проблемы со случайными записями в переменные. Обычно это называют watchpoint, вроде бы. У Кейла это называется data breakpoint. Если настроить всё как надо, отладчик остановится в тот момент, когда процессор попробует записать что-то в указанный диапазон адресов. Он не остановится, если туда полезет DMA, но это не ваш случай, насколько я понял. Плохой метод. Наличие watchpoint-ов вызывает изменение временной диаграммы работы программы (вызывает резкое её замедление). Видимо потому, что анализ условия watchpoint выполняется программно в ПО эмулятора (или отладчика?). Изменение времянки может привести к исчезновению проблемы. Применение MPU - менее инвазивный метод. Ещё другой способ: Запускаете высокочастотное прерывание от любого таймера. Частотой 500-1000кГц (зависит от производительности процессора). Так чтобы оно грузило процессор процентов на 50% или больше. В ISR сравниваете какие-то части rx_buffer с копией (Ваш ISR, который пишет в rx_buffer, должен дублировать запись и в его копию). Назначаете приоритет прерывания записи rx_buffer самым высоким, прерывания от таймера - выше других, но ниже прерывания пишущего rx_buffer. Если при очередной проверке данные не совпали - читаете из стека в какой точке идёт выполнение фоновой программы. Если обработчик таймера будет коротким (лучше на асм), то сможете обнаружить точку модификации с точностью до примерно десятка команд или меньше. Но конечно этот метод сильнее влияет на выполнение самой исследуемой программы чем метод с MPU. Да и весь rx_buffer сразу в одном прерывании не проконтролируешь, только 1-2 32-битных слова. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 19 января, 2017 Опубликовано 19 января, 2017 · Жалоба Насчёт Кейла не скажу, но у Вас же Cortex-M3? В нём есть MPU. Указано же, что это STM32F103. Нету там никакого MPU. Плохой метод. Наличие watchpoint-ов вызывает изменение временной диаграммы работы программы (вызывает резкое её замедление). Видимо потому, что анализ условия watchpoint выполняется программно в ПО эмулятора (или отладчика?). Когда я пользовался этой штукой, у меня ничто не замедлялось. Там же есть аппаратный watchpoint - вот он и был задействован, очевидно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 19 января, 2017 Опубликовано 19 января, 2017 · Жалоба Когда я пользовался этой штукой, у меня ничто не замедлялось. Там же есть аппаратный watchpoint - вот он и был задействован, очевидно. Как раз я (под IAR) когда его пробовал - было резкое замедление, во много раз. Поэтому тогда и реализовал метод с высокочастотным таймером. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 38 19 января, 2017 Опубликовано 19 января, 2017 (изменено) · Жалоба Опередили про MPU… PM0056 STM32F10xxx Cortex-M3 programming manual: About the STM32 core peripherals 0xE000ED90-0xE000ED93 MPU type register Reads as zero, indicating no MPU is implemented(1) Изменено 19 января, 2017 пользователем Obam Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 19 января, 2017 Опубликовано 19 января, 2017 · Жалоба 0xE000ED90-0xE000ED93 MPU type register Reads as zero, indicating no MPU is implemented(1) Не надо использовать такие МК. ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 38 19 января, 2017 Опубликовано 19 января, 2017 · Жалоба "Кутузов был без глаза. Нет! У Кутузова не было глаза!" Не надо использовать такие МК. ;) STM чумовая контора: с rev3 (PM0056) руководства по программированию в CM3 - есть MPU! Что меня и смутило: как так в L152 - есть, а в F103 вдруг нет?! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 19 января, 2017 Опубликовано 19 января, 2017 · Жалоба STM чумовая контора: с rev3 (PM0056) руководства по программированию в CM3 - есть MPU! Не надо наговаривать: This section describes the Memory protection unit (MPU) which is implemented in some STM32 microcontrollers. Refer to the corresponding device datasheet to see if the MPU is present in the STM32 type you are using. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 19 января, 2017 Опубликовано 19 января, 2017 (изменено) · Жалоба ///// Господа, в общем вывод такой - это глюк даже не отладчика, а самого кейла. Никто мне в переменную ничего не пишет. Об этом свидетельсвтует следующее 1.Несмотря на то, что по сообщениям окна watсh, переменную rx_buffer кто-то упорно насилует, брейкпоинты на запись не срабатывают. При этом они срабатывают когда туда на самом деле осуществляется запись. 2. Как я заметил, байт, который оказывается в буфере, зависит от того, что там было раньше. Если бы шла запись в переменную, то ее содержимое просто затиралось бы конкретным числом, а тут мусор есть производное от первоначального значения. Мне сложно представить себе такой глюк или конфликт с памятью, при котором из буфера что-то будет читаться, затем с полученным результатом что-то делается и результат записывается в ячейку.... А вот на порчу отдельных бит это похоже. Более того, как я писал, появление левых данных всегда кратковременное, через долю секунды данные возвращаются к исходному виду. Опять таки, мне сложно представить глюк, который считывает данные, гадит, а потом восстанавливает. Зато это очень похоже на периодическое искажение выведения результата кейлом - то есть данные в буфере постоянны, иногда KEIL считав их, теряет их правильность и выводит на экран бред, но при следующем чтении тех же самых правильных данных все нормально. Изменено 19 января, 2017 пользователем zheka Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 20 января, 2017 Опубликовано 20 января, 2017 · Жалоба Зато это очень похоже на периодическое искажение выведения результата кейлом - то есть данные в буфере постоянны, иногда KEIL считав их, теряет их правильность и выводит на экран бред, но при следующем чтении тех же самых правильных данных все нормально. В чём проблема проверить это? Когда появились странные данные, нажать кнопочку "Refresh" чтобы обновить данные в окне "watch". Или в кейле нет такой кнопочки? Мне сложно представить себе такой глюк или конфликт с памятью, при котором из буфера что-то будет читаться, затем с полученным результатом что-то делается и результат записывается в ячейку.... А вот на порчу отдельных бит это похоже. Например - при доступах через bitband. Хотя в Вашем МК и его похоже тоже нету... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 20 января, 2017 Опубликовано 20 января, 2017 · Жалоба Господа, в общем вывод такой - это глюк даже не отладчика, а самого кейла. Зато это очень похоже на периодическое искажение выведения результата кейлом - то есть данные в буфере постоянны, иногда KEIL считав их, теряет их правильность и выводит на экран бред, но при следующем чтении тех же самых правильных данных все нормально. Я бы не спешил ругать Кейл. Всё-таки он полагается на дрова для отладочного адаптера, которые написаны другими товарищами, и в них возможны глюки. Кроме того, весьма вероятно, что в протоколе SWD нет средств контроля целостности данных, поэтому в случае порчи сигналов SWD получите то, что получили. А тут уже вы виноваты - не надо портить сигналы :laughing: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться