Перейти к содержанию
    

STM32F7. Проблемы с рамещением стека в памяти

Господа, помогите, столкнулся с очень странной и непонятной мне проблемой.

Есть программа под STM32F746, которая уже как минимум пол-года  стабильно себе работает. Но, как выяснилось,  работает до тех пор, пока ее данные и стек влезают в первые 64К ОЗУ (с 0х2000 0000 до 0х2000 FFFF).  Если смещением начального адреса региона RAM или просто увеличением объема используемого ОЗУ сделать так, что бы начало стека вышло за эту границу, то программа начинает глючить.  Симптоматику пока описывать не буду, слишком долго, а просто спрошу: есть ли у сего камня какие-то ограничения на расположение стека в памяти? Возможно, где-то что-то еще надо подправить? Просто не так  давно я разбирался с расположением кода не с начала FLASH-памяти, а в другом ее секторе и не сразу понял, что изменить ICF-файл недостаточно, надо еще и объяснить контроллеру, где у него будет таблица векторов.  Может и со  стеком  такая же фигня?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, со стеком та же история. Нужно сказать, где он. Если делать по-правильному, то и в таблицу векторов, и в регистр указателя на стек, попадёт символ из скрипта линковки. Но, если стартап сделан иначе, например, в нём жёстко заданы адреса - то это надо переписать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

47 minutes ago, b-volkov said:

Может и со  стеком  такая же фигня?

И не забывайте, что их два у процессора: главный стэк MSP и стэк процессов PSP. Если у Вас приложение без ОСРВ, то, скорее всего, используется только один стэк по умолчанию MSP. Но, с другой стороны, для использования PSP не обязательно наличие ОСРВ. Он может использоваться и так. MSP инициализируется после сброса процессора чтением значения адреса из нулевой ячейки таблицы векторов. Его расположение может быть где угодно в разрешённой области ОЗУ на усмотрение линкера, а этот адрес вычисляется автоматическе на основании заданного размера стэка. Правда, расположение можно задать и принудительно. Например, в начале ОЗУ. Смотрите скрипт линкера, смотрите содержание MSP в отладчике. И, если используется, то и PSP.

52 minutes ago, b-volkov said:

вышло за эту границу

А что там за этой границей? Сразу тоже ОЗУ? Или какая-нибудь дыра или I/O? MPU не используете? Может быть он запрещает туда писать?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проект под IAR, ОСРВ нет, только HAL.  Используется только главный стек и его указатель (в отладчике обозначается как SP_main) инициализируется  правильно.  Стек процессов всегда нулевой. За границей та же RAM, иначе причина была бы ясна. 

Программа не то, что бы совсем не работает, она глючит. Пока нашел две ситуации, в которых это приходит:

1.У меня есть функции в которых используется выключение/включение кеширования данных (записываю данные в CPLD через FMC в реальном времени). При входе в эти функции в стек помещается неправильный адрес возврата, соответственно, при выходе программа улетает фиг знает куда.

2. Глючит  HAL, в частности работа с ETHERNET: не получает входящие пакеты, передает один кадр два раза подряд. 

У меня большое подозрение, что в программе есть какой-то баг, проявляющийся только при определенном расположении стека (или вообще, при определенном распределении ОЗУ). 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

37 minutes ago, b-volkov said:

инициализируется  правильно. 

Может зря спрашиваю, но выровнен на границу 8 байт?

38 minutes ago, b-volkov said:

2. Глючит  HAL, в частности работа с ETHERNET: не получает входящие пакеты, передает один кадр два раза подряд. 

Предположение на уровне "пальцев в небо": не смещаются ли буфера Ehternet в памяти так, что с частью из них DMA MAC работать уже не может? Там же у некоторой периферии строгие ограничения на расположение буферов в ОЗУ.

39 minutes ago, b-volkov said:

У меня большое подозрение, что в программе есть какой-то баг, проявляющийся только при определенном расположении стека (или вообще, при определенном распределении ОЗУ). 

Erratа? Молчит? Думаю, что проблема в выравнивании, либо недоступности куска ОЗУ, в котором находится буфер для периферии. Может быть, изменяется время доступа к определённым кускам памяти из-за особенности построения внутренних шин APB/AHB и прога начинает глючить, т.к. изначально написана неверно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Думается мне, что глюки - результат плохо написанного (или стыренного?) драйвера Ethernet-MAC.

Внимательно смотрите, где располагаете буферы Ethernet-DMA-контроллера и обеспечьте когерентность памяти при активном D-cache.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Почитал повнимательнее  доки. В самом деле,  первые 64к ОЗУ, это Tightly Coupled Memory. После того, как я принудительно  расположил стек в ТСМ области, а все остальное выше нее (в SRAM1), то первый глюк с возвратом из подпрограмм пропал. Это я могу понять, потому что раньше  стек оказывался на границе двух разных ОЗУ с разными шинами. Следующим шагом я запихнул в первые 64к еще и буфера ethernet и чудо, он то же стал нормально работать.  А вот этого я понять не смог. в RM0385 черным по белому написано:

2.1.10 Ethernet DMA bus
... The targets of this bus are data memories: internal SRAM1, SRAM2 and DTCM (through the AHBS bus of Cortex®-M7)
internal Flash memory, and external memories through the FMC or Quad SPI.

 Да, ТСМ быстрее, ну  пусть бы отклик был дольше при размещении в SRAM1, но глючить-то зачем? 

Ну это уже не так важно, теперь, по крайней мере, стало понятно, как мне распределять память.

Спасибо за ответы!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

20 minutes ago, b-volkov said:

но глючить-то зачем? 

Выравнивание? Оно важно там? С этим всё ок?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Отключите кэш данных и о чудо - все будет так же работать и в SRAM1...

Цитата

В обоих случаях задавалось выравнивание 4 байта.

ARM рекомендует 8, иначе могут быть глюки на ровном месте. Хотя в довольно редких ситуациях.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8 minutes ago, Arlleex said:

Отключите кэш данных и о чудо - все будет так же работать и в SRAM1...

 

То, что область ТСМ не кешируется, я знал, а вот о том, что кэш плохо дружит с DMA не подумал... 

Теперь понятно, еще раз спасибо. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Только отключение D-cache - это решение кривое, иначе какой смысл имеет его наличие в МК?:wink: Можно разместить дескрипторы в некэшируемой части (или настроить эту область с помощью MPU) ОЗУ, а сами буферы - в кэшируемой, но при этом вручную flush()-ить и incalidate()-ить кэш.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ещё DMA не дружит с неровными адресами.

С Ethernet-DMA модулем ловил похожую ситуацию, хотя данными портились рядом с буфером пакетов, т.к. он оказывался сильно ниже стэка и не в куче. Но заголовки случайным образом бились. Оказалось, что Eth-DMA в принципе пишет по 4 байта (DWORD) и в том случае, когда адрес не выравнен на границу 4 байт, затирает нулями (иногда старыми данными прошлого пакета) несколько байт, которые эту границу пересекают.

Так что буферы обязательно объявлять с аттрибутом "__attribute__((aligned(4)))". После этого у меня пропали "странные" сбои.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 минут назад, AlanDrakes сказал:

Так что буферы обязательно объявлять с аттрибутом "__attribute__((aligned(4)))". После этого у меня пропали "странные" сбои.

Чтобы не было "странных сбоев", буферы нужно размещать с атрибутом выравнивания на строку кэша, а не на 4.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне везло с доступом к памяти, но ломало именно буферы пакетов. Со стэком всё было нормально. Зато получил бесценный опыт =)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...