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

 
 
 
Reply to this topicStart new topic
> Microblaze, проблема с выравниванием данных?, Release 14.2 Build SDK_P.28xd
misyachniy
сообщение Sep 9 2013, 15:15
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 716
Регистрация: 27-05-05
Из: Kyiv
Пользователь №: 5 454



С компьютера по RS485 связываюсь с микроблейзом.
Послеприема кадра в байтовый буфер(прием, проверка контрольной суммы) передаю указатель в функцию разбора
Код
void exec_ssp_read(u8 *parameter)
{
u8 tmp_buf[2];
unsigned long addr;

addr = *((unsigned long*)parameter);

if (addr == GET_ORIENT_ADDR)
{
     tmp_buf[0] = SSP_ACK;
     tmp_buf[1] = one_shot();

     send_char_array_0(&tmp_buf[0], 2);
     return;
}

exec_ssp_nak_incorrect();
return;
}

Константа для сравнения определена
#define GET_ORIENT_ADDR ((unsigned long)0x00000001)

В отладчике видно что и переменная addr (рис. addr.PNG) и константа GET_ORIENT_ADDR(const.PNG) равны 1.
Но функция обходит скобки и уходит на exec_ssp_nak_incorrect().

Прямое сравнение if (addr == (u32) 0x00000001); работает.

При работе с ARM(SAM7S, IAR - не помню какой, лет 7 назад) я встречал случаи, что addr = *((unsigned long*)parameter); не работает если указатель на char не выровнен на двойное слово.

Можно предположить что отладчик и компилятор Eclipse работают по разному, но думаю, что ответ проще.

На сколько я помню, создавал в Визарде микроблейз с little endian расположением, но попробовал найти как это проверить и не нашел. Параметры синтеза и включаемых модулей в ядро есть, а "с какого гонца разбивать яйца" - нету.

Прикладываю еще рисунок expression.PNG в котором видно что в буфере данные little endian.

Эскизы прикрепленных изображений
Прикрепленное изображение
Прикрепленное изображение
 

Прикрепленные изображения
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
Alex77
сообщение Sep 10 2013, 05:48
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 295
Регистрация: 2-12-05
Пользователь №: 11 695



Цитата(misyachniy @ Sep 9 2013, 18:15) *
addr = *((unsigned long*)parameter);

1) Шина XPS или AXI ?
2) В каком месте Вы выставили параметр "little endian" для процессора ?
3) не по феншую писать
void exec_ssp_read(u8 *parameter)
addr = *((unsigned long*)parameter);

char tmp;
unsigned long addr;
tmp = *parameter;
addr = tmp;
или
addr = *parameter;
Go to the top of the page
 
+Quote Post
xor.kruger
сообщение Sep 10 2013, 07:45
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 290
Регистрация: 17-08-08
Из: Чернигов
Пользователь №: 39 647



Если используется AXI - 100 % Little Endian, иначе Big.
Go to the top of the page
 
+Quote Post
misyachniy
сообщение Sep 10 2013, 14:59
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 716
Регистрация: 27-05-05
Из: Kyiv
Пользователь №: 5 454



Цитата(Alex77 @ Sep 10 2013, 08:48) *
addr = *parameter;


1) Шина AXI.
2) По моему addr = *parameter; произведет скрытое преобразование байта в слово, а не 4 последовательных байта.
Go to the top of the page
 
+Quote Post
Alex77
сообщение Sep 11 2013, 05:08
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 295
Регистрация: 2-12-05
Пользователь №: 11 695



Цитата(misyachniy @ Sep 10 2013, 17:59) *
1) Шина AXI.
2) По моему addr = *parameter; произведет скрытое преобразование байта в слово, а не 4 последовательных байта.

Само собой "скрытое".
Дык не по феншую указатель на байт превращать в указатель на слово. Это очень вредно когда Big Endian. И на портируемость дурно влияет.
В случае Шина AXI там не всё так однозначно (есть смутное подозрение что там смесь Big и Little в процессоре и перифирии). Я ещё не уточнял как оно работает.
Сделайте printf(parameter, addr, GET_ORIENT_ADDR) - очень наглядно показывает
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Sep 14 2013, 06:02
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Микроблайз с акси шиной по умолчанию делается литл ендиан.

У микроблайза выравнивание по 32 бита.
то есть если вы делаете массив

char Temp[10];
потом делаете указатель
int *Pointer;

то Pointer = (int *)Temp;
Pointer = (int *)(&Temp[1]);
Pointer = (int *)(&Temp[2]);
Pointer = (int *)(&Temp[3]);

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

Go to the top of the page
 
+Quote Post
misyachniy
сообщение Sep 15 2013, 14:33
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 716
Регистрация: 27-05-05
Из: Kyiv
Пользователь №: 5 454



Цитата(Golikov A. @ Sep 14 2013, 09:02) *
Микроблайз с акси шиной по умолчанию делается литл ендиан.

У микроблайза выравнивание по 32 бита.
...


В конечном итоге я сложил адрес сдвигами.

Код
void exec_ssp_read(u8 *parameter)
{
u8 tmp_buf[2];
u32 addr;

  addr = parameter[3] << 24 |  parameter[2] << 16 |  parameter[1] <<8 | parameter[0];

if (addr == GET_ORIENT_ADDR)
{
     tmp_buf[0] = SSP_ACK;
     tmp_buf[1] = one_shot();

     get_regions(tmp_buf[1]);
     return;
}

exec_ssp_nak_incorrect();
return;
}
Go to the top of the page
 
+Quote Post
misyachniy
сообщение Sep 23 2013, 16:29
Сообщение #8


Знающий
****

Группа: Свой
Сообщений: 716
Регистрация: 27-05-05
Из: Kyiv
Пользователь №: 5 454



Нашел в настройках Eclipse __BIG_ENDIAN__, поменял на __LITTLE_ENDIAN__.

Теперь байты правильно лежат.
Go to the top of the page
 
+Quote Post

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

 


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


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