Jump to content

    

WinAVR & External memory

можно и без 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 обращения к памяти, что в данном случае бессмысленно

 

Через register тоже можно, не спорю. Но в данном случае главное не скорость, а чтобы заработало :-)

volatile - это для общности.... :)

Share this post


Link to post
Share on other sites
Через register тоже можно, не спорю. Но в данном случае главное не скорость, а чтобы заработало :-)

volatile - это для общности.... :)

 

Согласен, но мой вариант более предсказуем с точки зрения компилятора (GCC). И в дизассемблере с ним проще разобраться.

 

Axer, дизассемблируйте Ващу функцию и посмотрите чего там скомпилилос. Я неоднократно нарывался на "неправильный код"(сам был виноват), т.к. GCC очень требователен к конструкциям языка.

Проверьте, какое значение указателя записывается перед вызовом функции и

что находится по этому указателю.

Да и стоит ли на текстовые сообщения ОЗУ тратить? У меня они только во флеше сидят.

#include <avr\io.h>

#include <avr\pgmspace.h>

 

const prog_char str[] = "test message";

 

void print(const prog_char *s)

{

char ch;

 

while(1)

{

ch = pgm_read_byte(s);

if (ch == 0) break;

PORTA = ch;

s++;

}

}

 

int main (void)

{

 

print(str);

 

print(PSTR("TEST2"));//или так

 

return 0;

}

Share this post


Link to post
Share on other sites

Поднимаю тему, чтобы не плодить новых.

 

Задача:

- разместить в XRAM несколько длинных массивы, оставив все остальное во внутренней RAM

 

Во внутренней памяти все работает.

 

Что делаю:

1)

- в оболочке WinAVR указываю доп. сегмент .xdata 0x802000

- переопределяю размещение массивов (размерность сокращена)

volatile UCHAR BufAdc[281] __attribute__ ((section (".xdata")));

volatile UINT BufAdc1[281] __attribute__ ((section (".xdata")));

volatile UINT BufAdc2[281] __attribute__ ((section (".xdata")));

- разрешаю работу XRAM (тайменги и конфиг. XRAM сути не меняют, но привожу)

MCUCR = (1<<SRE) | (0<<SRW10);

XMCRA = (0<<SRL2) | (0<<SRL1) | (0<<SRL0) | (0<<SRW01) | (0<<SRW00) | (0<<SRW11);

XMCRB = (0<<XMBK) | (0<<XMM2) | (0<<XMM1) | (0<<XMM0);

Размещение:

.xdata 0x00802000 0x57d Variables.o

0x00802000 BufAdc

0x00802119 BufAdc1

0x0080234b BufAdc2

 

Это работает!

 

2)

Увеличиваю размерность одного массива до нужного (в *.h как extern естественно тоже), остальное без изменений.

volatile UCHAR BufAdc[1281] __attribute__ ((section (".xdata")));

Размещение:

.xdata 0x00802000 0x965 variables.o

0x00802000 BufAdc

0x00802501 BufAdc1

0x00802733 BufAdc2

 

Не работает, точнее слетает связь по UART!

Смотрю по map - все остальные переменные находятся на своих местах, т.е. не менялись...

Эти массивы в работе UART при ответах естественно не участвуют.

Возвращаю размер на обратно - работает!

 

В чем мой косяк?

Прошу пнуть в нужном направлении.

 

(Mega128A + SRAM, WinAVR + AVR Studio 4.18)

 

 

Share this post


Link to post
Share on other sites

Странно,

портится глобальный флаг готовности буфера приема объявленный как

volatile uint8_t fCmdComplite = 0;

 

прерывание его выставляет = "1", но где то он портится в "0" и в main() он уже "0"...

- свои "сбросы" этого флага убрал...

- его положение сместил в .bss

0x00800248 fCmdComplite

 

... один ---, т.е. не помогает..

 

(оптимизация Os)

 

.... (в 12:15)

 

Похоже это косяки WinAVR:

при оптимизации -О2 удалось "довести" массивы до 768 единиц!

 

Шаманство какое-то!!!

 

Кто нибудь знает как с ним бороться?

 

..... (18:06)

нет все таки, ряд глюков остался...

наверняка у меня где-то косяк в коде...

 

кто нибудь знает:

WinAVR при различной оптимизации может валидный код "убивать"?

для IAR, Keil и ICC, что то я таких проблем не припомню...

 

 

Edited by Dimy

Share this post


Link to post
Share on other sites

В общем проблемма решена.

 

Для тех кто наступит на те же грабли:

наплюйте на настройки WinAVR через оболочку (Project/Configeration Options)

просто пользуйтесь внешним Makefile с правками по рекомендации:

http://www.avrfreaks.net/index.php?name=PN...ght=winavr+xram

 

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this