hard fault на stm32f103rb при работе с указателями на uint64
hard fault на stm32f103rb при работе с указателями на uint64
программа улетает в hard fault на stm32f103rb при работе с указателями на uint64_t. Код на Си простой: берется указатель на uint64_t и загружается в переменную с таким же типом значение с произвольного адреса (ну получается нужно 2 регистра). Если смотреть по ассемблеру, то не идут команды LDMIA (или LDRD если компилить в другой версии GNU), но собственно сценарий примерно один, берется адрес, который по условиям ассемблерной команды должен быть кратен 4 (кто б подсказал зачем), а у меня он в принципе произвольный и выравнивание мне там не сделать, как быть?
- Реклама
Re: hard fault на stm32f103rb при работе с указателями на ui
Невыровненный доступ поддерживают только простые инструкции LDR/STR, а LDRD уже требует выравнивания. Когда-то мне помогало в подобном случае указатель объявлять как volatile, тогда gcc вместо LDRD генерил LDR, но никаких гарантий... Если не сработает, то пиши на инлайн ассме используя инструкции не требующие выравнивания или указатель приводи к 32-х битному.
-
Professor Chaos
- Открыл глаза
- Сообщения: 41
- Зарегистрирован: Вс мар 21, 2021 11:06:04
Re: hard fault на stm32f103rb при работе с указателями на ui
Написать функцию типа uint64_t GetUint64(void* p) и использовать её. Внутри неё будете считывать 8 байт по указателю и формировать из них возвращаемое значение. Это распата за невыровненный доступ. Зато работать будет всегда и везде.auric писал(а):у меня он в принципе произвольный и выравнивание мне там не сделать, как быть?
Re: hard fault на stm32f103rb при работе с указателями на ui
А не пробовали написать свой обработчик hard fault, может не страшно. Win-да в такие ситуации попадает по 20 раз в секунду и, ничего, никто не журчит....
"Every profession is a conspiracy against the uninitiated" (B. Shaw)
"A textbook can be defined as a book unsuitable for reading" (B. Shaw)
Tautology is humor in "this" place (Vigo Carpathian)
"A textbook can be defined as a book unsuitable for reading" (B. Shaw)
Tautology is humor in "this" place (Vigo Carpathian)
Re: hard fault на stm32f103rb при работе с указателями на ui
Порешал, обработка теперь интом, потом склейка, как и писали дольше, зато гарантировано. Просто странно, что мешало сделать инструкции без выравнивания и что мешало сделать в компиляторе проверки и не генерить падающий на асме код.
- Реклама
- ArtDen
- Мучитель микросхем
- Сообщения: 462
- Зарегистрирован: Пн фев 22, 2010 09:12:34
- Контактная информация:
Re: hard fault на stm32f103rb при работе с указателями на ui
А можно минимальный пример для воспроизведения? Похоже на баг в компиляторе
http://ufa-darts.ru/ - приходи играть в дартс в Уфе
Re: hard fault на stm32f103rb при работе с указателями на ui
[uquote="auric",url="/forum/viewtopic.php?p=4096658#p4096658"]Порешал, обработка теперь интом, потом склейка, как и писали дольше, зато гарантировано. Просто странно, что мешало сделать инструкции без выравнивания и что мешало сделать в компиляторе проверки и не генерить падающий на асме код.[/uquote]
Напишите обработчик HardFault, который исправляет ситуацию на лету.
Добавлено after 11 minutes 11 seconds:
[uquote="ArtDen",url="/forum/viewtopic.php?p=4096952#p4096952"]А можно минимальный пример для воспроизведения? Похоже на баг в компиляторе[/uquote]
Как-то неопределенно выразились. Это и есть БАГ компилятора. Только его исправлять никто не хочет. Сейчас модно писать на Java. Следуя этой моде как раз я и предлагаю поправить компилятор написав обработчик HardFault, исправляющий ситуацию "на лету". И вообще, нужно для всех без исключения HardFault иметь свои обработчики. Это не трудно, без них Вы делаете вывод о необходимости править исходники, а с ними этого можно не делать. Т.е. исходники не править. Компилятор считает, что это проблема процессора и не собирается под него подстраиваться. Это, своего рода традиция.
Напишите обработчик HardFault, который исправляет ситуацию на лету.
Добавлено after 11 minutes 11 seconds:
[uquote="ArtDen",url="/forum/viewtopic.php?p=4096952#p4096952"]А можно минимальный пример для воспроизведения? Похоже на баг в компиляторе[/uquote]
Как-то неопределенно выразились. Это и есть БАГ компилятора. Только его исправлять никто не хочет. Сейчас модно писать на Java. Следуя этой моде как раз я и предлагаю поправить компилятор написав обработчик HardFault, исправляющий ситуацию "на лету". И вообще, нужно для всех без исключения HardFault иметь свои обработчики. Это не трудно, без них Вы делаете вывод о необходимости править исходники, а с ними этого можно не делать. Т.е. исходники не править. Компилятор считает, что это проблема процессора и не собирается под него подстраиваться. Это, своего рода традиция.
"Every profession is a conspiracy against the uninitiated" (B. Shaw)
"A textbook can be defined as a book unsuitable for reading" (B. Shaw)
Tautology is humor in "this" place (Vigo Carpathian)
"A textbook can be defined as a book unsuitable for reading" (B. Shaw)
Tautology is humor in "this" place (Vigo Carpathian)
Re: hard fault на stm32f103rb при работе с указателями на ui
[uquote="ArtDen",url="/forum/viewtopic.php?p=4096952#p4096952"]А можно минимальный пример для воспроизведения? Похоже на баг в компиляторе[/uquote]
В таком виде gcc 10.2 генерит четыре STR, а если убрать volatile, то получим STR+STRD+STR. Заменив чтение IDR константой компилятор будет знать во время компиляции точный адрес и даже без volatile подставит STRD только если адрес выровненный.
Код: Выделить всё
uint32_t arr[10];
volatile uint32_t* p = (uint32_t*)((uint8_t*)arr + (GPIOA->IDR & 7));
*p++ = 0x55;
*p++ = 0x55;
*p++ = 0x55;
*p++ = 0x55;
- ArtDen
- Мучитель микросхем
- Сообщения: 462
- Зарегистрирован: Пн фев 22, 2010 09:12:34
- Контактная информация:
Re: hard fault на stm32f103rb при работе с указателями на ui
В этом примере программист сам себе злобный буратино, т.к. код изначально допускает обращение по невыровненному адресу.
http://ufa-darts.ru/ - приходи играть в дартс в Уфе
Re: hard fault на stm32f103rb при работе с указателями на ui
А ТС изначально написал, что адреса у него произвольные и выравнивание не сделать.
- ArtDen
- Мучитель микросхем
- Сообщения: 462
- Зарегистрирован: Пн фев 22, 2010 09:12:34
- Контактная информация:
Re: hard fault на stm32f103rb при работе с указателями на ui
Если компилятор заранее знает, что будет идти доступ по невыровненному адресу, то он будет это делать побайтно.
Последнюю строку gcc-arm-none-eabi-10.3-2021.07 при -O3 компилирует в
А если компилятор не знает, но программист допускает такое обращение - то повторюсь, он ССЗБ
Код: Выделить всё
char aaa[10] = {};
volatile uint64_t *ptr = (uint64_t*)(aaa+1);
*ptr = 0x1234567887654321;
Код: Выделить всё
ldrb.w r3, [sp, #13]
movs r3, #33 ; 0x21
strb.w r3, [sp, #13]
ldrb.w r3, [sp, #14]
movs r3, #67 ; 0x43
strb.w r3, [sp, #14]
ldrb.w r3, [sp, #15]
movs r3, #101 ; 0x65
strb.w r3, [sp, #15]
ldrb.w r3, [sp, #16]
mvn.w r3, #120 ; 0x78
strb.w r3, [sp, #16]
ldrb.w r3, [sp, #17]
movs r3, #120 ; 0x78
strb.w r3, [sp, #17]
ldrb.w r3, [sp, #18]
movs r3, #86 ; 0x56
strb.w r3, [sp, #18]
ldrb.w r3, [sp, #19]
movs r3, #52 ; 0x34
strb.w r3, [sp, #19]
ldrb.w r3, [sp, #20]
movs r3, #18
strb.w r3, [sp, #20]
http://ufa-darts.ru/ - приходи играть в дартс в Уфе
-
Professor Chaos
- Открыл глаза
- Сообщения: 41
- Зарегистрирован: Вс мар 21, 2021 11:06:04
Re: hard fault на stm32f103rb при работе с указателями на ui
А если неизвестно? Т.е. адрес может быть произвольным: как выровненным, так и нет. Что ДОЛЖЕН сделать компилятор?ArtDen писал(а):Если компилятор заранее знает, что будет идти доступ по невыровненному адресу
Например:
Код: Выделить всё
uint64_t getUint64(void* buf_p) {
return *((uint64_t*)buf_p));
}- ArtDen
- Мучитель микросхем
- Сообщения: 462
- Зарегистрирован: Пн фев 22, 2010 09:12:34
- Контактная информация:
Re: hard fault на stm32f103rb при работе с указателями на ui
Если заранее неизвестно, то компилятор генерирует максимально быстрый код, не допускающий невыровненные адреса Это достаточно разумный подход, но приводящий к хардфаулту у программистов, которые ещё не знают от такой особенности ))
http://ufa-darts.ru/ - приходи играть в дартс в Уфе
Re: hard fault на stm32f103rb при работе с указателями на ui
[uquote="auric",url="/forum/viewtopic.php?p=4096658#p4096658"]что мешало сделать в компиляторе проверки и не генерить падающий на асме код.[/uquote]
А что мешало вам прочитать доку на компилятор и узнать, что всё уже давно имеется?: если объявить указатель на пакованный тип, то компилятор вместо LDRD/STRD генерит пару LDR/STR.
IAR:
typedef __packed unsigned long long u64p;
и все обращения к u64p будут только инструкциями, умеющими невыровненный доступ.
Добавлено after 7 minutes 38 seconds:
[uquote="ArtDen",url="/forum/viewtopic.php?p=4097143#p4097143"]Последнюю строку gcc-arm-none-eabi-10.3-2021.07 при -O3 компилирует в[/uquote]
А какое это имеет отношение к теме? Такое сгенерилось видимо для какого-то младшего ядра (M0, etc.). А у ТС - Cortex-M3. Для него вменяемый компилятор, в случае невыровненного доступа, должен генерить пару LDR/STR, а не ворох LDRB/STRB.
А что мешало вам прочитать доку на компилятор и узнать, что всё уже давно имеется?: если объявить указатель на пакованный тип, то компилятор вместо LDRD/STRD генерит пару LDR/STR.
IAR:
typedef __packed unsigned long long u64p;
и все обращения к u64p будут только инструкциями, умеющими невыровненный доступ.
Добавлено after 7 minutes 38 seconds:
[uquote="ArtDen",url="/forum/viewtopic.php?p=4097143#p4097143"]Последнюю строку gcc-arm-none-eabi-10.3-2021.07 при -O3 компилирует в[/uquote]
А какое это имеет отношение к теме? Такое сгенерилось видимо для какого-то младшего ядра (M0, etc.). А у ТС - Cortex-M3. Для него вменяемый компилятор, в случае невыровненного доступа, должен генерить пару LDR/STR, а не ворох LDRB/STRB.
- ArtDen
- Мучитель микросхем
- Сообщения: 462
- Зарегистрирован: Пн фев 22, 2010 09:12:34
- Контактная информация:
Re: hard fault на stm32f103rb при работе с указателями на ui
[uquote="jcxz",url="/forum/viewtopic.php?p=4097296#p4097296"]А какое это имеет отношение к теме? Такое сгенерилось видимо для какого-то младшего ядра (M0, etc.)[/uquote]
Забыл указать. Компилировалось это с флагом -mcpu=cortex-m4 для STM32F401
Сейчас проверил. Для cortex-m3 генерируется точно такой-же код.
Забыл указать. Компилировалось это с флагом -mcpu=cortex-m4 для STM32F401
Сейчас проверил. Для cortex-m3 генерируется точно такой-же код.
http://ufa-darts.ru/ - приходи играть в дартс в Уфе
Re: hard fault на stm32f103rb при работе с указателями на ui
[uquote="ArtDen",url="/forum/viewtopic.php?p=4097387#p4097387"]Забыл указать. Компилировалось это с флагом -mcpu=cortex-m4 для STM32F401
Сейчас проверил. Для cortex-m3 генерируется точно такой-же код.[/uquote]
Странно это... Так как не нужно там по-байтно.
IAR, например, код:компилит в:
т.е. - по паре LDR/STR на обращение.
Полная оптимизация вкл.
Убираем __packed и получаем:что и ожидалось....
Может у вас там для компилятора какая-то опция выставлена, говорящая, что на CPU принудительно запрещён невыровненный доступ? Ведь и на >=Cortex-M3 можно запретить невыровненный доступ установкой бита UNALIGN_TRP в CCR.
Сейчас проверил. Для cortex-m3 генерируется точно такой-же код.[/uquote]
Странно это... Так как не нужно там по-байтно.
IAR, например, код:
Код: Выделить всё
__packed unsigned long long volatile z = 0;
z++;
printf("%llu", z);Код: Выделить всё
LDR.N R5,??DataTable12_1
LDR R0,[R5, #+72]
LDR R1,[R5, #+76]
ADDS R0,R0,#+1
SBC R1,R1,#-1
STR R0,[R5, #+72]
STR R1,[R5, #+76]
LDR R2,[R5, #+72]
LDR R3,[R5, #+76]
ADR.W R0,?_2
BL _printfПолная оптимизация вкл.
Убираем __packed и получаем:
Код: Выделить всё
LDR.N R5,??DataTable12_1
LDRD R0,R1,[R5, #+24]
ADDS R0,R0,#+1
SBC R1,R1,#-1
STRD R0,R1,[R5, #+24]
LDRD R2,R3,[R5, #+24]
ADR.W R0,?_2
BL _printfМожет у вас там для компилятора какая-то опция выставлена, говорящая, что на CPU принудительно запрещён невыровненный доступ? Ведь и на >=Cortex-M3 можно запретить невыровненный доступ установкой бита UNALIGN_TRP в CCR.
Re: hard fault на stm32f103rb при работе с указателями на ui
Так "всё уже давно имеется" говорил или все-же "странно"?
Так обработчик HardFault писать будем?
Так обработчик HardFault писать будем?
"Every profession is a conspiracy against the uninitiated" (B. Shaw)
"A textbook can be defined as a book unsuitable for reading" (B. Shaw)
Tautology is humor in "this" place (Vigo Carpathian)
"A textbook can be defined as a book unsuitable for reading" (B. Shaw)
Tautology is humor in "this" place (Vigo Carpathian)
Re: hard fault на stm32f103rb при работе с указателями на ui
[uquote="astrahard",url="/forum/viewtopic.php?p=4097458#p4097458"]Так "всё уже давно имеется" говорил или все-же "странно"?[/uquote]Может сначала научимся читать сообщения?
Я это говорил про пакованные данные.
Где пример для GCC с пакованными 64-битными данными? Не вижу - никто не попробовал видимо. Для IAR я привёл.
Я это говорил про пакованные данные.
Где пример для GCC с пакованными 64-битными данными? Не вижу - никто не попробовал видимо. Для IAR я привёл.
- ArtDen
- Мучитель микросхем
- Сообщения: 462
- Зарегистрирован: Пн фев 22, 2010 09:12:34
- Контактная информация:
Re: hard fault на stm32f103rb при работе с указателями на ui
jcxz, если не веришь, можешь просто поиграться онлайн:
https://gcc.godbolt.org/z/ex1e5dcah
Там налету и компилируется и дизасемблер отображается. Опции компиляции тоже можно менять
https://gcc.godbolt.org/z/ex1e5dcah
Там налету и компилируется и дизасемблер отображается. Опции компиляции тоже можно менять
http://ufa-darts.ru/ - приходи играть в дартс в Уфе
Re: hard fault на stm32f103rb при работе с указателями на ui
[uquote="ArtDen",url="/forum/viewtopic.php?p=4097468#p4097468"]jcxz, если не веришь, можешь просто поиграться онлайн:
https://gcc.godbolt.org/z/ex1e5dcah
Там налету и компилируется и дизасемблер отображается[/uquote]
Понял. Компилит он так, потому что пример ваш некорректный. Вы объявили байтовый массив, а не 64-битную переменную (о чём вообще-то эта тема).
Видимо, так как GCC видит, что это именно массив байт, потому его оптимизатор и генерит такой код.
Достаточно ему написать корректный пример:
Как будут вполне ожидаемые LDRD/STRD.
Т.е. - volatile в случае GCC никак не спасает от исключения невыровненного доступа. Не поможет оно.
https://gcc.godbolt.org/z/ex1e5dcah
Там налету и компилируется и дизасемблер отображается[/uquote]
Понял. Компилит он так, потому что пример ваш некорректный. Вы объявили байтовый массив, а не 64-битную переменную (о чём вообще-то эта тема).
Видимо, так как GCC видит, что это именно массив байт, потому его оптимизатор и генерит такой код.
Достаточно ему написать корректный пример:
Код: Выделить всё
extern volatile uint64_t aaa;
volatile uint64_t *ptr = (uint64_t*)(&aaa+1);
*ptr = 0x1234567887654321;Т.е. - volatile в случае GCC никак не спасает от исключения невыровненного доступа. Не поможет оно.
Последний раз редактировалось jcxz Пн сен 27, 2021 12:24:34, всего редактировалось 2 раза.


