|
|
  |
STM32L0 HardFault: заморочки с выравниванием |
|
|
|
Feb 1 2017, 09:38
|
Знающий
   
Группа: Свой
Сообщений: 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.
|
|
|
|
|
Feb 1 2017, 09:54
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(ViKo @ Feb 1 2017, 11:49)  Красиво - это когда просто.  Перегрузка операторов - это не красиво. Вообще не знаю, зачем это придумали. Какая-то "феня" высоких интеллектуалов. Чем именно не красиво??? Вам это нравится: int x; x = y; а это нет: u32p8 x; x = y; почему?
|
|
|
|
|
Feb 1 2017, 10:22
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(ViKo @ Feb 1 2017, 12:02)  Покажите полное решение вопроса, с макросами или функциями. Вот чтобы скопипастить в исходник, и оно работало.  Тогда оценим красоту. А пока вижу только идею. Идею я обрисовал, а чтобы работало - это может проверить только тот, у кого 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 Реализация остальные типов - на домашнее задание  ADDR_ALIGN должен быть определён для случая если: a) процессор не поддерживает выравнивание; ...И...
б) компилятор не понимает префикса __packed.
|
|
|
|
|
Feb 1 2017, 10:34
|

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

|
Цитата(ViKo @ Feb 1 2017, 13:29)  И все это ради того, чтобы не дать указание компилятору-линкеру разместить переменную в правильном месте.  Нет. Это для того чтобы из принятого буфера прочесть переменную с произвольным смещением в этом буфере. Такой вариант никто не предлагал: Код uint32_t __packed* p = &buff[33]; uint32_t x = *p; Около года назад в gcc эта шляпа не сработала, а в кейле работала.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Feb 1 2017, 10:46
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 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 эта шляпа не сработала, а в кейле работала. Поясните. Выше интересовался таким же вопросом. Указатель на упакованную структуру - как это помогает обратиться к слову по не выровненному адресу? Ясно. Читает по байтам.
|
|
|
|
|
Feb 1 2017, 10:51
|

неотягощённый злом
     
Группа: Свой
Сообщений: 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)  Поясните. Выше интересовался таким же вопросом. Указатель на упакованную структуру - как это помогает обратиться к слову по не выровненному адресу? Очень просто. Компилятор, видя такой указатель, сам генерирует правильные инструкции для доступа по невыровненному адресу.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Feb 1 2017, 10:53
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(ViKo @ Feb 1 2017, 12:46)  Для M0 здесь нет решения, кроме как читать по байтам. ... Ясно. Читает по байтам. А Вы что хотели - некую чудесную инструкцию процессора? M0 физически не умеет невыровненный доступ - нет таких инструкций у него! Так что такой доступ можно только эмулировать. Либо встроенными возможностями компилятора (__packed) либо реализовав это самостоятельно (свой класс с перегрузками, например). PS: Более того - даже для ядра M4 (и прочих) если переменная находится (или может находиться) по невыровненному адресу, для неё надо указывать спецификатор __packed. А то, что у ТС "В STM32F4 камне тот же самый код работает нормально" - о говорит только о кривости написания этого кода, который сейчас работает, завтра перекомпилят его на другом компиляторе (или новой версии того же компилятора) - он будет падать в тот же HF на том же самом ядре M4. Так как никто не мешает компилятору для обращения к этим данным использовать не инструкции LDR/STR, а например LDRD/STRD или LDM/STM, которые не умеют невыровненный доступ. И компилятор имеет право это сделать, например при оптимизации. Так что надо взять за правило: на любом процессоре, если переменная невыровнена, она должна быть объявлена как невыровненная.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|