spongebob 0 24 апреля, 2012 Опубликовано 24 апреля, 2012 · Жалоба Всем привет! Поясните, пожалуйста, есть ли какая-нибудь взаимосвязь между стеком программы и стеками процессов в ОС? И между их размерами... Что конкретно хранится в стеках процессов? Допустим, правильно ли следующее. В системе два процесса (П1 и П2). П1 завершает работу. Планировщик копирует содержимое стека программы в стек П1, а содержимое стека П2 в стек программы и передает управление П2. П2 работает, потом завершает работу. Планировщик копирует содержимое стека программы в стек П2, а содержимое стека П1 в стек программы и передает управление П1. Далее все повторяется по кругу... Стеки процессов не должны превышать размеры стека программы. Допустим, если в mega1280 во внутренней памяти размещается только стек программы, то стеки каждого из процессов не должны превышать 8192 байт. Бьюсь который день со спонтанной перезагрузкой, никак баг поймать не могу :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 24 апреля, 2012 Опубликовано 24 апреля, 2012 · Жалоба Допустим, если в mega1280 во внутренней памяти размещается только стек программы, то стеки каждого из процессов не должны превышать 8192 байт. Это чтож за ПРОЦЕСС с таким размером стека? Бьюсь который день со спонтанной перезагрузкой, никак баг поймать не могу :( Может стек здесь и ни причём? Был у меня такой случай: задача копировала данные из кругового буфера в линейней для дальнейшей обработки. И в функции копирования была ошибка: функция начинала копировать из буфера ~64 кБ данных в линейный буфер и при этом переписывала всё ОЗУ. Через какое-то время происходил сброс (по WDT или как-то ещё). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
spongebob 0 24 апреля, 2012 Опубликовано 24 апреля, 2012 · Жалоба Это чтож за ПРОЦЕСС с таким размером стека? В процессе вызываются функции обработки данных, в которых используются локальные крупные массивы. На самом деле памяти меньше съедается, я просто хочу понять принцип :) Например, что произойдет, если я объявлю размер стека в процессе 10 кБ, а стек программы, как писалось выше, будет иметь размер не более 8 кБ? Может стек здесь и ни причём? Был у меня такой случай: задача копировала данные из кругового буфера в линейней для дальнейшей обработки. И в функции копирования была ошибка: функция начинала копировать из буфера ~64 кБ данных в линейный буфер и при этом переписывала всё ОЗУ. Через какое-то время происходил сброс (по WDT или как-то ещё). Может и ни при чем... Сторожевого таймера нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 24 апреля, 2012 Опубликовано 24 апреля, 2012 · Жалоба Например, что произойдет, если я объявлю размер стека в процессе 10 кБ, а стек программы, как писалось выше, будет иметь размер не более 8 кБ? У вас внешняя память? Стек программы - стек на котором работают прерывания и main до вызова OS::Run. Стеки для процессов задаются индивидуально и их размеры никак не связаны друг с другом (лишбы памяти хватило и при этом всё работало). Какой у вас компилятор IAR или GCC? Сторожевого таймера нет. Сейчас не помню точно был ли у меня включен WDT. Может и не был, но как оно тогда на reset попадало? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
spongebob 0 24 апреля, 2012 Опубликовано 24 апреля, 2012 · Жалоба У вас внешняя память? Ага, к 8 кБ на кристалле еще 32 кБ снаружи. Стек программы - стек на котором работают прерывания и main до вызова OS::Run. Вы хотите сказать, что стек программы после запуска ОС не используется? :) Кстати, мы ведь ради интереса можем взять адрес какой-нибудь локальной переменной, принадлежащей процессу. По адресу будет видно где она лежит... Стеки для процессов задаются индивидуально и их размеры никак не связаны друг с другом (лишбы памяти хватило и при этом всё работало). Об этом я знаю... я спрашивал как связан стек программы со стеками процессов... стеки процессов конечно не зависят друг от друга... Какой у вас компилятор IAR или GCC? GCC. Сейчас не помню точно был ли у меня включен WDT. Может и не был, но как оно тогда на reset попадало? Очень интересный вопрос, но для того, чтобы на резет попадало вотчдога не всегда нужно, нужен просто баг хороший ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 24 апреля, 2012 Опубликовано 24 апреля, 2012 · Жалоба Ага, к 8 кБ на кристалле еще 32 кБ снаружи. Интересно как скажется на производительности то, что стек расположен по внешней ОЗУ? Вы хотите сказать, что стек программы после запуска ОС не используется? :) Если не ошибаюся, то возможны варианты: 1. В прерывании используется TISRW - прерывание работает на стеке прерванного процесса. 2. В прерывании используется TISRW_SS - прерывание использует стек выделенный для функции main. я спрашивал как связан стек программы со стеками процессов... стеки процессов конечно не зависят друг от друга... Да вроде никак не связан. Какая между ними связь может вообще быть? Очень интересный вопрос, но для того, чтобы на резет попадало вотчдога не всегда нужно, нужен просто баг хороший ;) Возможный вариант: моя функция копирования портила часть (или всё озу), но в конечном итоге делала ret. Но стек уже был заполнен непонятно чем. Програма была небольшая (10-15 кБ). И в результате возврат происходил в область заполненную FF. И программа могла дойти до адреса 0. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 25 апреля, 2012 Опубликовано 25 апреля, 2012 · Жалоба Интересно как скажется на производительности то, что стек расположен по внешней ОЗУ?Каждый push будет занимать не два такта, а минимум три, зависимо от настроек внешнего интерфейса. Ну и вся работа с локальными переменными на стеке (LDD Rx, Y+d). Стоило бы подумать о том, чтобі большие массивы не делать локальными, стеки разместить во внутреннем ОЗУ, а большие массивы — во внешнем. Если не ошибаюся, то возможны варианты: 1. В прерывании используется TISRW - прерывание работает на стеке прерванного процесса. 2. В прерывании используется TISRW_SS - прерывание использует стек выделенный для функции main. Да. Второй вариант несколько медлительнее, но экономичнее по суммарному объёму стеков при разрешении вложенных прерываний. При входе в первое прерывание регистры сохраняются на стеке прерванной задачи, а вложенные прерывания уже сохраняют всё на выделенном стеке общем для всех процессов. Если вложенные прерывания не разрешаются, то для AVR особого смысла использовать TISRW_SS нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
spongebob 0 25 апреля, 2012 Опубликовано 25 апреля, 2012 · Жалоба Стоило бы подумать о том, чтобі большие массивы не делать локальными, стеки разместить во внутреннем ОЗУ, а большие массивы — во внешнем. Ну как большие... около 300 байт. Несколько их (по одному в каждой вложенной функции), функций несколько... вот и набегает. Фактически, большая часть из этих массивов - временные, нужны иногда, поэтому было принято решение делать их локальными, чтобы они создавались на стеке (типа, память сэкономить). По поводу размещения... тут я совсем слаб... Делаем большие массивы глобальными и с помощью ключей компилятора (линкера) перемещаем секции data, bss во внешнюю память (-Wl,--section-start,.data=0x802200)? А как тогда разместить стеки процессов во внутреннем ОЗУ? Если процессов много, то хватит ли им 8 кБ внутреннего ОЗУ? :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IgorKossak 0 25 апреля, 2012 Опубликовано 25 апреля, 2012 · Жалоба Если массивы большие и нужда в них возникает редко, то может очень помочь использование кучи. Писал в своё время менеджер кучи для AVR, ничего сложного в этом нет. На производительность не слишком влияет ибо событие, как я уже говорил, редкое. Зато память экономится радикально. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 25 апреля, 2012 Опубликовано 25 апреля, 2012 · Жалоба Если массивы временные, то почему бы не использовать один и тот же, глобальный, для разных целей? Только уже без ОС. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 25 апреля, 2012 Опубликовано 25 апреля, 2012 · Жалоба Если массивы временные, то почему бы не использовать один и тот же, глобальный, для разных целей? Только уже без ОС.А почему это вы думаете, что ОС запрещает использовать глобальные объекты? :) Фактически, большая часть из этих массивов - временные, нужны иногда, поэтому было принято решение делать их локальными, чтобы они создавались на стеке (типа, память сэкономить). В scmRTOS 4.0 появился механизм для вычисления используемого каждым процессом стека (см. пример 4-Debug). Включите его, погоняйте. Узнаете, сколько чего и где. Может быть, всё спокойно влезет во внутреннее ОЗУ. По поводу размещения... тут я совсем слаб... Почитайте про линкерные скрипты. Примеры используемых avr-gcc скриптов находятся в lib\ldscripts. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 25 апреля, 2012 Опубликовано 25 апреля, 2012 · Жалоба А почему это вы думаете, что ОС запрещает использовать глобальные объекты? :) Думаю, что в ОС будет сложно контролировать, кто пользуется в данный момент универсальным массивом. upd. Разве что с кооперативной многозадачностью... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 25 апреля, 2012 Опубликовано 25 апреля, 2012 · Жалоба А вот как раз для такого контроля в ОС и предусмотрены средства синхронизации :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 25 апреля, 2012 Опубликовано 25 апреля, 2012 · Жалоба Делаем большие массивы глобальными и с помощью ключей компилятора (линкера) перемещаем секции data, bss во внешнюю память (-Wl,--section-start,.data=0x802200)?Не надо так. Не только стеки, все внутренние структуры scmRTOS полетят во внешнюю память. Вообще всё. С соответствующим замедлением. Во внутренней останется только «стек main()», который и использовать-то толком тяжело. Перенести только нужное во внешнюю память можно так http://electronix.ru/forum/lofiversion/index.php/t47714.html Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 25 апреля, 2012 Опубликовано 25 апреля, 2012 · Жалоба А вот как раз для такого контроля в ОС и предусмотрены средства синхронизации :) Что это? :) Мьютексы? Работа с массивами - дело долгое. От многозадачности мало что останется, пмсм. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться