Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Размер стека
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
d7d1cd
Привет всем. Подскажите, размер памяти, выделяемой под стек, в устройствах MSP430 всегда одинаков или все зависит от компилятора?
_Артём_
Цитата(d7d1cd @ Nov 21 2012, 15:43) *
Подскажите, размер памяти, выделяемой под стек, в устройствах MSP430 всегда одинаков или все зависит от компилятора?

Размер как правило определяется в каждом проекте, за исключением случая когда стек аппаратный.
d7d1cd
Цитата(_Артём_ @ Nov 21 2012, 18:20) *
Размер как правило определяется в каждом проекте, за исключением случая когда стек аппаратный.


Тогда два вопроса.

1. В каких устройствах MSP430 стек аппаратный?

2. Как может быть определен размер стека, если я, например, в своем проекте использую рекурсивную функцию? Заранее нельзя сказать сколько раз она будет вызвана и, соответственно, выделить под стек необходимое количество памяти.

_Артём_
Цитата(d7d1cd @ Nov 21 2012, 16:25) *
1. В каких устройствах MSP430 стек аппаратный?

ДУмаю, что в MSP430 аппаратный стек не использовался.
Такой стек использовался например в PIC-ах.

Цитата(d7d1cd @ Nov 21 2012, 16:25) *
2. Как может быть определен размер стека, если я, например, в своем проекте использую рекурсивную функцию? Заранее нельзя сказать сколько раз она будет вызвана и, соответственно, выделить под стек необходимое количество памяти.

Глубина вызовов не может быть больше, чем размер стека - работать перестанет.
Выбирите максимально возможное значение глубины вызовов и задайте стек в соответствии с ним.
d7d1cd
Цитата(_Артём_ @ Nov 21 2012, 19:33) *
Глубина вызовов не может быть больше, чем размер стека - работать перестанет.Выбирите максимально возможное значение глубины вызовов и задайте стек в соответствии с ним.


Возможно мы не поняли друг друга. Я сам задаю размер стека?

_Артём_
Цитата(d7d1cd @ Nov 21 2012, 18:22) *
Возможно мы не поняли друг друга. Я сам задаю размер стека?

Да, задаёте сами.

Из slau049c.pdf:
Цитата
Software Initialization
After a system reset, user software must initialize the MSP430 for the
application requirements. The following must occur:
- Initialize the SP, typically to the top of RAM.
- Initialize the watchdog to the requirements of the application.
- Configure peripheral modules to the requirements of the application.
zhevak
Цитата(d7d1cd @ Nov 21 2012, 19:43) *
Привет всем. Подскажите, размер памяти, выделяемой под стек, в устройствах MSP430 всегда одинаков или все зависит от компилятора?

Вот тут --
http://zhevak.wordpress.com/2012/11/22/раз...стека-в-msp430/
я написал о-очень длинный ответ. Такой длинный, что понял, что помещать его сюда -- лучше не надо.
HHIMERA
А ещё лучше... его вообще не читать...
_pv
Цитата(zhevak @ Nov 22 2012, 00:53) *
я написал о-очень длинный ответ. Такой длинный, что понял, что помещать его сюда -- лучше не надо.

если выкинуть несколько бредовые рассуждения про avr, то вполне бы и сюда поместилось.
d7d1cd
Цитата(zhevak @ Nov 21 2012, 22:53) *
Вот тут --
http://zhevak.wordpress.com/2012/11/22/раз...стека-в-msp430/
я написал о-очень длинный ответ. Такой длинный, что понял, что помещать его сюда -- лучше не надо.
Спасибо, почитаю...
MrYuran
В IAR есть какие-то настройки, в mspgcc по умолчанию стек растет навстречу статическим переменным, расположенным "с другого конца" ОЗУ до тех пор, пока не начнет затирать их. После этого дальнейший ход событий непредсказуем.
Рекурсия в мелкоконтроллерных проектах - неоправданная глупость, которая приводит к перерасходу стека и возможности краха.
Даже на "взрослых" компьютерах бесконтрольная рекурсия может закончиться аварийным завершением.
Большинство рекурсивных алгоритмов можно преобразовать в обычный вид.
rezident
Цитата(d7d1cd @ Nov 21 2012, 21:22) *
Возможно мы не поняли друг друга. Я сам задаю размер стека?

Размер стека это абстрактная величина, определяемая программистом для компилятора. Потому, что в MSP430 аппаратный лишь сам указатель стека. Размер стека никак аппаратно не задается и не контролируется. "Наползание" стека на область статических/глобальных данных это самая трудновыявляемая ошибка в программировании. Компилятор может немного помочь в определении этого момента, но не всегда и с вероятностью, сильно отличающейся от 100%. Тем более он этого не может, когда идут рекурсивные вызовы в прерываниях, которые компилятор спрогнозировать вообще не в силах. Используйте программные ухищрения, типа счетчика рекурсии.
Код
#define MAX_NESTED_VALUE   5    //максимальное значение уровня вложенности прерываний
#pragma vector=TIMERB0_VECTOR
#pragma type_attribute=__interrupt
void TIMERB0_ISR(void)
{ static unsigned int cntr_nested=0;
  cntr_nested++; //инкремент счетчика вложенности прерываний
  if (cntr_nested < MAX_NESTED_VALUE) //проверяем уровень вложенности, если он меньше допустимого, то выполняем какие-то действия
  {

    ... //выполняем какие-то действия, необходимые до вложенных прерываний

    __enable_interrupt(); //разрешаем прерывания, в т.ч. вложенные

    ... //выполняем какие-то действия

  }
  --cntr_nested; //декремент счетчика вложенности прерываний
}
_Артём_
Цитата(rezident @ Nov 22 2012, 17:19) *
Код
#define MAX_NESTED_VALUE   5    //максимальное значение уровня вложенности прерываний
#pragma vector=TIMERB0_VECTOR
#pragma type_attribute=__interrupt
void TIMERB0_ISR(void)
{ static unsigned int cntr_nested=0;
  cntr_nested++; //инкремент счетчика вложенности прерываний
  if (cntr_nested < MAX_NESTED_VALUE) //проверяем уровень вложенности, если он меньше допустимого, то выполняем какие-то действия
  {

    ... //выполняем какие-то действия, необходимые до вложенных прерываний

    __enable_interrupt(); //разрешаем прерывания, в т.ч. вложенные

    ... //выполняем какие-то действия

  }
  --cntr_nested; //декремент счетчика вложенности прерываний
}

Зачем cntr_nested объявлена как static, а не как глобальная?
Это подсчёт вложенности одного и того же прерывания? Не лучше ли на входе прерывания делать запрет вызова, а на выходе опять разрешать?
rezident
Цитата(_Артём_ @ Nov 22 2012, 20:33) *
Зачем cntr_nested объявлена как static, а не как глобальная?
Чтобы зря не "засирать" namespace sm.gif
Цитата(_Артём_ @ Nov 22 2012, 20:33) *
Это подсчёт вложенности одного и того же прерывания?
Конечно. Ведь переменная имеет область видимости и изменяется только внутри данной конкретной функции обработки прерывания.
Цитата(_Артём_ @ Nov 22 2012, 20:33) *
Не лучше ли на входе прерывания делать запрет вызова, а на выходе опять разрешать?
Данный вопрос свидетельствует о том, что вы слабо знакомы с системой прерываний MSP430. При переходе по вектору прерывания сохраняется состояние регистра SR (на стеке), затем флаг GIE (Global Interrupt Enable - глобальное разрешение маскируемых прерываний), входящий в состав этого регистра, сбрасывается (точнее сбрасывается состояние всего статусного регистра SR) и таким образом вложенные прерывания автоматически запрещаются. Так что отдельно запрещать прерывания непосредственно в функции обработки прерывания не требуется. Если вам нужны вложенные прерывания, то в обработчике прерывания их можно разрешить (установив бит GIE). Естественно, что при выходе из прерывания состояние регистра SR (и бита GIE) восстанавливается.
_Артём_
Цитата(rezident @ Nov 22 2012, 21:46) *
Чтобы зря не "засирать" namespace sm.gif

Ну если так...то понятно.

Цитата(rezident @ Nov 22 2012, 21:46) *
Конечно. Ведь переменная имеет область видимости и изменяется только внутри данной конкретной функции обработки прерывания.

Мне как-то трудно представить, зачем допускать ситуацию, когда вложенность одного и того же прерывания больше 1. Разрешить работать другим прерываниям - понятно, а так - не очень.

Цитата(rezident @ Nov 22 2012, 21:46) *
Данный вопрос свидетельствует о том, что вы слабо знакомы с системой прерываний MSP430.

Я их даже не видел ни разу. sm.gif

Цитата(rezident @ Nov 22 2012, 21:46) *
Если вам нужны вложенные прерывания, то в обработчике прерывания их можно разрешить (установив бит GIE).

Обычно так и делаю (на АВР правда, но какая разница). Но перед этим запрещаю тот обработчик, который выполняется в текущий момент.
rezident
Цитата(_Артём_ @ Nov 23 2012, 01:35) *
Мне как-то трудно представить, зачем допускать ситуацию, когда вложенность одного и того же прерывания больше 1. Разрешить работать другим прерываниям - понятно, а так - не очень.
Ну мало ли какие алгоритмы работы встречаются. Иногда бывает, что весь алгоритм выполняется внутри одного единственного прерывания, а main при этом просто пустой цикл. Сходу могу припомнить только один пример - перерывание "системных тиков" в котором работает программный RTC. Счетчик RTC должен инкрементироваться на каждый "системный тик", а все остальное, обслуживаемое в данном прерывании, может и подождать. В случае, когда период вызова "системных тиков" оказывается меньше, чем время его обработки, часть его можно "обойти", вызвав лишь функцию RTC. Но для этого нужен какой-то детектор вложенности прерываний, хотя бы в виде счетчика.
Цитата(_Артём_ @ Nov 23 2012, 01:35) *
Обычно так и делаю (на АВР правда, но какая разница). Но перед этим запрещаю тот обработчик, который выполняется в текущий момент.
Да, так и делают при необходимости. Дело в том, что у MSP430 не все флаги прерываний сбрасываются автоматически при переходе по вектору прерывания. Некоторые сбрасываются лишь при определеных условиях (после чтения регистра статуса UART, например), а другие вообще только программно очищаются (P1IFG и P2IFG, например). Бит GIE же при переходе по вектору прерывания автоматически сбрасывается всегда.
Steve Key
Цитата(_Артём_ @ Nov 23 2012, 00:35) *
Мне как-то трудно представить, зачем допускать ситуацию, когда вложенность одного и того же прерывания больше 1.

Это называется "реэнтерабельность" прерываний, т. е., способность входить в прерывание, пока оно не закончено, и не разрушить программу, видимо, иногда нужная штука... biggrin.gif
zhevak
Реентерабебльность (от re-enter -- повторный вход) -- это, конечно, хорошо! Но всему должна быть мера.

Реентерабельность обычных функций (не обработчиков прерываний) -- это нормальное явление. Хотя оно и требует к себе повышенного внимания. То есть вполне допустимо, если вы понимаете, что вы делаете, и что на самом деле у вас в системе происходит.

Реентерабельность прерываний -- это уже из области работы со взрывчаткой. Тут, в отличие от простых функций, внимание этому вопросу нужно уделять максимальное. Если вы профи, то, если что, вы наверняка разберетесь со странным поведением системы. Но если вы только-только, то геммор на несколько дней вам обеспечен без гарантии того, что вам вообще удастся обуздать ситуацию.

Вообще реентерабельность прерываний подразумевает то, что прерывания разбиты на несколько уровней -- по приоритетам. Более приоритетные прерывания имеют право прерывать работу обработчиков прерываний с более низким приоритетом. (Блин, ну и тавтология. Сам поражаюсь!) Реентерабельность прерываний -- это вынужденная мера. Это нужно делать только тогда, когда другими способами не удается разрулить работу системы (девайса). По возможности нужно избегать реентерабельности прерываний.

Если реентерабельность прерываний одного уровня -- очень и очень сомнительна (это явно не от великого ума), то реентерабелность одного прерывания -- это мега-зло!

Применение уровней прерываний и создание реентерабельности может быть оправдано только в двух случаях. Первый -- программа на столько небольшая, что логика работы ее прозрачна и осязаема. Ну, например, моргание светодиодами. Второй случай -- это когда система достаточно большая и сложная, но должна отвечать жестким требованиям по скорости отклика на события. Это в основном системы реального времени с заранее оговоренной скоростью реакции.

Во всех остальных случаях, следует придерживаться следующей логики. Из нескольких, одновременно возникших в системе событий мы должны создать очередь, и последовательно их обработать. Например, одновременно пришедшие события от клавиатуры, мышки и RS485, могут быть обработаны в ЛЮБОМ порядке относительно друг друга. Собственно, порядок их обработки может быть легко измениться, если какое-то событие возникнет на мгновение раньше другого. Невозможно учесть абсолютно все жизненные ситуации, поэтому проще считать, что

"мы будем бороться с проблемами в порядке их возникновения" (с) не помню чье высказывание

Вообще это очень большая тема и конкретное решение по реентерабельности прерываний нужно рассматривать не абстрактно, а применительно и конкретно.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.