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

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> STM32L0 HardFault: заморочки с выравниванием
ViKo
сообщение Feb 1 2017, 09:35
Сообщение #16


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Разве не достаточно создать union для обращения к переменной по байтам и словом?
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Feb 1 2017, 09:38
Сообщение #17


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Цитата(scifi @ Feb 1 2017, 12:25) *
Если уж мы тут образованием занимаемся, то более кошерно формат указывать вот так:
Код
uint32_t value;
memcpy(&value, ptr, sizeof(value));
printf("val = %" PRIu32 "\n", value);

Всё хорошо в меру, те эмбедед библиотеки с которыми я работал такой формат не понимают. Можно конечно определить самому, но тогда насколько я помню у меня были проблемы с постоянными варнингами на size_t/ptrdiff_t.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 1 2017, 09:39
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ViKo @ Feb 1 2017, 11:35) *
Разве не достаточно создать union для обращения к переменной по байтам и словом?

Достаточно. О чём я выше и написал. Но ТС хочет красиво. А красиво это - или перегрузить в этом union-e/struct-е операторы присваивания/приведения типа или воспользоваться соответствующим префиксом компилятора если таковой есть (как в IAR).
Go to the top of the page
 
+Quote Post
ViKo
сообщение Feb 1 2017, 09:49
Сообщение #19


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Красиво - это когда просто. sm.gif Перегрузка операторов - это не красиво. Вообще не знаю, зачем это придумали. Какая-то "феня" высоких интеллектуалов.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 1 2017, 09:54
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ViKo @ Feb 1 2017, 11:49) *
Красиво - это когда просто. sm.gif Перегрузка операторов - это не красиво. Вообще не знаю, зачем это придумали. Какая-то "феня" высоких интеллектуалов.

Чем именно не красиво???
Вам это нравится:
int x;
x = y;
а это нет:
u32p8 x;
x = y;
почему?
Go to the top of the page
 
+Quote Post
ViKo
сообщение Feb 1 2017, 10:02
Сообщение #21


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(jcxz @ Feb 1 2017, 12:54) *
Чем именно не красиво???
u32p8 x;
x = y;
почему?

Покажите полное решение вопроса, с макросами или функциями. Вот чтобы скопипастить в исходник, и оно работало. biggrin.gif Тогда оценим красоту. А пока вижу только идею.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 1 2017, 10:22
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ViKo @ Feb 1 2017, 12:02) *
Покажите полное решение вопроса, с макросами или функциями. Вот чтобы скопипастить в исходник, и оно работало. biggrin.gif Тогда оценим красоту. А пока вижу только идею.

Идею я обрисовал, а чтобы работало - это может проверить только тот, у кого M0 или ARM7. У меня сейчас такого МК нет под рукой.
Вот для типов u16p8 и s16p8 (пакованный до байт беззнаковый и знаковый u16/s16):
CODE
#ifdef ADDR_ALIGN
#define u16load(p) (*(u8 *)(p) | (u16)((u8 *)(p))[1] << 8)
#define s16load(p) (*(u8 *)(p) | (s16)((s8 *)(p))[1] << 8)
#define u16save(p, x) { *(u8 *)(p) = (u8)(x); ((u8 *)(p))[1] = (x) >> 8; }
#else //ADDR_ALIGN
#define u16load(p) (*(u16 *)(p))
#define s16load(p) (*(s16 *)(p))
#define u16save(p, x) { *(u16 *)(p) = (x); }
#endif

#ifdef ADDR_ALIGN

struct u16p8 {
u8 bytes[2];
operator u16() const { return u16load(&bytes); }
u16p8 & operator =(u32 val) { u16save(&bytes, val); return *this; }
};
struct s16p8 {
u8 bytes[2];
operator s16() const { return s16load(&bytes); }
s16p8 & operator =(s32 val) { u16save(&bytes, val); return *this; }
};

#else //ADDR_ALIGN

typedef __packed u16 u16p8;
typedef __packed s16 s16p8;

#endif //ADDR_ALIGN

Реализация остальные типов - на домашнее задание wink.gif
ADDR_ALIGN должен быть определён для случая если:
a) процессор не поддерживает выравнивание;
...И...
б) компилятор не понимает префикса __packed.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Feb 1 2017, 10:29
Сообщение #23


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



И все это ради того, чтобы не дать указание компилятору-линкеру разместить переменную в правильном месте. laughing.gif
Go to the top of the page
 
+Quote Post
k000858
сообщение Feb 1 2017, 10:32
Сообщение #24


Местный
***

Группа: Участник
Сообщений: 319
Регистрация: 31-01-12
Пользователь №: 69 978



Цитата(ViKo @ Feb 1 2017, 13:29) *
И все это ради того, чтобы не дать указание компилятору-линкеру разместить переменную в правильном месте. laughing.gif

лично для меня это нужно, что бы обратиться к переменной, не заморачиваясь, куда же ее разместил линкер-компилятор
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 1 2017, 10:34
Сообщение #25


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(ViKo @ Feb 1 2017, 13:29) *
И все это ради того, чтобы не дать указание компилятору-линкеру разместить переменную в правильном месте. laughing.gif

Нет. Это для того чтобы из принятого буфера прочесть переменную с произвольным смещением в этом буфере.
Такой вариант никто не предлагал:
Код
uint32_t __packed* p = &buff[33];
uint32_t x = *p;

Около года назад в gcc эта шляпа не сработала, а в кейле работала.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 1 2017, 10:44
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(demiurg_spb @ Feb 1 2017, 12:34) *
Около года назад в gcc эта шляпа не сработала, а в кейле работала.

__packed не все компиляторы поддерживают. IAR поддерживает. И Keil значит - тоже.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Feb 1 2017, 10:46
Сообщение #27


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(demiurg_spb @ Feb 1 2017, 13:34) *
Нет. Это для того чтобы из принятого буфера прочесть переменную с произвольным смещением в этом буфере.

Для M0 здесь нет решения, кроме как читать по байтам.
Цитата
Такой вариант никто не предлагал:
Код
uint32_t __packed* p = &buff[33];
uint32_t x = *p;

Около года назад в gcc эта шляпа не сработала, а в кейле работала.

Поясните. Выше интересовался таким же вопросом. Указатель на упакованную структуру - как это помогает обратиться к слову по не выровненному адресу?
Ясно. Читает по байтам.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 1 2017, 10:51
Сообщение #28


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(jcxz @ Feb 1 2017, 13:44) *
__packed не все компиляторы поддерживают. IAR поддерживает. И Keil значит - тоже.
__packed и gcc поддерживаете, но не полностью - он не отрабатывает указатели с квалификатором __packed...

У меня так сделано:
Код
#if defined(__MINGW32__)
#    define __packed       __attribute__((__gcc_struct__, __packed__, __aligned__(1)))
#else
#    define __packed       __attribute__((__packed__, __aligned__(1)))
#endif

Цитата(ViKo @ Feb 1 2017, 13:46) *
Поясните. Выше интересовался таким же вопросом. Указатель на упакованную структуру - как это помогает обратиться к слову по не выровненному адресу?
Очень просто. Компилятор, видя такой указатель, сам генерирует правильные инструкции для доступа по невыровненному адресу.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
jcxz
сообщение Feb 1 2017, 10:53
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ViKo @ Feb 1 2017, 12:46) *
Для M0 здесь нет решения, кроме как читать по байтам.
...
Ясно. Читает по байтам.

А Вы что хотели - некую чудесную инструкцию процессора? biggrin.gif
M0 физически не умеет невыровненный доступ - нет таких инструкций у него!
Так что такой доступ можно только эмулировать. Либо встроенными возможностями компилятора (__packed) либо реализовав это самостоятельно (свой класс с перегрузками, например).

PS: Более того - даже для ядра M4 (и прочих) если переменная находится (или может находиться) по невыровненному адресу, для неё надо указывать спецификатор __packed.
А то, что у ТС "В STM32F4 камне тот же самый код работает нормально" - о говорит только о кривости написания этого кода, который сейчас работает, завтра перекомпилят его на другом компиляторе (или новой версии того же компилятора) - он будет падать в тот же HF на том же самом ядре M4. Так как никто не мешает компилятору для обращения к этим данным использовать не инструкции LDR/STR, а например LDRD/STRD или LDM/STM, которые не умеют невыровненный доступ. И компилятор имеет право это сделать, например при оптимизации.
Так что надо взять за правило: на любом процессоре, если переменная невыровнена, она должна быть объявлена как невыровненная.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Feb 1 2017, 11:11
Сообщение #30


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(jcxz @ Feb 1 2017, 13:53) *
А Вы что хотели - некую чудесную инструкцию процессора?

Так что надо взять за правило: на любом процессоре, если переменная невыровнена, она должна быть объявлена как невыровненная.

Я руками (головой) размещаю переменные в структуре так, чтобы стояли ровно. biggrin.gif Если есть дыры, забиваю их uint8_t RESERVED_n. А саму структуру линкер знает, куда разместить. Без указаний.
И компиляторы не пугают, ни прошлые, ни будущие.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 13th August 2025 - 14:24
Рейтинг@Mail.ru


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