Есть система, которая включает Nios и некоторые самодельные компоненты.
Она на рисунке показана. Зелененьким обведена onchip память, которая указана процессору как exception memory,
а синеньким обведен самодельный компонент, основой которого является также onchip память, двухпортовая. К этой области памяти проц обращается через IOWR/IORD.
Нельзя ли создать переменную, которая была бы размещена уже в этой области памяти (некая структура)? Как это сделать, какие-нибудь директивы вроде pragma нужны?
Ой, забыл картинку
vadimuzzz
Mar 28 2011, 11:43
ну так создать структуру, объявить указатель на нее, а потом указателю присвоить адрес компонента - не пойдет?
Мне надо чтобы структура уже располагалась в памяти по адресу 0х042000. Тогда самодельный компонент будет забирать оттуда данные.
А указатель не поможет в этом, ведь данные будут располагаться там где скажет компилятор...
vadimuzzz
Mar 28 2011, 11:56
тогда через атрибуты, например:
Код
int some_variable __attribute__ ((section (".onchip_memory_0.rwdata"))) = 0;
Да, уже ближе.
Но компонент свой самодельный надо бы, наверное, сделать с галочкой Memory Device...
vadimuzzz
Mar 28 2011, 12:07
Цитата(torik @ Mar 28 2011, 19:05)

Но компонент свой самодельный надо бы, наверное, сделать с галочкой Memory Device...
да. другой вариант - использовать готовый он-чип, он умеет 2-портовый доступ. а из компонента вытянуть авалон-мм
Пишем:
Код
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
Mar 28 2011, 12:21
Цитата(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;
по поводу ошибки - надо настройки линкера посмотреть
А это зачем?
Цитата
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
Mar 28 2011, 12:54
Цитата(torik @ Mar 28 2011, 16:49)

А это зачем?
Отделить мух от котлет.
В смысле, Memory от IO.
vadimuzzz
Mar 28 2011, 13:07
Цитата(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)."
Вот так вот работает:
Код
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
Mar 28 2011, 13:25
Цитата(torik @ Mar 28 2011, 20:17)

Наверное, надо поколдовать с типами данных, не?
возможно, это связано с выравниваем полей в структуре. надо еще в атрибутах покопаться
где бы почитать чё-нибудь про эти атрибуты?
Запись char:
Код
chibis->tmp1 = (FCTX_CH1C2_0_BASE) | 0x80000000;
chibis->tmp1->ps1.ps.zoom_ik = 0x05;
дает результат (сигналтабом смотрю) 0х05050505;
vadimuzzz
Mar 28 2011, 13:32
Цитата(torik @ Mar 28 2011, 20:29)

дает результат (сигналтабом смотрю) 0х05050505;
а может, это и правильно. что там с byteenable?
смотреть любые маны по gnu-тым тулзам. например, nios2eds/documents/index.htm
Цитата
а может, это и правильно. что там с byteenable?
Не смотрел. В любом случае, как 0х05 превратилось в 0х05050505?
Цитата
смотреть любые маны по gnu-тым тулзам. например, nios2eds/documents/index.htm
Чё? Там еще поди найди.
vadimuzzz
Mar 28 2011, 14:22
Цитата(torik @ Mar 28 2011, 20:39)

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

как 0х05 превратилось в 0х05050505?
ну если байт-энейбл постоянно на все разряды "энейбл" он ведь не сможет записать только 1 байт, будет по-любому 4 писать, а компилятор подсовывает это значение. Может поэтому? Посмотрите сигналтапом что в это время на be[3..0] творится.
Да, кстати... Кхе кхе... У меня не используется сигнал byteenable в интерфейсе моего компонента, разве что SOPC сам его добавил.
Но если здраво рассудить: даже если byteenable работает корректно, все равно обращение к переменной минимум сможет поменять 1 байт целиком. Для работы с битовыми полями требуются операции чтение-изменение-запись. Я правильно понимаю?
В обычных МК так и происходит, если смотреть дизассемблер. Здесь не знаю, потому и интересно.
А с практической же точки зрения я посмотрел повнимательнее, и оказалось, что нужные данные занимают всего десяток-другой 32-бит слов. Memcpy с этим справится легко, полагаю (завтра проверю)
vadimuzzz
Mar 29 2011, 02:59
Код
IOWR_8DIRECT(ONCHIP_RAM_BASE,0,0x05);

ничего не напоминает?
Вот как получается. Мда, т.е. нужен, конечно, byteenable. Однако, если вместо IOWR() сделать a = 2222, компилер сделает тоже самое? Все же чтение-модификация-запись необходимо чтобы поменять только один бит...
И, кстати, чтобы byteenable работал надо 4 ончип памяти по 8 бит вместо одной 32-бит?
vadimuzzz
Mar 29 2011, 06:32
Код
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;

похоже, действительно, это из-за выравнивания полей
Сейчас добавил оничипу сигналы byteenable.
в программе делаю IOWR_8DIRECT(ONCHIP_RAM_BASE,0,0x05);
Сигналтабом наблюдаю, что byteenable всегда 0х0f.
Чё-то расходится с вашей картинкой.
vadimuzzz
Mar 29 2011, 09:01
давайте настройки RAM сравним
Исправил у себя ошибочку...
Кстати, у меня не сопсовская он-чип, у меня он-чип в моем компоненте, а к нему уже авалоновский интерфейс. Но это не имеет отношения к делу пожалуй.
Наблюдаю byteenable = 0x01. Однако записываются все равно все 4 байта!
Чё-то не так...
Ё-моё, опять ступил. Сигнал byteenable подал, да не на ту ончипу

.
Теперь все заработало.
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.