Вчера ловил интересный глюк, с UcOS, достаточно добавить переменную любую почти в любом месте кода и все рушилось. Но если добавить ещё одну - снова работало. Оказалось в итоге что это меняет положение стека задач в оське, и если он не 8allign то рушится. В доках Арм что то о требовании такого выравнивания для внешней памяти. Но тут то внутренняя. Откуда ноги, ткните плз. Просто ради интереса
Цитата(DASM @ Aug 1 2018, 18:48)

Откуда ноги, ткните плз. Просто ради интереса
LDRD/STRD, работа с 64-битными данными.
Цитата(aaarrr @ Aug 1 2018, 18:54)

LDRD/STRD, работа с 64-битными данными.
Ну хорошо, я решил свою проблему, создав сегмент с аллигн 8 и поместив в него стеки задач ос. Но до того, обычный проект совершенно, у него стек просто на конец озу чипа, в сегменте с алигн4. Почему работает? Да и все равно не совсем ясно, если в стек пушить 4байтные данные, то ведь станет криво. Чего то не понимаю я. Или арм при заталкивании в стек, допустим одного байта, на самом деле меняет указатель стека на 8? Компа нет под рукой, но стало интересно
Цитата(DASM @ Aug 1 2018, 19:09)

Да и все равно не совсем ясно, если в стек пушить 4байтные данные, то ведь станет криво.
При вызове функции должно быть ровно, в остальное время все равно.
То есть компилер при вызове примет меры для выравнивания, зная что стек в 8байтном сегменте? А во всех этих хелло ворд как такое соблюдается? Просто потому что конец озу и так кратен 8 ?
Цитата(DASM @ Aug 1 2018, 19:35)

То есть компилер при вызове примет меры для выравнивания, зная что стек в 8байтном сегменте?
Да, примет.
Цитата(DASM @ Aug 1 2018, 19:35)

А во всех этих хелло ворд как такое соблюдается? Просто потому что конец озу и так кратен 8 ?
Про всякие хелло ворды ничего не скажу, но требованию уже много лет.
MasterElectric
Aug 2 2018, 07:16
Это связано с выравниванием стекового фрейма к двойному слову. Это можно отключить в NVIC регистр CCR бит STKALIGN, после чего выравнивание будет к слову. Но отключать можно не во всех МК, m7 нельзя точно. По идее падало во время переключения задач, т.е. при вызове прерывания.
Цитата(aaarrr @ Aug 1 2018, 18:54)

LDRD/STRD, работа с 64-битными данными.
Это не так. LDRD/STRD требуют выравнивания только на 4.
Цитата(jcxz @ Aug 2 2018, 12:31)

Это не так. LDRD/STRD требуют выравнивания только на 4.
- Не на всех архитектурах это разрешено по умолчанию (ARMv5TE, ARMv6)
- Эффективнее работать с выравниванием (ARMv7-M)
Цитата(DASM @ Aug 1 2018, 18:48)

В доках Арм что то о требовании такого выравнивания для внешней памяти. Но тут то внутренняя. Откуда ноги, ткните плз.
Они ссылаются на LDRD, STRD, причём в разных вариантах архитектуры ARM эффект может быть или не быть, но сделали стандартом, чтобы не путаться.
Тут.
Цитата(DASM @ Aug 1 2018, 18:48)

Оказалось в итоге что это меняет положение стека задач в оське, и если он не 8allign то рушится.
Компилятор, зная, что стек выравнен на 8 байт, может использовать такую арифметику с адресами, которая ломается при отсутствии выравнивания.
Вот пример.
Итого в линкер файлах того же gcc мина лежит? Там везде стек а аллигн4 сегментах. Либо его библиотеки и соглашения о вызовах нечуствительны к этому, а fault я получаю потому что ucOS что то там упускает? Она явно написана с требованием аллигн8, в вариантах под IAR везде pragma locaton stacks, и он в icf отдельно обьявлен с аллигн8. Хотелось бы понять, причина в ОСи такой, или все же аллигн8 необязателен без нее?
И еще тупой вопрос. Сегменты с аллигнами это ведь для линкера. Компилятор вообще в курсе?
Цитата(DASM @ Aug 2 2018, 18:52)

Хотелось бы понять, причина в ОСи такой, или все же аллигн8 необязателен без нее?
Обязателен, т.к. это требование прописано в ATPCS/AAPCS с 2000 года (после введения ARMv5).
Gcc не в курсе? Или кто делает lds файлы.. честно даже не знаю. Ну нет там аллигн8 (насколько помню), с телефона пишу, не посмотреть
Цитата(DASM @ Aug 2 2018, 18:55)

Итого в линкер файлах того же gcc мина лежит? Там везде стек а аллигн4 сегментах.
Мина. Но такая, что вряд ли когда рванет.
Цитата(DASM @ Aug 2 2018, 18:55)

И еще тупой вопрос. Сегменты с аллигнами это ведь для линкера. Компилятор вообще в курсе?
А как он может быть в курсе? Он просто считает, что стек выровнен на 2 слова.
Цитата(aaarrr @ Aug 2 2018, 19:00)

2000 года (после введения ARMv5).
Господи, как время летит. Вчера же делали плату на AT91M55800A, бешеные 33 МГц, аж 8к озу и интерфейс к внешней. Так и не доделали. А он еще и in production. Доделать и в музей )). То есть если в lds написать размер сегмента (что был) минус 4 байта - и привет hard fault?
Цитата(DASM @ Aug 2 2018, 19:07)

Господи, как время летит. Вчера же делали плату на AT91M55800A, бешеные 33 МГц, аж 8к озу и интерфейс к внешней. Так и не доделали. А он еще и in production. Доделать и в музей ))
55800 - это возмутительный свежак, то ли дело 40800. У меня, возможно, еще где-то лежат. А платы вот выкинул.
Точно уже не помню, может и 40800, 2002 год был, с ShiphT собирались, мегаджон в курсе наверное
Цитата(DASM @ Aug 2 2018, 19:03)

Gcc не в курсе? Или кто делает lds файлы.. честно даже не знаю. Ну нет там аллигн8 (насколько помню), с телефона пишу, не посмотреть
Уже потратили кучу времени на написание множества сообщений, а просто взять и потратить пару минут на проверку - не судьба?
Ещё ни в одном из использованных Cortex-M я не сталкивался с исключением на LDRD/STRD из-за выравнивания всего на 32 бита. И Вашем МК я думаю эти исключения на 90% не из-за этого.
Не сталкивались и хорошо. А мне интересно кто сталкивался. Может и еще что узнаю. А то в М7 ещё и линии кэша есть, а паре с restrict может стать совсем весело. И кстати, были не исключения, в хард фалт не валился, просто частично не работал. И отследить как и почему не очень понятно мне как
Arlleex
Aug 3 2018, 04:47
Добавлю лишь, что в компиляторах ключ PRESERVE8 или подобный говорит, чтобы этот самый компилятор следил за выравниванием на 8 байт перед и после вызова функций.
Бит STACKALIGN в регистрах управления NVIC влияет на корректировку адреса стека только при входе в исключение, поскольку они асинхронны и могут произойти между вызовами функций, где стек может быть, собственно, не выровнен на требуемую границу.
P.S. DASM, вот в FreeRTOS, например, даже простейший диспетчер динамической памяти будет выровнен независимо от положения самого статического массива Heap. Там проверяется, находится ли он по границе, если нет - обрезает первые элементы кучи, чтобы действительный адрес кучи был выровнен. А дальше при каждом выделении обеспечивается механизм "добития" запрашиваемого количества до выровненного.
Цитата(DASM @ Aug 2 2018, 18:55)

Итого в линкер файлах того же gcc мина лежит? Там везде стек а аллигн4 сегментах. Либо его библиотеки и соглашения о вызовах нечуствительны к этому, а fault я получаю потому что ucOS что то там упускает?
Сталкивался с тем, что sprintf на плавучке глючил, когда нет выравнивания. Выдавал не то, что нужно, но не валился. Уже не припомню, был это яр или gcc. Моя версия: компилятор может использовать факт, что SP кратен 8, при генерации кода в адресной арифметике. Кстати, плохая адресная арифметика к разным вещам может приводить. Может тихо глюкануть, а может и глобально всё поломать.
Цитата(DASM @ Aug 1 2018, 19:09)

Ну хорошо, я решил свою проблему, создав сегмент с аллигн 8 и поместив в него стеки задач ос.
В принципе не обязательно для стеков задач создавать отдельный сегмент со своим выравниваем. Иначе придется
размер стека каждой задачи делать кратным 8 байт.
Но можно сделать с нужным выравниваем стек
каждой задачи, попутно "вынудив" компилятор выравнивать еще и размер стека автоматом. Например, я делаю так (лишнее "вырезал"):
Код
class AbstractThread
{
public:
....
using StackItem = uint64_t;
using StackSize = uint32_t;
...
}
....
template <AbstractThread::StackSize STACK_SIZE = THREAD_DEFAULT_STACK_SIZE>
class Thread : public AbstractThread
{
....
private:
StackItem stack[STACK_SIZE/(sizeof(StackItem))] __attribute__ ((aligned(sizeof(StackItem))));
};
Используется расширения самого компилятора, в данном случаем речь про
__attribute__ ((aligned(....))))
Цитата(Forger @ Aug 3 2018, 12:40)

В принципе не обязательно для стеков задач создавать отдельный сегмент со своим выравниваем. Иначе придется размер стека каждой задачи делать кратным 8 байт.
И что это реально так сильно нужно - задавать размер стека с точностью до слова? Зачем??
Выравнивание на 8 и размер кратным 8 и нечего впустую мудрить.
Цитата(jcxz @ Aug 4 2018, 00:30)

И что это реально так сильно нужно - задавать размер стека с точностью до слова? Зачем??
"Слово" в данном случае = int64, т.е. 8 байт. Или я не понял вопроса?
Цитата
Выравнивание на 8 и размер кратным 8 и нечего впустую мудрить.
Что я и делаю (см. пример выше).
Сегмент, по-моему, имеет смысл выделять под стеки, если камень имеет отдельное спец. быстрое ОЗУ, "прикрученное" к ядру специально для подобных целей.
Туда же еще смысл класть обработчики прерываний вместе с самой таблицей векторов.
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.