|
Стэк в scmRTOS |
|
|
|
Apr 24 2012, 18:19
|
Частый гость
 
Группа: Участник
Сообщений: 126
Регистрация: 14-11-10
Пользователь №: 60 879

|
Всем привет! Поясните, пожалуйста, есть ли какая-нибудь взаимосвязь между стеком программы и стеками процессов в ОС? И между их размерами... Что конкретно хранится в стеках процессов? Допустим, правильно ли следующее. В системе два процесса (П1 и П2). П1 завершает работу. Планировщик копирует содержимое стека программы в стек П1, а содержимое стека П2 в стек программы и передает управление П2. П2 работает, потом завершает работу. Планировщик копирует содержимое стека программы в стек П2, а содержимое стека П1 в стек программы и передает управление П1. Далее все повторяется по кругу... Стеки процессов не должны превышать размеры стека программы. Допустим, если в mega1280 во внутренней памяти размещается только стек программы, то стеки каждого из процессов не должны превышать 8192 байт. Бьюсь который день со спонтанной перезагрузкой, никак баг поймать не могу
|
|
|
|
|
Apr 24 2012, 18:40
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(spongebob @ Apr 24 2012, 21:19)  Допустим, если в mega1280 во внутренней памяти размещается только стек программы, то стеки каждого из процессов не должны превышать 8192 байт. Это чтож за ПРОЦЕСС с таким размером стека? Цитата(spongebob @ Apr 24 2012, 21:19)  Бьюсь который день со спонтанной перезагрузкой, никак баг поймать не могу  Может стек здесь и ни причём? Был у меня такой случай: задача копировала данные из кругового буфера в линейней для дальнейшей обработки. И в функции копирования была ошибка: функция начинала копировать из буфера ~64 кБ данных в линейный буфер и при этом переписывала всё ОЗУ. Через какое-то время происходил сброс (по WDT или как-то ещё).
|
|
|
|
|
Apr 24 2012, 18:52
|
Частый гость
 
Группа: Участник
Сообщений: 126
Регистрация: 14-11-10
Пользователь №: 60 879

|
Цитата(_Артём_ @ Apr 24 2012, 22:40)  Это чтож за ПРОЦЕСС с таким размером стека? В процессе вызываются функции обработки данных, в которых используются локальные крупные массивы. На самом деле памяти меньше съедается, я просто хочу понять принцип  Например, что произойдет, если я объявлю размер стека в процессе 10 кБ, а стек программы, как писалось выше, будет иметь размер не более 8 кБ? Цитата Может стек здесь и ни причём? Был у меня такой случай: задача копировала данные из кругового буфера в линейней для дальнейшей обработки. И в функции копирования была ошибка: функция начинала копировать из буфера ~64 кБ данных в линейный буфер и при этом переписывала всё ОЗУ. Через какое-то время происходил сброс (по WDT или как-то ещё). Может и ни при чем... Сторожевого таймера нет.
|
|
|
|
|
Apr 24 2012, 19:05
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(spongebob @ Apr 24 2012, 21:52)  Например, что произойдет, если я объявлю размер стека в процессе 10 кБ, а стек программы, как писалось выше, будет иметь размер не более 8 кБ? У вас внешняя память? Стек программы - стек на котором работают прерывания и main до вызова OS::Run. Стеки для процессов задаются индивидуально и их размеры никак не связаны друг с другом (лишбы памяти хватило и при этом всё работало). Какой у вас компилятор IAR или GCC? Цитата(spongebob @ Apr 24 2012, 21:52)  Сторожевого таймера нет. Сейчас не помню точно был ли у меня включен WDT. Может и не был, но как оно тогда на reset попадало?
|
|
|
|
|
Apr 24 2012, 19:28
|
Частый гость
 
Группа: Участник
Сообщений: 126
Регистрация: 14-11-10
Пользователь №: 60 879

|
Цитата(_Артём_ @ Apr 24 2012, 23:05)  У вас внешняя память? Ага, к 8 кБ на кристалле еще 32 кБ снаружи. Цитата Стек программы - стек на котором работают прерывания и main до вызова OS::Run. Вы хотите сказать, что стек программы после запуска ОС не используется?  Кстати, мы ведь ради интереса можем взять адрес какой-нибудь локальной переменной, принадлежащей процессу. По адресу будет видно где она лежит... Цитата Стеки для процессов задаются индивидуально и их размеры никак не связаны друг с другом (лишбы памяти хватило и при этом всё работало). Об этом я знаю... я спрашивал как связан стек программы со стеками процессов... стеки процессов конечно не зависят друг от друга... Цитата Какой у вас компилятор IAR или GCC? GCC. Цитата Сейчас не помню точно был ли у меня включен WDT. Может и не был, но как оно тогда на reset попадало? Очень интересный вопрос, но для того, чтобы на резет попадало вотчдога не всегда нужно, нужен просто баг хороший
|
|
|
|
|
Apr 24 2012, 20:04
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(spongebob @ Apr 24 2012, 22:28)  Ага, к 8 кБ на кристалле еще 32 кБ снаружи. Интересно как скажется на производительности то, что стек расположен по внешней ОЗУ? Цитата(spongebob @ Apr 24 2012, 22:28)  Вы хотите сказать, что стек программы после запуска ОС не используется?  Если не ошибаюся, то возможны варианты: 1. В прерывании используется TISRW - прерывание работает на стеке прерванного процесса. 2. В прерывании используется TISRW_SS - прерывание использует стек выделенный для функции main. Цитата(spongebob @ Apr 24 2012, 22:28)  я спрашивал как связан стек программы со стеками процессов... стеки процессов конечно не зависят друг от друга... Да вроде никак не связан. Какая между ними связь может вообще быть? Цитата(spongebob @ Apr 24 2012, 22:28)  Очень интересный вопрос, но для того, чтобы на резет попадало вотчдога не всегда нужно, нужен просто баг хороший  Возможный вариант: моя функция копирования портила часть (или всё озу), но в конечном итоге делала ret. Но стек уже был заполнен непонятно чем. Програма была небольшая (10-15 кБ). И в результате возврат происходил в область заполненную FF. И программа могла дойти до адреса 0.
|
|
|
|
|
Apr 25 2012, 04:32
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(_Артём_ @ Apr 24 2012, 23:04)  Интересно как скажется на производительности то, что стек расположен по внешней ОЗУ? Каждый push будет занимать не два такта, а минимум три, зависимо от настроек внешнего интерфейса. Ну и вся работа с локальными переменными на стеке (LDD Rx, Y+d). Стоило бы подумать о том, чтобі большие массивы не делать локальными, стеки разместить во внутреннем ОЗУ, а большие массивы — во внешнем. Цитата(_Артём_ @ Apr 24 2012, 23:04)  Если не ошибаюся, то возможны варианты: 1. В прерывании используется TISRW - прерывание работает на стеке прерванного процесса. 2. В прерывании используется TISRW_SS - прерывание использует стек выделенный для функции main. Да. Второй вариант несколько медлительнее, но экономичнее по суммарному объёму стеков при разрешении вложенных прерываний. При входе в первое прерывание регистры сохраняются на стеке прерванной задачи, а вложенные прерывания уже сохраняют всё на выделенном стеке общем для всех процессов. Если вложенные прерывания не разрешаются, то для AVR особого смысла использовать TISRW_SS нет.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Apr 25 2012, 05:57
|
Частый гость
 
Группа: Участник
Сообщений: 126
Регистрация: 14-11-10
Пользователь №: 60 879

|
Цитата(ReAl @ Apr 25 2012, 08:32)  Стоило бы подумать о том, чтобі большие массивы не делать локальными, стеки разместить во внутреннем ОЗУ, а большие массивы — во внешнем. Ну как большие... около 300 байт. Несколько их (по одному в каждой вложенной функции), функций несколько... вот и набегает. Фактически, большая часть из этих массивов - временные, нужны иногда, поэтому было принято решение делать их локальными, чтобы они создавались на стеке (типа, память сэкономить). По поводу размещения... тут я совсем слаб... Делаем большие массивы глобальными и с помощью ключей компилятора (линкера) перемещаем секции data, bss во внешнюю память (-Wl,--section-start,.data=0x802200)? А как тогда разместить стеки процессов во внутреннем ОЗУ? Если процессов много, то хватит ли им 8 кБ внутреннего ОЗУ?
|
|
|
|
|
Apr 25 2012, 07:44
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(ViKo @ Apr 25 2012, 13:25)  Если массивы временные, то почему бы не использовать один и тот же, глобальный, для разных целей? Только уже без ОС. А почему это вы думаете, что ОС запрещает использовать глобальные объекты?  Цитата(spongebob @ Apr 25 2012, 11:57)  Фактически, большая часть из этих массивов - временные, нужны иногда, поэтому было принято решение делать их локальными, чтобы они создавались на стеке (типа, память сэкономить). В scmRTOS 4.0 появился механизм для вычисления используемого каждым процессом стека (см. пример 4-Debug). Включите его, погоняйте. Узнаете, сколько чего и где. Может быть, всё спокойно влезет во внутреннее ОЗУ. Цитата(spongebob @ Apr 25 2012, 11:57)  По поводу размещения... тут я совсем слаб... Почитайте про линкерные скрипты. Примеры используемых avr-gcc скриптов находятся в lib\ldscripts.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Apr 25 2012, 07:56
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(spongebob @ Apr 25 2012, 08:57)  Делаем большие массивы глобальными и с помощью ключей компилятора (линкера) перемещаем секции data, bss во внешнюю память (-Wl,--section-start,.data=0x802200)? Не надо так. Не только стеки, все внутренние структуры scmRTOS полетят во внешнюю память. Вообще всё. С соответствующим замедлением. Во внутренней останется только «стек main()», который и использовать-то толком тяжело. Перенести только нужное во внешнюю память можно так http://electronix.ru/forum/lofiversion/index.php/t47714.html
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|