Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Microblaze, проблема с выравниванием данных?
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
misyachniy
С компьютера по 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.
Alex77
Цитата(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;
xor.kruger
Если используется AXI - 100 % Little Endian, иначе Big.
misyachniy
Цитата(Alex77 @ Sep 10 2013, 08:48) *
addr = *parameter;


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

Само собой "скрытое".
Дык не по феншую указатель на байт превращать в указатель на слово. Это очень вредно когда Big Endian. И на портируемость дурно влияет.
В случае Шина AXI там не всё так однозначно (есть смутное подозрение что там смесь Big и Little в процессоре и перифирии). Я ещё не уточнял как оно работает.
Сделайте printf(parameter, addr, GET_ORIENT_ADDR) - очень наглядно показывает
Golikov A.
Микроблайз с акси шиной по умолчанию делается литл ендиан.

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

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

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

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

misyachniy
Цитата(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;
}
misyachniy
Нашел в настройках Eclipse __BIG_ENDIAN__, поменял на __LITTLE_ENDIAN__.

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