|
|
  |
Выравнивание в NIOSII |
|
|
|
Jan 6 2011, 04:19
|

Профессионал
    
Группа: Свой
Сообщений: 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 похоже тоже из-за выравнивания. Как тут массив выравнять? Или если не выравнивание, то что? Как побороть?
|
|
|
|
|
Jan 6 2011, 04:51
|

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

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

Профессионал
    
Группа: Свой
Сообщений: 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 - не помогло ((
|
|
|
|
|
Jan 6 2011, 07:51
|

Профессионал
    
Группа: Свой
Сообщений: 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 и по адресу р Есть у кого какие мысли?
|
|
|
|
|
Jan 8 2011, 05:02
|

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

|
Цитата(juvf @ Jan 6 2011, 13:51)  Есть у кого какие мысли? Мысль такая, что на вашем процессоре так нельзя делать. И компилятор не виноват. То, что reinterpret_cast порождает адрес, который невозможно корректно разименовать - это ваша вина, а не компиляторы. Потому что reinterperet_cast предназначен для грамотного обхода защит компилятора. Пишите в память сами по одному байту. Тогда не будет проблем с невыравненным доступом.
--------------------
Пишите в личку.
|
|
|
|
|
Jan 9 2011, 15:44
|

Группа: Новичок
Сообщений: 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 то енто надо искать в доках на ниос и гцц. да... и это не выравнивание. это нормальное положение байтов в памяти отведенной под переменную. как вариант - написать макросы для переворачивания байтовых последовательностей при присваивании.
Сообщение отредактировал shenick - Jan 9 2011, 15:48
|
|
|
|
|
Jan 11 2011, 00:56
|

Профессионал
    
Группа: Свой
Сообщений: 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), который хранит массив и записывает/читает байты в/из него любого типа, любой длинны и по любому адресу. Проблема решена. Всем спасибо.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|