Перейти к содержанию
    

STM32L0 HardFault: заморочки с выравниванием

Я руками (головой) размещаю переменные в структуре так, чтобы стояли ровно. :biggrin: Если есть дыры, забиваю их uint8_t RESERVED_n. А саму структуру линкер знает, куда разместить. Без указаний.

Очевидно Вы не работали никогда например с протоколами передачи данных. В кадрах которых данные находятся упакованными. И объявлять такие кадры удобно структурами.

Поэтому Вам и сложно представить такое применение.

И дырок в таких кадрах нет - ну не заложили их разработчики этого протокола!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Очевидно Вы не работали никогда например с протоколами передачи данных. В кадрах которых данные находятся упакованными. И объявлять такие кадры удобно структурами.

Поэтому Вам и сложно представить такое применение.

И дырок в таких кадрах нет - ну не заложили их разработчики этого протокола!

Очевидно, что с таким пакетом работал бы по байтам. Ибо все "красивые решения" в конечном итоге так и работают. Под маской продвинутости прячут простоту.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Очевидно, что с таким пакетом работал бы по байтам. Ибо все "красивые решения" в конечном итоге так и работают. Под маской продвинутости прячут простоту.

Это называется "сериализация и десериализация". Это кошерно, халяльно и по феншую, народ одобряет. Там ещё индейцы большие и малые.

Но, к примеру, в lwip сделано через структуры. Это действительно удобнее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Очевидно, что с таким пакетом работал бы по байтам.

А в следующей версии добавят байтик в середину и все смещения нужно будет выискивать по-новой.

Или некоторые переменные станут невыровненными и т.п.

 

В gcc объявляю так:

typedef struct sPACKET_RT_SET_TIME
{
    BYTE    cmd;
    BYTE    cid;
    DWORD    datetime;
} __attribute((packed)) sPACKET_RT_SET_TIME;

А все остальное - дело компилятора.

Правда, есть еще пара ключиков, относящихся к теме

-fpack-struct -Wpadded

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Очевидно, что с таким пакетом работал бы по байтам. Ибо все "красивые решения" в конечном итоге так и работают. Под маской продвинутости прячут простоту.

А завтра переносим Вашу реализацию на процессор, умеющий работать с невыровненными данными и получаем неэффективность из-за кучи лишней возни с байтовым доступом и склеиванием этих байт в слова хотя на данном CPU это не нужно. И всё придётся переписывать.

А если работа идёт через члены пакованных структур, то код вообще менять не нужно - компилятор сам знает, что на данном CPU можно не разбирать {u32 x = y} на байты.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Легким движением руки структура превращается... превращается...

typedef struct sPACKET_RT_SET_TIME
{
    DWORD    datetime;
    BYTE    cmd;
    BYTE    cid;
}

 

А если работа идёт через члены пакованных структур, то код вообще менять не нужно - компилятор сам знает, что на данном CPU можно не разбирать {u32 x = y} на байты.

Убедили! :biggrin: беру __packed.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А если работа идёт через члены пакованных структур, то код вообще менять не нужно - компилятор сам знает, что на данном CPU можно не разбирать {u32 x = y} на байты.

Как минимум для DS5 это несколько сложнее и требует внимания программиста. Для упакованной структуры нет предположений о том что её начало выравнено, поэтому такая оптимизация не произойдет в общем случае. Всегда будет рассматриваться худший случай невыравненного размещения. А невыравненный доступ на абсолютном большинстве архитектур дороже выравненного, поэтому если есть возможность привести данные в выравненное состояние то этим стоит воспользоваться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А невыравненный доступ на абсолютном большинстве архитектур дороже выравненного, поэтому если есть возможность привести данные в выравненное состояние то этим стоит воспользоваться.

Ну так на M3/M4 код генерируемый компилятором от этого не меняется. Меняется только время доступа к таким данным. Работать будет всё равно пусть медленнее немного.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ВЫРОВНЯТЬ, -яю, -яешь; св. (нсв. также ровнять). кого-что. 1. Сделать ровным, прямым без изгибов. В. поверхность. В. дорогу. В. шеренгу, строй. 2. что. Расположить, направить по прямой линии в вертикальной или горизонтальной плоскости. В. самолёт. 3. Сделать размеренным, равномерным. В. дыхание. В. шаг.

<Выравнивать, -аю, -аешь; нсв. Выравниваться, -ается; страд. Выравнивание (см.).

http://www.gramota.ru/slovari/dic/?lop=x&a...%8F%D1%82%D1%8C

post-10362-1485954328.gif

 

выравнять(ся), -яю(сь), -яет(ся) (к равный)

http://www.gramota.ru/slovari/dic/?word=%D...D1%8C&all=x

post-10362-1485954328.gif

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

выра́внивать

 

Глагол, несовершенный вид, переходный, тип спряжения по классификации А. Зализняка — 1a. Соответствующий глагол совершенного вида — выровнять.

 

Приставка: вы-; корень: -равн-; суффикс: -ива; глагольное окончание: -ть [Тихонов, 1996].

:rolleyes:

 

ВЫРОВНЯТЬ, -яю, -яешь; св. (нсв. также ровнять). кого-что. 1. Сделать ровным, прямым без изгибов. В. поверхность. В. дорогу. В. шеренгу, строй. 2. что. Расположить, направить по прямой линии в вертикальной или горизонтальной плоскости. В. самолёт. 3. Сделать размеренным, равномерным. В. дыхание. В. шаг.

<Выравнивать, -аю, -аешь; нсв. Выравниваться, -ается; страд. Выравнивание (см.).

post-10362-1485954328.gif

http://www.gramota.ru/slovari/dic/?lop=x&a...%8F%D1%82%D1%8C

выравнять(ся), -яю(сь), -яет(ся) (к равный)

http://www.gramota.ru/slovari/dic/?word=%D...D1%8C&all=x

post-10362-1485954328.gif

см. выделенное жирным :rolleyes:

Последние два поста (начиная с этого) они конечно очень к тебе относятся.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Последние два поста (начиная с этого) они конечно очень к тебе относятся.

Со вчерашнего дня думал, как писать. :laughing: Пропустишь раз, потом наверстывай.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я там видимо опечатался :blush: "к теме" имел ввиду.

Ну так на M3/M4 код генерируемый компилятором от этого не меняется. Меняется только время доступа к таким данным. Работать будет всё равно пусть медленнее немного.

Внутренний перфекционист негодует когда работает медленней, наверное его пора топить. :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Легким движением руки структура превращается... превращается...

typedef struct sPACKET_RT_SET_TIME
{
    DWORD    datetime;
    BYTE    cmd;
    BYTE    cid;
}

Я при разработке протоколов стараюсь выравнивать данные, но не всегда есть такая возможность.

В данном случае менять порядок нельзя, т.к. первые два байта нужны для адресации контроллера

и указания номера команды, а уже за ними следуют различные данные.

Я бы проголосавал за такой вариант, будь моя воля.

typedef struct sPACKET_RT_SET_TIME
{
    BYTE    cmd;
    BYTE    cid;
    WORD    none;
    DWORD    datetime;
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Внутренний перфекционист негодует... :)

Так похоже поводов нет: если предположить, что реализация (в IAR) __aeabi_uread4 аналогична __aeabi_memcpy, то оба варианта идентичны по затратам.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Извините за подъйм старой темы. Но что-то я запутался.

Вот фрагмент кода из функции для Cortex=M4F

uint8_t * ptr1 = new uin8_t[128];
uint8_t * ptr2 = new uint8_t[128];
memcpy( ptr1, ptr2, 128);

Периодически схватываю HF, в окне Call Sack отладчика точка вылета __aeabi_memcpy4 + 0x5. В отладчике HF у меня есть анализ регистров, и причина указан "A data bus error has occurred". Я так понимаю, это невыровненный доступ.

Значит надо писать так?

__packed uint8_t * ptr1 = new uin8_t[128];
__packed uint8_t * ptr2 = new uint8_t[128];
memcpy( ptr1, ptr2, 128);

Ошибка, вроде, ушла. А для uint32_t * ключевое слово __packed выходит не требуется?!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...