ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Среда
24 апреля
541726 Топик полностью
dimonomid (24.08.2014 18:52 - 29.08.2014 00:26, просмотров: 169) ответил Alex B. на «Ну так отсчеты отправляются в очередь сообщений, ISR тут же завершается» – плюс накладные расходы на переключение контекста. Лучше – копить отсчеты в буфер и поднимать задачу, когда буфер заполнился (2 буфера пинг-понгом или один наполовину).
"Если нужно быстро реагировать на численное значение одного отсчета – делать это в прерывании." - может, так и придется сделать. В другом режиме прибора, где не нужно быстро реагировать, так и сделано (прерывание 1 раз в 8 измерений; пока обрабатываем 8 значений, АЦП пишет следующую половину буфера). Но тут нужно быстро реагировать, поэтому сделал прерывание на каждый сэмпл. Анализ значений в прерывании, отдельно от основного кода - выглядит как костыль, но, возможно, так и придется поступить (хотя, пока что очередь сообщений не переполняется, так что успеваю)
Дык у тебя почти рекурсия получилась, чего ж ты хотел. Задача еще не начала обработку одного прерывания а уже возникло другое.
Ну неет, task_adc уже завершила обработку прерывания, и вот когда переключались на другую задачу, именно тогда случается новое прерывание, и еще больше поднимает стек. Конечно, оверхед на переключение контекста неоправданно большой в данном случае, так что, может, действительно сделаю частичный анализ значения в прерывании. Если бы была "почти рекурсия", то я, запретив прерывания на всю работу tn_switch_context, получал бы постоянные ошибки о переполнении очереди (когда прерывание отправляет в очередь новый результат измерений, а задача не успевает их обрабатывать). Но нет - все успевается. UPD: разобрался: успевается т.к. обычно задача завершает работу быстро, но иногда (когда вследствие сигнала состояние меняется) работает долго, и именно в эти моменты происходит это многократное сохранение стека.
по сути эту «проблему» ты увидишь в любой вытесняющей оси
Ну вот если сохранять стек прерываний отдельно - нет такой проблемы, по определению. Так что не "в любой вытесняющей оси". Все-таки это как-то неочевидно, что контекст может быть сохранен в стек несколько раз, неважно как это может происходить. Когда прикидываешь, сколько стека выделить под задачу, то учитываешь что тебе нужно место под контекст (сохраненный один раз), и все остальное - собственно под нужды конкретной задачи. Может я не прав, но я считаю, что в процессе сохранения/восстановления контекста нельзя позоволять прерываниям сохранять контекст еще раз. Можно позволить выполняться т.н. несистемным прерываниям, для этого нужно реализовать tn_switch_contex как core software interrupt. Это вот в моем случае получалось, что контекст сохранялся много раз, и я это заметил; но даже в любом другом проекте может получиться, что прерывание произойдет вот именно тогда, когда контекст восстанавливался, и отожрет еще лишние 136 байт стека. Да, пусть это произойдет только один раз, а не как у меня, но все равно контекст уже сохранен дважды, и то, что это возможно - плохо. Если прерывание случается нечасто, то и проблема эта (с внезапным увеличением стека на 136 байт) будет происходить редко. Прикинь отлаживать такой баг - жопа =( Может это я такой ламир, но для меня вот было неочевидно, что в нормальном режиме работы ОС контекст может быть сохранен в стек два раза. Да, наверное все-таки это я такой ламир. Буду знать теперь, что когда планируем стек под задачу, нужно выделять место под ДВА контекста, а не под один. Но подход с отдельным стеком для прерываний мне все-таки больше нравится :) см. ниже.
ХЗ, интуитивно. Не прозрачно, не понятно, как профилировать.
Хмм.. Пока не особо понял я твои аргументы. По-моему, единственный минус отдельного стека - если нужно переключить задачу после выполнения ISR, то это будет работать медленнее, т.к. сначала нужно восстановить контекст из стека прерываний, и уже потом сохранить его в стек задачи и переключиться на другую задачу. Но зато реальная экономия RAM. Плюс, когда происходит прерывание, то не обязательно сохранять регистры s0..s9, т.к. компилятор по-любому сохраняет их сам. Так что сохранение контекста перед вызовом ISR - быстрее, чем сохранение контекста перед для переключения задачи.
Наоборот, я организовал код так, что переносить стало гораздо проще. Гемор с поддержкой оригинальных апдейтов, но только последний апдейт был год назад и ничего не предвещает новых.
Это да, но люди же портируют оригинальный код, а не этот. Захотел я перейти на порт andersm - гемор. :) Не спорю, ты организовал код лучше чем он был, риальни. То, что можно выделить ОС как либу - супер (порт от andersm нельзя в текущем виде, он должен быть собран в составе проекта).