Axer 0 24 мая, 2005 Опубликовано 24 мая, 2005 · Жалоба Здравствуйте. У меня проблема с внешней памятью при работе с АтМега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. Версия ВинАВР последняя. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BorisRozentsvaig 0 24 мая, 2005 Опубликовано 24 мая, 2005 · Жалоба Здравствуйте. У меня проблема с внешней памятью при работе с АтМега64. Есть программа, рабочая. При подключении внешней памяти начинаются непонятные ошибки, причем ошибки начинаются при выполнении команды memmove() или при выполнении функции вывода строки: while (*s) ce210_send(*s++); <{POST_SNAPBACK}> А каким образом у вас "s" объявлена и инициализирована? И потом, если s - указатель на массив, то надо смотреть приоритет операторов, может лучше пока написать так: while (*s) { ce210_send(*s); s++; } Про приоритет операторов можно посмотреть тут: http://cclib.nsu.ru/projects/gnudocs/texts/bogatir/9.html Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Axer 0 24 мая, 2005 Опубликовано 24 мая, 2005 · Жалоба А каким образом у вас "s" объявлена и инициализирована? void ce210_print(char *s) { while (*s) ce210_send(*s++); } Я совершенно уверен, что дело тут не в приоритетах, как я уже сказал, без внешней памяти все работает правильно. Да, еще одно наблюдение. При инициализации всей памяти, которая учавствует в memmove(), ошибки вроде исчезают. Шаманство какое-то... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pulsar-17 0 24 мая, 2005 Опубликовано 24 мая, 2005 · Жалоба Возможно проблема в __heap_end=0x8090ff как я понял, объем Вашей внешней памяти = 32k: 90ffH - 1100H = 7fffH = 32767 с учетом нулевого адреса 32768 У AVRа адресация ОЗУ начинается с адреса 0, следовательно при подключении внешней памяти объемом 32к адреса с 0x0000 по 0x10ff будут адресоваться как внутренние, а конец памяти будет = 0x7fff а не 0x90ff. Если Ваш указатель попадал на область выше 0x7fff то обращение шло в никуда, оттуда и могли возникать ошибки. Это замечание справедливо если у вас нет конвертора адреса, который Ваш 0x1100 на шине адреса AVR преобрезует в 0x0000 на шине адреса ОЗУ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Axer 0 24 мая, 2005 Опубликовано 24 мая, 2005 · Жалоба Нет, не в этом дело :( Да и не мог указатель так далеко забраться, я памяти мало использую. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BorisRozentsvaig 0 24 мая, 2005 Опубликовано 24 мая, 2005 · Жалоба Нет, не в этом дело :( Да и не мог указатель так далеко забраться, я памяти мало использую. <{POST_SNAPBACK}> Вы не ответили на вопрос: каким образом у вас "s" объявлена и инициализирована? Какую внешнюю память вы используете? Кстати, я в своем проекте (правда, у меня ATmega128), вообще никаких -Tdata=0x801100,--defsym=__heap_end=0x8090ff не использую, все без этого великолепно работает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Axer 0 25 мая, 2005 Опубликовано 25 мая, 2005 · Жалоба Вы не ответили на вопрос: каким образом у вас "s" объявлена и инициализирована? Я ответил. void ce210_print(char *s) { while (*s) ce210_send(*s++); } это вся функция. Какую внешнюю память вы используете? Samsung 328А Кстати, я в своем проекте (правда, у меня ATmega128), вообще никаких -Tdata=0x801100,--defsym=__heap_end=0x8090ff не использую, все без этого великолепно работает. Попробую так... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BorisRozentsvaig 0 25 мая, 2005 Опубликовано 25 мая, 2005 · Жалоба Вы не ответили на вопрос: каким образом у вас "s" объявлена и инициализирована? Я ответил. void ce210_print(char *s) { while (*s) ce210_send(*s++); } это вся функция. Я понимаю, что это вся функция :-) Вы в неё в качестве параметра передаете указатель, который объявлен и инициализирован у вас где-то в основной программе или в другой функции. Про объявление и инициализацию этого указателя я у вас и спрашивал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Axer 0 25 мая, 2005 Опубликовано 25 мая, 2005 · Жалоба так: ce210_print("string"); или так: char* a; ce210_print(a); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BorisRozentsvaig 0 25 мая, 2005 Опубликовано 25 мая, 2005 · Жалоба так: ce210_print("string"); или так: char* a; ce210_print(a); <{POST_SNAPBACK}> А с чего вы решили, что данные переменные будут размещены во внешней памяти? Кстати, во втором случае, я не вижу инициализации указателя. Вот, например, если бы вы написали: char* a = 0x2000; то это был бы адрес внешней памяти. Попробуйте посмотреть здесь: http://www.avrfreaks.net/index.php?name=PN...ewtopic&t=29499 Там, правда, речь идет о ATmega128, но принципы одинаковые. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Axer 0 26 мая, 2005 Опубликовано 26 мая, 2005 · Жалоба А с чего вы решили, что данные переменные будут размещены во внешней памяти? А это здесь причем? Во внешней или во внутренней, все равно глючит. А во внешней вот почему: EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x8090ff Кстати, во втором случае, я не вижу инициализации указателя. Подразумевается, что char* a используется для хранения различных строк. Попробуйте посмотреть здесь: http://www.avrfreaks.net/index.php?name=PN...ewtopic&t=29499 Там, правда, речь идет о ATmega128, но принципы одинаковые. Да, они практически не отличаются. Читаю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BorisRozentsvaig 0 26 мая, 2005 Опубликовано 26 мая, 2005 · Жалоба А что, если вам попробовать запустить для начала тест внешней памяти/ Например, так: #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; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Axer 0 1 июня, 2005 Опубликовано 1 июня, 2005 · Жалоба Сделал тест памяти. Все работает. С указателями ситуация так и не ясна. Когда он во встроенной памяти - все работает. Как только во внешнюю его помещаю, начинается ерунда. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BorisRozentsvaig 0 3 июня, 2005 Опубликовано 3 июня, 2005 · Жалоба Сделал тест памяти. Все работает. С указателями ситуация так и не ясна. Когда он во встроенной памяти - все работает. Как только во внешнюю его помещаю, начинается ерунда. <{POST_SNAPBACK}> Это хорошо, что тест памяти работает - значит дело не в оборудовании, уже легче. А попробуйте объявить указатель след. образом: 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++); } Думаю, что все заработает сразу :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pulsar-17 0 3 июня, 2005 Опубликовано 3 июня, 2005 · Жалоба можно и без 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 обращения к памяти, что в данном случае бессмысленно Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться