Указатель на uint32_t должен быть выровнен по 32-бита. Ядро Cortex-M не может считывать 32-битные значения с произвольного адреса. При попытке чтения uint32_t с нечетного адреса или адреса кратного 2 происходит прерывание HardFault. Если нужно именно uint32_t придется лепить его из отдельных байтов или прочитать сначала char и привести это значение к uint32_t.
[uquote="BorisSPB",url="/forum/viewtopic.php?p=3454697#p3454697"]придется лепить его из отдельных байтов или прочитать сначала char и привести это значение к uint32_t.[/uquote] Или просто в union их объединить.
PS: Вообще, странно, что компилятор не выровнял адрес начала массива.
[uquote="Аlex",url="/forum/viewtopic.php?p=3454790#p3454790"]PS: Вообще, странно, что компилятор не выровнял адрес начала массива.[/uquote]
Он выровнял, просто в случае char это равнозначно отсутствию выравнивания. В С++ можно написать:
В С придется использовать всякие прагмы/атрибуты конкретного компилятора.
И да, почему-то никто не сказал, что проблемы с выравниванием есть только у Cortex-M0, с M3/M4 все будет работать, но чуть медленнее.
Последний раз редактировалось Reflector Вт сен 11, 2018 19:55:06, всего редактировалось 1 раз.
Не пойму, только, зачем манипулировать четырьмя символами, как одним беззнаковым словом? там же явно наблюдаются цифры в ASCII. Какая может быть польза от манипуляций с кодом 0x30303030 ? Как число, оно не годится, как текст - тоже не очень...
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Сравнение строк через указатели на int32_t ? Хм... То ещё извращение
Для этого есть стандартные библиотечные функции.
Но мы этого не узнаем. ТС, как и многие другие, - запустит пулю и сидит молча, подсматривает за темой. Ведь то, что он делает, и его код - большой большой секрет !
[uquote="Аlex",url="/forum/viewtopic.php?p=3454806#p3454806"]Если бы он выровнял, проблем не было бы.[/uquote]
Компилятор выровнял начало массива исходя из размера его элементов, в данном случае у нас массив байт, потому считай никакого выравнивания и нет. Но оно есть Можно было бы объявить массив как
[uquote="BorisSPB",url="/forum/viewtopic.php?p=3454697#p3454697"]Указатель на uint32_t должен быть выровнен по 32-бита. Ядро Cortex-M не может считывать 32-битные значения с произвольного адреса. При попытке чтения uint32_t с нечетного адреса или адреса кратного 2 происходит прерывание HardFault.[/uquote]
Да ладно?!! Может стоить матчасть подучить прежде чем чушь нести?
Добавлено after 2 minutes 28 seconds:
[uquote="Аlex",url="/forum/viewtopic.php?p=3454875#p3454875"]Ведь то, что он делает, и его код - большой большой секрет ! [/uquote]
Дык - сопрёте же его гениальный код!
VladislavS писал(а):Компилятор выровнял начало массива исходя из размера его элементов, в данном случае у нас массив байт, потому считай никакого выравнивания и нет. Но оно есть
Согласен. Он выровнял по байту. Для слов (2, 4 байта) уже, считай, что выравнивания нет
По этому и странно, что не положил массив начиная с выровненного по 4 байта поля. Хотя ... хз... хз...
[uquote="Аlex",url="/forum/viewtopic.php?p=3454915#p3454915"]НУ почему сразу чушь ?[/uquote]Потому что в том виде как оно сформулировано это ложное утверждение. Впрочем, тем кто это понимает цепляться к словам особого смысла нет.
Аlex писал(а):По этому и странно, что не положил массив начиная с выровненного по 4 байта поля. Хотя ... хз... хз...
Какие то древние ARMы имели доступ как памяти только выравненный по словам. На пикче слева, видна существенная потеря памяти, против современных, справа. Так что ничего странного.
BorisSPB писал(а):Указатель на uint32_t должен быть выровнен по 32-бита. Ядро Cortex-M не может считывать 32-битные значения с произвольного адреса. При попытке чтения uint32_t с нечетного адреса или адреса кратного 2 происходит прерывание HardFault.
Код прошагал, исключения не произошло. Buf присвоилось 0x01020304, затем изменилось на 0x88010203.
Ниже дамп памяти. Красным подчернкнут адрес начала дампа, черным Buf после выполнения всего вышеуказанного кода, зеленым указатель.
Ser-B писал(а):
При выполнениии приведенных операций происходит зависание мк.
Надо в отладке поглядеть где висите.
ARV писал(а):ну, наверное, сравнивать быстрее числа, чем символы - или 4 символа за раз, или 1...
32разрядный МК должен работать быстрее с 32 разрядными числами, но душа просит все время 8битные переменные объявлять , даже очень локальные флаги, которые скорее всего будут в регистре и само-собой займут его весь.
[uquote="VladislavS",url="/forum/viewtopic.php?p=3454955#p3454955"]Впрочем, тем кто это понимает цепляться к словам особого смысла нет.[/uquote]
Вряд-ли это понимает автор темы, так как даже не указал какой у него МК.
Никакого секрета нет.
Всего лишь хотел передать суть проблемы.
В М3 действительно все было норм, а М0 такая вот ерунда.
Задача записывать во флеш настройки скопом из всех массивов и считывать в массивы при включении мк.
Проблема исчезла при объявлении 32-разрядных массивов. Правда, появился дополнительный расход памяти.
//Write to Page
FLASH->CR |= FLASH_CR_PG; //Write 1 to PG (programming bit)
//*pPage = Temperature; //Write to flash page
*(__IO uint16_t*)(Address) = (uint16_t)data; //GET HARDFAULT HERE. CODE FROM ST
while ((FLASH->SR & FLASH_SR_BSY) != 0); //Wait until bus is not busy
if ((FLASH->SR & FLASH_SR_EOP) != 0){ //Check if flash is completed
FLASH->SR |= FLASH_SR_EOP; //Clear flag is flash is complete
}
data >>=16;
Address +=2;
*(__IO uint16_t*)(Address) = (uint16_t)data; //GET HARDFAULT HERE. CODE FROM ST
while ((FLASH->SR & FLASH_SR_BSY) != 0); //Wait until bus is not busy
if ((FLASH->SR & FLASH_SR_EOP) != 0){ //Check if flash is completed
FLASH->SR |= FLASH_SR_EOP; //Clear flag is flash is complete
}
FLASH->CR &= ~FLASH_CR_PG; //Clear prog bit to disable write to flash
3.3.5. Address alignment
An aligned access is an operation where a word-aligned address is used for a word, dual word, or multiple word access, or where a halfword-aligned address is used for a halfword access. Byte accesses are always aligned.
The Cortex-M4 processor supports unaligned access only for the following instructions:
LDR, LDRT
LDRH, LDRHT
LDRSH, LDRSHT
STR, STRT
STRH, STRHT
All other load and store instructions generate a UsageFault exception if they perform an unaligned access, and therefore their accesses must be address aligned.