Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблемы с исполнением кода
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
AlexeyT
Есть проблема с исполнением кода на сделанном на отечественном предприятии процессоре ARM Corteх-M4F.

Кристалл флэш-памяти не имеет, прошивка загружается извне во встроенное ОЗУ объемом 128 кБ, которое используется как память программ. Есть ОЗУ объемом 68 кБ, которое используется как память данных.

Запустили успешно, но на объемах прошивки, превышающих 32 кБ, процессор зависал.
Путем последовательных упрощений нашли причину: процессор виснет при вызове функций, расположенных в разных 32 кБ сегментах (см.рисунок).

Т.е. если программа вызывает функцию f2(), расположенную в том же 32-кБ участке, что и остальная программа - все ОК. Причем все нормально работает независимо от того, в каком именно 32-кБ сегменте размещена программа. Стоит вызвать функцию (типа printf), размещенную в соседнем 32-кБ сегменте памяти - сваливаемся в HardFault.

Память тестировали - записывали данные, считывали - все ОК, память работоспособна, но при переходе границы 32-кБ блоков происходит HardFault:
PC = 0x0800016A, LR = 0xFFFFFFE9, XPSR = 0x21000003

Дебаггер показал, что падаем в районе вызова команды LDR
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


Есть идеи?
scifi
ЕМНИП, Cortex-M4 позволяет получить довольно много информации о причинах Hard Fault. Скажем, сохранённые в стеке регистры процессора, специальные регистры с информацией о причинах исключения и т.п. Почему бы вам не проделать это всё? Может быть, тогда вопрос решился бы сам собой?
редактор
Цитата
Есть проблема с исполнением кода на сделанном на отечественном предприятии процессоре ARM Corteх-M4F.

Если это Миландр, то камушек еще не отлажен, в процессе так сказать. Поэтому возможны всякие эксцессы.
Если кто-то еще эти занмется, хотелось бы подробностей (если не военная тайна).
AlexeyT
Цитата(редактор @ Jul 20 2015, 08:10) *
Если это Миландр, то камушек еще не отлажен, в процессе так сказать. Поэтому возможны всякие эксцессы.
Если кто-то еще эти занмется, хотелось бы подробностей (если не военная тайна).


http://mvc-nn.ru/продукция/микропроцессоры...кроконтроллеры/

Первый процессор из перечня
kolobok0
Цитата(AlexeyT @ Jul 20 2015, 14:01) *
...Первый процессор из перечня


OFF/2:
И тут оказалось, что выпустить железку это даже не половина, а самая малюсенький шажочек на общий рынок...


Obam
Любезный, AlexeyT, вам не здесь надо вопросы задавать, а напрямую в славный город НН.
Они должны с вас пылинки сдувать ( sm.gif вот сказанул, самому смешно), ведь представляете вы, подозреваю, не частную лавочку.
"Микросхемка"-то в специсполнении, стоит как самолёт.

Цитата(kolobok0 @ Jul 20 2015, 15:42) *
OFF/2:
И тут оказалось, что выпустить железку это даже не половина, а самая малюсенький шажочек на общий рынок...

Эти "игрушки" не для общего рынка, для него ST, Atmel, ну даже TI…
AlexeyT
Цитата
ЕМНИП, Cortex-M4 позволяет получить довольно много информации о причинах Hard Fault. Скажем, сохранённые в стеке регистры процессора, специальные регистры с информацией о причинах исключения и т.п. Почему бы вам не проделать это всё? Может быть, тогда вопрос решился бы сам собой?

Память Вас не подводит, позволяет. Но от анализа регистров легче не становится:

XPSR 0x21000003
CFSR 0x00000100
HFSR 0x40000000
AFSR 0x00000000
MMAR 0xE000EDF8
BFAR 0xE000EDF8

Т.е. выставлены биты ошибок IBUSERR, FORCED. Что IBUSERR - логично, при исполнении проекта из внешней памяти все работает. Что FORCED - непонятно, контроллер прерываний не инициализирован в пользовательской программе.
При этом падение в HardFault происходит при только исполнении программы из внутренней ОЗУ в реальном времени, при пошаговом исполнении той же самой программы из той же самой области памяти через отладчик - все работает.
Собственно и вопрос - в каком направлении есть смысл копать дальше?

Цитата
Если кто-то еще эти занмется, хотелось бы подробностей (если не военная тайна).

Описание на микросхему существует в виде рабочих материалов, цивильное появится примерно к концу ОКРа. На какие именно подробности стоит обратить внимание и выложить их здесь?
AlexeyT
Цитата(Obam @ Jul 20 2015, 15:03) *
Любезный, AlexeyT, вам не здесь надо вопросы задавать, а напрямую в славный город НН.
Они должны с вас пылинки сдувать ( sm.gif вот сказанул, самому смешно), ведь представляете вы, подозреваю, не частную лавочку.


Любезный Obam, что заставляет Вас думать, что в славном городе НН не пытались решить проблему? Микросхема ОКРовская (если Вам это о чем-то говорит), требовать техподдержки рано.

Хотелось бы таки предложений по решению
scifi
Цитата(AlexeyT @ Jul 20 2015, 16:43) *
Хотелось бы таки предложений по решению

Изучить явление поглубже. Попробовать все типы инструкций, пересекающие барьер 32 кб и посмотреть, какие из них работают, а какие - нет. Покрутить тактирование, питание и посмотреть, будут ли изменения.
Alex11
Разговоры про отладчик наводят на грустные мысли про прерывания, которые как-то включились, но вектора не прописаны. В пошаговом режиме они запрещены.
Golikov A.
скорее на время выполнения иснтрукций, в отладчике оно все дольше.

Может при переходе через границу памяти данные выбираются не за 1 а за 2 такта, и где то не хватает паузы? Даже не за 1, а за 1.5 такта, а отладчик в пошаговом режиме тянет все на меньшей частоте клока?
AlexeyT
Цитата(Golikov A. @ Jul 21 2015, 07:28) *
скорее на время выполнения иснтрукций, в отладчике оно все дольше.

Может при переходе через границу памяти данные выбираются не за 1 а за 2 такта, и где то не хватает паузы? Даже не за 1, а за 1.5 такта, а отладчик в пошаговом режиме тянет все на меньшей частоте клока?


Клок сбрасывали до килогерц - все также.

Мысль об увеличенном времени перехода через границу посещала, но как её измерить - есть идеи?

Располагаем логическим анализатором, подключенным к шине
редактор
Цитата
На какие именно подробности стоит обратить внимание и выложить их здесь?

Интересовали подробности о производителе-разработчике. Вся инфа будет закрыта (только по официальному запросу - гласит сайт). Грустно.

А по теме - склоняюсь к мнению предыдущих авторов - проблема выбора инструкций. Конвеер не успевает готовить данные для ядра. Скорее всего дополнительные задержки при чтении инструкций из разных блоков. В пользу этого варианта - работа с отладчиком.
Obam
Цитата(AlexeyT @ Jul 20 2015, 17:43) *
Любезный Obam, что заставляет Вас думать, что в славном городе…


Из моего поста совершенно не следует "что в славном городе НН…", а следует только то, что они должны (если солидная фирма) ухватиться за вас и помогать всем чем можно (и иногда чем нельзя). Форумное сообщество в данном случае, ну только, для психологической помощи.
Что такое "Микросхема ОКРовская", не сомневайтесь, знаю.

Кстати, ваша м/с код исполняет из ОЗУ (вы сами об этом писали), но cortex-m имеет регулярное адресное пространство (ни о каких страницах ни 32, ни сколько угодно речи быть не должно, или что, при 32-разрядном PC - ОЗУ с сегментной (по 32кБ) организацией?), частота ядра тоже не бог весть какая (тем более для работы с ОЗУ, тем более "…Клок сбрасывали до килогерц…"), так что выход один - "пинать" производителя и менять на другой экземпляр.
AlexeyT
Цитата(Obam @ Jul 21 2015, 09:24) *
Кстати, ваша м/с код исполняет из ОЗУ (вы сами об этом писали), но cortex-m имеет регулярное адресное пространство (ни о каких страницах ни 32, ни сколько угодно речи быть не должно, или что, при 32-разрядном PC - ОЗУ с сегментной (по 32кБ) организацией?), частота ядра тоже не бог весть какая (тем более для работы с ОЗУ, тем более "…Клок сбрасывали до килогерц…"), так что выход один - "пинать" производителя и менять на другой экземпляр.


У нас 2 экземпляра, результаты одинаковые. Разработчики микросхемы гоняли на модели - у них все ок. Если есть проблема в реализации кристалла, то наша задача - помочь её им определить.

Высказанные выше конструктивные идеи: 1) прерывания и 2) увеличенная задержка при обращении через границу блоков проверяем.

Нет ли еще идей?
Ruslan1
Цитата(AlexeyT @ Jul 21 2015, 10:42) *
Нет ли еще идей?

Извините если глупость сморожу, но может просто технологический дефект во время изготовления? две штуки не статистика.
AlexeyT
Цитата(Ruslan1 @ Jul 21 2015, 12:23) *
Извините если глупость сморожу, но может просто технологический дефект во время изготовления? две штуки не статистика.

Думали уже в эту сторону. Не совсем 2, было 3 - один сожгли( Но образцы, которые у нас, прошли отбраковку как на пластине, так и после корпусирования. Поэтому здесь было предположение, что какой-то сбой тестами не обнаруживается.
Кроме функциональных тестов производителя, мы сами еще гоняли проблемную область памяти на чтение-запись, сбоев не обнаружили даже на высокой скорости.

Кроме того, дефект кристалла не объясняет работоспособность программы при пошаговом исполнении в debug'е
jcxz
Цитата(AlexeyT @ Jul 21 2015, 13:42) *
Нет ли еще идей?

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=-
Цитата(AlexeyT @ Jul 21 2015, 10:42) *
У нас 2 экземпляра, результаты одинаковые. Разработчики микросхемы гоняли на модели - у них все ок. Если есть проблема в реализации кристалла, то наша задача - помочь её им определить.

Высказанные выше конструктивные идеи: 1) прерывания и 2) увеличенная задержка при обращении через границу блоков проверяем.

Нет ли еще идей?



Делайте фейковую константу по этому адресу где происходит сбой. Перекомпилируйте код, проверяйте далее. Теперь код точно не будет в этой ячейке.

И вот еще ссылка на анализ ситуации в HardFaulte.
http://community.arm.com/servlet/JiveServl...20for%20ARM.pdf
AlexeyT
Цитата
Приведите карту памяти МК.

Секция 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 A.
А там никаких конвейеров нигде не рушиться? если барьеров памяти и инструкций напихать что будет?
AlexeyT
Цитата(Golikov A. @ Jul 23 2015, 08:36) *
А там никаких конвейеров нигде не рушиться? если барьеров памяти и инструкций напихать что будет?



Эммммм... Какие барьеры и куда напихать? Прошу пояснить
scifi
.
jcxz
Цитата(AlexeyT @ Jul 23 2015, 11:30) *
Это не мусор, это фрагмент кода).
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... sm.gif

Цитата(AlexeyT @ Jul 23 2015, 11:30) *
Секция CODE (доступ по I, D шинам)
0x0000_0000-0x0000_0FFF Область для загрузчика, отражается на внешнюю шину
0x0800_0000-0x0805_FFFF Область внутреннего ОЗУ с пользовательской программой
0x1000_0000-0x1FFF_FFFF Область доступа к внешней системной шине


Раз в МК есть разделение ОЗУ на ОЗУ для кода и данных, то может быть что первая часть не поддерживает невыровненный доступ.
Область для загрузчика, отражается на внешнюю шину - а сам загрузчик не встроенный в МК что-ль???

Цитата(AlexeyT @ Jul 23 2015, 11:30) *
Чтобы отмести подозрения на загрузчик - он не используется, идет напрямую загрузка bin-файла в ОЗУ через SWD. Потом выставляется MSP, VTOR, PC - и запуск на исполнение.

Обычно это (стек и PC) выставляется первым вектором таблицы прерывания, с которого CPU их считывает при подаче reset-а эмулятором.

Цитата(AlexeyT @ Jul 20 2015, 18:16) *
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. Точно узнать можно по содержимому стекинга.

Цитата(AlexeyT @ Jul 19 2015, 23:28) *
Память тестировали - записывали данные, считывали - все ОК, память работоспособна, но при переходе границы 32-кБ блоков происходит HardFault:
PC = 0x0800016A, LR = 0xFFFFFFE9, XPSR = 0x21000003

Вы привели неправильные регистры. Это состояние регистров внутри ISR. Толку от него мало. Вам нужно привести регистры сохранённые при стекинге при входе в fault.
Прочитайте раздел описания ядра кортекс, посвящённый описанию стекинга и формата сохраняемых регистров.
Тогда узнаете значение PC перед срабатыванием fault.

Ещё - проверьте стек. Может он у вас элементарно переполняется.
AlexeyT
Цитата
Покрутить тактирование, питание и посмотреть, будут ли изменения.

Про тактирование уже писали - сбрасывали до 100 кГц, результат такой же.
Сейчас проверили и с питанием - во всем диапазоне напряжений питания результат такой же.

Цитата
А там никаких конвейеров нигде не рушится? Если барьеров памяти и инструкций напихать, что будет?

Будем пробовать, т.к. на этом проекте падаем при возврате в основную функцию из вызываемой.

Цитата
Вы отладчиком в окне дизассемблера прошлись? Удалось найти инструкцию, на которой "всё падает"?

Да, и не раз. Повторюсь - при пошаговом исполнении из отладчика (s) программа работает до тех пор, пока пользователю не надоест запускать пошагово.
При запуске на исполнение из отладчика (g) - падаем вскоре после начала работы основной функции main.
В этом конкретном случае падаем в вызываемой функции putc, во втором вызове по ходу исполнения основной программы.
При первом вызове она отработала нормально.

Цитата
Ещё - проверьте стек. Может он у вас элементарно переполняется.

С переполнением стека сталкивались в самом начале. С тех пор стека МНОГОsm.gif
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
Цитата(AlexeyT @ Jul 23 2015, 17:46) *
R0 = 0x40002000, R1 = 0x00000052, R2 = 0x40002000, R3 = 0x000003e8
R12 = 0x2000084C, LR = 0x0800BE47, PC = 0x07FF4FBE, xPSR = 0x21000000
!!! PC улетает ниже области, где лежит программа( Но почему при первом вызове той же процедуры все работает???

Точка возврата в LR правильная, а команда 0800_BE46: 4E21 MOV R1, #78 уже не была выполнена.
Хмммм.... да уж.... wacko.gif
Я бы ещё попробовал позаменять регистр возврата LR на какой другой или вернуться через стек POP {PC} или попробовать выровнять целевую точку возврата на 4...
Но походу явно тут торчат ослиные уши "отечественного предприятия".
AlexeyT
Цитата
или попробовать выровнять целевую точку возврата на 4...

Как это можно сделать средствами компилятора для проекта на С?

Цитата
Разговоры про отладчик наводят на грустные мысли про прерывания, которые как-то включились, но вектора не прописаны. В пошаговом режиме они запрещены.

Проверили регистры при падении - действительно, кроме исключения HardFault, есть прерывания, ожидающие обслуживания. Обработчики для них прописаны.
Но они маскируемые, и по умолчанию (в программе) не разрешены. Если разрешить их обработку из отладчика, после какого-нибудь из breakpoint'ов, то попадем в исключение DebugMonitor (№=12).
Это правильная логика работы, или здесь
Цитата
торчат ослиные уши
?
jcxz
Цитата(AlexeyT @ Jul 24 2015, 12:19) *
Как это можно сделать средствами компилятора для проекта на С?

на си - вряд-ли. Сделайте отдельную функцию на асме в пределах 32К исходной точки вызова.
А уже из неё - выровненный вызов за пределы 32К.

Цитата(AlexeyT @ Jul 24 2015, 12:19) *
Но они маскируемые, и по умолчанию (в программе) не разрешены. Если разрешить их обработку из отладчика, после какого-нибудь из breakpoint'ов, то попадем в исключение DebugMonitor (№=12).
Это правильная логика работы, или здесь ?

Даташита нет под рукой, но насколько помню, в системной области есть регистр, в котором разрешаются различные fault-ы.
Там, среди прочих, вроде есть разрешение DebugFault. Видно Вы случайно разрешили его. Его вроде только отладчик может
использовать/разрешать. Проверьте.
AlexeyT
Цитата
Даташита нет под рукой, но насколько помню, в системной области есть регистр, в котором разрешаются различные fault-ы.

Регистр такой есть. SCB->SHCSR (0xE000ED24). Но в нем устанавливаются только UsageFault, BusFault, MemFault. По умолчанию все обработчики были запрещены.
При их разрешении и намеренных ошибках процессор стал падать не в Hard, а в Usage или Bus.

Но вот основной косяк объяснению не поддается wacko.gif .
Имеем один и тот же простейший проект, с чуть разными картами памяти. 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.

Нажмите для просмотра прикрепленного файла
Нажмите для просмотра прикрепленного файла
AlexeyT
Тестовая программа стала работать при вот таких изменениях:

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 также не работает.

Кто-то может предположить причины такого бреда?
Нажмите для просмотра прикрепленного файла
Golikov A.
А кешей никаких нет? Выглядит как буд-то кеши не синхронизовались с памятью в момент когда вы в них обращаетесь на чтение во время исполнения программы. Если через отладчик, то он сам их синхронизит, если пописать в сегменты памяти то опять же они инвалидейтятся....

может банк памяти при первом обращении выдает память с задержкой, или первое выдаваемое значение банка левое, там никаких буферных регистров внутри банка нет? То есть похоже на аппаратный сбой...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.