Easyelectronics.ru

Электроника для всех
Текущее время: 06 июл 2022, 19:05

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/5шт. два слоя. $5/5шт. четыре слоя
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 28 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 08 май 2021, 13:40 
Заглядывает иногда

Зарегистрирован: 17 фев 2021, 18:47
Сообщения: 37
Откуда: Кемерово
Тут такое дело, работаю с PIC16F716(пока программатор не собрал, код не заливал да и вообще опыта с пиками не имел), вычитал в даташите что у него 8 уровней аппаратного стека. Получается, что можно только до 8 вложенных подпрограмм или компилятор Си как-то это может решить, пакуя значение указателя памяти программ куда-то не в стек? Просто уже написал код где много функций для своего же удобства, а тут вот так и переписывать, не хотелось бы.

_________________
Копаю экзотику


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 08 май 2021, 15:30 
Старожил
Аватара пользователя

Зарегистрирован: 06 окт 2019, 21:35
Сообщения: 236
Откуда: Ukraine
Переписывать прийдеться.
Как правило первым делом формируются задачи возлагаемые на МК, затем под задачи подбирается МК.
Не хватает стека размером 8, берем МК с размером 16. Если и этого не хватает, выбираем МК из ARM линейки.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 08 май 2021, 15:35 
Старожил
Аватара пользователя

Зарегистрирован: 11 фев 2021, 21:02
Сообщения: 1174
Доступа к регистрам стека из кода программы не предусмотрено иначе, чем инструкциями call/return, поэтому компилятор ничего сделать не может.
У этого ПИКа и так лишних ресурсов то нету, ОЗУ на 128 байт, а вы over8 уровней вложенности пихаете. Младшие ПИКи - это не то место, где можно "для своего удобства". Старайтесь писать не так, как удобно вам, а так, как позволит работать микроконтроллеру. То есть минимум дробления на функции, минимум пустых операций, всё должно быть четко и по делу.
В принципе, 7 уровней вложенности функций и 1 уровень на прерывание - это более чем хватит для такого мелкоконтроллера. При расчете уровней не забывайте о прерываниях и функциях внутри прерываний - они входят в в это же число. Вообще, для таких мелкашек завсегда на асме писали раньше - и ничо.
Микрочипы щас рекомендуют замену старого 716 на новый PIC16F18344 - там уже 16-уровневый стек и ОЗУ в 4 раза больше. Хотя проблемы так и остались старые - банковая ОЗУ и прочие ограничения свободы.
Ввиду сложившейся ситуации, не буду советовать взять STM32F030F4, хотя мелкие ПИКи - это тупиковая ветвь эволюции.

_________________
СМЕРТЬ БАЙДЕНУ!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 08 май 2021, 17:44 
Заглядывает иногда

Зарегистрирован: 17 фев 2021, 18:47
Сообщения: 37
Откуда: Кемерово
да у меня тут ситуация, хотел сделать радио чтобы с удобством... ну чтож, придется извиваться, оставить только функции отправки/приема по софтовому I2C, все остальное кое-как самому

_________________
Копаю экзотику


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 08 май 2021, 19:58 
Старожил

Зарегистрирован: 03 июл 2012, 19:16
Сообщения: 209
Если что, стек используется только для хранения адресов возврата из подпрограмм. Параметры в функцыи (и локальные переменные) не через этот стек передаются. Так что следи только, чтобы не было вложенных функцый более 8 уровней и все.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 08 май 2021, 20:31 
Заглядывает иногда

Зарегистрирован: 17 фев 2021, 18:47
Сообщения: 37
Откуда: Кемерово
[quote="Int_13h"]Если что, стек используется только для хранения адресов возврата из подпрограмм. Параметры в функцыи (и локальные переменные) не через этот стек передаются. Так что следи только, чтобы не было вложенных функцый более 8 уровней и все.[/quote
у меня больше будет наверное, но я видел как на пиках вполне себе много функций кидали и ничего, работало...

_________________
Копаю экзотику


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 09 май 2021, 12:43 
Старожил

Зарегистрирован: 19 мар 2013, 19:37
Сообщения: 3075
Откуда: Санкт-Петербург
__force_inline в компиляторе есть?
Ну, чтобы писать по человечески, небольшими функциями.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 09 май 2021, 15:25 
Старожил
Аватара пользователя

Зарегистрирован: 06 окт 2019, 21:35
Сообщения: 236
Откуда: Ukraine
__forceinline у автора появится если он выберет МК с ядром ARM и среду разработки, например Keil.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 09 май 2021, 18:42 
Старожил
Аватара пользователя

Зарегистрирован: 11 фев 2021, 21:02
Сообщения: 1174
Вообще, 7 уровней вложенности это:
Код:
void Foo_1(void)
{
   Foo_2();
}

void Foo_2(void)
{
   Foo_3();
}

void Foo_3(void)
{
   Foo_4();
}

void Foo_4(void)
{
   Foo_5();
}

void Foo_5(void)
{
   Foo_6();
}

void Foo_6(void)
{
   Foo_7();
}

void Foo_7(void)
{
   
}

что даже для ARM-системы не является частым случаем.
Именно вложенность функций, а не вот такое:
Код:
void Foo_1(void)
{
   Foo_2();
   Foo_3();
   Foo_4();
   Foo_5();
   Foo_6();
   Foo_7();
}

void Foo_2(void)
{
}

void Foo_3(void)
{
}

void Foo_4(void)
{
}

void Foo_5(void)
{
}

void Foo_6(void)
{
}

void Foo_7(void)
{
}

в этом случае используется всего 2 уровня вложенности, поскольку каждая функция после вызова возвращается к первой, и глубина использования стека равна всего лишь двум уровням

Ну и повторюсь, когда пишите для такой мелочи как PIC16F716, старайтесь писать как можно проще, без программерских "удобств".

_________________
СМЕРТЬ БАЙДЕНУ!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 11 май 2021, 10:42 
Заглядывает иногда

Зарегистрирован: 17 фев 2021, 18:47
Сообщения: 37
Откуда: Кемерово
еще вот хотел спросить, если например такая конструкция встречается:
Код:
void myFunc1{
if(myVar){
myFunc2();
}
}

тут две вложенности или три? и вообще являются ли циклы вложенными или как-то вставляются как макросы?

_________________
Копаю экзотику


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 11 май 2021, 11:16 
Старожил

Зарегистрирован: 10 мар 2012, 11:11
Сообщения: 234
Int_13h писал(а):
Так что следи только, чтобы не было вложенных функцый более 8 уровней и все.

Как будто нефиг делать. Обычно компилер следит. И выдаёт предупреждение.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 11 май 2021, 11:17 
Старожил

Зарегистрирован: 10 мар 2012, 11:11
Сообщения: 234
us3rname писал(а):
тут две вложенности или три?

Такая конструкция не катит. Изучайте Си внимательно и тренируйтесь побольше.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 11 май 2021, 11:33 
Старожил

Зарегистрирован: 15 ноя 2015, 12:11
Сообщения: 296
us3rname писал(а):
вычитал в даташите что у него 8 уровней аппаратного стека.


Цитата:
2.4 Stack
The stack allows a combination of up to 8 program calls and interrupts to occur. The stack contains the return address from this branch in program execution.Mid-range devices have an 8-level deep x 13-bit widehardware stack. The stack space is not part of either program or data space, and the Stack Pointer is not readable or writable. The PC is PUSHed onto the stack when a CALL instruction is executed or an interrupt causes a branch. The stack is POPed in the event of a RETURN, RETLW or a RETFIE instruction execution.PCLATH is not modified when the stack is PUSHed or POPed.After the stack has been PUSHed 8 times, the ninth push overwrites the value that was stored from the first push. The tenth push overwrites the second push (andso on).


Т.е. на стеке сохраняются адреса возврата как из функций, так и из прерываний. Поскольку глубина стека известна, компилятору не составило бы труда отследить вложенность и при превышении завершиться с ошибкой. Но то нормальному компилятору (и без рекурсии в коде, ага). Впрочем это легко проверить - собрать тестовую программу с дюжиной вызывающих друг друга функций. Если соберётся - глянуть в ассемблерный выхлоп и посчитать последовательно CALL-ы и уравновешивающие их RET*. На CALL загибать один палец, а на RET - отгибать. Когда на руках останется меньше двух свободных пальцев - проблема. Можно ещё загрузить такую программу в какой эмулятор типа Proteus-а и посмотреть стек в режиме отладки.

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 11 май 2021, 14:06 
Старожил

Зарегистрирован: 08 авг 2013, 09:43
Сообщения: 3854
Вроде xc8 умеет как минимум предупреждать при возможном превышении кол-ва уровней стека.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 11 май 2021, 14:16 
Старожил
Аватара пользователя

Зарегистрирован: 11 фев 2021, 21:02
Сообщения: 1174
Код:
void myFunc1(void)   // <- не забываем в скобках указывать параметр. Если параметра нет - пишем void
{                       
    if(myVar)             // <- это не цикл, а условие
    {
        myFunc2();      // +1 уровень вложенности при вызове этой ф-ции в случае совпадения условия.
                               // без совпадения условия уровень вложенности не поменяется.
    }       
}


Код:
myFunc1();  // +1 уровень вложенности при вызове этой ф-ции.

Итого, в результате вызова myFunc1() указатель стека смещается на 1 уровень, и в самой функции при совпадении условия указатель стека при вызове myFunc2() сместится еще на 1 уровень.
Указатель стека ( <-- ) показывает на первую свободную ячейку, в которую БУДЕТ записан адрес возврата при вызове функции. SP (Stack Pointer) показывает число использованных в данный момент уровней.
Вложение:
1.png
1.png [ 41.83 Кб | Просмотров: 3015 ]


В цикле for или while, в каждой итерации происходит вызов функции и возврат из нее, поэтому независимо от того, сколько итераций цикла производится, число уровней вложенности остается постоянным:
Вложение:
4.png
4.png [ 21.77 Кб | Просмотров: 3017 ]


При переполнении стека повреждается порядок адресов возврата и возврата к первоначальной функции main() уже не происходит, программа зависает:
Вложение:
7.png
7.png [ 43.2 Кб | Просмотров: 3017 ]


Учитывайте так же, что прерывания тоже используют этот же стек для хранения адреса возврата. Под прерывание нужно резервировать как минимум один уровень, а лучше два.
Параметры функций и возвращаемое значение передаются через ячейки ОЗУ, которых тоже не много.

_________________
СМЕРТЬ БАЙДЕНУ!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 14 май 2021, 09:56 
Заглядывает иногда

Зарегистрирован: 17 фев 2021, 18:47
Сообщения: 37
Откуда: Кемерово
Lambo писал(а):
Учитывайте так же, что прерывания тоже используют этот же стек для хранения адреса возврата. Под прерывание нужно резервировать как минимум один уровень, а лучше два.

у меня просто прерывание с условиями внутри(ну эти говнопики с одним вектором, все дела) и инкремент, там же два а лучше три уровня как я понимаю?

_________________
Копаю экзотику


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 14 май 2021, 12:52 
Старожил

Зарегистрирован: 19 мар 2013, 19:37
Сообщения: 3075
Откуда: Санкт-Петербург
В смысле – с условиями? По условию вызываете одну из функций (тут получится плюс уровень, если компилятор не заинлайнит вызов... какой там у вас компилятор? C18 точно древнее говно, не инлайнит – не знаю, как другие) или внутри одной функции пачка разных обработчиков при разных условиях?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 14 май 2021, 14:27 
Старожил

Зарегистрирован: 15 ноя 2015, 12:11
Сообщения: 296
us3rname писал(а):
у меня просто прерывание с условиями внутри(ну эти говнопики с одним вектором, все дела) и инкремент, там же два а лучше три уровня как я понимаю?


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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 14 май 2021, 23:02 
Старожил
Аватара пользователя

Зарегистрирован: 06 окт 2019, 21:35
Сообщения: 236
Откуда: Ukraine
Да здесь похоже не понимание автором работы стека...
us3rname писал(а):
у меня просто прерывание с условиями внутри(ну эти говнопики с одним вектором, все дела) и инкремент, там же два а лучше три уровня как я понимаю?

Вот например отбросить специфичность МК и понять как работает стек:
Цитата:
Функция вычислила значение, положила его в стек и закончила работу. Управление передаётся оператору, вызвавшему эту функцию, который забирает из стека вычисленное значение и присваивает его переменной.

Сколько при этом этих функций в коде не особо то и важно. Главное последовательность соблюдать избегая переполнения стека относительного выбранного МК. Переполнение приведет к перезаписи ячеек что вызовет сбой выполнения программы ввиду нехватки ОЗУ.
Ну и выше писал, нужен большой стек -- подбираем соответствующий контроллер...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 15 май 2021, 01:20 
Старожил

Зарегистрирован: 15 ноя 2015, 12:11
Сообщения: 296
Droid 77 писал(а):
Вот например отбросить специфичность МК и понять как работает стек:

Не надо отбрасывать специфичность - иначе коллегу совсем запутаем. Данная сиротская платформа использует стек исключительно для хранения адресов возврата функций и обработчика прерывания. Остальное нам [пока] не важно - ни параметры функции, ни локальные переменные.
Droid 77 писал(а):
Цитата:
Функция вычислила значение, положила его в стек и закончила работу. Управление передаётся оператору, вызвавшему эту функцию, который забирает из стека вычисленное значение и присваивает его переменной.


Это на какой платформе возвращаемое значение функции передаётся через стек? И где в последовательности (а.параметры)(б.адрес возврата)(в.локальные переменные) оно находится? Выход из функции уничтожает всё, что после (б.) Чтобы писать перед (а.) - функция должна знать сколько стека занято параметрами. Между (а.) и (б.) - тоже неуютно, поскольку первая задача после возвращения из функции - очистить стек от её параметров - т.е. нужно будет сохранять возвращаемое значение в регистр. И не проще ли тогда договориться, что функция всегда кладёт возврат в регистр А? Как это обычно и делается. ;-)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 15 май 2021, 05:50 
Старожил

Зарегистрирован: 03 июл 2012, 19:16
Сообщения: 209
siarzhuk писал(а):
Это на какой платформе возвращаемое значение функции передаётся через стек? И где в последовательности (а.параметры)(б.адрес возврата)(в.локальные переменные) оно находится? Выход из функции уничтожает всё, что после (б.) Чтобы писать перед (а.) - функция должна знать сколько стека занято параметрами. Между (а.) и (б.) - тоже неуютно, поскольку первая задача после возвращения из функции - очистить стек от её параметров - т.е. нужно будет сохранять возвращаемое значение в регистр. И не проще ли тогда договориться, что функция всегда кладёт возврат в регистр А? Как это обычно и делается. ;-)

а что мешает вернуть через стек? :) особенно если несколько возвращаемых значений?
например d=fn(a, b,c)
[sp]=a ;ну соглашение о вызове у нас такое, сначала первый параметр, а не последний
[sp+1]=b
[sp+2]=c
call fn ;здесь кладем результат в "вершину" или "дно" стека [sp+3]
d = [sp+3]
sp=sp-3


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 15 май 2021, 09:00 
Старожил
Аватара пользователя

Зарегистрирован: 11 фев 2021, 21:02
Сообщения: 1174
Стек вызовов у PIC16 работает только адреса возврата переходов. В этом стеке не сохраняются параметры и переменные!
Прежде, чем писать много букв, загляните в даташите PIC16

_________________
СМЕРТЬ БАЙДЕНУ!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 15 май 2021, 16:12 
Старожил

Зарегистрирован: 03 июл 2012, 19:16
Сообщения: 209
Lambo писал(а):
Стек вызовов у PIC16 работает только адреса возврата переходов. В этом стеке не сохраняются параметры и переменные!
Прежде, чем писать много букв, загляните в даташите PIC16

а кто мешает организовать свой стек с покером и поэтессами? через FSR. правда несколько неэффективно...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 16 май 2021, 03:39 
Старожил

Зарегистрирован: 15 ноя 2015, 12:11
Сообщения: 296
Int_13h писал(а):
а что мешает вернуть через стек? :) особенно если несколько возвращаемых значений?

"Мешает" используемый ТС язык программирования. ;-) Особенно второму утверждению.

Int_13h писал(а):
например d=fn(a, b,c)
[sp]=a ;ну соглашение о вызове у нас такое, сначала первый параметр, а не последний
[sp+1]=b
[sp+2]=c
call fn ;здесь кладем результат в "вершину" или "дно" стека [sp+3]
d = [sp+3]
sp=sp-3

good bye, printf? В sp+3 будет адрес возврата. Его переписать - значит улететь по ret на околоземную орбиту. Выделить место за ним (sp+4) - суть обращаться к локальной переменной функции - работать будет до тех пор пока прерывание не подловит нас прямо на выходе из функции, пока мы ещё не успели прочитать "результат", и не попользует "свободное" место стека под свои нужды.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Возможен ли срыв стека на PIC?
СообщениеДобавлено: 16 май 2021, 03:44 
Старожил

Зарегистрирован: 15 ноя 2015, 12:11
Сообщения: 296
Lambo писал(а):
Прежде, чем писать много букв, загляните в даташите PIC16

Прежде чем писать в тему, её можно почитать и увидеть как ровно цитату из даташита про это самое что вы написали, так и определённую ригидность ТС в плане доверия к нашим ему советам. ;-D Простите великодушно за тон.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 28 ]  На страницу 1, 2  След.


Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB