|
|
  |
NIOS II, программирование ниос2 на СИ |
|
|
|
Jan 20 2015, 09:36
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(Golikov A. @ Jan 20 2015, 12:24)  нет потому что нужно адрес не int addr_on_chip=0x4008000
а int *addr_on_chip = (int *)0x4008000;
записать туда *addr_on_chip = 10; считать оттуда int Temp = *addr_on_chip;
при условии что 0x4008000 - это адрес в ДДР Спасибо за разъяснение. Цитата(doom13 @ Jan 20 2015, 12:26)  Да, data - то, что хотите видеть на выходе порта или то, что читаете. Адреса pio_in, pio_out, pio_out_on берёте из system.h. Спасибо, теперь все понятно стало
|
|
|
|
|
Jan 20 2015, 09:57
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(doom13 @ Jan 20 2015, 12:42)  Нет, не правильная, все действия через указатель. имеете ввиду надо как запись повыше у Golikov A.
Сообщение отредактировал x66 - Jan 20 2015, 09:57
|
|
|
|
|
Jan 20 2015, 10:19
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(Golikov A. @ Jan 20 2015, 12:59)  В процах вообще все делается через обращения в адреса памяти. Потому что в вашем проце вся периферия - это модули которые весят на шине и имеют свой адрес, и все их регистры доступны как данные через этот адрес (группу адресов) Только вот в случае ниоса обращение к регистрам периферии лучще осуществлять с использованием макросов из BSP, чтобы потом не думать, что же оно не работает. Цитата(x66 @ Jan 20 2015, 12:57)  имеете ввиду надо как запись повыше у Golikov A. да, подробный механизм работы с указателем у Golikov A расписан, а пример того, как это делается (указатель на память) приводил выше (сообщение #10), что и было потом расписано с подробностями.0
|
|
|
|
|
Jan 20 2015, 10:26
|
Знающий
   
Группа: Участник
Сообщений: 527
Регистрация: 4-06-14
Из: Санкт-Петербург
Пользователь №: 81 866

|
Цитата Только вот в случае ниоса обращение к регистрам периферии лучще осуществлять с использованием макросов из BSP, чтобы потом не думать, что же оно не работает. Присоединяюсь. Есть там такая тонкость: если общаться с переферийным модулем (в т.ч. самописным) посредством макросов типа IOWR/IORD, то все должно работать нормально, если общаться через сишные пойнтеры, то могут возникнуть проблемы. Сам сталкивался с этим и долго думал, что же не работает. Объявил пойнтеры на начало массива по адресу, выделенному переферийному модулю, но при попытке чтения/записи массива стандартным для С способом получалась ошибка. Проблема была в Nios Data Cache. Когда он включен, адекватно работают только макросы IOWR/IORD. Если его вырубить, то можно использовать стандартные методы С, но если в этом нет необходимости, я тоже советую использовать макросы.
|
|
|
|
|
Jan 20 2015, 10:45
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Когда смотрел примеры, на сайте альтеры нашел файл где была программа с использованием указателей. натыкался на другие примеры там с использованием макросов было. Это меня и сбивало с толку, как я понял это два способа работы с одним и тем же
|
|
|
|
|
Jan 20 2015, 10:53
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(x66 @ Jan 20 2015, 13:45)  Когда смотрел примеры, на сайте альтеры нашел файл где была программа с использованием указателей. натыкался на другие примеры там с использованием макросов было. Это меня и сбивало с толку, как я понял это два способа работы с одним и тем же Сомневаюсь, что Вы могли найти примеры от Alter-ы с использованием указателей для обращения к регистрам периферии, тут всё только через макросы (возможно какой-то очень "особенный" пример для ниоса без кэша, но очень маловероятно). Для работы с памятью (On-Chip, SDRAM, DDR и т.д.) указатели и используются.
|
|
|
|
|
Jan 20 2015, 11:00
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 7-05-10
Пользователь №: 57 122

|
Цитата(doom13 @ Jan 20 2015, 13:53)  Сомневаюсь, что Вы могли найти примеры от Alter-ы с использованием указателей для обращения к регистрам периферии, тут всё только через макросы (возможно какой-то очень "особенный" пример для ниоса без кэша, но очень маловероятно). Для работы с памятью (On-Chip, SDRAM, DDR и т.д.) указатели и используются. вот код примера int to_hex(char* pkt) { int value[8]; int value1; int q; for (q=0; q <= 7; q++) { value[q] = (pkt[q] > 0x39) ? (pkt[q] - 0x37) : (pkt[q] - 0x30); if (q == 0) value1 = (0 + value[q]); else value1 = ((value[q-1] << 4) + value[q]); } return value1; } int main() { unsigned long *DDR_address; //long is 32 bits. int addr; int datar; int ddr_data_out; char packet[32]; DDR_address = (unsigned long *)0x2000000; //make non-cache iprintf("DDR test installed \n"); while (1) { gets(packet); switch(packet[0]) { case 'B': // write operation addr = to_hex(&packet[1]); datar = to_hex(&packet[9]); DDR_address[addr] = datar; iprintf("Written %08x to address %08x \n", datar, addr); break; case 'C': // Read operation addr = to_hex(&packet[1]); ddr_data_out = DDR_address[addr]; iprintf("Read %08x from address %08x \n", ddr_data_out, addr); break; default: iprintf("Error: Unexpected command. Switch was - %C \n",packet[0]); break; } } return 0; }
|
|
|
|
|
Jan 20 2015, 11:38
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(Golikov A. @ Jan 20 2015, 13:59)  Ну прекратите сбивать человека ну возьмите вы свои макросы и поглядите, все в конце сводиться к volatile записи ну или на худой конец к записи с вызовом слива кеша. Чудес то не бывает, макрос то тоже написан средствами языка С, просто иногда делает больше чем 1 действие.
У ксалинкса можно еще выбрать не кешируемое пространство, куда периферию пихаешь чтобы проблем не было, уверен у ниоса тоже должно что-то такое быть.
Так что все можно и ручками сделать, если по какой-то причине макросы вредят. А такое бывает если у вас запись в 10 портов под кешевой областью, то кешь сливать лучше не после каждой записи а сразу после всех. Ну или наоборот, нюансы бывают... Это Вы прекратите сбивать человека. Если я использую указатель для записи памяти/регистра, то я предполагаю, что после записи значения по данному указателю, необходимое значение попадает по нужному адресу и нет необходимости в выполнении ещё каких-то дополнительных действий. В случае регистров Ниоса этого не происходит, т.е. тут правильно исполтьзовать макросы для работы с регистрами. Макросы не вредят, они и присутствуют в BSP, чтобы их использовать. Код // 1 IOWR(BASE, DATA); Код // 2 unsigned int *base_ptr = (unsigned int *)BASE; *base_ptr = DATA; Первый код будет работать, а второй нет (BASE - адресс какого-либо регистра). Цитата(x66 @ Jan 20 2015, 14:00)  вот код примера Но это и есть использование указателя для обращения к памяти (тут всё ок), речь шла про настройку регистров. Например код для GPIO: Код // 1 unsigned int *gpio_data_ptr; unsigned int *gpio_direction_ptr; gpio_data_ptr = (unsigned int) GPIO_OUT_BASE; gpio_direction_ptr = (unsigned int) (GPIO_OUT_BASE + 1); *gpio_data_ptr = 1; *gpio_direction_ptr = 1; может не работать. А 100% рабочий вариант: Код // 2 IOWR_ALTERA_AVALON_PIO_DATA(GPIO_OUT_BASE, 1); IOWR_ALTERA_AVALON_PIO_DIRECTION(GPIO_OUT_BASE, 1); Подразумевалось что код и 1 и 2 должен выполнить одно и то же, на на деле - нет. Для других процов первый вариант кода будет работать - для Ниоса НЕТ!
|
|
|
|
|
Jan 20 2015, 11:51
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
ох... Цитата Первый код будет работать, а второй нет (BASE - адресс какого-либо регистра). а так? volatile unsigned int *base_ptr = (unsigned int *)BASE; *base_ptr = DATA;
|
|
|
|
|
Jan 20 2015, 12:01
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
раскройте вы макрос и поглядите что в нем, я не спорю что у всех может быть все по своему, но не думаю что альтера себе враг. вот ксалиновский макрос Код XGpio_WriteReg(BASE, XGPIO_DATA_OFFSET, Data); который на самом деле Код #define XGpio_WriteReg(BaseAddress, RegOffset, Data) \ XGpio_Out32((BaseAddress) + (RegOffset), (u32)(Data)) который на самом деле Код #define XGpio_Out32 Xil_Out32 который на самом деле Код #define Xil_Out32(Addr, Value) \ (*(volatile u32 *)((Addr)) = (Value)) то есть эта обычная запись по адресу, но с принудительным указанием того что он valotile Цитата И каким образом volatile тут будет влиять на то, чтоб запись данных шла мимо кэша? Знающие люди советовали другое. я и не утверждаю что valotile на это повлияет и я видел что пишут другие люди. Нету у меня среды альтеры, потому не могу макрос поглядеть, и прошу вас его показать. В ксалинксе периферия вешается в не кешируемую область памяти, неужели ниосы до этого не догадались? Так делают на всех процах. А так как я правды не знаю, то и прошу раскрыть макрос
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|