Ruslan1 17 21 июля, 2015 Опубликовано 21 июля, 2015 · Жалоба Нет ли еще идей? Извините если глупость сморожу, но может просто технологический дефект во время изготовления? две штуки не статистика. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexeyT 0 21 июля, 2015 Опубликовано 21 июля, 2015 (изменено) · Жалоба Извините если глупость сморожу, но может просто технологический дефект во время изготовления? две штуки не статистика. Думали уже в эту сторону. Не совсем 2, было 3 - один сожгли( Но образцы, которые у нас, прошли отбраковку как на пластине, так и после корпусирования. Поэтому здесь было предположение, что какой-то сбой тестами не обнаруживается. Кроме функциональных тестов производителя, мы сами еще гоняли проблемную область памяти на чтение-запись, сбоев не обнаружили даже на высокой скорости. Кроме того, дефект кристалла не объясняет работоспособность программы при пошаговом исполнении в debug'е Изменено 21 июля, 2015 пользователем AlexeyT Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 22 июля, 2015 Опубликовано 22 июля, 2015 · Жалоба Нет ли еще идей? 1. Проблема именно при передаче управления в другой 32К сегмент? 2. Или при длинном переходе (исполнение инструкции, позволяющей больший диапазон расстояний перехода)? Проверьте точно. Расположив источник вызова и целевой адрес близко к границе. А если пересечение границы происходит без передачи управления, просто код находится на границе сегментов? Если первое, то какова конфигурация шин и регионов памяти в данном МК? Во многих МК ОЗУ разбита на банки с отдельными шинами доступа к ним (часто они по соседним адресам). Возможно, что какие-то банки могут быть отключены (или тактирование для них идёт на другой частоте, или ...) и надо их включить где-то в регистрах периферии. При пошаговой отладке, отладчик может незаметно автоматом их включать. Просто доступ по чтению/записи данных в эти сегменты есть? А если прочитать целевой адрес перехода как данные, а потом перейти на него? DMA и прочие bus-master-ы активны? Может конфликт CPU с другим bus-master? Если второе - какие именно инструкции перехода по адресу вызывают сбой? Пробовали разные (B/BL с разными длинами смещения, BX/BLX, MOV PC, ...)? есть ли разница по инструкциям? Смотрели map-файл? Не создаётся-ли промежуточная функция подскока для данного вызова? Например IAR, при вызове функций, находящихся далеко (за пределами макс. дальности инструкции BL), создаёт спец. функцию (обзывает её Venner) возле источника вызова, на которую и прыгает BL, а внутри находится одна инструкция LDR PC, [PC, #0] с целевым адресом. Может компилятор генерит что-то подобное? 3. Так как в пошаговом режиме проблема не проявляется, может источник проблемы совсем не выполнение кода в текущем потоке? Может возникает какое-то прерывание или исключение, а у Вас не проинициализирован NVIC и таблица прерываний? Проинициализируйте их, запрет прерываний может не помогать, так как есть немаскируемое прерывание и исключения. Также - как работает отладчик с этими сегментами: ставит бряки программные или аппаратные? В каком состоянии находится MPU? Инициализировали его? То что Вы привели в первом посте: 0800_01DC: 7047 BX LR 0800_BE46: 4E21 MOV R1, #78 //где-то здесь падаем 0800_BE48: 6D48 LDR R0, [PC, #+0x1B4] //где-то здесь падаем 0800_BE4A: F4F7B6F9 BL #-0xBC94 0800_01BA: 0246 MOV R2, R0 не похоже на код, это какой-то мусор. По этим адресам вообще память есть? По каком адресам расположен сегмент кода? Может у Вас элементарный баг в программе и управление улетает по случайнвм адресам? Приведите карту памяти МК. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
-=Sergei=- 0 22 июля, 2015 Опубликовано 22 июля, 2015 · Жалоба У нас 2 экземпляра, результаты одинаковые. Разработчики микросхемы гоняли на модели - у них все ок. Если есть проблема в реализации кристалла, то наша задача - помочь её им определить. Высказанные выше конструктивные идеи: 1) прерывания и 2) увеличенная задержка при обращении через границу блоков проверяем. Нет ли еще идей? Делайте фейковую константу по этому адресу где происходит сбой. Перекомпилируйте код, проверяйте далее. Теперь код точно не будет в этой ячейке. И вот еще ссылка на анализ ситуации в HardFaulte. http://community.arm.com/servlet/JiveServl...20for%20ARM.pdf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexeyT 0 23 июля, 2015 Опубликовано 23 июля, 2015 · Жалоба Приведите карту памяти МК. Секция CODE (доступ по I, D шинам) 0x0000_0000-0x0000_0FFF Область для загрузчика, отражается на внешнюю шину 0x0800_0000-0x0805_FFFF Область внутреннего ОЗУ с пользовательской программой 0x1000_0000-0x1FFF_FFFF Область доступа к внешней системной шине Секция DATA 0x2000_0000-0x2000_03FF Область ОЗУ на внешней системной шине 0x2000_0400-0x2001_FFFF Область внутреннего ОЗУ данных, доступ по D шине 0x3000_0000-0x3FFF_FFFF Область доступа к внешней системной шине Peripheral 0x4000_0000-0x4002_F00C Периферия EXT_BUS 0х6000_0000-0x9FFF_FFFF Внешняя системная шина System 0xE000_0000-0xEFFF_FFFF Системная область ядра Чтобы отмести подозрения на загрузчик - он не используется, идет напрямую загрузка bin-файла в ОЗУ через SWD. Потом выставляется MSP, VTOR, PC - и запуск на исполнение. Если первое, то какова конфигурация шин и регионов памяти в данном МК? Во многих МК ОЗУ разбита на банки с отдельными шинами доступа к ним (часто они по соседним адресам). ОЗУ инструкций не разбита на банки, с точки зрения системы - единый блок Возможно, что какие-то банки могут быть отключены (или тактирование для них идёт на другой частоте, или ...) и надо их включить где-то в регистрах периферии. Тактирование общее на весь блок памяти, всегда включено Просто доступ по чтению/записи данных в эти сегменты есть? Просто доступ на чтение/запись есть на всю ОЗУ инструкций, гоняли тестами. DMA и прочие bus-master-ы активны? Может конфликт CPU с другим bus-master? DMA есть, но неактивен, больше ведущих на шине нет. Также - как работает отладчик с этими сегментами: ставит бряки программные или аппаратные? Программные В каком состоянии находится MPU? Инициализировали его? Явно нет, стоят значения по умолчанию MPU->TYPE = 0x0000_0800. Унифицированная карта памяти, 8 регионов MPU->CTRL = 0x0000_0000. MPU запрещен То что Вы привели в первом посте: Цитата 0800_01DC: 7047 BX LR 0800_BE46: 4E21 MOV R1, #78 //где-то здесь падаем 0800_BE48: 6D48 LDR R0, [PC, #+0x1B4] //где-то здесь падаем 0800_BE4A: F4F7B6F9 BL #-0xBC94 0800_01BA: 0246 MOV R2, R0 не похоже на код, это какой-то мусор. По этим адресам вообще память есть? По каком адресам расположен сегмент кода? Это не мусор, это фрагмент кода). 0x0800_01DC – возврат из вызываемой функции putc(вывод символа по UART) в main. Main занимает пространство 0х0800_B8CA-0x0800_BF6C Затем идет подготовка к передаче нового байта. Вход в следующий putc – 0x8000_01BA, putc занимает адреса 0x0800_01BA – 0x0800_01DC Память по этим адресам есть (см. карту памяти), программа занимает адреса 0х0800_0000-0x0800_CCC0 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 23 июля, 2015 Опубликовано 23 июля, 2015 · Жалоба А там никаких конвейеров нигде не рушиться? если барьеров памяти и инструкций напихать что будет? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexeyT 0 23 июля, 2015 Опубликовано 23 июля, 2015 · Жалоба А там никаких конвейеров нигде не рушиться? если барьеров памяти и инструкций напихать что будет? Эммммм... Какие барьеры и куда напихать? Прошу пояснить Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 23 июля, 2015 Опубликовано 23 июля, 2015 · Жалоба . Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 23 июля, 2015 Опубликовано 23 июля, 2015 · Жалоба Это не мусор, это фрагмент кода). 0x0800_01DC – возврат из вызываемой функции putc(вывод символа по UART) в main. Main занимает пространство 0х0800_B8CA-0x0800_BF6C Затем идет подготовка к передаче нового байта. Вход в следующий putc – 0x8000_01BA, putc занимает адреса 0x0800_01BA – 0x0800_01DC Память по этим адресам есть (см. карту памяти), программа занимает адреса 0х0800_0000-0x0800_CCC0 Вы как-то странно написали... сразу трудно въехать... У Вас идёт команда по адресу 080001DC - возврат из функции и за ней сразу идёт команда по другому адресу... Это адрес, на который происходит возврат? Далее идёт загрузка R1 и за ней - загрузка константы с адреса [0x8000BFFE]. 0x8000BFFE по Вашим словам находится сразу за функцией main() - там похоже лежит таблица констант, используемых в main(). Так вот, я Вас спрашивал - по адресу 0x8000BFFE какие-то данные (согласно map-файлу) есть? И кстати - адрес 0x8000BFFE (если я правильно посчитал) выровнен на границу 2, а доступ в команде LDR R0, [PC, #+0x1B4] осуществляется к двойному слову (32бит). В ядре Кортекс можно включить запрет невыровненных доступов к памяти, тогда будет генериться исключение (не помню какое). У Вас это разрешено? А если оно разрешено, но не разрешены всякие MMfault и UserFault, то будет происходить эскалация до HardFault насколько я помню. Да и вообще странно, что компилятор генерит такой невыровненный код.... Попробуйте поставить бряк на точку входа в ISR HardFault и выполнить эту команду, а потом попробуйте подровнять адрес на 4 и сделать то же самое. ЗЫ: Кстати - у Вас putc() похоже какая-то очень простая, раз выход из неё BX LR... :) Секция CODE (доступ по I, D шинам) 0x0000_0000-0x0000_0FFF Область для загрузчика, отражается на внешнюю шину 0x0800_0000-0x0805_FFFF Область внутреннего ОЗУ с пользовательской программой 0x1000_0000-0x1FFF_FFFF Область доступа к внешней системной шине Раз в МК есть разделение ОЗУ на ОЗУ для кода и данных, то может быть что первая часть не поддерживает невыровненный доступ. Область для загрузчика, отражается на внешнюю шину - а сам загрузчик не встроенный в МК что-ль??? Чтобы отмести подозрения на загрузчик - он не используется, идет напрямую загрузка bin-файла в ОЗУ через SWD. Потом выставляется MSP, VTOR, PC - и запуск на исполнение. Обычно это (стек и PC) выставляется первым вектором таблицы прерывания, с которого CPU их считывает при подаче reset-а эмулятором. CFSR 0x00000100 Этим 8-мым битом CPU Вам говорит: A bus fault on an instruction prefetch has occurred. The fault is signalled only if the instruction is issued. И у меня вызывает большие подозрения Ваша строка: 0800_BE4A: F4F7B6F9 BL #-0xBC94 Это вызов функции? Скорее всего именно она и вызывает fault. Точно узнать можно по содержимому стекинга. Память тестировали - записывали данные, считывали - все ОК, память работоспособна, но при переходе границы 32-кБ блоков происходит HardFault: PC = 0x0800016A, LR = 0xFFFFFFE9, XPSR = 0x21000003 Вы привели неправильные регистры. Это состояние регистров внутри ISR. Толку от него мало. Вам нужно привести регистры сохранённые при стекинге при входе в fault. Прочитайте раздел описания ядра кортекс, посвящённый описанию стекинга и формата сохраняемых регистров. Тогда узнаете значение PC перед срабатыванием fault. Ещё - проверьте стек. Может он у вас элементарно переполняется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexeyT 0 23 июля, 2015 Опубликовано 23 июля, 2015 · Жалоба Покрутить тактирование, питание и посмотреть, будут ли изменения. Про тактирование уже писали - сбрасывали до 100 кГц, результат такой же. Сейчас проверили и с питанием - во всем диапазоне напряжений питания результат такой же. А там никаких конвейеров нигде не рушится? Если барьеров памяти и инструкций напихать, что будет? Будем пробовать, т.к. на этом проекте падаем при возврате в основную функцию из вызываемой. Вы отладчиком в окне дизассемблера прошлись? Удалось найти инструкцию, на которой "всё падает"? Да, и не раз. Повторюсь - при пошаговом исполнении из отладчика (s) программа работает до тех пор, пока пользователю не надоест запускать пошагово. При запуске на исполнение из отладчика (g) - падаем вскоре после начала работы основной функции main. В этом конкретном случае падаем в вызываемой функции putc, во втором вызове по ходу исполнения основной программы. При первом вызове она отработала нормально. Ещё - проверьте стек. Может он у вас элементарно переполняется. С переполнением стека сталкивались в самом начале. С тех пор стека МНОГО:) MSP = 0x20014870 при запуске программы, MSP = 0x20013B00 при падении. Используется 0xD70 из выделенных 0x4000 Вам нужно привести регистры сохранённые при стекинге при входе в fault. R0 = 0x40002000, R1 = 0x00000052, R2 = 0x40002000, R3 = 0x000003e8 R12 = 0x2000084C, LR = 0x0800BE47, PC = 0x07FF4FBE, xPSR = 0x21000000 !!! PC улетает ниже области, где лежит программа( Но почему при первом вызове той же процедуры все работает??? Обычно это (стек и PC) выставляется первым вектором таблицы прерывания, с которого CPU их считывает при подаче reset-а эмулятором. По ресету управление передается на 0х0, где должен лежать загрузчик. Как в эмуляторе, так и на железе. Сам загрузчик не встроенный в МК что-ль??? Таки да. Микросхема ОКРовская, есть нюансы. Есть вывод, в зависимости от которого обращения в область 0х0-0х1000 отправляются либо на внешнюю шину, либо на внутреннюю ПЗУ с кодом загрузчика. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 24 июля, 2015 Опубликовано 24 июля, 2015 · Жалоба R0 = 0x40002000, R1 = 0x00000052, R2 = 0x40002000, R3 = 0x000003e8 R12 = 0x2000084C, LR = 0x0800BE47, PC = 0x07FF4FBE, xPSR = 0x21000000 !!! PC улетает ниже области, где лежит программа( Но почему при первом вызове той же процедуры все работает??? Точка возврата в LR правильная, а команда 0800_BE46: 4E21 MOV R1, #78 уже не была выполнена. Хмммм.... да уж.... Я бы ещё попробовал позаменять регистр возврата LR на какой другой или вернуться через стек POP {PC} или попробовать выровнять целевую точку возврата на 4... Но походу явно тут торчат ослиные уши "отечественного предприятия". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexeyT 0 24 июля, 2015 Опубликовано 24 июля, 2015 · Жалоба или попробовать выровнять целевую точку возврата на 4... Как это можно сделать средствами компилятора для проекта на С? Разговоры про отладчик наводят на грустные мысли про прерывания, которые как-то включились, но вектора не прописаны. В пошаговом режиме они запрещены. Проверили регистры при падении - действительно, кроме исключения HardFault, есть прерывания, ожидающие обслуживания. Обработчики для них прописаны. Но они маскируемые, и по умолчанию (в программе) не разрешены. Если разрешить их обработку из отладчика, после какого-нибудь из breakpoint'ов, то попадем в исключение DebugMonitor (№=12). Это правильная логика работы, или здесь торчат ослиные уши? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 24 июля, 2015 Опубликовано 24 июля, 2015 · Жалоба Как это можно сделать средствами компилятора для проекта на С? на си - вряд-ли. Сделайте отдельную функцию на асме в пределах 32К исходной точки вызова. А уже из неё - выровненный вызов за пределы 32К. Но они маскируемые, и по умолчанию (в программе) не разрешены. Если разрешить их обработку из отладчика, после какого-нибудь из breakpoint'ов, то попадем в исключение DebugMonitor (№=12). Это правильная логика работы, или здесь ? Даташита нет под рукой, но насколько помню, в системной области есть регистр, в котором разрешаются различные fault-ы. Там, среди прочих, вроде есть разрешение DebugFault. Видно Вы случайно разрешили его. Его вроде только отладчик может использовать/разрешать. Проверьте. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexeyT 0 25 июля, 2015 Опубликовано 25 июля, 2015 · Жалоба Даташита нет под рукой, но насколько помню, в системной области есть регистр, в котором разрешаются различные fault-ы. Регистр такой есть. SCB->SHCSR (0xE000ED24). Но в нем устанавливаются только UsageFault, BusFault, MemFault. По умолчанию все обработчики были запрещены. При их разрешении и намеренных ошибках процессор стал падать не в Hard, а в Usage или Bus. Но вот основной косяк объяснению не поддается . Имеем один и тот же простейший проект, с чуть разными картами памяти. 64 КБ разбиты на 2 части по 32 КБ. В первом случае (Проект55) в верхнюю область памяти закинуты лишь 3 простых пользовательских функции. Во втором (Проект56) - в верхнюю область линкер на свое усмотрение закинул и часть системных. При этом Проект55 - работает, Проект56 - падает в UsageFault. Активные регистры при падении: LR=0xFFFFFFF9 (9 - использовался основной стек), MSP=0x20005370 (использовано 0xF0 из 0x1000), PC=0x08008080 (UsageFault_Handler), xPSR=0x01000006 (UsageFault) В стеке лежат: LR=0x080080CB (следующая после команды _dadd), PC=0x08008184 (SUBS - вроде ничего страшного. А вот команда перед ней, BMI.W 0x0800033C - условно-подозрительная) xPSR=0x01000000. ______55.zip ______56.zip Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexeyT 0 28 июля, 2015 Опубликовано 28 июля, 2015 (изменено) · Жалоба Тестовая программа стала работать при вот таких изменениях: 1) НЕ РАБОТАЛО (сваливалось в Hard Fault): main() { ..... qq = simple_proc_int(ww,ee);//Hard Fault ... } 2) ЗАРАБОТАЛО: main() { ... *(volatile unsigned int*)(0x30010000) = 0xFFFF5500; // пишем во внешнюю шину неважно какие значения *(volatile unsigned int*)(0x30010000) = 0xAAAAFF01; // пишем во внешнюю шину неважно какие значения *(volatile unsigned int*)(0x30010000) = 0xFFFF5500; // пишем во внешнюю шину неважно какие значения qq = simple_proc_int(ww,ee);//нормально проходим, в Hard Fault не сваливаемся! ... } Здесь int simple_proc_int(int a, int B) { int c = 0; c += a<<2; c += b<<3; return c; } - элементарная тестовая функция, записанная в другом 32-кБ сегменте памяти. Память данных условно разбита на 2 сегмента по 32 кБ. "Условно" - потому что с точки зрения процессора, вся память представляет собой единый массив до 128 кБ. Проект57 - в верхнем сегменте памяти только тестовые функции, исполняется корректно. Между всеми вызовами тестовых функций стоят обращения на внешнюю шину. Проект58 - линкер закинул в верхний сегмент памяти часть системных функций, но проект исполняется. Между всеми вызовами тестовых функций стоят обращения на внешнюю шину. Проект59 - в верхней части находятся тестовые и часть системных функций. Но обращения стоят только в начале и конце процедуры main. Проект НЕ исполняется, падает в UsageFault при выполнении процедуры a = simple_proc_dbl(b,c). Вроде бы времена обращений - но при пошаговом исполнении из-под отладчика проект59 также не работает. Кто-то может предположить причины такого бреда? _______.rar Изменено 28 июля, 2015 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться