Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Nios II и размещение переменных
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
torik
Есть система, которая включает Nios и некоторые самодельные компоненты.
Она на рисунке показана. Зелененьким обведена onchip память, которая указана процессору как exception memory,
а синеньким обведен самодельный компонент, основой которого является также onchip память, двухпортовая. К этой области памяти проц обращается через IOWR/IORD.

Нельзя ли создать переменную, которая была бы размещена уже в этой области памяти (некая структура)? Как это сделать, какие-нибудь директивы вроде pragma нужны?

Ой, забыл картинку sm.gif
vadimuzzz
ну так создать структуру, объявить указатель на нее, а потом указателю присвоить адрес компонента - не пойдет?
torik
Мне надо чтобы структура уже располагалась в памяти по адресу 0х042000. Тогда самодельный компонент будет забирать оттуда данные.
А указатель не поможет в этом, ведь данные будут располагаться там где скажет компилятор...
vadimuzzz
тогда через атрибуты, например:
Код
int some_variable __attribute__ ((section (".onchip_memory_0.rwdata"))) = 0;
torik
Да, уже ближе.
Но компонент свой самодельный надо бы, наверное, сделать с галочкой Memory Device...
vadimuzzz
Цитата(torik @ Mar 28 2011, 19:05) *
Но компонент свой самодельный надо бы, наверное, сделать с галочкой Memory Device...

да. другой вариант - использовать готовый он-чип, он умеет 2-портовый доступ. а из компонента вытянуть авалон-мм
torik
Пишем:

Код
unsigned int temp1 __attribute__ ((section (".onchip_memory2_0.rwdata"))) = 0;


Результат:
Код
Description    Resource    Path    Location    Type
error: no memory region specified for loadable section `.onchip_memory2_0.rwdata'    MI_2        line 0    C/C++ Problem




Цитата
да. другой вариант - использовать готовый он-чип, он умеет 2-портовый доступ. а из компонента вытянуть авалон-мм


Суть в том, что в компоненте как раз и есть готовый он-чип с двухпортовым доступом. Один порт отдаю ниосу, дабы он писал данные в он-чип, а из второго компонент забирает эти данные.
Т.е. если указать эклипсу, что переменная temp1 должна лежать по адресу компонента, то я смогу обращаться к ней как:
Код
temp1 = 111;

а не
Код
IOWR(....);
vadimuzzz
Цитата(torik @ Mar 28 2011, 19:14) *
Т.е. если указать эклипсу, что переменная temp1 должна лежать по адресу компонента, то я смогу обращаться к ней как:
Код
temp1 = 111;

а не
Код
IOWR(....);

ну, так а кто мешает сделать так:
Код
int* temp1_ptr;
temp1_ptr = onchip_memory2_0_base;
temp1_ptr |=0x80000000;
*temp1_ptr=111;


по поводу ошибки - надо настройки линкера посмотреть
torik
А это зачем?
Цитата
temp1_ptr |=0x80000000;



С обычной переменной вроде работает. Теперь делаю указатель на структуру, котрая содержит 512 байт - пока что-то не пашет...

Пля, как указатель на элемент структуры-то обратиться?
Код
*chibis->can_mi_ps.ps4.ps.VAL_IK = VALID;


дает ошибку:
Код
FCRX_CH1C/fcrx_ch1c.c:172: error: request for member 'ps4' in something not a structure or union

Stewart Little
Цитата(torik @ Mar 28 2011, 16:49) *
А это зачем?

Отделить мух от котлет.
В смысле, Memory от IO.
vadimuzzz
Цитата(torik @ Mar 28 2011, 19:49) *
С обычной переменной вроде работает. Теперь делаю указатель на структуру, котрая содержит 512 байт - пока что-то не пашет...

смотрите в сторону alt_remap_uncached, там размер можно указать

Цитата
Пля, как указатель на элемент структуры-то обратиться?
Код
*chibis->can_mi_ps.ps4.ps.VAL_IK = VALID;


дает ошибку:
Код
FCRX_CH1C/fcrx_ch1c.c:172: error: request for member 'ps4' in something not a structure or union


я так понимаю, либо "chibis->", либо "(*chibis)."
torik
Вот так вот работает:
Код
chibis->can_mi_ps->ps4.ps.VAL_IK = VALID;


Однако, почему-то некорректно. Структура содержит:

Код
typedef union CAN_MI_PS1
{
    struct {
        unsigned char    zoom_ik;
        unsigned char    zoom_tv;
        unsigned short    distance;
//        unsigned char    num_ch;
//        unsigned char    subsampling;
        unsigned int    r1;
    }    ps;
    struct {
        unsigned    char    d[8];
    }    b;
} CAN_MI_PS1;


При записи в zoom_ik, пишется сразу 4 одинаковых байта. Во как. Наверное, надо поколдовать с типами данных, не?
vadimuzzz
Цитата(torik @ Mar 28 2011, 20:17) *
Наверное, надо поколдовать с типами данных, не?

возможно, это связано с выравниваем полей в структуре. надо еще в атрибутах покопаться
torik
где бы почитать чё-нибудь про эти атрибуты?

Запись char:
Код
    chibis->tmp1 = (FCTX_CH1C2_0_BASE) | 0x80000000;
    chibis->tmp1->ps1.ps.zoom_ik = 0x05;


дает результат (сигналтабом смотрю) 0х05050505;
vadimuzzz
Цитата(torik @ Mar 28 2011, 20:29) *
дает результат (сигналтабом смотрю) 0х05050505;

а может, это и правильно. что там с byteenable?
смотреть любые маны по gnu-тым тулзам. например, nios2eds/documents/index.htm
torik
Цитата
а может, это и правильно. что там с byteenable?

Не смотрел. В любом случае, как 0х05 превратилось в 0х05050505?

Цитата
смотреть любые маны по gnu-тым тулзам. например, nios2eds/documents/index.htm

Чё? Там еще поди найди.
vadimuzzz
Цитата(torik @ Mar 28 2011, 20:39) *
Не смотрел. В любом случае, как 0х05 превратилось в 0х05050505?

была как-то такая же штука. тоже удивлялся. попробуйте на 32-битных транзакциях
torik
Цитата
попробуйте на 32-битных транзакциях

Если переменные структуры 2-разрядные, то вроде все нормально. С битовыми полями все же интересно понять...
alexPec
Цитата(torik @ Mar 28 2011, 17:39) *
как 0х05 превратилось в 0х05050505?


ну если байт-энейбл постоянно на все разряды "энейбл" он ведь не сможет записать только 1 байт, будет по-любому 4 писать, а компилятор подсовывает это значение. Может поэтому? Посмотрите сигналтапом что в это время на be[3..0] творится.
torik
Да, кстати... Кхе кхе... У меня не используется сигнал byteenable в интерфейсе моего компонента, разве что SOPC сам его добавил.
Но если здраво рассудить: даже если byteenable работает корректно, все равно обращение к переменной минимум сможет поменять 1 байт целиком. Для работы с битовыми полями требуются операции чтение-изменение-запись. Я правильно понимаю?
В обычных МК так и происходит, если смотреть дизассемблер. Здесь не знаю, потому и интересно.

А с практической же точки зрения я посмотрел повнимательнее, и оказалось, что нужные данные занимают всего десяток-другой 32-бит слов. Memcpy с этим справится легко, полагаю (завтра проверю)
vadimuzzz
Код
IOWR_8DIRECT(ONCHIP_RAM_BASE,0,0x05);




ничего не напоминает? sm.gif
torik
Вот как получается. Мда, т.е. нужен, конечно, byteenable. Однако, если вместо IOWR() сделать a = 2222, компилер сделает тоже самое? Все же чтение-модификация-запись необходимо чтобы поменять только один бит...

И, кстати, чтобы byteenable работал надо 4 ончип памяти по 8 бит вместо одной 32-бит?
vadimuzzz
Код
typedef union CAN_MI_PS1
{
    struct {
        unsigned char    zoom_ik;
        unsigned char    zoom_tv;
        unsigned short    distance;
        unsigned int    r1;
    }    ps;
    struct {
        unsigned    char    d[8];
    }    b;
} CAN_MI_PS1;
...
p1->ps.zoom_ik=0x05;




похоже, действительно, это из-за выравнивания полей
torik
Сейчас добавил оничипу сигналы byteenable.
в программе делаю IOWR_8DIRECT(ONCHIP_RAM_BASE,0,0x05);
Сигналтабом наблюдаю, что byteenable всегда 0х0f.
Чё-то расходится с вашей картинкой.
vadimuzzz
давайте настройки RAM сравним

torik
Исправил у себя ошибочку...
Кстати, у меня не сопсовская он-чип, у меня он-чип в моем компоненте, а к нему уже авалоновский интерфейс. Но это не имеет отношения к делу пожалуй.

Наблюдаю byteenable = 0x01. Однако записываются все равно все 4 байта!
Чё-то не так...

Ё-моё, опять ступил. Сигнал byteenable подал, да не на ту ончипу sm.gif.
Теперь все заработало.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.