|
STM32L0 HardFault: заморочки с выравниванием |
|
|
|
Jan 31 2017, 12:27
|

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

|
Цитата(Сергей Борщ @ Jan 31 2017, 15:21)  Потому что не поддерживает невыровненный доступ. можно поподробнее? пока все проблемы выравнивая обходил стороной, проектов на M0+ минимум
|
|
|
|
|
Feb 1 2017, 04:04
|

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

|
Цитата(adnega @ Jan 31 2017, 15:35)  Нужно гарантировать, что uint32_t* указывает на переменную, расположенную по адресу, кратному 4. а, вот оно что. теперь более менее понимаю. буфер в котором содержится нужное мне 32-битное значение uint8_t buf[100]; указатель на место, в котором содержится значением uint8_t* ptr = &buf[5]; на Cortex-M4 не заморачивался и делал вот так printf("val = %lu\n", *(uint32_t*)ptr); на Cortex-M0+ такая запись приводит к HardFault'у. Причину теперь понимаю хорошо, и как не получать такой эффект тоже. Пока сделал вот так: Код uint8_t value[4]; value[0] = *ptr; value[1] = *(ptr + 1); value[2] = *(ptr + 2); value[3] = *(ptr+ 3); uint32_t val = (value[0]) | (value[1] << 8) | (value[2] << 16) | (value[3] << 24); printf("val = %lu\n", val); но чувствую, можно сделать это поизящнее. Подскажите красивый способ получения доступа к 32-битному значению
Сообщение отредактировал k000858 - Feb 1 2017, 04:05
|
|
|
|
|
Feb 1 2017, 05:52
|

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

|
Цитата(Alechek @ Feb 1 2017, 08:06)  Код #pragma pack(push, 1) struct _input { uint32_t Value; }; #pragma pack(pop)
struct _input * I = (struct _input *) ptr; printf("val = %lu\n", I->Value); да, спасибо, такой способ вполне подойдет.
|
|
|
|
|
Feb 1 2017, 07:08
|
Знающий
   
Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842

|
... или более каноничный через memcpy. Код uint32_t value; memcpy(&value, ptr, sizeof(value)); printf("val = %lu\n", value); Он вам кстати еще много где пригодится.
|
|
|
|
|
Feb 1 2017, 07:31
|

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

|
Цитата(Kabdim @ Feb 1 2017, 10:08)  ... или более каноничный через memcpy. Код uint32_t value; memcpy(&value, ptr, sizeof(value)); printf("val = %lu\n", value); Он вам кстати еще много где пригодится. заработали оба способа второй способ понравился даже больше. еще раз спасибо, теперь мне тема выравнивания еще более понятна.
|
|
|
|
|
Feb 1 2017, 09:25
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(Kabdim @ Feb 1 2017, 10:08)  ... или более каноничный через memcpy. Код uint32_t value; memcpy(&value, ptr, sizeof(value)); printf("val = %lu\n", value); Он вам кстати еще много где пригодится. Если уж мы тут образованием занимаемся, то более кошерно формат указывать вот так: Код uint32_t value; memcpy(&value, ptr, sizeof(value)); printf("val = %" PRIu32 "\n", value);
|
|
|
|
|
Feb 1 2017, 09:26
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(k000858 @ Feb 1 2017, 06:04)  но чувствую, можно сделать это поизящнее. Подскажите красивый способ получения доступа к 32-битному значению Если компилятор поддерживает соответствующий префикс, создать пакованные типы: Код typedef __packed u16 u16p8; typedef __packed s16 s16p8; typedef __packed u32 u32p8; typedef __packed s32 s32p8; typedef __packed u64 u64p8; typedef __packed s64 s64p8; либо, если в компиляторе нет соответствующего префикса, создать соотв. классы и перегрузить в них операторы присваивания и приведения типа: Код struct u32p8 { u8 bytes[4]; operator u32() const { return u32load(&bytes); } u32p8 & operator =(u32 val) { u32save(&bytes, val); return *this; } }; где: u32load() и u32save() - макросы, которые на процессоре поддерживающем невыровненный доступ определены просто как чтение или запись значения по этому адресу, а на процессоре не поддерживающем невыровненный доступ - они осуществляют побайтное чтение/запись слова.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|