реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Выравнивание в NIOSII
juvf
сообщение Jan 6 2011, 04:19
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



вот код
Код
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 похоже тоже из-за выравнивания. Как тут массив выравнять? Или если не выравнивание, то что? Как побороть?
Go to the top of the page
 
+Quote Post
vadimuzzz
сообщение Jan 6 2011, 04:35
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 291
Регистрация: 21-07-05
Пользователь №: 6 988



Цитата(juvf @ Jan 6 2011, 13:19) *
В Nios-e похоже тоже из-за выравнивания. Как тут массив выравнять? Или если не выравнивание, то что? Как побороть?

как-то так:
Код
char bufRecive[100] __attribute__ ((aligned (4)));
Go to the top of the page
 
+Quote Post
juvf
сообщение Jan 6 2011, 04:51
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(vadimuzzz @ Jan 6 2011, 12:35) *
как-то так:
Код
char bufRecive[100] __attribute__ ((aligned (4)));
не помогло ((
а в какой доке расписаны дерективы процессора, всякие __attribute__, прагмы и т.п.?
Go to the top of the page
 
+Quote Post
vadimuzzz
сообщение Jan 6 2011, 04:54
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 291
Регистрация: 21-07-05
Пользователь №: 6 988



Цитата(juvf @ Jan 6 2011, 13:51) *
не помогло ((
а в какой доке расписаны дерективы процессора, всякие __attribute__, прагмы и т.п.?

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

а насчет __attribute__ и т.п. - смотрите маны по gcc, все утилиты там GNUтые
Go to the top of the page
 
+Quote Post
juvf
сообщение Jan 6 2011, 06:38
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



странно, в другом месте обнаружил
Код
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 - не помогло ((
Go to the top of the page
 
+Quote Post
juvf
сообщение Jan 6 2011, 07:51
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



ну короче прошагал по коду 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 и по адресу р

Есть у кого какие мысли?
Go to the top of the page
 
+Quote Post
Oldring
сообщение Jan 8 2011, 05:02
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 3 041
Регистрация: 10-01-05
Из: Москва
Пользователь №: 1 874



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


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

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

Пишите в память сами по одному байту. Тогда не будет проблем с невыравненным доступом.


--------------------
Пишите в личку.
Go to the top of the page
 
+Quote Post
shenick
сообщение Jan 9 2011, 15:44
Сообщение #8





Группа: Новичок
Сообщений: 7
Регистрация: 31-07-08
Пользователь №: 39 350



Цитата(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
как вариант - написать макросы для переворачивания байтовых последовательностей при присваивании.

Сообщение отредактировал shenick - Jan 9 2011, 15:48
Go to the top of the page
 
+Quote Post
vadimuzzz
сообщение Jan 9 2011, 20:55
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 291
Регистрация: 21-07-05
Пользователь №: 6 988



Цитата(shenick @ Jan 10 2011, 00:44) *
как вариант - написать макросы для переворачивания байтовых последовательностей при присваивании.

а еще лучше - вообще не нагружать CPU такой работой, есть ведь DMA
Go to the top of the page
 
+Quote Post
juvf
сообщение Jan 11 2011, 00:56
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



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

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

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

Проблема решена. Всем спасибо.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 04:00
Рейтинг@Mail.ru


Страница сгенерированна за 0.01429 секунд с 7
ELECTRONIX ©2004-2016