k000858 0 31 января, 2017 Опубликовано 31 января, 2017 (изменено) · Жалоба Есть какие то ограничения в ядре, приводящие к HardFault? Пришлось в одной функции привести указатель типа uint8_t* к типу uint32_t* изза чего получил HardFault. В STM32F4 камне тот же самый код работает нормально. Почему же M0+ вылетает в HardFault? Изменено 1 февраля, 2017 пользователем k000858 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 141 31 января, 2017 Опубликовано 31 января, 2017 · Жалоба Почему же M0+ вылетает в HardFault?Потому что не поддерживает невыровненный доступ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k000858 0 31 января, 2017 Опубликовано 31 января, 2017 · Жалоба Потому что не поддерживает невыровненный доступ. можно поподробнее? пока все проблемы выравнивая обходил стороной, проектов на M0+ минимум Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 31 января, 2017 Опубликовано 31 января, 2017 · Жалоба Нужно гарантировать, что uint32_t* указывает на переменную, расположенную по адресу, кратному 4. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 141 31 января, 2017 Опубликовано 31 января, 2017 · Жалоба можно поподробнее?PM0223: STM32L0 Series Cortex®-M0+ programming manual, искать словосочетание "unaligned access" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k000858 0 1 февраля, 2017 Опубликовано 1 февраля, 2017 (изменено) · Жалоба Нужно гарантировать, что 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-битному значению Изменено 1 февраля, 2017 пользователем k000858 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alechek 0 1 февраля, 2017 Опубликовано 1 февраля, 2017 · Жалоба #pragma pack(push, 1) struct _input { uint32_t Value; }; #pragma pack(pop) struct _input * I = (struct _input *) ptr; printf("val = %lu\n", I->Value); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k000858 0 1 февраля, 2017 Опубликовано 1 февраля, 2017 · Жалоба #pragma pack(push, 1) struct _input { uint32_t Value; }; #pragma pack(pop) struct _input * I = (struct _input *) ptr; printf("val = %lu\n", I->Value); да, спасибо, такой способ вполне подойдет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 1 февраля, 2017 Опубликовано 1 февраля, 2017 · Жалоба да, спасибо, такой способ вполне подойдет. Отпишитесь о результате. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kabdim 0 1 февраля, 2017 Опубликовано 1 февраля, 2017 · Жалоба ... или более каноничный через memcpy. uint32_t value; memcpy(&value, ptr, sizeof(value)); printf("val = %lu\n", value); Он вам кстати еще много где пригодится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k000858 0 1 февраля, 2017 Опубликовано 1 февраля, 2017 · Жалоба ... или более каноничный через memcpy. uint32_t value; memcpy(&value, ptr, sizeof(value)); printf("val = %lu\n", value); Он вам кстати еще много где пригодится. заработали оба способа второй способ понравился даже больше. еще раз спасибо, теперь мне тема выравнивания еще более понятна. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 1 февраля, 2017 Опубликовано 1 февраля, 2017 · Жалоба Допустим, memcpy умеет правильно обращаться по невыровненному адресу. Или тупо байтами копирует. Но как помогает приведение указателя к указателю на выровненную структуру? От этого положение данных не меняется же. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kabdim 0 1 февраля, 2017 Опубликовано 1 февраля, 2017 · Жалоба Почему ж она выровненная? Там прагма спереди и в конце стоит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 1 февраля, 2017 Опубликовано 1 февраля, 2017 · Жалоба ... или более каноничный через 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); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 1 февраля, 2017 Опубликовано 1 февраля, 2017 · Жалоба но чувствую, можно сделать это поизящнее. Подскажите красивый способ получения доступа к 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() - макросы, которые на процессоре поддерживающем невыровненный доступ определены просто как чтение или запись значения по этому адресу, а на процессоре не поддерживающем невыровненный доступ - они осуществляют побайтное чтение/запись слова. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться