реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Не работает 32-х битный режим SDRAM, Не работает 32-х битный режим SDRAM (LPC2478, Keil, FreeRTOS)
_Mikhail_
сообщение Aug 9 2013, 07:21
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 55
Регистрация: 19-04-11
Пользователь №: 64 477



День добрый!
Имею:
1. Плату LPC2478-STK ( http://mail.olimex.com/Products/ARM/NXP// );
2. Среда разработки Keil;
3. Программа под FreeRTOS 7.4.

Программа под РТОС-ом размещается во внешней SDRAM.
Внешняя оператива - две микросхемы, обе подключенные на CS0 их 16-и разрядные шины данных вместе образуют 32-х разрядную (схема на сайте по ссылке выше).
Настраиваю EMC через асмовский startup кейла. За основу беру настройки с IAR-овского проекта все с того же сайта.
Программа нормально функционирует в 16-и разрядном External bus data width. При попытке переключиться в 32-х разрядный программа "зависает" на первой же
вызываемой РТОС функции (xSemaphoreCreateMutex). Если посмотреть в отладчике, то останов происходит в файле startup.s на строке "DAbt_Handler B DAbt_Handler".
Причем, если эту функцию выполнять пошагово, то она выполняется без проблем и следующие за ней аналогичные функции уже нормально выполняются не по шагам.
Но потом опять (через несколько вызововов функций) происходит вылет на "DAbt_Handler B DAbt_Handler".

Создавал пустой проект без РТОСа, делал аналогичные настройки EMC, читал/писал в память в 16/32bit режиме - все нормально.

Подскажите куда копать?
Go to the top of the page
 
+Quote Post
_Mikhail_
сообщение Aug 13 2013, 18:13
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 55
Регистрация: 19-04-11
Пользователь №: 64 477



Ситуация, похоже, интереснее.
Решил повозиться с "чистым" проектом.
Шина памяти в - 32 бита.
//------------------------------------------------------
Пишу в память/сравниваю:

Int32U *SDRAM = (Int32U*)0xA0000000;
DWORD i=0, c=0;

for ( i = 0x0000000; i < 0x1000000; i+=sizeof(Int32U))
{
*(Int32U*)(((Int32U*)SDRAM)+i) = i;
}
i = 0x0000000;
c = *(Int32U*)(((Int32U*)SDRAM)+i);

После выполнения "с" равен 0x0000000. Ожидаемо! ))
//------------------------------------------------------
А если немного модифицировать:

for ( i = 0x0000000; i < 0x1000004; i+=sizeof(Int32U))
{
*(Int32U*)(((Int32U*)SDRAM)+i) = i;
}
i = 0x0000000;
c = *(Int32U*)(((Int32U*)SDRAM)+i);
То "с" равен 0x1000000!
//------------------------------------------------------
Еще меняю:
for ( i = 0x0000000; i < 0x1000004; i+=sizeof(Int32U))
{
*(Int32U*)(((Int32U*)SDRAM)+i) = i;
}
i = 0x0000004;
c = *(Int32U*)(((Int32U*)SDRAM)+i);

"с" равен 0x0000004! и далее 0x08, 0xb и т.д. Все нормально инкремент на 4 байта.

//------------------------------------------------------
Можно сместить диапазон:
for ( i = 0x1000000; i < 0x2000004; i+=sizeof(Int32U))
{
*(Int32U*)(((Int32U*)SDRAM)+i) = i;
b = *(Int32U*)(((Int32U*)SDRAM)+i);
}
i = 0x1000000;
c = *(Int32U*)(((Int32U*)SDRAM)+i);

"с" равен 0x2000000!

Т.е. при переходе через каждые 16Мб 0x0000000 = 0x1000000, 0x1000000 = 0x2000000.
Если в цикле не переходим через 0x1000000, 0x2000000, то такой картины не наблюдается.

Угробил кучу времени. Что у меня не так?
Go to the top of the page
 
+Quote Post
gerber
сообщение Aug 13 2013, 20:23
Сообщение #3


Знающий
****

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



Цитата(_Mikhail_ @ Aug 13 2013, 21:13) *
Ситуация, похоже, интереснее.
Решил повозиться с "чистым" проектом.
................................................................................
............
Т.е. при переходе через каждые 16Мб 0x0000000 = 0x1000000, 0x1000000 = 0x2000000.
Если в цикле не переходим через 0x1000000, 0x2000000, то такой картины не наблюдается.
Угробил кучу времени. Что у меня не так?

Дело в арифметике указателей - она у Вас неправильная.
У Вас в цикле инкремент i идёт на величину sizeof(Int32U), то бишь на 4, далее i прибавляется к указателю Int32U* SDRAM, и получается, что указатель при этом смещается на 4 элемента Int32U, то есть на одной итерации цикла на 16 байт, а не на 4, как Вы ожидаете.
Поэтому, с учётом того, что на Вашей плате 64 Мб - логично, что всю память Вы проходите "в 4 раза быстрее", то есть "зацикливание" памяти будет при индексе 0x1000000 (16 Мб), так как указатель при этом "прыгает" на 64 Мб вперёд.
Правильно будет в цикле делать обычный инкремент индекса, то есть i++.

Сообщение отредактировал gerber - Aug 13 2013, 20:24


--------------------
"... часами я мог наблюдать, как люди работают." (М. Горький)
Go to the top of the page
 
+Quote Post
_Mikhail_
сообщение Aug 14 2013, 08:35
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 55
Регистрация: 19-04-11
Пользователь №: 64 477



Цитата(gerber @ Aug 14 2013, 00:23) *
Дело в арифметике указателей - она у Вас неправильная.
У Вас в цикле инкремент i идёт на величину sizeof(Int32U), то бишь на 4, далее i прибавляется к указателю Int32U* SDRAM, и получается, что указатель при этом смещается на 4 элемента Int32U, то есть на одной итерации цикла на 16 байт, а не на 4, как Вы ожидаете.
Поэтому, с учётом того, что на Вашей плате 64 Мб - логично, что всю память Вы проходите "в 4 раза быстрее", то есть "зацикливание" памяти будет при индексе 0x1000000 (16 Мб), так как указатель при этом "прыгает" на 64 Мб вперёд.
Правильно будет в цикле делать обычный инкремент индекса, то есть i++.


Да, Вы правы. Стыдно, взял готовый пример, принял на веру, но не разобрался. Все четыре "странички" заполнялись по кругу.
Протестил:

for ( SDRAM = (Int32U*)0xA0000000; SDRAM < (Int32U*)0xA4000000; SDRAM++)
{
*SDRAM = (DWORD)SDRAM;
}

for ( SDRAM = (Int32U*)0xA0000000; SDRAM < (Int32U*)0xA4000000; SDRAM++)
{
if ( *SDRAM != (DWORD)SDRAM)
{
result = FALSE;
break;
}
}

Все нормально.
Остается только вопрос, почему проект со РТОСом ЗАРАБОТАЛ в режиме 32 бит SDRAM при установленной опции External bus memory type - Low-power SDRAM в регистре EMCDynamicConfig0 EMC?
При High-performance работать отказывается.

Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 22:10
Рейтинг@Mail.ru


Страница сгенерированна за 0.01377 секунд с 7
ELECTRONIX ©2004-2016