Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: IAR (STM32+Ext SRAM)
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
athlon64
Использую связку STM32F217IG + SRAM CY7C1061AV33 (1 M × 16bit). IAR 6.30

Инициализацию FSMC взял из демо-проекта к плате STM322xG EVAL.
Память прекрасно читается и пишется (если писать 16-битными словами) по указателю. Скорость порадовала.
Пробовал размещать в этой памяти heap FreeRTOS, подменив указатель - некоторые задачи работают, некоторые нет (видимо из-за выравнивания).

Хотелось бы, конечно, чтобы линкер знал про эту область памяти и мог размещать в ней глобальные структуры, которых планируется много. Ну, конечно, с поправкой на выравнивание по 16 бит. Возможно такое? Попытался поправить скрипт линкера, но при попытке разместить в секции любые данные, процессор не стартует. Если такое возможно сделать, поделитесь, плис, примером скрипта линкера. И откуда в данном случае инициализировать FSMC?

Если нет, то какой способ размещения данных можно применить? Данные - массивы, структуры.
Непомнящий Евгений
Дайте свой скрипт, посмотрим
athlon64
Вот, например, моя попытка разместить стек во внешней памяти
Отладчик виснет
KRS
Цитата(athlon64 @ May 3 2012, 12:24) *
Вот, например, моя попытка разместить стек во внешней памяти
Отладчик виснет

Вы хотите сказать что без отладчика работает?
До использования внешнюю память же проинитить надо.
athlon64
Цитата(KRS @ May 3 2012, 15:53) *
Вы хотите сказать что без отладчика работает?

Нет, не работает.
Я о том, что не могу даже в отладке посмотреть куда попадает проц.

Непомнящий Евгений
Дык а вы инициализируете эту память? Это надо делать до входа в main в какой-то специальной функции или стартап самому написать...
KRS
Цитата(Непомнящий Евгений @ May 3 2012, 16:09) *
Это надо делать до входа в main в какой-то специальной функции или стартап самому написать...

На cortex-m3 проблематично потому что указатель стека ставится сразу из таблицы прерываний.
теоретически можно конечно поставить точку входа на кусок написанный на асме что бы не трогать стек до инициализации памяти...
_Артём_
Цитата(KRS @ May 3 2012, 15:35) *
На cortex-m3 проблематично потому что указатель стека ставится сразу из таблицы прерываний.

А что SP нельзя после инициализации поменять?
А сначала загрузит чем нибудь из диапазона внутренней RAM?
KRS
Цитата(_Артём_ @ May 3 2012, 17:37) *
А что SP нельзя после инициализации поменять?
А сначала загрузит чем нибудь из диапазона внутренней RAM?

можно конечно! даже функция есть __set_MSP
но для этого контроллера очень сомнительно что именно стек нужно во внешнюю память пихать.
_Артём_
Цитата(KRS @ May 3 2012, 18:24) *
можно конечно!

Ну, так и думал.

Цитата(KRS @ May 3 2012, 18:24) *
даже функция есть __set_MSP

Её и использовать, если так хочется стек во внешнее озу расположить.
Это гораздо проще чем
Цитата
поставить точку входа на кусок написанный на асме что бы не трогать стек до инициализации памяти...


Цитата(KRS @ May 3 2012, 18:24) *
но для этого контроллера очень сомнительно что именно стек нужно во внешнюю память пихать.

И для многих других МК - сомнительно.
SSerge
Цитата(athlon64 @ May 3 2012, 14:16) *
И откуда в данном случае инициализировать FSMC?

Самое подходящее для этого место - функция __low_level_init
Посмотрите в файле \arm\doc\EWARM_DevelopmentGuide.ENU.pdf что это такое и с чем его употребляют.

Добавлено:
Впрочем, если пользоваться STM32F2xx_StdPeriph_Lib от ST, то там уже есть свой стартап CMSIS\CM3\DeviceSupport\ST\STM32F2xx\startup\iar\startup_stm32f2xx.s,
из него вызывается функция SystemInit, её код находится в файле CMSIS\CM3\DeviceSupport\ST\STM32F2xx\system_stm32f2xx.c,
а уже там есть вызов
#ifdef DATA_IN_ExtSRAM
SystemInit_ExtMemCtl();
#endif /* DATA_IN_ExtSRAM */

так что инициализировать FSMC можно и таким способом, только нужно будет поправить эту функцию под свою конфигурацию памяти.
athlon64
Цитата(SSerge @ May 3 2012, 22:44) *
Самое подходящее для этого место - функция __low_level_init


Ага, точно. Раскомментировал DATA_IN_ExtSRAM, поправил SystemInit_ExtMemCtl();.
Теперь в майне сразу же могу работать с ОЗУ, инициализация к тому моменту уже выполнена. Вопрос с местом инициализации решён.
Теперь как указать линкеру что это ОЗУ можно использовать? Объявить новый блок с выравниванием 16? А дальше? как разместить в нём нужные мне данные?
athlon64
Всё ещё актуально
_Артём_
Цитата(athlon64 @ May 4 2012, 06:41) *
как разместить в нём нужные мне данные?

Открыть Compiler Reference- ...-Placing code and data.
athlon64
Цитата(_Артём_ @ May 12 2012, 17:47) *
Открыть Compiler Reference- ...-Placing code and data.

Сильно понятнее не стало rolleyes.gif

Пошёл с другой строны. Нашёл в примерах IAR демо проект "SRAM_DataMemory" для платы STM322xG-EVAL, использующий аналогичную внешнюю память как основную.
В скрипте линкера этого проекта просто изменены адреса начала и конца RAM, также проект использует изменённый cstartup.s, в котором во время исполнения SystemInit() используется стек во внутренней SRAM, после чего заменяется на стек во внешней SRAM.
Переделал свой cstartup.s по аналогии с демкой, скрипт линкера тоже.
Судя по map-файлу, глобальные переменные теперь все размещены во внешней SRAM
Контроллер стартует, но не работают прерывания.
Причём после вызова vTaskStartScheduler(), а точнее vPortStartFirstTask(), значение регистра SP запарывается адресом внутреннего SRAM. До этого вызова в SP указатель во внешней SRAM.
Получившийся cstartup и скрипт линкера во вложении
athlon64
1. Правильно ли я понял что эту 16-бит память нельзя использовать как внутреннюю (для стека, глобальных переменных), т.к. записать в неё корректно 1 байт невозможно (пишется полуслово разом)?
2. Прозрачно для программы это обойти нельзя (средствами FSMC или компилятора)?
3. Если можно, то что для этого нужно сделать, какие минусы?

В идеале хотелось бы чтобы стек и куча FreeRTOS остались в intSRAM, остальное в extSRAM.
_Артём_
Цитата(athlon64 @ May 14 2012, 10:19) *
Сильно понятнее не стало rolleyes.gif

Код
#pragma location=0xFFFF0400
__no_init volatile char PORT1; /* PORT1 is located at address
                                  0xFFFF0400 */

KRS
Цитата(athlon64 @ May 15 2012, 15:53) *
1. Правильно ли я понял что эту 16-бит память нельзя использовать как внутреннюю (для стека, глобальных переменных), т.к. записать в неё корректно 1 байт невозможно (пишется полуслово разом)?

Нет, не правильно!
там есть сигналы byte enable.

athlon64
Цитата(_Артём_ @ May 16 2012, 00:38) *
Код
#pragma location=0xFFFF0400
__no_init volatile char PORT1; /* PORT1 is located at address 0xFFFF0400 */

а, такой вариант определения переменных я пробовал. В принципе подойдёт, но всё же не хотелось бы вручную считать адреса для каждой глобальной структуры.

У меня проблема сейчас в том, что не удаётся корректно записать во внешнюю SRAM 8-битные данные.
Например, заполняю область с адреса 0x60000000 256ю байтами от 0 до 255:
Код
void MemTest(char *pMem)
{
  for (int i=0; i<256; i++)
    *(pMem+i) = i;
}

int main(void)
{
  Init();

  while (1)
  {
    MemTest((char*) (0x60000000));
  }
}

Смотрю в отладке, что записалось:
При записи 0 - записался байт 0x00 по адресу 0x60000001
При записи 1 - записался байт 0x01 по адресу 0x60000000
При записи 2 - записался байт 0x00 по адресу 0x60000003
При записи 3 - записался байт 0x03 по адресу 0x60000002
При записи 4 - записался байт 0x00 по адресу 0x60000005
При записи 5 - записался байт 0x05 по адресу 0x60000004
и так далее

Если заполнять память данными по 16-32 бит - данные пишутся верно.

Цитата(KRS @ May 16 2012, 01:13) *
Нет, не правильно!
там есть сигналы byte enable.

Тут конечно моя ошибка в том что, не посмотрел на подключение SRAM и настройку FSMC (плату разрабатывал, трассировал другой сотрудник).

Покурил Reference Manual по FSMC и Application Note AN2784.
Проверил сигналы NBL[1..0] - выставляются верно, выбирается по очереди сначала младший байт, потом старший. При записи 16-32битных значений - выбираются оба байта.
Посмотреть шину данных и адреса в данный момент проблематично на этой плате.

Код инициализации ExtSRAM и фрагмент схемы с подключением микросхемы памяти привожу (шины адреса и данных так развёрнуты для удобства трассировки sm.gif ).
athlon64
Похоже что ошибка найдена.
Конструктора развернули шину данных, а дороги выбора байта на запись поменять местами забыли. rolleyes.gif
Плата на перепайке линий BHE, BLE.
KRS
Цитата(athlon64 @ May 16 2012, 10:36) *
а, такой вариант определения переменных я пробовал. В принципе подойдёт, но всё же не хотелось бы вручную считать адреса для каждой глобальной структуры.

можно вместо адреса указать секцию
#pragma location = "EXT_SRAM"
можно еще --section использовать для переноса всех данных или кода целиком для файла(ов).
athlon64
Перепаяли дорожки, запись байта теперь заработала. rolleyes.gif
Потестировал полчаса внешнюю SRAM (запись-чтение-проверка того что прочитано), всё ОК, ошибок нет.
Перенёс секцию readwrite в RAMext_region, стек оставил во внутренней SRAM. И заметил такой баг: постоянно пингуя контроллер (проект на FreeRTOS 6.1 + LwIP 1.3.2) некоторое время (10 секунд - 2 минуты) пинг нормальный, а дальше начинает расти и прекращается совсем, лишь изредка "простреливая" с временем 2000-3000 мс. Если размещать секцию readwrite во внутренней SRAM, то такого не наблюдается.
Подозреваю, что запарываются какие то структуры стека в ОЗУ.
Куда копать, кроме настроек таймингов FSMC? Завтра буду разбираться дальше.
KRS
Цитата(athlon64 @ May 16 2012, 17:40) *
Подозреваю, что запарываются какие то структуры стека в ОЗУ.
Куда копать, кроме настроек таймингов FSMC? Завтра буду разбираться дальше.

Вы бы для начала тест памяти сделали - что бы убедится что ОЗУ нормальное и настройки...
athlon64
Цитата(KRS @ May 17 2012, 01:10) *
Вы бы для начала тест памяти сделали - что бы убедится что ОЗУ нормальное и настройки...

Погонял сегодня память в течении часа - 0 ошибок чтения/записи
athlon64
Странно, конечно, но глючить начинает только обмен по ethernet, все остальные задачи работают нормально.

В течении дня никаких ошибок во время теста памяти не зафиксировано.
Может быть у LwIP есть какие то особенности при работе с внешней памятью?

Ещё заметил, пинг портится примерно так же, как портится после выхода из сессии отладки (без использования внешней памяти). Пока не выйдешь из отладки - всё ОК, или если не запускать отладку вообще. А после выхода из отладки, пинг сразу портится, в остальном контроллер продолжает работать. То же самое если поставить контроллер на паузу в отладке.
Не разбирался ещё почему, может быть изза нарушения обмена с с MICREL KS8995.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.