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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> WinAVR & External memory, проблема
Axer
сообщение May 24 2005, 08:28
Сообщение #1





Группа: Новичок
Сообщений: 7
Регистрация: 24-05-05
Пользователь №: 5 336



Здравствуйте. У меня проблема с внешней памятью при работе с АтМега64.
Есть программа, рабочая. При подключении внешней памяти начинаются непонятные ошибки, причем ошибки начинаются при выполнении команды memmove() или при выполнении функции вывода строки:
Код
while (*s) ce210_send(*s++);

Вот строчка в мейкфайле, где включаю память, и потом флаги:
Код
EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x8090ff
   ASFLAGS = -Wa,-ahlms=$(<:%.S=lst/%.lst),-gstabs -mmcu=$(MCU)
   CPFLAGS = -MMD -g -O$(OPT) -funsigned-char -funsigned-bitfields -fpack-struct -Wall -Wstrict-prototypes -Wa,-ahlms=$(<:%.c=lst/%.lst) -mmcu=$(MCU) $(CDEFS)
   LDFLAGS = -Wl,-Map=lst/$(TRG).map,--cref, -L$(LIBDIR), $(EXTMEMOPTS) -lm -mmcu=$(MCU)

Вот инициализация в программе:
Код
   setreg(MCUCR, SRE, 1);    // enable external memory (xram)
   setreg(MCUCR, SRW10, 1);                      // configure xram
   XMCRA = _BV(SRW00) | _BV(SRW01) | _BV(SRW11); //

Видно, что проблемы именно с памятью, но вот только где конкретно, не могу понять.
Что не так?
P.S. Версия ВинАВР последняя.
Go to the top of the page
 
+Quote Post
BorisRozentsvaig
сообщение May 24 2005, 08:34
Сообщение #2


Участник
*

Группа: Свой
Сообщений: 36
Регистрация: 23-03-05
Из: Санкт-Петербург
Пользователь №: 3 617



Цитата(Axer @ May 24 2005, 12:28)
Здравствуйте. У меня проблема с внешней памятью при работе с АтМега64.
Есть программа, рабочая. При подключении внешней памяти начинаются непонятные ошибки, причем ошибки начинаются при выполнении команды memmove() или при выполнении функции вывода строки:
Код
while (*s) ce210_send(*s++);

*


А каким образом у вас "s" объявлена и инициализирована?

И потом, если s - указатель на массив, то надо смотреть приоритет операторов, может лучше пока написать так:
Код
while (*s)
{
   ce210_send(*s);
   s++;
}


Про приоритет операторов можно посмотреть тут:
http://cclib.nsu.ru/projects/gnudocs/texts/bogatir/9.html
Go to the top of the page
 
+Quote Post
Axer
сообщение May 24 2005, 09:17
Сообщение #3





Группа: Новичок
Сообщений: 7
Регистрация: 24-05-05
Пользователь №: 5 336



Цитата
А каким образом у вас "s" объявлена и инициализирована?


Код
void ce210_print(char *s)
{
   while (*s) ce210_send(*s++);
}

Я совершенно уверен, что дело тут не в приоритетах, как я уже сказал, без внешней памяти все работает правильно.

Да, еще одно наблюдение. При инициализации всей памяти, которая учавствует в memmove(), ошибки вроде исчезают. Шаманство какое-то...
Go to the top of the page
 
+Quote Post
pulsar-17
сообщение May 24 2005, 09:18
Сообщение #4


Участник
*

Группа: Свой
Сообщений: 32
Регистрация: 7-12-04
Из: Московская область
Пользователь №: 1 376



Возможно проблема в __heap_end=0x8090ff

как я понял, объем Вашей внешней памяти = 32k:
90ffH - 1100H = 7fffH = 32767 с учетом нулевого адреса 32768

У AVRа адресация ОЗУ начинается с адреса 0, следовательно при подключении внешней памяти объемом 32к адреса с 0x0000 по 0x10ff будут адресоваться как внутренние, а конец памяти будет = 0x7fff а не 0x90ff. Если Ваш указатель попадал на область выше 0x7fff то обращение шло в никуда, оттуда и могли возникать ошибки.

Это замечание справедливо если у вас нет конвертора адреса, который Ваш 0x1100 на шине адреса AVR преобрезует в 0x0000 на шине адреса ОЗУ.
Go to the top of the page
 
+Quote Post
Axer
сообщение May 24 2005, 10:37
Сообщение #5





Группа: Новичок
Сообщений: 7
Регистрация: 24-05-05
Пользователь №: 5 336



Нет, не в этом дело sad.gif
Да и не мог указатель так далеко забраться, я памяти мало использую.
Go to the top of the page
 
+Quote Post
BorisRozentsvaig
сообщение May 24 2005, 13:23
Сообщение #6


Участник
*

Группа: Свой
Сообщений: 36
Регистрация: 23-03-05
Из: Санкт-Петербург
Пользователь №: 3 617



Цитата(Axer @ May 24 2005, 14:37)
Нет, не в этом дело sad.gif
Да и не мог указатель так далеко забраться, я памяти мало использую.
*


Вы не ответили на вопрос: каким образом у вас "s" объявлена и инициализирована?

Какую внешнюю память вы используете?

Кстати, я в своем проекте (правда, у меня ATmega128), вообще никаких
-Tdata=0x801100,--defsym=__heap_end=0x8090ff не использую, все без этого великолепно работает.
Go to the top of the page
 
+Quote Post
Axer
сообщение May 25 2005, 11:26
Сообщение #7





Группа: Новичок
Сообщений: 7
Регистрация: 24-05-05
Пользователь №: 5 336



Цитата
Вы не ответили на вопрос: каким образом у вас "s" объявлена и инициализирована?


Я ответил.
void ce210_print(char *s)
{
while (*s) ce210_send(*s++);
}
это вся функция.

Цитата
Какую внешнюю память вы используете?

Samsung 328А
Цитата
Кстати, я в своем проекте (правда, у меня ATmega128), вообще никаких
-Tdata=0x801100,--defsym=__heap_end=0x8090ff не использую, все без этого великолепно работает.

Попробую так...
Go to the top of the page
 
+Quote Post
BorisRozentsvaig
сообщение May 25 2005, 12:34
Сообщение #8


Участник
*

Группа: Свой
Сообщений: 36
Регистрация: 23-03-05
Из: Санкт-Петербург
Пользователь №: 3 617



Цитата(Axer @ May 25 2005, 15:26)
Цитата
Вы не ответили на вопрос: каким образом у вас "s" объявлена и инициализирована?


Я ответил.
void ce210_print(char *s)
{
while (*s) ce210_send(*s++);
}
это вся функция.


Я понимаю, что это вся функция :-) Вы в неё в качестве параметра передаете указатель, который объявлен и инициализирован у вас где-то в основной программе или в другой функции. Про объявление и инициализацию этого указателя я у вас и спрашивал.
Go to the top of the page
 
+Quote Post
Axer
сообщение May 25 2005, 12:45
Сообщение #9





Группа: Новичок
Сообщений: 7
Регистрация: 24-05-05
Пользователь №: 5 336



так:
ce210_print("string");
или так:
char* a;
ce210_print(a);
Go to the top of the page
 
+Quote Post
BorisRozentsvaig
сообщение May 25 2005, 14:30
Сообщение #10


Участник
*

Группа: Свой
Сообщений: 36
Регистрация: 23-03-05
Из: Санкт-Петербург
Пользователь №: 3 617



Цитата(Axer @ May 25 2005, 16:45)
так:
ce210_print("string");
или так:
char* a;
ce210_print(a);
*


А с чего вы решили, что данные переменные будут размещены во внешней памяти?
Кстати, во втором случае, я не вижу инициализации указателя.
Вот, например, если бы вы написали:
char* a = 0x2000;
то это был бы адрес внешней памяти.

Попробуйте посмотреть здесь:
http://www.avrfreaks.net/index.php?name=PN...ewtopic&t=29499

Там, правда, речь идет о ATmega128, но принципы одинаковые.
Go to the top of the page
 
+Quote Post
Axer
сообщение May 26 2005, 07:14
Сообщение #11





Группа: Новичок
Сообщений: 7
Регистрация: 24-05-05
Пользователь №: 5 336



Цитата(BorisRozentsvaig @ May 25 2005, 17:30)
А с чего вы решили, что данные переменные будут размещены во внешней памяти?

А это здесь причем? Во внешней или во внутренней, все равно глючит.
А во внешней вот почему:
EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x8090ff

Цитата
Кстати, во втором случае, я не вижу инициализации указателя.

Подразумевается, что char* a используется для хранения различных строк.

Цитата
Попробуйте посмотреть здесь:
http://www.avrfreaks.net/index.php?name=PN...ewtopic&t=29499
Там, правда, речь идет о ATmega128, но принципы одинаковые.

Да, они практически не отличаются. Читаю.
Go to the top of the page
 
+Quote Post
BorisRozentsvaig
сообщение May 26 2005, 08:10
Сообщение #12


Участник
*

Группа: Свой
Сообщений: 36
Регистрация: 23-03-05
Из: Санкт-Петербург
Пользователь №: 3 617



А что, если вам попробовать запустить для начала тест внешней памяти/
Например, так:

#define EXT_MEM_START 0x1100

BOOL ram_test(void)
{
unsigned short j;

for (j = 0; j < RAM_SIZE; j++) _SFR_MEM8((j) + EXT_MEM_START) = (unsigned char)(j);

for (j = 0; j < RAM_SIZE; j++)
{
if (_SFR_MEM8((j) + EXT_MEM_START) != (unsigned char)(j)) return FALSE;
}
return TRUE;
}
Go to the top of the page
 
+Quote Post
Axer
сообщение Jun 1 2005, 09:47
Сообщение #13





Группа: Новичок
Сообщений: 7
Регистрация: 24-05-05
Пользователь №: 5 336



Сделал тест памяти. Все работает.
С указателями ситуация так и не ясна. Когда он во встроенной памяти - все работает. Как только во внешнюю его помещаю, начинается ерунда.
Go to the top of the page
 
+Quote Post
BorisRozentsvaig
сообщение Jun 3 2005, 06:10
Сообщение #14


Участник
*

Группа: Свой
Сообщений: 36
Регистрация: 23-03-05
Из: Санкт-Петербург
Пользователь №: 3 617



Цитата(Axer @ Jun 1 2005, 13:47)
Сделал тест памяти. Все работает.
С указателями ситуация так и не ясна. Когда он во встроенной памяти - все работает. Как только во внешнюю его помещаю, начинается ерунда.
*


Это хорошо, что тест памяти работает - значит дело не в оборудовании, уже легче.

А попробуйте объявить указатель след. образом:

void ce210_print(volatile char *s)
{
while (*s) ce210_send(*s++);
}

или:

void ce210_print(char *s)
{
volatile char* a = s;
while (*a) ce210_send(*a++);
}

Думаю, что все заработает сразу smile.gif
Go to the top of the page
 
+Quote Post
pulsar-17
сообщение Jun 3 2005, 11:18
Сообщение #15


Участник
*

Группа: Свой
Сообщений: 32
Регистрация: 7-12-04
Из: Московская область
Пользователь №: 1 376



можно и без volatile:

void ce210_print(char *s)
{
register char ch;

while (1)
{
ch = *s;
if (ch == 0) break; //(или return)
ce210_send(ch);
s++;
}
}

при while (*a) ce210_send(*a++); да еще и volatile будет скорее всего 2 обращения к памяти, что в данном случае бессмысленно
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 20th July 2025 - 18:51
Рейтинг@Mail.ru


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