Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Высшая степень вложенности Real/Soft FIQ/IRQ
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Страницы: 1, 2
GetSmart
Посвящается zltigo и прочим противникам вложенности прерываний smile.gif

Только что закончил прикручивать звук в и без того сложный проект под FreeRTOS на LPC2368. Звук - это воспроизведение WAV с MicroSD карточки. Работа с SD сделана на основе исходников ffsample.zip (elm-chan.org).

1. Вложенные FIQ
Звук (вывод в DAC) пришлось весить на FIQ для того, чтобы он не тормозился программой и осью. Но на FIQ уже висело АЦП и переносить его на IRQ было нельзя. Сначала поставил в начале обработчика проверку откуда источник FIQ и развилку на два обработчика. Всё вроде работало. Но при воспроизведении синуса 48000 Гц на осциллографе (да и в динамике) были искажения из-за того, что проц долго находился в FIQ от АЦП. Пришлось исхитряться и делать вложенные FIQ, работающие в режиме и на стеке Undefined Instruction. Работать в режиме FIQ и отрабатывать другие FIQ нельзя (по крайней мере в известных мне компиляторах), т.к. компиляторы используют регистр LR для своих целей. А обработчик FIQ для АЦП у меня имеет очень сложный алгоритм и переписывать его на асм желания не было. Только пролог и эпилог на асме. Вот если бы была опция (атрибут функции), которая запрещала использовать LR внутри функции, то это было бы реально. На асме (асм-обработчике) такое сделать вообще без проблем.

2. Вложенные Software IRQ
Звук в FIQе выводится из двух буферов по 256 байт. Пока один буфер выводится, второй должен успеть обновить данные из SD карточки. Для заполнения этого буфера было выбрано прерывание IRQ со средним приоритетом, вызываемое софтовым способом. То есть как только внутри FIQ произошёл вывод последнего сэмпла из буфера то сразу же записывается (не OR-ится!) бит в VICSoftInt. Далее уровень FIQов продолжает работать с максимальной латентностью не замечая что происходит на более низких уровнях (IRQ,System и прочие). Если на выходе из FIQ есть приоритетные IRQ, то они отрабатываются. Если их нет, то срабатывает софтовое IRQ для подгрузки данных. В начале софтового обработчика сбрасывается флаг софтового прерывания через VICSoftIntClear (не AND-ится!) и происходит переключение в режим и на стек Undefined. То есть я сделал так, что все вложенные прерывания (FIQ & IRQ) работают в режиме и на стеке Undefined Instruction, чтобы они не потребляли "без спросу" стек тредов. Вобщем внутри этого обработчика происходила подгрузка данных и установка флага готовности данных. Затем переключение обратно в IRQ, восстановление регистров, SPSR и окончательный выход в тред или на ещё менее приоритетное прерывание.

Тред при этом, отвечающий за воспроизведение WAV, почти ничего не делает, только запускает воспроизведение и ждёт окончания, вызывая delay(). Всё остальное происходит "автоматически". А софтовое IRQ обеспечивает максимальную латентность подгрузки новых данных.

LPC2368 @ 24MHz легко справляется с воспроизведением 56000 Гц звука в реальном времени из файла на MicroSD без каких-либо глюков. Глюки появляются на 64000. Но и это не предел, если доработать Ченовский исходник так, чтобы там не было лишнего копирования, то 64000 без проблем. Если ещё убрать конвертацию WAV данных при воспроизведении и копировать (через DMA) прямо в буфер, использующийся в FIQ, то и думаю 80000 реально достичь. И это при том, что модуль воспроизведения WAV использует только 1 КБ данных (буферА) в раме плюс стек Undef. Без вложенности таких параметров никогда не достичь. Если поллить флаг подгрузки данных из треда, то он отъест слишком много времени проца, будет иметь самый высокий приоритет и от силы будет поспевать подгружать данные для звука в 10000 Гц. А садить подгрузку данных в невложенное IRQ тоже не выход, т.к. прога там достаточно долго сидит, и множество других, более приоритетных прерываний "заткнутся" и работа девайса нарушится.

Программа в нормальном режиме почти постоянно переключается между пятью режимами ARM-ядра (System, Supervizor, IRQ, FIQ, Undefined) и прекрасно себя чувствует smile.gif

На картинке - воспроизведение синуса со вложенными FIQ, на нижней - с обычными FIQ. Вместе с FIQ от АЦП.


Пример пролога/эпилога Nested Software IRQ для CW 1.7
Код
static    void WavIntr_Wrapper() __attribute__((naked));
    void WavIntr();            // без static - для стандартной передачи параметров (меньшего сохранения регистров извне)

// софтверное прерывание (VICSoft...), работает в режиме и на стеке Undefined Instruction
static void WavIntr_Wrapper()
{
    asm(  "STMDB    SP!,{R12,LR}        \n\t"        // 8 байт на стеке IRQ, плюс xx байт на стеке Undefined
            "MVN      LR,#~0xFFFFFF00        \n\t"
            "MOV      R12,#" STRINGFY(1 << RES1_INT) "\n\t"
            "STR      R12,[LR,#0xFFFFF01C-0xFFFFFF00] \n\t"    // VICSoftIntClear = (1 << RES1_INT);
            "MRS      R12,SPSR        \n\t"
            "MSR      CPSR_c,#0x1b        \n\t"        // Undef_Mode + Enable IRQ + Enable FIQ
            "STMDB    SP!,{R0-R3,R12,LR}    \n\t");

    WavIntr();            // должна объявляться глобально, без static

    asm(  "LDMIA    SP!,{R0-R3,R12,LR}    \n\t"
            "MSR      CPSR_c,#0x92        \n\t"        // IRQ_Mode + Disable IRQ + Enable FIQ
            "MSR      SPSR_all,R12        \n\t"
            "MVN      LR,#~0xFFFFFF00        \n\t"
//          "MOV      R12,#" STRINGFY(1 << RES1_INT) "\n\t"
//          "STR      R12,[LR,#0xFFFFF01C-0xFFFFFF00] \n\t"    // VICSoftIntClear = (1 << RES1_INT);
            "STR      LR,[LR]            \n\t"        // VICAddress = xx; (сброс приоритетов IRQ)
            "LDMIA    SP!,{R12,LR}        \n\t"
            "SUBS     PC,LR,#4        \n\t");
}


Ещё родилась идея вместо Undef использовать и работать на Supervizor-е. Для этого надо бы внимательно изучить порт LPC2300 FreeRTOS.

Прошу высказываться. Критика приветствуется. Готов услышать про недостатки, хотя сам пока ни одного не нашёл smile.gif
_Pasha
Цитата(GetSmart @ Nov 13 2009, 10:14) *
Звук (вывод в DAC) пришлось весить на FIQ

Если вывод по I2S, то почему не используете GPDMA? Или ЦАП не стандартный?
GetSmart
Цитата(_Pasha @ Nov 13 2009, 13:26) *
Если вывод по I2S, то почему не используете GPDMA? Или ЦАП не стандартный?

Вывод конкретно в DAC (периферия проца), а не в I2S. GPDMA не работает с DAC.
GetSmart
Взято из другой темы
Цитата(KRS @ Oct 27 2009, 03:48) *
А кто нибудь посчитал расходы на вложенные прерывания - именно для ARM7 ? IMHO если убрать весь этот оверхед - окажется что вложенных прерываний и не надо wink.gif.
Если уж обработчик такой тяжелый что жрет много времени - не проще ли перекинуть большую его часть на обычный уровень!
А для совсем критических вещей есть же FIQ - два уровня IRQ, FIQ вполне достаточно.

Информирую, оверхед не просто нулевой, а отрицательный! smile.gif Не просто нет ничего лишнего, а наоборот одна только экономия от правильного применения вложенности.

Ещё из другой темы
Цитата(zltigo @ Oct 26 2009, 18:35) *
Цитата(GetSmart @ Oct 26 2009, 18:23) *
Вложенные прерывания - гениальная весчь в умелых руках. Не надо ля-ля smile.gif
А вложенные софтовые прерывания - вообще наше всё!

Нет sad.gif В 99% тяжелая кувалда используемая неумелыми руками во исполнение принципа "а чего-тут думать - трясти вкладывать надо"

cool.gif

------------
Маленькая поправка первого поста. Синуса 48000 ==> следует читать Синуса 750 Гц при сэмплировании (FIQом) 48000.
zltigo
Цитата(GetSmart @ Nov 13 2009, 10:14) *
...было нельзя.
...А обработчик FIQ для АЦП у меня имеет очень сложный алгоритм и переписывать...

Обычное дело, сначала в виде аргументов постулаты "было нельзя" и абстрактно написанные "сложные алгоритмы". Потом конечно берем кувалду и начинаем выкручиваться из ситуации куда сами и залезли. Обычное дело sad.gif. Подходим к делу не удивили.
И вообще в описанном Вами случае собственно вложенности-то и нет - есть очевидная разбивка ранее не продуманного обработчика прерывания на собственно обработчик прерывания и псевдопроцесс продолжения обработки. Собственно чем и доказали, что без вложенные обработчики без надобности, если думать системно - поздравляю!
VslavX
Цитата(GetSmart @ Nov 13 2009, 09:33) *
Вывод конкретно в DAC (периферия проца), а не в I2S. GPDMA не работает с DAC.

Хм, мне не очень понятно зачем выводить 48кГц на 10-битный линейный DAC, да еще и моно. Обычно два класса звуковых приложений - или хотя бы минимальные стерео 48кГц/16 бит - типа простейших плееров, или уже моно 8кГц 8 бит - типа диспетчерских матюгальников/телефонной связи. Ну придумать применение моно/48кГц/10 бит конечно можно, но "ни рыба, ни мясо", ИМХО. Поставили бы уже дешевый I2S кодек, отдавали бы по GPDMA и никаких мучений.

Цитата(GetSmart @ Nov 13 2009, 09:33) *
А обработчик FIQ для АЦП у меня имеет очень сложный алгоритм

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

Как мне видится решение Вашей задачи - выносится АЦП в приоритетный поток, а ЦАП - на прерывания, раз уж очень хочется и нету нормальной аппаратуры. А так как сделано сейчас - тут я согласен с zltigo - сами поставили себя в нечеловеческие условия, выкрутились и радуетесь. Замечательно, но потраченным усилиям можно только удивиться.

В-общем, я не против вложенных прерываний, все мои порты используемой TN-Kernel их поддерживают. Но, мое мнение - если уж понадобились вложенные прерывания, то в консерватории что-то не так - где-то "главный консерватор" провтыкал.
defunct
Цитата
А обработчик FIQ для АЦП у меня имеет очень сложный алгоритм

В новых LPC по прежнему нет DMA для АЦП?!
GetSmart
Цитата(zltigo @ Nov 13 2009, 17:52) *
Обычное дело, сначала в виде аргументов постулаты "было нельзя" и абстрактно написанные "сложные алгоритмы". Потом конечно берем кувалду и начинаем выкручиваться из ситуации куда сами и залезли. Обычное дело sad.gif. Подходим к делу не удивили.
И вообще в описанном Вами случае собственно вложенности-то и нет - есть очевидная разбивка ранее не продуманного обработчика прерывания на собственно обработчик прерывания и псевдопроцесс продолжения обработки. Собственно чем и доказали, что без вложенные обработчики без надобности, если думать системно - поздравляю!

Поражаюсь чьей-то глупости необъективности.
А теперь пожалуйста конкретней - что значит "ранее не продуманного обработчика" ?
Заранее предупреждаю. Разделение алгоритма на IRQ/FIQ/треды проектировал лично я. Могу обосновать каждую песчинку алгоритма. С Вашей стороны пока вижу только пространственные сравнения и никакой конкретики. Если я пишу "было нельзя" значит было нельзя весить на IRQ. IRQ внутри FreeRTOS не обеспечивает необходимой латентности для оцифровки нужных сигналов. Причём тут постулаты? Ни откуда я не "выкручивался". Может я не знаю более "гениального" решения? Подскажите. Посмотрим.

Цитата(VslavX @ Nov 13 2009, 18:21) *
Хм, мне не очень понятно зачем выводить 48кГц на 10-битный линейный DAC, да еще и моно. Обычно два класса звуковых приложений - или хотя бы минимальные стерео 48кГц/16 бит - типа простейших плееров, или уже моно 8кГц 8 бит - типа диспетчерских матюгальников/телефонной связи. Ну придумать применение моно/48кГц/10 бит конечно можно, но "ни рыба, ни мясо", ИМХО. Поставили бы уже дешевый I2S кодек, отдавали бы по GPDMA и никаких мучений.

48 КГц моно для качественного воспроизведения звуковых файлов на одном динамике. 8кГц 8 бит - ховно и прошлый век. Принудительно делать 8кГц 8 бит в системе, которая способна воспроизводить 48 КГц удел слабаков.
defunct
Цитата(GetSmart @ Nov 13 2009, 19:10) *
Разделение алгоритма на IRQ/FIQ/треды проектировал лично я. Могу обосновать каждую песчинку алгоритма.

Обоснуйте необходимость вешать обработчик ADC на FIQ.
GetSmart
Цитата(VslavX @ Nov 13 2009, 18:21) *
Наверное, так тоже можно делать. Но я уже пару лет при наличии ОС с приоритизацией потоков так не делаю - все сложные алгоритмы выносятся "на раз" в приоритетную задачу и там колбасятся. Сложный - значит долгий, если делать его в прерывании - то будет влияние на реал-тайм. Что Вы успешно и доказали - раз Вам понадобились вложенные прерывания.

Сложный, не значит долгий. Сложный - это сложный, долгий - это долгий. Если посмотрите на осциллограмму, то увидите, что в FIQ АЦП прога висит по-разному, но максимум 40 мкс. Это не много для прерываний вообще, но много для FIQ DAC, что явилось объективной причиной для реализации вложенности. Переносить алгоритм в тред = затормозить его (алгоритм) или проц (все другие алгоритмы) на порядок. Либо отнять ещё лишнюю память для буферов, увеличить размер кода и прочее. В моей реализации процессор не делает ничего лишнего, чего не надо делать. Это как два варианта - 1. в нужный момент вызвать софтовое прерывание и 2. в треде максимального приоритета тупо поллить флаг, ожидая когда же он установится, тратя напрасно процессорное время.

Цитата(defunct @ Nov 13 2009, 23:12) *
Обоснуйте необходимость вешать обработчик ADC на FIQ.

Чтобы переключения контекстов FreeRTOS и критические секции не вызывали пауз в оцифровке сигналов (а там 14 каналов) и по возможности иметь минимально возможный джиттер.
defunct
Цитата(GetSmart @ Nov 13 2009, 19:25) *
Чтобы переключения контекстов FreeRTOS и критические секции не вызывали пауз в оцифровке сигналов (а там 14 каналов) и по возможности иметь минимально возможный джиттер.

Т.е. DMA для ADC в LPC23xx нет. Тогда обоснуйте выбор камня.
SAM7 с DMA для ADC полностью избавил бы Вас от джиттера, и от необходимости работы с железом ADC после инициализации вообще, сделал бы возможным обрабатывать данные с АЦП в самой низкоприоритетной задаче вашего RTOS'а.
GetSmart
Цитата(VslavX @ Nov 13 2009, 18:21) *
Как мне видится решение Вашей задачи - выносится АЦП в приоритетный поток, а ЦАП - на прерывания, раз уж очень хочется и нету нормальной аппаратуры. А так как сделано сейчас - тут я согласен с zltigo - сами поставили себя в нечеловеческие условия, выкрутились и радуетесь. Замечательно, но потраченным усилиям можно только удивиться.

Зачем мне заведомо проигрышное по производительности и ресурсоёмкости решение? Никак не могу понять, где здесь нечеловеческие условия? Вроде всё обыденно. Я с подобными задачами (требованиями) встречаюсь постоянно и очень редко приходится говорить кому-то, что это на данном девайсе сделать невозможно. Плохому танцору мешают только яйца biggrin.gif
И усилий было потрачено меньше, чем получено кайфа от работы и от осознания красоты и эффективности решения.
Все вышеотписавшиеся живут во власти предрассудков по поводу вложенности. И что бы не случилось, всеми способами пытаются заменить наиболее производительное решение на менее производительное только потому, что не понимают всех хитростей ядра для высокоэффективной организации вложенных прерываний.

Цитата(defunct @ Nov 13 2009, 23:37) *
Т.е. DMA для ADC в LPC23xx нет. Тогда обоснуйте выбор камня.

А кто сказал, что я девайс разрабатывал? Я разрабатывал только программу для готового девайса.
Только не делайте поспешного заявления о том, что девайс проектировал дилетант. Дело совсем не в девайсе. Дело в том, что реальный профессионал способен выжать из любого девайса 200% эффективности, тогда как пытающиеся выглядеть профессионалами будут выдавать работодателю заумные объяснения почему что-то там сделать нельзя. Вот здесь вот кодека не хватает. А любимый ход конём - а у вас процессор не той системы biggrin.gif
defunct
Цитата(GetSmart @ Nov 13 2009, 19:39) *
Зачем мне заведомо проигрышное по производительности и ресурсоёмкости решение? Никак не могу понять,

А с чего вы взяли что оно по производительности более проигрышное и ресурсоемкое?
У меня к примеру на SAM7X (частота меньше, нет LPCшного MAM - отсюда thumb код, нет peripheral FIFO как в LPC у всего кроме EMAC ) делается тоже что и у вас только вывод 44.1kHz не моно, а стерео (DAC на PWM)... АЦП шлепает себе с нулевым джиттером на 44.1ksps на канал, по данным с АЦП считается fft в реалтайм, накладываются фильтры... Есть еще ethernet и fs... ну и там 232-й, 485-й, часики и прочая мелочь.
~50% ресурсов проца свободно, вложенными прерываниями там и не пахнет.
GetSmart
Цитата(defunct @ Nov 14 2009, 00:00) *
А с чего вы взяли что оно по производительности более проигрышное и ресурсоемкое?

Потому, что в LPC23xx АЦП не подключён к DMA. И реализовать свой алгоритм вы не сможете. И аргумент ваш мимо кассы. Моя оценка была не вашему алгоритму/девайсу, а предложенному VslavX. Если сделать именно так, как он указал на LPC2368, то будет именно так, как я оценил. Поэтому приводить алгоритм, реализованный на другом камне в той ситуации, в которой я работаю не вижу разумного смысла.

Цитата(defunct @ Nov 14 2009, 00:00) *
АЦП шлепает себе с нулевым джиттером на 44.1ksps на канал

Сколько там возможно разных каналов от АЦП скидывать в DMA? У меня снаружи проца стоит ещё мультиплексор. Внутри FIQа приходится ещё менять адрес на нём.
VslavX
Цитата(GetSmart @ Nov 13 2009, 19:46) *
Все вышеотписавшиеся живут во власти предрассудков по поводу вложенности. И что бы не случилось, всеми способами пытаются заменить наиболее производительное решение на менее производительное только потому, что не понимают всех хитростей ядра для высокоэффективной организации вложенных прерываний.

Сильное заявление. После него даже и отвечать как-то неудобно...
GetSmart
Цитата(VslavX @ Nov 14 2009, 00:27) *
Сильное заявление. После него даже и отвечать как-то неудобно...

Оно необъективно ровно настолько же, насколько и чужие заявления. Если есть желание их пересмотреть или обсудить более конкретно и объективно, то возможно, что я заберу свои слова обратно.
defunct
Цитата(GetSmart @ Nov 13 2009, 20:19) *
Сколько там возможно разных каналов от АЦП скидывать в DMA? У меня снаружи проца стоит ещё мультиплексор. Внутри FIQа приходится ещё менять адрес на нём.

Все имеющиеся, а имеется 8. DMA поочереди читает данные с enabled каналов.
GetSmart
Цитата(defunct @ Nov 14 2009, 00:34) *
Все имеющиеся, а имеется 8. DMA поочереди читает данные с enabled каналов.

Отлично. Даже SAM ситуацию не спасёт. Остаётся единственно правильное решение biggrin.gif
defunct
Цитата(GetSmart @ Nov 13 2009, 20:38) *
Отлично. Даже SAM ситуацию не спасёт. Остаётся единственно правильное решение biggrin.gif
"Ну помогай Вам Бох" © Никифоровна smile.gif
Мультиплексор внешний поставили, а счетчик внешний для автоматической смены адреса по пульсу таймера который тактирует АЦП слабо поставить?
zltigo
Цитата(GetSmart @ Nov 13 2009, 20:10) *
Поражаюсь чьей-то глупости необъективности.

Это я произнесено, как я понимаю, исключительно по той причине, что на, повторяю:
Цитата
....в описанном Вами случае собственно вложенности-то и нет - есть очевидная разбивка (skip) обработчика прерывания на собственно обработчик прерывания и псевдопроцесс продолжения обработки.

ответить-то по существу и нечего.
GetSmart
Цитата(defunct @ Nov 14 2009, 00:46) *
Мультиплексор внешний поставили, а счетчик внешний для автоматической смены адреса по пульсу таймера который тактирует АЦП слабо поставить?

smile.gif Не поверите, но у каналов есть ещё приоритеты опроса и они опрашиваются совсем не по порядку. Для них я "собственноручно" придумал рулезный алгоритм опроса с заданием приоритетов, который опрашивает каналы так, что частота их опроса стабильна во времени, то есть алгоритм не добавляет джиттера.
singlskv
Решения с вложенными прерываниями имеют право на жисть, и Ваше не такое уж и плохое,
но ИМХО, оно применено в условиях когда и без него можно обойтись.
Вложенность нужна когда прерывания идут очень неравномерно, т.е. бывают ситуации что идет много
одновременно от разных источников и главное успеть зарегестрировать все(т.е. не пропустить ни одного),
ну и еще довольно быстро минимально реагировать.
У Вас же оба прерывания АЦП и ЦАП вполне себе переодичны.
Значит главное обеспечить маленький джитер вывода в ЦАП при работующем FIQ АЦП
Цитата(GetSmart @ Nov 13 2009, 20:25) *
Сложный, не значит долгий. Сложный - это сложный, долгий - это долгий. Если посмотрите на осциллограмму, то увидите, что в FIQ АЦП прога висит по-разному, но максимум 40 мкс. Это не много для прерываний вообще, но много для FIQ DAC, что явилось объективной причиной для реализации вложенности.

Ну вот просто вставьте в FIQ АЦП пару раз проверку на то не пора ли обслужить ЦАП,
и обслужите его не отходя от кассы.
И джитер можно сделать необходимо малым.
GetSmart
Цитата(zltigo @ Nov 13 2009, 17:52) *
...на собственно обработчик прерывания и псевдопроцесс продолжения обработки

Я извиняюсь, но что такое "псевдопроцесс продолжения обработки" ?
Нельзя ли то же самое, но сформулировать конкретней?
zltigo
Цитата(GetSmart @ Nov 13 2009, 21:55) *
Нельзя ли то же самое, но сформулировать конкретней?

Можно. Уберите приставку 'псевдо'. Останется процесс обработки. Все в терминах операционных систем. Вы просто организовали процесс НЕ средствами операционной системы, по этой причине я и назвал его 'псевдопроцесс'. Но суть осталась - вложенного прерывания нет - произведена оптимизация обработчика FIQ прерывания и часть его вынесена из этого обработчика. Так и надо строить системы БЕЗ вложенных прерываний.
GetSmart
Цитата(singlskv @ Nov 14 2009, 00:53) *
Значит главное обеспечить маленький джитер вывода в ЦАП при работующем FIQ АЦП
...
Ну вот просто вставьте в FIQ АЦП пару раз проверку на то не пора ли обслужить ЦАП,

Сейчас средний джиттер 0.3 мкс (@24 MHz). Мне что, на каждые 10 тактов внутри FIQ вставлять проверку на флаг от таймера для DAC ? А Вы в курсе, что только чтение из T0IR занимает 8 тактов плюс ещё загрузка адреса T0IR ? У меня времени просто не останется собственно для чтения АЦП и действий над оцифрованными данными. Вот! Типичный случай из-за боязни вложенности предлагать заведомо неэффективное решение smile.gif
Цитата(zltigo @ Nov 14 2009, 01:00) *
Можно. Уберите приставку 'псевдо'. Останется процесс обработки. Все в терминах операционных систем. Вы просто организовали процесс НЕ средствами операционной системы, по этой причине я и назвал его 'псевдопроцесс'. Но суть осталась - вложенного прерывания нет - произведена оптимизация обработчика FIQ прерывания и часть его вынесена из этого обработчика. Так и надо строить системы БЕЗ вложенных прерываний.

Я не понимаю альтернативу. Предложите конкретный другой вариант. Что такое умеет делать ОС применительно к моему случаю о чём я не знаю?
defunct
Цитата(GetSmart @ Nov 13 2009, 20:51) *
smile.gif Не поверите, но у каналов есть ещё приоритеты опроса и они опрашиваются совсем не по порядку.

В этом наверное есть некий скрытый глубокий смысл, который я боюсь ниасилю.

Цитата
Что такое умеет делать ОС применительно к моему случаю о чём я не знаю?

Опишите ваш случай вначале, а то получается разговор ни о чем.

Я не понимаю какое действие из трех перечисленных может занимать существенное время:
1. прочитать АЦП;
2. сменить канал;
3. записать результат в память.

Все три в купе @24Mhz должны занимать отсилы 1мкс.
Я не понимаю, что мешает семплировать АЦП на одинаковой (или хотя бы кратной) частоте с ЦАПом, тогда будем иметь одно прерывание и порядок операций:

1. Вывести данные в ЦАП;
2. прочитать АЦП;
3. сменить канал;
4. записать рез-тат в приемный буфер.
singlskv
Цитата(GetSmart @ Nov 13 2009, 22:05) *
Сейчас средний джиттер 0.3 мкс (@24 MHz). Мне что, на каждые 10 тактов внутри FIQ вставлять проверку на флаг от таймера для DAC ? А Вы в курсе, что только чтение из T0IR занимает 8 тактов плюс ещё загрузка адреса T0IR ? У меня времени просто не останется собственно для чтения АЦП и действий над оцифрованными данными.

Вероятно я не до конца понял организацию Вашей вложенности FIQ
поэтому вопрос, FIQ ЦАП может прерываться FIQ АЦП ?
defunct
Цитата(singlskv @ Nov 13 2009, 21:17) *
Вероятно я не до конца понял организацию Вашей вложенности FIQ
поэтому вопрос, FIQ ЦАП может прерываться FIQ АЦП ?

Нет, у него обработка АЦП прерывается ЦАПом.
GetSmart
Цитата(defunct @ Nov 14 2009, 01:28) *
Нет, у него обработка АЦП прерывается ЦАПом.

Именно так.

Цитата
В этом наверное есть некий скрытый глубокий смысл, который я боюсь ниасилю.

Осилите smile.gif Смысл только в увеличении пропускной частотной способности быстродействующих каналов при одинаковой загруженности проца (одинаковом кол-ве FIQs). Когда проц умеет аппаратно складывать значения из АЦП в раму, то можно смело оцифровывать все каналы по очереди. Правда есть минус - требуется буфер (два!), достаточно большой, чтобы тред успевал его выгребать. Но опять же, в девайсе нет никакого счётчика и опять (!) проц не той системы biggrin.gif Поэтому заказчик/работодатель идёт в ж..у. Или я? smile.gif

Цитата(defunct @ Nov 14 2009, 01:12) *
Я не понимаю, что мешает семплировать АЦП на одинаковой (или хотя бы кратной) частоте с ЦАПом, тогда будем иметь одно прерывание и порядок операций:

1. Вывести данные в ЦАП;
2. прочитать АЦП;
3. сменить канал;
4. записать рез-тат в приемный буфер.

Мешает заранее неизвестная частота сэмплирования в WAV файле, которая может оказаться совершенно некратной частоте сэмплирования следующего WAV файла. Во-вторых как я уже уточнил, длительнось расчётов некоторых каналов в FIQ АЦП достигает ~40 мкс. Неужели непонятно, что длительность отработки FIQ АЦП больше, чем период прерывания от ЦАП? Вашим алгоритмом можно обойти только джиттер, возникающий из-за вторичного короткого FIQа, но он бесполезен для вторичного длинного FIQа.

Цитата(defunct @ Nov 14 2009, 01:12) *
Опишите ваш случай вначале, а то получается разговор ни о чем.

Я не понимаю какое действие из трех перечисленных может занимать существенное время:
1. прочитать АЦП;
2. сменить канал;
3. записать результат в память.

Все три в купе @24Mhz должны занимать отсилы 1мкс.

Плюс пункт
4. расчёт оцифрованного быстродействующего канала для выявления искомого события. (40 мкс)

Повторюсь ещё раз. Этот расчёт нельзя переносить в тред, т.к. скорость реакции будет непредсказуемой или черезмерно большой.
singlskv
Цитата(GetSmart @ Nov 13 2009, 23:01) *
Именно так.
Понятно, то есть необходимы 3 уровня старшинства прерываний
IRQ, FIQ с разрешенным "Fast" FIQ и сам "Fast" FIQ
тогда наверное вложенные прерывания необходимы
Цитата
Плюс пункт
4. расчёт оцифрованного быстродействующего канала для выявления искомого события. (40 мкс)

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

З.Ы. Если SoftInt слишком медленно, можно и какое-нить переферийное с максимальным приоритетом взводить...
прямо из FIQ АЦП
defunct
Цитата(GetSmart @ Nov 13 2009, 22:01) *
Этот расчёт нельзя переносить в тред, т.к. скорость реакции будет непредсказуемой или черезмерно большой.

Ок, я понял у Вас нечто очень-очень специфичное требующее жесткого реал-тайма (модуль управления ядерным реактором?), на батарейном питании. Затем кому-то захотелось чтобы этот модуль (управления реактором на батарейках) научился исполнять голосовые команды, и, отвечать пользователю тоже голосом. Но денег на смену элементной базы не дали, и питать модуль от реактора которым он управляет тоже не разрешили. smile.gif
Что ж для неординарной задачи, бывает необходимо неординарное решение...
Вероятно для такой постановки задачи найденное вами решение единственно возможное. Поздравляю что Вы его нашли и успешно реализовали!

Из конструктивной критики Вашего решения могу сказать только:
вместо Undef mode определенно лучше использовать SVC (и быстрее переключение, и адекватный обработчик undef abort'а в системе останется), конфликт с ОС, которая наверняка использует SVC для своих нужд, решается подменой SWI вектора переходом на обработчик АЦП перед вызовом SWI, и его восстановлением после окончания обработки. Если треды тоже работают в SVC тогда можно и стек вручную переключить не так и накладно:

Код
туда
mov    r0, sp
ldr    sp, =const
stmia  sp!, {r0 ...}

и назад
ldmia  sp!, {r0 ...}
mov    sp, r0


а если нет, тогда вообще никаких проблем - просто увеличте SVC стек в стартапе.
GetSmart
Цитата(singlskv @ Nov 14 2009, 03:57) *
хотя с другой стороны, кто Вам мешает рассчет перенести не в тред а в SoftIRQ ?
и иметь просто FIQ с двумя короткими ветками
или так тоже будет недостаточно оперативно ?

З.Ы. Если SoftInt слишком медленно, можно и какое-нить переферийное с максимальным приоритетом взводить...
прямо из FIQ АЦП

Это можно. Можно сделать два SoftIRQ, но я в упор не вижу выгоды, вижу только увеличение джиттера FIQ. Т.к. два FIQа асинхронны. Плюс невложенные IRQ и критические секции в тредах будут добавлять лишнюю задержку входа в это SoftIRQ. Выигрыша нет, сплошные проигрыши.
GetSmart
Цитата(zltigo @ Nov 14 2009, 01:00) *
Можно. Уберите приставку 'псевдо'. Останется процесс обработки. Все в терминах операционных систем. Вы просто организовали процесс НЕ средствами операционной системы, по этой причине я и назвал его 'псевдопроцесс'. Но суть осталась - вложенного прерывания нет - произведена оптимизация обработчика FIQ прерывания и часть его вынесена из этого обработчика. Так и надо строить системы БЕЗ вложенных прерываний.

Проспался, и понял о чём речь. В FIQ ADC нужно по-быстрому скидывать данные в кольцевой (например, ну или в два обычных) буфер. И по-быстрому выходить из FIQ. Далее высокоприоритетный тред будет анализировать указатели RD + WR для буфера и обрабатывть новые поступившие данные. Хорошо. Это простой, классический, но не самый эффективный алгоритм. По сравнению с моим имеет множество недостатков и ни одного достоинства ИМХО.
Список недостатков:
1. Нет вложенности FIQ (казалось бы smile.gif бонус), из-за чего латентность FIQ DAC уменьшается, а джиттер увеличивается почти в 2 раза, т.к. нет разрешения FIQов по середине обработчика (при вложенных есть).
2. Требуется буфер в раме размером на максимально возможный интервал работы других тредов, пока управление не вернётся к треду, разгребающему буфер. Пускай даже я соглашусь на тормознутую реакцию на событие, но буфер в раме требуется немалый.
3. Кол-во вычислений над оцифрованными данными будет одинаковое, но без nested FIQ будет лишнее сохранение/ восстановление данных в буфере. Плюс очень (черезмерно?) частый анализ RD WR указателей. То есть очевидна пустая трата процессорного времени тогда, когда её можно избежать.
4. Во время воспроизведения WAV у меня тормозятся именно треды (у них может упасть производительность в 4 раза например) и не тормозится ни одного важного прерывания, вот в чём фишка! А если тормозятся треды, то и тот приоритетный тред, который разгребает данные от АЦП тоже затормозится и либо потеряет данные, либо буфер ему потребуется в 4 раза больший.

Три конкретных минуса и ни одного плюса. Если я что-то не учёл, пожалуйста поправьте.

Цитата(defunct @ Nov 14 2009, 05:28) *
Ок, я понял у Вас нечто очень-очень специфичное требующее жесткого реал-тайма (модуль управления ядерным реактором?), на батарейном питании. Затем кому-то захотелось чтобы этот модуль (управления реактором на батарейках) научился исполнять голосовые команды, и, отвечать пользователю тоже голосом. Но денег на смену элементной базы не дали, и питать модуль от реактора которым он управляет тоже не разрешили. smile.gif

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

А теперь я расскажу историю до вчерашнего дня. Есть заказчик. У него был девайс, который что-то заложенное в нём умел делать. Появился я, и первым делом поднял производительность АЦП в 3..5 раз, плюс стабильность частоты и джиттера и прочие бонусы. Затем возник вопрос - а можно ли ещё сделать это... И когда я сделал в параллель ко всему, что девайс умеет ещё и качественное воспроизведение WAV абсолютно не задев тайм-критичные характеристики пробора, то у заказчика просто челюсть отпала. Как я уже указывал, воспроизведение WAV тормозит только треды, и ни одного важного прерывания или события. И всё это требует рамы меньше, чем в любом другом варианте реализации алгоритма. И соответственно выдаёт больше производительности в каких-нибуть у.е. вычислений (например допустимая частота сигналов АЦП) по сравнению с другим вариантом реализации при одинаковой тактовой процессора.
zltigo
Цитата
Далее высокоприоритетный тред будет

Это может быть и не задача операционной системы, а вернемся к приставке 'псевдо' задача - тот-же софтово взводимый обработчик IRQ с наивысшим приоритетом или любой другой exception. Что примерно Вы и сделали, только утверждаете, что это назывется "вложенные FIQ" smile.gif
Цитата(GetSmart @ Nov 14 2009, 11:48) *
А теперь я расскажу историю до вчерашнего дня....

О чем я все время и говорю - вложенные прерывания в абсолютно подавляющеи большинстве случаев есть заплатка для плохо спроектированных систем. При этом причины по которым система спроектированы плохо значения не имеют. Причем проектирование системы и большинство системных проблем начинается с постановки задачи. В Вашем случае заказчик принес откуда-то какую-то железку и захотел всего больше в разы. И Вы это сделали ВСЕМИ ДОСТУПНЫМИ СРЕДСТВАМИ.
GetSmart
Цитата(zltigo @ Nov 14 2009, 15:55) *
Это может быть и не задача операционной системы, а вернемся к приставке 'псевдо' задача - тот-же софтово взводимый обработчик IRQ с наивысшим приоритетом или любой другой exception.

Любой другой exception не вызывается из FIQ, не говорите глупостей. Если же вызовется, то в нём все FIQи будут запрещены. По поводу софтового варианта уже ответил singlskv, что вариант однозначно хуже вложенных FIQ. Если Вы так не считаете, то укажите конкретные недостатки моего варианта (nested FIQ) и достоинства SoftIRQ применительно к моей проге.

Цитата(zltigo @ Nov 14 2009, 15:55) *
Что примерно Вы и сделали, только утверждаете, что это назывется "вложенные FIQ" smile.gif

Опять 25. Как это ещё назвать, если обёртка обработчика на 100% аналогична вложенным IRQ (за искл. разрешения FIQ, а не IRQ) ?

Вот кастрированная обёртка:
Код
#define NESTED_FIQ

void AdcIntr_Wrapper()
{
    asm("MOV    R8,#0xe0000000        \n\t"        // 0xE0070000 = T2IR
        "ORR    R8,#0x00070000        \n\t"
        "LDR    R9,[R8, #0]           \n\t"
        "ANDS   R9,R9,#0xff           \n\t"
        "BEQ    adc9                  \n\t"
        "STR    R9,[R8, #0]           \n\t"        // сбрасываю все флаги в T2IR
.... Вывод в DAC
        "SUBS   PC,LR,#4              \n\t"

#ifdef NESTED_FIQ
   "adc9:STMDB  SP!,{R0,LR}           \n\t"
        "MVN    LR,#~0xFFFFFF00       \n\t"
        "MOV    R0,#" STRINGFY(1 << ADC0_INT) "\n\t"
        "STR    R0,[LR,#0xFFFFF014-0xFFFFFF00] \n\t"    // VICIntEnClr = (1 << ADC0_INT);
        "MRS    R0,SPSR               \n\t"
        "MSR    CPSR_c,#0x9b          \n\t"        // Undef_Mode + Disable IRQ + Enable FIQ
        "STMDB  SP!,{R0-R3,R12,LR}    \n\t");
#else
   "adc9:STMDB  SP!,{R0-R3,LR}        \n\t");
#endif

    AdcIntr();            // должна объявляться глобально, без static

#ifdef NESTED_FIQ
    asm("LDMIA  SP!,{R0-R3,R12,LR}    \n\t"
        "MSR    CPSR_c,#0xD1          \n\t"        // FIQ_Mode + Disable IRQ + Disable FIQ
        "MSR    SPSR_all,R0           \n\t"
        "MVN    LR,#~0xFFFFFF00       \n\t"
        "MOV    R0,#" STRINGFY(1 << ADC0_INT) "\n\t"
        "STR    R0,[LR,#0xFFFFF010-0xFFFFFF00] \n\t"    // VICIntEnable = (1 << ADC0_INT);
        "LDMIA  SP!,{R0,LR}           \n\t"
        "SUBS   PC,LR,#4              \n\t");
#else
    asm("LDMIA  SP!,{R0-R3,LR}        \n\t"        // эпиолог для FIQ
        "SUBS   PC,LR,#4              \n\t");
#endif
}


Я одну вещь понять не могу. Изначально я хотел чтобы вложенный FIQ работал на стеке IRQ с запрещёнными IRQ. Насколько я знаю архитектуру ARMа, так можно. Единственное ограничение - не влетать в текущий режим если в обработчике используется LR (когда прога на Си). Прямо в этой обёртке (при заходе во вложенный FIQ) меняю режим с 0x9b (Undef) на 0x92 (IRQ) и где-то (пока непонятно где) улетаю в Data Abort. То есть первый уровень вне аборта я вижу - в макросе portSAVE_CONTEXT(), а дальше пока не отследил. Теряюсь в догадках - почему?
zltigo
Цитата(GetSmart @ Nov 15 2009, 16:10) *
Любой другой exception не вызывается из FIQ, не говорите глупостей.

Где Вы у меня видели "из"? Я писал "после". После КОРОТКОГО обработчика FIQ, если надо продолжить что-то делать без привлечения задачи операционной системы и без затрат времени на переключения контекста операционной системой.
Цитата
применительно к моей проге.

Пока Вы пытаетесь свести обсуждение к ограниченному кусочку неведомой "моей проги", Вы можете называть любые "преимущества".
Я давным-давно утверждаю только одно - в нормально спроектированной системе вложенные прерывания нужны в исключительнейших случаях. За этим утверждением мой опыт, в том числе и опыт использования вложенных прерываний.
GetSmart
Цитата(zltigo @ Nov 15 2009, 19:28) *
Где Вы у меня видели "из"? Я писал "после". После КОРОТКОГО обработчика FIQ, если надо продолжить что-то делать без привлечения задачи операционной системы и без затрат времени на переключения контекста операционной системой.

Exception (за искл. FIQ и IRQ) можно вызвать только "из", а не "после". Поэтому остаётся только SoftIRQ без вариантов.
yuri_t
Цитата(zltigo @ Nov 15 2009, 17:28) *
Я давным-давно утверждаю только одно - в нормально спроектированной системе вложенные прерывания нужны в исключительнейших случаях. За этим утверждением мой опыт, в том числе и опыт использования вложенных прерываний.


Полностью согласен.
GetSmart
Цитата(zltigo @ Nov 15 2009, 19:28) *
Пока Вы пытаетесь свести обсуждение к ограниченному кусочку неведомой "моей проги", Вы можете называть любые "преимущества".

В начале топа Вы пытались меня критиковать даже без знания каких-либо нюансов алгоритма. Давайте продолжим. Я уже много подробностей рассказал. Даже готов согласиться на ооочень тормознутую реакцию на сигнал от АЦП. Только расскажите какие конкретно приемущества мне сулит отказ от вложенных FIQ ?

Цитата
Я давным-давно утверждаю только одно - в нормально спроектированной системе вложенные прерывания нужны в исключительнейших случаях. За этим утверждением мой опыт, в том числе и опыт использования вложенных прерываний.

Ну я же только что привёл прекрасный наглядный пример использования софтового IRQ для подгрузки данных при проигрывании файлов. Такие характеристики, которые он обеспечивает не достичь никаких другим способом. Или у Вас есть другие решения?

Цитата(yuri_t @ Nov 15 2009, 19:39) *
Полностью согласен.

Ага. Будда лучше всех biggrin.gif
Конкретные примеры в студию.
zltigo
Цитата(GetSmart @ Nov 15 2009, 16:38) *
Exception (за искл. FIQ и IRQ) можно вызвать только "из", а не "после". Поэтому остаётся только SoftIRQ без вариантов.

Вариантов Вы назвали целых три. Один действительно отпадает. Остались два. Не говоря о том, что можно просто перейти не на прерванную программу без всяких трюков с exception.
GetSmart
Цитата(zltigo @ Nov 15 2009, 19:28) *
Я давным-давно утверждаю только одно - в нормально спроектированной системе вложенные прерывания нужны в исключительнейших случаях. За этим утверждением мой опыт, в том числе и опыт использования вложенных прерываний.

Щас придумал идеальную аналогию в понятиях ОС для определения вложенных прерываний. Это как "на лету" создающийся тред максимального приоритета именно в момент когда он понадобился. Он прерывает все другие треды, но не мешает прерываниям. Вложенными делают обычно тяжёлые прерывания. Этот признак делает аналогию ещё более точной. Когда тред полностью выполнил алгоритм, то он самоликвидируется smile.gif И больше не тратит процессорного времени до очередного события.
zltigo
Цитата(GetSmart @ Nov 15 2009, 16:56) *
Щас придумал...

Об этом я самого начала и говорю, начиная с поста №5 если перечитаете sad.gif. Теперь Вы четко поставили задачу. Для ее решения "вкладывать прерывания" совершенно не обязательно. Как и проектировать "тяжелые прерывания"
yuri_t
Цитата(GetSmart @ Nov 15 2009, 16:48) *
Ну я же только что привёл прекрасный наглядный пример использования софтового IRQ для подгрузки данных при проигрывании файлов. Такие характеристики, которые он обеспечивает не достичь никаких другим способом. Или у Вас есть другие решения?


Dear GetSmart !

-во-первых:

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

- во-вторых:

Не стоит, даже в пылу полемики, заявлять:

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

Поверте, эти "вышеотписавшиеся" понимают "все хитрости ядра" намного лучше нас с Baми...
VslavX
Цитата(GetSmart @ Nov 15 2009, 15:56) *
Щас придумал идеальную аналогию в понятиях ОС для определения вложенных прерываний. Это как "на лету" создающийся тред максимального приоритета именно в момент когда он понадобился.

"Лучше поздно, чем никогда" smile.gif

Создавать "когда понадобился" - это неоптимально по производительности - создание задачи выполняется относительно долго. А вот создать высокоприоритетный поток заранее и перевести его в ожидание некоторого события - самое оно. В прерывании сделать только самые-самые необходимые действия и активировать ожидаемое событие.

Цитата(GetSmart @ Nov 15 2009, 15:56) *
Он прерывает все другие треды, но не мешает прерываниям.

Именно

Цитата(GetSmart @ Nov 15 2009, 15:56) *
Когда тред полностью выполнил алгоритм, то он самоликвидируется smile.gif И больше не тратит процессорного времени до очередного события.

Немного не так - "засыпает" на новом ожидании события. И при этом точно так же не тратит ни такта процессорного времени. Создание/ликвидация более времязатратны и по ресурсам никакого выигрыша не дадут.

Вы будете удивлены, но маленькие ОСи переключают контекст очень быстро. Самая медленная из мной тестированных - uC/OS, со всеми наворотами (учет времени исполнения задачи, счетчик переключений контекста, вызов "рюшечных" колбеков) на SAM7S@48MHz (я думаю быстродействие LPC23@24 сравнимо) переключалась примерно за 14мкс - это полное время смены контекста, если выходить из прерывания - то это время располовиниться. То есть, задержка обработки данных по сравнению с моментом обработки в самом прерывании составит всего 7мкс - это менее 20 процентов от Ваших 40мкс. SCMrtos - в два раза быстрее, TNKernel тоже можно ускорить до этих цифр. Никто не говорит, что временнЫх издержек нет, они есть, но, как правило, незначительные, и эту цену часто стОит заплатить за архитектурную простоту и другие удобства.
KRS
А взяли бы уже достпуный Cortex-M3 ( LPC1768 вроде, кстати пнисовместимый с 2368) и получили бы аппаратные вложенные прерывания и pendsv - примерно то что у вас сейчас получилось.
singlskv
Цитата(GetSmart @ Nov 15 2009, 16:10) *
По поводу софтового варианта уже ответил singlskv, что вариант однозначно хуже вложенных FIQ. Если Вы так не считаете, то укажите конкретные недостатки моего варианта (nested FIQ) и достоинства SoftIRQ применительно к моей проге.
Я полагаю(не видя конечно Вашей проги целиком) что вариант с взведением IRQ из FIQ ничем не хуже.
Если посчитать все накладные расходы на переключение режимов то джиттер скорее всего будет примерно одинаков.
Если посчитать общую загрузку проца, то мой вариант будет просто лучше т.к. издержки одного лишнего IRQ
будут существенно меньше чем расходы на все переключения режимов/контекстов.
Остается только скорость реакции на событие посчитанное по данным АЦП,
если так важна скорость то конечно нужно использовать не SoftIRQ а взводить высокоприоритетное переферийное,
ну и конечно не иметь слишком длинных других IRQ.

По крайней мере я бы сначала так попробовал(и скорее всего и остановился на этом) прежде
чем замутить вложенные прерывания...
defunct
Цитата(singlskv @ Nov 16 2009, 00:35) *
Если посчитать все накладные расходы на переключение режимов то джиттер скорее всего будет примерно одинаков.

Считайте:
__asm{ swi ADC_HandlerId }
singlskv
Цитата(defunct @ Nov 16 2009, 03:19) *
Считайте:
__asm{ swi ADC_HandlerId }
Не понял Вашей глубокой мысли...
defunct
Цитата(singlskv @ Nov 16 2009, 02:59) *
Не понял Вашей глубокой мысли...

На джиттер влияет только время пребывания в FIQ, поэтому расходы на переключение из любого режима обратно в FIQ не волнуют, т.к. на джиттер они не влияют.
А переключение из FIQ в SVC делается __одной__ приведенной выше командой, т.е. приведенное и есть __все__ накладные расходы на переключение режимов, влияющие на джиттер.
SVC режим можно заранее подготовить так как требуется для наименьшего джиттера - запретить в нем IRQ и разрешить FIQ.
GetSmart
Цитата(defunct @ Nov 16 2009, 06:19) *
__asm{ swi ADC_HandlerId }

SWI используется FreeRTOSом. Так просто (без накладных раскодов) скорее всего не получится. Проще может получиться применить "Undef Instruction" для "влёта" в исключение. Кроме того, при "влёте" флаг FIQ наследуется из текущего режима, его нельзя предустановить.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.