|
Stm32f7 stack pointer, Медленная работа езернета при нестандартной разметке памяти |
|
|
|
Jul 17 2018, 12:43
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Всем привет.
Столкнулся с очень непонятной штукой. GCC под Stm32F767, оптимизация О2, никакой линкер оптимизации.
Разметка памяти: RAM = 0x20000000, size 0x80000, data и bss - лежит с начала RAM stack poitner задается на 0x20080000
тут все работает прекрасно, если сделать RAM = 0x20000000, size 0x80000, data и bss - лежит с 0x20010000 stack poitner задается на 0x20010000
тоже все работает хорошо, но если сделать RAM = 0x20010000, size 0x70000, data и bss - лежит с 0x20010000 (с начала RAM) stack poitner задается на 0x20010000
то никаких падений нет, но начинаются проблемы в обмене по езернету. Пакеты застревают, причем не теряются, они все есть, но почему то временами не отправляются. То есть приходит UDP запрос, ответа нет, а со следующим запросом приходит ответ на этот и на предыдущий.
При этом в разметке RAM = 0x20000000, size 0x20000, data и bss - лежит с начала RAM stack poitner задается на 0x20080000 тоже есть проблемы, но значительно реже проявляющиеся.
размеры областей роли особой не играют, то есть никаких невлезаний в область памяти нет. Из вещей мной неуправляемых это кусок работы с езернетом забранный из куба. Есть у кого какие-то идеи как может разметка памяти так драматически влиять?
|
|
|
|
|
Jul 17 2018, 14:48
|
Частый гость
 
Группа: Участник
Сообщений: 84
Регистрация: 7-05-05
Пользователь №: 4 819

|
Цитата(Golikov A. @ Jul 17 2018, 17:26)  Там есть кривое место при заправке дма езернета, вероятно там и косяк... напишите плис, если разберетесь
|
|
|
|
|
Jul 18 2018, 18:14
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата(jcxz @ Jul 18 2018, 12:09)  Всё тривиально: какая-то переменная наезжает на другую и пакостит ей. Когда меняете размётку, то она наезжает или на пустое место или на некритичную переменную. Вангую активное использование кучи и указателей в вашем проекте  несостоятельная теория. Регионы большие я их двигал и вместе и отдельно, там общих данных меньше чем расстояния между регионами. И не понятно почему если граница 0x10000 не наезжают, а если граница 0x20000 наезжают. Куча расположена в конце памяти после bss, и стек она не может достать.... Цитата(scifi @ Jul 18 2018, 12:17)  Там, где Ethernet, там и DMA. Если сделано криво, DMA тоже может напакостить там, куда ему лезть не положено. не объясняет изменение поведения от передвижки границы стек-память.
|
|
|
|
|
Jul 18 2018, 19:15
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Golikov A. @ Jul 18 2018, 21:14)  Куча расположена в конце памяти после bss, и стек она не может достать.... Хех!... молодо-зелено-наивно... Любая операция адресации памяти по указателю в ARM может "достать" куда угодно в пределах 4гиг. Что-то на что-то залезло внутри этих ваших больших регионов, и это "второе что-то" вдруг оказалось указателем, по которому потом выполнилась запись, куда угодно в пределах 4гиг. Повезло - попала в пустое место, не повезло - снесла нафиг что-нить полезное или не очень. А потом это полезное или не очень опять оказалось указателем (ну или каким-то индексом, по которому указатель вычисляется; или счётчиком цикла, от которого зависит размер записываемой области памяти; и ещё 100500 вариантов....). И пострадало ещё нечто полезно-бесполезное. Строите Вы своё ПО, строите как здание из доминошек, а потом одну доминошку криво ставите - и всё насмарку  PS: А насчёт дин.памяти я был прав.  И MPU наверняка даже не инициализирован. Вангую
|
|
|
|
|
Jul 19 2018, 07:55
|

Местный
  
Группа: Участник
Сообщений: 257
Регистрация: 5-09-17
Пользователь №: 99 126

|
Цитата(Arlleex @ Jul 19 2018, 08:48)  Смеетесь что ли. У процессоров Intel x86 в защищённом режиме можно настроить дескрипторы так, чтобы из региона, где выполняется код чтение данных было запрещено. На то он дескриптор кода. У STM32F7 также, не?
Сообщение отредактировал __inline__ - Jul 19 2018, 07:56
|
|
|
|
|
Jul 19 2018, 07:56
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(__inline__ @ Jul 19 2018, 10:32)  MPU : настроить секцию 1 только для выполнения кода. Секция 2 - для RO данных. Секция 3 - R/W. Секция 4 - стек. Секция 5 - куча. При попытке считать данные их секции кода - эксепшн При попытке записать данные в RO Данные - экспешн Почти во всём соглашусь, кроме того, что чтение данных из секции кода необходимо: если посмотреть любой асм-листинг ARM, то компилятор располагает константные данные вблизи функций их использующих, в этом же самом сегменте. Чтобы можно было дотянуться до них через косвенную адресацию по PC. И доступ ко всем переменным начинается с чтения её адреса в регистр через PC+смещение. Ну не предусмотрена в архитектуре ARM прямая адресация. Только косвенная. А в остальном - у меня в MPU тоже примерно так же настроены сегменты, за исключением кучи. А стек - он у меня часть R/W-сегмента, не выделяю его в отдельный регион. Ещё можно с помощью MPU отлавливать несанкционированные доступы к каким-то переменным: обнаружили что кто-то портит переменную, а кто - не знаем: выделяем её в отдельный сегмент и через MPU открываем доступ к этому сегменту на запись только в тех местах, где по алгоритму это нужно. И когда кто-то левый полезет в неё писать - получим fault. Но вот для дин.памяти эта полезность сразу отпадает - только статически.
|
|
|
|
|
Jul 19 2018, 07:58
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
Цитата(__inline__ @ Jul 19 2018, 11:55)  У процессоров Intel x86 в защищённом режиме можно настроить дескрипторы так, чтобы из региона, где выполняется код чтение данных было запрещено. На то он дескриптор кода.
У STM32F7 также, не? Пардон, я не заметил, что Вы предложили эту область кода сделать только для кода.
|
|
|
|
|
Jul 19 2018, 11:17
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Воу воу воу!! Парни остановитесь  Я только jcxz хотел чтобы меня научил. Это связано его, очевидно, очень глубоким познанием работы АРМа... По сути дела: 1. конфигурация переменные в начале - стэк в конце работает всегда, с небольшим общим объемом, и любыми передвижениями этой конструкции по памяти 2. конфигурация стек до переменных - работает временами на каких-то значения границы работает, на каких-то нет. 3. Я по всякому двигал границы, раздвигал их и перемещал, в случае плохой работы повторяемость 100%. При этом нет фатального падения, есть задержка работы. Этим я исключаю случайные повреждения памяти, потому что вероятность такого везения что в разных конфигурациях я херю одну и туже переменную, да так что это не приводит к тотальному падению - ноль. Так же я исключаю нехватку памяти, потому что имею работоспособные комбинации на объеме значительно меньшем общего объема. Из интересных симптомов пакет данных посылаемый по УДП не теряется, а задерживается до следующего приема (возможно отправки). Причем каждый 4 пакет. То есть я запускаю пинг 3 ответа приходят сразу, 4 приходить только вместе с 5 запросом. И так по кругу. Смотрю диагностику LwIP похоже пакет отдают, то есть скорее всего все застревает в драйвере езернет. Пока нет времени разбираться дальше, но я думаю неверно заправляется ДМА езернета. И мак не стартует перекладку до следующего пакета. Потом происходит еще одна заправка и 2 пакета уходят разом. Как влияет раскладка в памяти? Думаю задержками при переключении басматрикса. Это изменяет время копирования пакетов данных, и конкуренцию с ДМА. Как то так...
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|