Перейти к содержанию
    

Stack, 8-byte alligment, откуда ноги?

2000 года (после введения ARMv5).

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Господи, как время летит. Вчера же делали плату на AT91M55800A, бешеные 33 МГц, аж 8к озу и интерфейс к внешней. Так и не доделали. А он еще и in production. Доделать и в музей ))

55800 - это возмутительный свежак, то ли дело 40800. У меня, возможно, еще где-то лежат. А платы вот выкинул.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Точно уже не помню, может и 40800, 2002 год был, с ShiphT собирались, мегаджон в курсе наверное

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Gcc не в курсе? Или кто делает lds файлы.. честно даже не знаю. Ну нет там аллигн8 (насколько помню), с телефона пишу, не посмотреть

Уже потратили кучу времени на написание множества сообщений, а просто взять и потратить пару минут на проверку - не судьба?

Ещё ни в одном из использованных Cortex-M я не сталкивался с исключением на LDRD/STRD из-за выравнивания всего на 32 бита. И Вашем МК я думаю эти исключения на 90% не из-за этого.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не сталкивались и хорошо. А мне интересно кто сталкивался. Может и еще что узнаю. А то в М7 ещё и линии кэша есть, а паре с restrict может стать совсем весело. И кстати, были не исключения, в хард фалт не валился, просто частично не работал. И отследить как и почему не очень понятно мне как

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Добавлю лишь, что в компиляторах ключ PRESERVE8 или подобный говорит, чтобы этот самый компилятор следил за выравниванием на 8 байт перед и после вызова функций.

Бит STACKALIGN в регистрах управления NVIC влияет на корректировку адреса стека только при входе в исключение, поскольку они асинхронны и могут произойти между вызовами функций, где стек может быть, собственно, не выровнен на требуемую границу.

 

P.S. DASM, вот в FreeRTOS, например, даже простейший диспетчер динамической памяти будет выровнен независимо от положения самого статического массива Heap. Там проверяется, находится ли он по границе, если нет - обрезает первые элементы кучи, чтобы действительный адрес кучи был выровнен. А дальше при каждом выделении обеспечивается механизм "добития" запрашиваемого количества до выровненного.

Изменено пользователем Arlleex

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Итого в линкер файлах того же gcc мина лежит? Там везде стек а аллигн4 сегментах. Либо его библиотеки и соглашения о вызовах нечуствительны к этому, а fault я получаю потому что ucOS что то там упускает?

Сталкивался с тем, что sprintf на плавучке глючил, когда нет выравнивания. Выдавал не то, что нужно, но не валился. Уже не припомню, был это яр или gcc. Моя версия: компилятор может использовать факт, что SP кратен 8, при генерации кода в адресной арифметике. Кстати, плохая адресная арифметика к разным вещам может приводить. Может тихо глюкануть, а может и глобально всё поломать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну хорошо, я решил свою проблему, создав сегмент с аллигн 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(....))))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В принципе не обязательно для стеков задач создавать отдельный сегмент со своим выравниваем. Иначе придется размер стека каждой задачи делать кратным 8 байт.

И что это реально так сильно нужно - задавать размер стека с точностью до слова? Зачем??

Выравнивание на 8 и размер кратным 8 и нечего впустую мудрить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И что это реально так сильно нужно - задавать размер стека с точностью до слова? Зачем??

"Слово" в данном случае = int64, т.е. 8 байт. Или я не понял вопроса?

 

Выравнивание на 8 и размер кратным 8 и нечего впустую мудрить.

Что я и делаю (см. пример выше).

 

Сегмент, по-моему, имеет смысл выделять под стеки, если камень имеет отдельное спец. быстрое ОЗУ, "прикрученное" к ядру специально для подобных целей.

Туда же еще смысл класть обработчики прерываний вместе с самой таблицей векторов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...