x66 0 January 20, 2015 Posted January 20, 2015 · Report post нет потому что нужно адрес не int addr_on_chip=0x4008000 а int *addr_on_chip = (int *)0x4008000; записать туда *addr_on_chip = 10; считать оттуда int Temp = *addr_on_chip; при условии что 0x4008000 - это адрес в ДДР Спасибо за разъяснение. Да, data - то, что хотите видеть на выходе порта или то, что читаете. Адреса pio_in, pio_out, pio_out_on берёте из system.h. Спасибо, теперь все понятно стало Quote Share this post Link to post Share on other sites More sharing options...
doom13 0 January 20, 2015 Posted January 20, 2015 · Report post Имеется внешняя DDR2, также есть On-chip memory, которая необходима для моментов времени, когда происходит чтение из DDR2. В эклипсе для работы с адресами я использую строки, например int addr_on_chip=0x4008000; Правильная ли такая запись? Нет, не правильная, все действия через указатель. Quote Share this post Link to post Share on other sites More sharing options...
x66 0 January 20, 2015 Posted January 20, 2015 (edited) · Report post Нет, не правильная, все действия через указатель. имеете ввиду надо как запись повыше у Golikov A. Edited January 20, 2015 by x66 Quote Share this post Link to post Share on other sites More sharing options...
Golikov 0 January 20, 2015 Posted January 20, 2015 · Report post имеет ввиду тоже что и я... просто ответил позже кстати если копнете макрос IOWR_ALTERA_AVALON_PIO_DATA то на конце найдете что это таже самая запись через указатели, в определенный адрес В процах вообще все делается через обращения в адреса памяти. Потому что в вашем проце вся периферия - это модули которые весят на шине и имеют свой адрес, и все их регистры доступны как данные через этот адрес (группу адресов) Quote Share this post Link to post Share on other sites More sharing options...
doom13 0 January 20, 2015 Posted January 20, 2015 · Report post В процах вообще все делается через обращения в адреса памяти. Потому что в вашем проце вся периферия - это модули которые весят на шине и имеют свой адрес, и все их регистры доступны как данные через этот адрес (группу адресов) Только вот в случае ниоса обращение к регистрам периферии лучще осуществлять с использованием макросов из BSP, чтобы потом не думать, что же оно не работает. имеете ввиду надо как запись повыше у Golikov A. да, подробный механизм работы с указателем у Golikov A расписан, а пример того, как это делается (указатель на память) приводил выше (сообщение #10), что и было потом расписано с подробностями.0 Quote Share this post Link to post Share on other sites More sharing options...
serjj1333 0 January 20, 2015 Posted January 20, 2015 · Report post Только вот в случае ниоса обращение к регистрам периферии лучще осуществлять с использованием макросов из BSP, чтобы потом не думать, что же оно не работает. Присоединяюсь. Есть там такая тонкость: если общаться с переферийным модулем (в т.ч. самописным) посредством макросов типа IOWR/IORD, то все должно работать нормально, если общаться через сишные пойнтеры, то могут возникнуть проблемы. Сам сталкивался с этим и долго думал, что же не работает. Объявил пойнтеры на начало массива по адресу, выделенному переферийному модулю, но при попытке чтения/записи массива стандартным для С способом получалась ошибка. Проблема была в Nios Data Cache. Когда он включен, адекватно работают только макросы IOWR/IORD. Если его вырубить, то можно использовать стандартные методы С, но если в этом нет необходимости, я тоже советую использовать макросы. Quote Share this post Link to post Share on other sites More sharing options...
x66 0 January 20, 2015 Posted January 20, 2015 · Report post Когда смотрел примеры, на сайте альтеры нашел файл где была программа с использованием указателей. натыкался на другие примеры там с использованием макросов было. Это меня и сбивало с толку, как я понял это два способа работы с одним и тем же Quote Share this post Link to post Share on other sites More sharing options...
doom13 0 January 20, 2015 Posted January 20, 2015 · Report post Когда смотрел примеры, на сайте альтеры нашел файл где была программа с использованием указателей. натыкался на другие примеры там с использованием макросов было. Это меня и сбивало с толку, как я понял это два способа работы с одним и тем же Сомневаюсь, что Вы могли найти примеры от Alter-ы с использованием указателей для обращения к регистрам периферии, тут всё только через макросы (возможно какой-то очень "особенный" пример для ниоса без кэша, но очень маловероятно). Для работы с памятью (On-Chip, SDRAM, DDR и т.д.) указатели и используются. Quote Share this post Link to post Share on other sites More sharing options...
Golikov 0 January 20, 2015 Posted January 20, 2015 · Report post Ну прекратите сбивать человека ну возьмите вы свои макросы и поглядите, все в конце сводиться к volatile записи ну или на худой конец к записи с вызовом слива кеша. Чудес то не бывает, макрос то тоже написан средствами языка С, просто иногда делает больше чем 1 действие. У ксалинкса можно еще выбрать не кешируемое пространство, куда периферию пихаешь чтобы проблем не было, уверен у ниоса тоже должно что-то такое быть. Так что все можно и ручками сделать, если по какой-то причине макросы вредят. А такое бывает если у вас запись в 10 портов под кешевой областью, то кешь сливать лучше не после каждой записи а сразу после всех. Ну или наоборот, нюансы бывают... Quote Share this post Link to post Share on other sites More sharing options...
x66 0 January 20, 2015 Posted January 20, 2015 · Report post Сомневаюсь, что Вы могли найти примеры от 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; } Quote Share this post Link to post Share on other sites More sharing options...
krux 9 January 20, 2015 Posted January 20, 2015 · Report post http://www.altera.com/literature/hb/nios2/n2sw_nii52007.pdf для данных есть такой метод как Bit-31 Cache Bypass для Nios II/f Quote Share this post Link to post Share on other sites More sharing options...
doom13 0 January 20, 2015 Posted January 20, 2015 · Report post Ну прекратите сбивать человека ну возьмите вы свои макросы и поглядите, все в конце сводиться к volatile записи ну или на худой конец к записи с вызовом слива кеша. Чудес то не бывает, макрос то тоже написан средствами языка С, просто иногда делает больше чем 1 действие. У ксалинкса можно еще выбрать не кешируемое пространство, куда периферию пихаешь чтобы проблем не было, уверен у ниоса тоже должно что-то такое быть. Так что все можно и ручками сделать, если по какой-то причине макросы вредят. А такое бывает если у вас запись в 10 портов под кешевой областью, то кешь сливать лучше не после каждой записи а сразу после всех. Ну или наоборот, нюансы бывают... Это Вы прекратите сбивать человека. Если я использую указатель для записи памяти/регистра, то я предполагаю, что после записи значения по данному указателю, необходимое значение попадает по нужному адресу и нет необходимости в выполнении ещё каких-то дополнительных действий. В случае регистров Ниоса этого не происходит, т.е. тут правильно исполтьзовать макросы для работы с регистрами. Макросы не вредят, они и присутствуют в BSP, чтобы их использовать. // 1 IOWR(BASE, DATA); // 2 unsigned int *base_ptr = (unsigned int *)BASE; *base_ptr = DATA; Первый код будет работать, а второй нет (BASE - адресс какого-либо регистра). вот код примера Но это и есть использование указателя для обращения к памяти (тут всё ок), речь шла про настройку регистров. Например код для 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 должен выполнить одно и то же, на на деле - нет. Для других процов первый вариант кода будет работать - для Ниоса НЕТ! Quote Share this post Link to post Share on other sites More sharing options...
Golikov 0 January 20, 2015 Posted January 20, 2015 · Report post ох... Первый код будет работать, а второй нет (BASE - адресс какого-либо регистра). а так? volatile unsigned int *base_ptr = (unsigned int *)BASE; *base_ptr = DATA; Quote Share this post Link to post Share on other sites More sharing options...
doom13 0 January 20, 2015 Posted January 20, 2015 · Report post а так? volatile unsigned int *base_ptr = (unsigned int *)BASE; *base_ptr = DATA; И каким образом volatile тут будет влиять на то, чтоб запись данных шла мимо кэша? Знающие люди советовали другое. Quote Share this post Link to post Share on other sites More sharing options...
Golikov 0 January 20, 2015 Posted January 20, 2015 · Report post раскройте вы макрос и поглядите что в нем, я не спорю что у всех может быть все по своему, но не думаю что альтера себе враг. вот ксалиновский макрос 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 на это повлияет и я видел что пишут другие люди. Нету у меня среды альтеры, потому не могу макрос поглядеть, и прошу вас его показать. В ксалинксе периферия вешается в не кешируемую область памяти, неужели ниосы до этого не догадались? Так делают на всех процах. А так как я правды не знаю, то и прошу раскрыть макрос Quote Share this post Link to post Share on other sites More sharing options...