Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Выравнивание в NIOSII
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
juvf
вот код
Код
char bufRecive[100];
alt_u16 countRxTx = 0x0025;
*reinterpret_cast<alt_u16*>(&bufRecive[1]) = countRxTx;


после этого bufRecive[0] равно 0х25, а bufRecive[1] равно 0х00. Сталкивался с такой проблемой в msp430 в IAR-e. Там нужно адрес массива bufRecive при объявлении выравнивать дерективой, типа #pragma aligment = 2
В Nios-e похоже тоже из-за выравнивания. Как тут массив выравнять? Или если не выравнивание, то что? Как побороть?
vadimuzzz
Цитата(juvf @ Jan 6 2011, 13:19) *
В Nios-e похоже тоже из-за выравнивания. Как тут массив выравнять? Или если не выравнивание, то что? Как побороть?

как-то так:
Код
char bufRecive[100] __attribute__ ((aligned (4)));
juvf
Цитата(vadimuzzz @ Jan 6 2011, 12:35) *
как-то так:
Код
char bufRecive[100] __attribute__ ((aligned (4)));
не помогло ((
а в какой доке расписаны дерективы процессора, всякие __attribute__, прагмы и т.п.?
vadimuzzz
Цитата(juvf @ Jan 6 2011, 13:51) *
не помогло ((
а в какой доке расписаны дерективы процессора, всякие __attribute__, прагмы и т.п.?

погодите, это я ступил sm.gif выравнивание тут ни причем, NIOS же Little Endian. Можно попробовать Endian Converter Custom Instruction

а насчет __attribute__ и т.п. - смотрите маны по gcc, все утилиты там GNUтые
juvf
странно, в другом месте обнаружил
Код
alt_u16 command = *reinterpret_cast<alt_u16*>(&bufRecive[4]);
такой код ни разу не сбоил.

Цитата
а насчет __attribute__ и т.п. - смотрите маны по gcc, все утилиты там GNUтые
ну в ниосе компилятор nios2-elf-gcc, линкер nios2-elf-g++. У алтеры про них скудно как-то написанно. Попробую покопаться в манах gnu gcc

Цитата
Можно попробовать Endian Converter Custom Instruction
а вот это интересней, щя буду пробовать...

Endian Converter Custom Instruction - не помогло ((
juvf
ну короче прошагал по коду reinterpret_cast работает как надо. а вот разименование не работает как надо
я вот по такой штуке прошагал
Код
alt_u16* p = reinterpret_cast<alt_u16*>(&bufRecive[0]);
*p = 0x1234;
p = reinterpret_cast<alt_u16*>(&bufRecive[1]);
*p = 0x7890;
p = reinterpret_cast<alt_u16*>(&bufRecive[2]);
*p = 0x4321;
p = reinterpret_cast<alt_u16*>(&bufRecive[3]);
*p = 0x0987;
p = reinterpret_cast<alt_u16*>(&bufRecive[4]);
*p = 0x6571;
p = reinterpret_cast<alt_u16*>(&bufRecive[5]);
*p = 0x4294;
p = reinterpret_cast<alt_u16*>(&bufRecive[6]);
*p = 0x5302;
p = reinterpret_cast<alt_u16*>(&bufRecive[7]);
*p = 0x0192;

если p указывает на четный адрес, то всё нормально, после*p = 0xХХХХ; меняется два байта по адресам р и р+1. если р указывает на нечётный адрес,то меняется два байта по адресу р-1 и по адресу р

Есть у кого какие мысли?
Oldring
Цитата(juvf @ Jan 6 2011, 13:51) *
Есть у кого какие мысли?


Мысль такая, что на вашем процессоре так нельзя делать.

И компилятор не виноват. То, что reinterpret_cast порождает адрес, который невозможно корректно разименовать - это ваша вина, а не компиляторы. Потому что reinterperet_cast предназначен для грамотного обхода защит компилятора.

Пишите в память сами по одному байту. Тогда не будет проблем с невыравненным доступом.
shenick
Цитата(juvf @ Jan 6 2011, 09:19) *
вот код
Код
char bufRecive[100];
alt_u16 countRxTx = 0x0025;
*reinterpret_cast<alt_u16*>(&bufRecive[1]) = countRxTx;


после этого bufRecive[0] равно 0х25, а bufRecive[1] равно 0х00. Сталкивался с такой проблемой в msp430 в IAR-e. Там нужно адрес массива bufRecive при объявлении выравнивать дерективой, типа #pragma aligment = 2
В Nios-e похоже тоже из-за выравнивания. Как тут массив выравнять? Или если не выравнивание, то что? Как побороть?


мммм.......
а не проще ли так(?):
Код
bufRecive[1] = ((char*)&countRxTx)[0];

а если таки охота ворочать little/big-endian то енто надо искать в доках на ниос и гцц.
да... и это не выравнивание. это нормальное положение байтов в памяти отведенной под переменную. biggrin.gif
как вариант - написать макросы для переворачивания байтовых последовательностей при присваивании.
vadimuzzz
Цитата(shenick @ Jan 10 2011, 00:44) *
как вариант - написать макросы для переворачивания байтовых последовательностей при присваивании.

а еще лучше - вообще не нагружать CPU такой работой, есть ведь DMA
juvf
вобщем проблема в том, скорее всего процессор игнорирует младший бит для указателя на слово. Поэтому если указатель на слово нечетный, например 0х0890015, то он воспринимается как 0х0890014. Однако указатель на char по нечетному адресу работает нормально. Особенности архитектуры. Отчасти есть тут вина компилятора. В стандарте с++ не оговариваются подобные нюансы. И если компилятором заявленно "с++", то компилятор должен придерживаться стандарта. Возможно где-то в доках на компилятор этот нюанс оговорен, но я не нашел. А возможно, что компилятор с каким нибудь ключем, правильно разименует нечетный указатель на слово, ведь возможно же обращение к нечётной ячейке памяти.

Цитата
как вариант - написать макросы для переворачивания байтовых последовательностей при присваивании.

Вобщем для себя проблему решиль примерно так, тока не макросы, а вместо char bufRecive[100]; написал класс с 2-мя шаблонными функциями write<class T>(const T& t, int adr) и T read<class T>(int adr), который хранит массив и записывает/читает байты в/из него любого типа, любой длинны и по любому адресу.

Проблема решена. Всем спасибо.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.