Я бы предположил, что этот вопрос зависит от операционной системы или платформы.
Это произошло, когда я писал код на C ++ в Windows, используя аудио библиотеки портов.
В документации сказано, что в моей функции обратного вызова не пишется слишком много кода, который будет передаваться звуковому механизму порта, потому что в зависимости от системы его можно вызывать из ISR и чтения из другого форума, заявляя, что это может вызвать переполнение стека.
Я здесь не для того, чтобы спрашивать о каком-либо конкретном звуковом порте, но мне было интересно, почему возникнет проблема с пространством стека, если в ISR написано больше кода, чем в основной функции.
Я хочу вызвать несколько различных функций из обратного вызова. Если этот обратный вызов фактически вызывается из ISR, вызывает ли проблема вызов большего количества функций из ISR?
Позволит ли мне при вызове каждой функции дополнительное пространство в стеке, поскольку каждая функция имеет свой максимальный размер стека? Это меня немного смущает.
Я всегда думал, что функции и ISR могут использовать столько стекового пространства стека, сколько им нужно, вплоть до полного выделенного стека. Означает ли это, что основная функция имеет большую часть стека, чем другие.
Спасибо заранее.
Если этот обратный вызов фактически вызывается из ISR, вызывает ли проблема вызов большего количества функций из ISR?
Возможно. Существует множество разновидностей ISR, используемых во многих контекстах, и некоторые комбинации предоставляют ISR довольно ограниченное пространство стека. Пространство стека используется (по крайней мере) собственными параметрами ISR и локальными переменными, а также параметрами каждой функции, которую он вызывает, прямо или косвенно, с некоторыми накладными расходами на вызовы функций. Это пространство используется повторно для последовательных вызовов функций, но оно накапливается, когда одна функция вызывает другую.
Позволит ли мне при вызове каждой функции дополнительное пространство в стеке, поскольку каждая функция имеет свой максимальный размер стека?
Нет, вообще нет. ISR, скорее всего, будет вызываться со своим собственным пространством стека, отдельно от той, что у любой программы, с которой он связан, но это особый случай. Функции обычно используют тот же стек, что и их вызывающие, но ISR не иметь абоненты в общепринятом смысле.
Я всегда думал, что функции и ISR могут использовать столько стекового пространства стека, сколько им нужно, вплоть до полного выделенного стека. Означает ли это, что основная функция имеет большую часть стека, чем другие [?]
ISR может использовать сколько угодно стекового пространства, предоставленного ему. Это пространство часто отделено от основного стека ассоциированной программы, что может быть полезно для предотвращения вмешательства в состояние основной программы, когда запускается ISR, и важно, когда ISR является асинхронным. В отдельности стек ISR часто намного меньше.
Размер (основного) стека процесса зависит от системы, а иногда и от исполняемого файла; оно поделено между main
и все функции, вызываемые прямо или косвенно из main
, В однопоточных программах main
делает иметь доступ к большему количеству стеков, чем любая другая функция f
, но основная причина этого main
и (как правило) каждая функция в цепочке вызовов от main
в f
занимает место в стеке, которое f
не можете использовать.
Мне было интересно, почему возникла бы проблема с пространством стека, если в ISR написано больше кода, чем в основной функции.
Пространство стека, вероятно, не является главной задачей для ISR. ISR должен быть максимально простым и быстрым, чтобы минимизировать задержку, поэтому он не должен необходимость большой стек в любом случае. Если вам нужно выполнить какую-либо нетривиальную обработку, ваш ISR должен поставить в очередь задачу для запуска в обычном потоке позже, чтобы завершить работу (иногда называемую верхней половиной и нижней половиной). Этого можно добиться с помощью условной переменной, семафора или очереди сообщений (чтобы назвать несколько механизмов IPC). Поэтому, если ISR использует много стека, это может указывать на то, что он пытается выполнить слишком много обработки в течение периода планирования, критичного по времени.
Кроме того, многие системы (например, RTOS) требуют, чтобы вы объявляли размер стека для потоков и ISR.
Я хочу вызвать несколько различных функций из обратного вызова. Если этот обратный вызов фактически вызывается из ISR, вызывает ли проблема вызов большего количества функций из ISR?
Только в том случае, если вызов других функций из ISR должен быть сведен к минимуму, как обсуждалось выше. Вы Можно вызывать другие функции, но вы должен отложить как можно больше бежать после ISR возвратился к планировщику ядра (и не маскирует прерывания!).
Также — остерегайтесь гоночных условий! Осторожное использование мьютексов необходимо для защиты общего состояния.
Позволит ли мне при вызове каждой функции дополнительное пространство в стеке, поскольку каждая функция имеет свой максимальный размер стека? Это меня немного смущает.
Нет — у функции нет собственного размера стека, как у потоков. Для ISR это зависит от ОС. Вызов каждой функции потреблять хотя больше места в стеке (в зависимости от уровня вложенности вызовов).
Я всегда думал, что функции и ISR могут использовать столько стекового пространства стека, сколько им нужно, вплоть до полного выделенного стека.
Да, но стек для каждого потока, а не для процесса, как куча. Использование большого количества стекового пространства может быть признаком проблемы проектирования: выделение больших объектов в стеке, а не в куче, слишком много вызовов вложенных функций и т. Д.
Означает ли это, что основная функция имеет большую часть стека, чем другие.
Нет, так как стек нить. main
Функция будет в нижней части стека вызовов приложения, но может потреблять небольшой или большой объем стека, в зависимости только от своих локальных переменных.
Некоторое хорошее чтение:
Честно говоря, я бы не стал доверять «другому форуму».
Документация ничего не говорит об использовании слишком много пространство стека. Это говорит о слишком много код, и в контексте обратных вызовов ISR это означает тратить слишком много время в ISR.
ISR (включая обратные вызовы) выполняется с заблокированными прерываниями. Теперь прерывания не накапливаются; контроллер может только сказать, что прерывание находится на рассмотрении. Если выполнение ISR занимает слишком много времени, прерывания, возникшие во время его выполнения, теряются.
Пространство стеков также может быть проблемой, но, прежде всего, сделайте ваш обратный вызов быстрым.