Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: SWI
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
серый волк
начал разбираться с армом
наткнулся на SWI
не понимаю смысл его использования
так из примера ничего не ясно
похоже на вызов обкновенной функции
спасибо

#include <LPC21xx.H>

void SWI_Call1(int pattern) //Software interrupt with passed parameters
{
IOCLR1 = 0x00FF0000; //set the leds
IOSET1 = pattern;
}

void SWI_Call2(void)
{
IOCLR1 = 0x00FF0000;
IOSET1 = 0x00AA0000;
}

void main(void)
{
int pattern = 0x00550000;
IODIR1 = 0x00FF0000;
IOCLR1 = 0x00FF0000;

SWI_Call1(pattern);
SWI_Call2();

while(1)
{
; //Loop forever
}
}
Vitaliy_ARM
Функция SWI (программное прерывание) часто используется в операционных системах ресльного времени для осуществления механизма перепланировки по событию, произошедшему в фоновой задаче. Польза от этого механизма - уменьшение размера стека процессов. При возникновении этого события контроллер входит в режим супер пользователя. В основном она и работает как обыкновенная функция, отличие у нее (характерно не только для ARM) от обычной функции в доступе к уникальным регистрам, например возможность устанавливать или сбрасывать прерывания и т.п.
alexander55
Цитата(серый волк @ Aug 29 2007, 13:12) *
начал разбираться с армом
наткнулся на SWI
не понимаю смысл его использования
так из примера ничего не ясно
похоже на вызов обкновенной функции
спасибо

Вы правы, за одним маленьким нюансом. SWI защищено от прерываний. Колеса без программных прерываний жить не могут.
Создатель scmRTOS жаловался, что пришлось использовать прерывание от компаратора при портировании в AVR для получения программного прерывания.
серый волк
спасибо

1.может ли исполнение прерывания быть прервано вызовом другого прерывания?


2."в доступе к уникальным регистрам, например возможность устанавливать или сбрасывать прерывания и т.п." Из описания я не нашел , что нельзя устанавливать или сбрасывать прерывания
в user mode.

успехов
zltigo
Цитата(серый волк @ Aug 29 2007, 12:12) *
похоже на вызов обкновенной функции

Только эта 'функция' может находится в другом модуле, например, bootloader-е, ядре системы и соответственно вообще не линковаться в один модуль.
alexander55
Цитата(серый волк @ Aug 29 2007, 14:16) *
спасибо

1.может ли исполнение прерывания быть прервано вызовом другого прерывания?

SWI нельзя.
FIQ, IRQ - если сделать стандартно, то нет. Если приложить усилия - то можно.
серый волк
Александр,

я правильно понимаю...
если у меня идет выполнение IRQ и в процессе выполнения приходит SWI ,
то выполнение IRQ прерывается и начинается выполнение SWI. Потом заканчивается выполнение
IRQ. Это верно? И наоборот судя по Вашим словам невозможно.


Из таблицы приоритетов кстати IRQ имеет более высокий приоритет чем SWI 05.gif

Тут скорее всего надо различать стуации возникновения двух прерываний одновременно и
ситуация, когда один произошел и уже выполняется... help.gif

Можно ли как-нить это прояснить....

Спасибо
Сергей
zltigo
Цитата(серый волк @ Aug 29 2007, 15:27) *
я правильно понимаю...

Что-то у Вас совсем каша.
Оно не 'приходит' самопроизвольно. Его Вы сами 'вызываете'.
серый волк
с кашей это точно...

интересует в общем что поисходит при прерывании во время исполнения кода другого прерывания?
Dron_Gus
Обычно ничего. Если Вы не позаботились о вложеных прерываниях. Уже начатое прерывание завершается, после этого из всех ждущих выбирается прерывание с максимальным приоритетом и выполняется. И так пока прерывания не кончатся. smile.gif
серый волк
СПАСИБО
alexander55
[quote name='серый волк' date='Aug 29 2007, 16:27' post='288617']
Александр,

я правильно понимаю...
если у меня идет выполнение IRQ и в процессе выполнения приходит SWI ,
[/quote]
SWI Вы вызываете сами. По выходу из прерывания IRQ в режим USER, SWI выполнится.

[quote name='серый волк' date='Aug 29 2007, 16:27' post='288617']
Александр,

я правильно понимаю...
если у меня идет выполнение IRQ и в процессе выполнения приходит SWI ,
то выполнение IRQ прерывается и начинается выполнение SWI. Потом заканчивается выполнение
IRQ. Это верно?
[/quote]
Нет. См. выше.

quote name='серый волк' date='Aug 29 2007, 16:27' post='288617']
Александр,

я правильно понимаю...
если у меня идет выполнение IRQ и в процессе выполнения приходит SWI ,
то выполнение IRQ прерывается и начинается выполнение SWI. Потом заканчивается выполнение
IRQ. Это верно? И наоборот судя по Вашим словам невозможно.
Сергей
[/quote]
Не приписывайте мне,что я не говорил. SWI ничем не прерывается. Это SuperVisor.

quote name='серый волк' date='Aug 29 2007, 16:27' post='288617']
Из таблицы приоритетов кстати IRQ имеет более высокий приоритет чем SWI 05.gif
Тут скорее всего надо различать стуации возникновения двух прерываний одновременно
[/quote]
Да, при одновременном приходе заявок на прерывание выполняется прерывание с более высоким приоритетом.

[quote name='серый волк' date='Aug 29 2007, 16:27' post='288617']

Тут скорее всего надо различать ..., когда один произошел и уже выполняется...

Можно ли как-нить это прояснить....
[/quote]
Проясняю для IRQ и FIQ, т.к. они выполняются через векторный контроллер (я говорю про LPC) при входе и выходе вставляются макросы. Смысл их: корректно разрешить прерывание и корректно запретить, но уже спасение и восстановление осуществляется через стек, т.к. без стека возможен только один уровень. Тогда внутри IRQ может быть еще один IRQ.

[quote name='серый волк' date='Aug 29 2007, 16:27' post='288617']
Спасибо
Сергей
[/quote]
Вежливому человеку всегда рад помочь, если не в напряг.
ig_z
Цитата(alexander55 @ Aug 29 2007, 12:24) *
Вы правы, за одним маленьким нюансом. SWI защищено от прерываний. Колеса без программных прерываний жить не могут.
Создатель scmRTOS жаловался, что пришлось использовать прерывание от компаратора при портировании в AVR для получения программного прерывания.

scmRTOS не использует сви, это уже обсуждалось. Наиболее "красив" в этом смысле сам7. Пррерывания вешаются на FIQ а перепланировкой занимается IRQ.
Paramon
Цитата(alexander55 @ Aug 29 2007, 16:08) *
SWI нельзя.
FIQ, IRQ - если сделать стандартно, то нет. Если приложить усилия - то можно.


FIQ - можно всегда!
Из любых мест.
Может я ошибаюсь?
alexander55
Цитата(Paramon @ Aug 30 2007, 07:45) *
FIQ - можно всегда!
Из любых мест.
Может я ошибаюсь?

Ошибаетесь.
Paramon
Цитата(alexander55 @ Aug 30 2007, 08:30) *
Ошибаетесь.


потому-то и поставил вопрос!(Может я ошибаюсь?)
Я его (FIQ) пользую к таймеру.(Нужны относительно стабильные по времени выборки).
Правда пока не наткнулся ни на какие казусы(кроме времени реакции на FIQ).
IRQ использую еще с 3 таймерами (там точности большой ненадо)
SWI использую из основного цикла.
Будьте добры поясните, а то может быть мне жизнь раем показалась и надо переделать проект.
Спасибо!
alexander55
Цитата(Paramon @ Aug 30 2007, 11:56) *
потому-то и поставил вопрос!(Может я ошибаюсь?)
Я его (FIQ) пользую к таймеру.(Нужны относительно стабильные по времени выборки).
Правда пока не наткнулся ни на какие казусы(кроме времени реакции на FIQ).
IRQ использую еще с 3 таймерами (там точности большой ненадо)
SWI использую из основного цикла.
Будьте добры поясните, а то может быть мне жизнь раем показалась и надо переделать проект.
Спасибо!

Проверьте сами, я не классик, чтобы себя цитировать.
серый волк
Thanks
AVR
Цитата(alexander55 @ Aug 29 2007, 13:24) *
Создатель scmRTOS жаловался, что пришлось использовать прерывание от компаратора при портировании в AVR для получения программного прерывания.
Пользуюсь scmRTOS для AVR... Мне нужно написать программу для платы у которой все выводы компаратора заняты. Я использовал прерывание по сравнению третьего ненужного мне таймера в качестве программного прерывания. Насколько это безопасно и надежно? Пока ещё есть возможность исправить... Но вроде работает стабильно и достаточно быстро...
Сергей Борщ
Цитата(AVR @ Sep 2 2007, 20:29) *
Я использовал прерывание по сравнению третьего ненужного мне таймера в качестве программного прерывания. Насколько это безопасно и надежно? Пока ещё есть возможность исправить... Но вроде работает стабильно и достаточно быстро...
Никаких препятствий для использования любого свободного прерывания нет. Проблема только в том, что не всякое прерывание можно вызвать программно. Я подумывал об использовании прерывания SPM - оно уж точно никогда не нужно и если я правильно понял описание флаг его всегда взведен, когда SPMEN = 0. А SPMEN = 1 только при перепрограммировании, когда переключать контексты не нужно. Если вам эта идея покажется стоящей и вы ее реализуете - отпишите сюда, пожалуйста.
Vitaliy_ARM
Здесь есть ответы на многие вопросы smile.gif

Там на филипсе когда-то скачал книжку по LPC2300ю Называется lpc2300_book_v2_srn. Там есть много ответов на ваши вопросы. smile.gif Кто не найдет могу выложить на форуме, она около 10 Мб
Alechek
Подниму тему.
Вопрос "если у меня идет выполнение IRQ и в процессе выполнения приходит SWI" остался.
Что будет, если из IRQ вызвать SWI?
По приоритетам у SWI низший, то есть как бы не должен вытеснять IRQ. Но если вызов SWI блокирующий, то как тогда дальше быть?
Нашел похожую по проблеме тему, но там тоже суть не раскрыта.
MK2
Цитата(Alechek @ Mar 20 2013, 14:00) *
Подниму тему.
Вопрос "если у меня идет выполнение IRQ и в процессе выполнения приходит SWI" остался.
Что будет, если из IRQ вызвать SWI?

на cortex M3 как зададите приоритет прерываний так и будет происходить, приоритет так же можно задавать для программного прерывания ( я имею ввиду обработчик SVC_Handler или PendSV_Handler ) . только на мой взгляд если вы не пишете планировщик их лучше от греха подальше не использовать. заюзайте какой-нить свободное от переферии прерывание и запускайте по pending bit его.
Д_М
Здравствуйте!
Выше много писали о том, что во время IRQ происходит SWI. На AVR я реализовал многозадачность, с использованием псевдо-SWI (аппаратное прерывание, как программное - INT0). Моя идея заключалась в том, чтобы при выполнении IRQ, в обработчике надо быть, как можно меньше времени. Только сохранение данных и инициация работы кода, который занимает нечто промежуточное по важности, между фоновой задачей (которая может длиться до единиц миллисекунд) и обработчиками прерываний. То есть, обработать данные надо, как можно скорее, но не в ущерб аппаратным прерываниям. Для этого обработчик IRQ инициирует SWI. После завершения IRQ вызывается SWI, который является диспетчером обработчиков, вызывающим наиболее важный обработчик. SWI, перед вызовом обработчика, разрешает прерывания, что позволит без ущерба отрабатывать обработчикам аппаратных прерываний. А как это работает на ARM? Правильно ли я понял, что если в обработчике IRQ вызвать SWI, то его код будет отработан после того, как отработают все IRQ? Если во время работы SWI произойдёт IRQ, управление сразу же будет передано IRQ, а по его завершению вернётся обратно в SWI?
Спасибо!
jcxz
Цитата(Д_М @ Mar 24 2015, 02:29) *
Правильно ли я понял, что если в обработчике IRQ вызвать SWI, то его код будет отработан после того, как отработают все IRQ? Если во время работы SWI произойдёт IRQ, управление сразу же будет передано IRQ, а по его завершению вернётся обратно в SWI?

Неправильно. SWI - синхронное исключение, а не обычное асинхронное внешнее прерывание типа IRQ или FIQ. Т.е. - собственно для Вас это как простой вызов функции (с переключением CPU в привилегированный режим).
Если процессор перед вызовом SWI находился в режиме IRQ, то произойдёт переключение в режим SWI (с запретом FIQ и IRQ). При выходе из режима SWI произойдёт возврат в режим IRQ.
SWI например может использоваться для вызова функций OS из непривилегированного режима (режима пользователя).
SII
FIQ не запрещается икакими прерываниями, кроме самого FIQ. И, кстати говоря, SWI уже давным-давно переименована в SVC.
jcxz
Цитата(SII @ Mar 24 2015, 11:52) *
FIQ не запрещается икакими прерываниями, кроме самого FIQ.

Да, наверное. Писал по памяти.
Цитата(SII @ Mar 24 2015, 11:52) *
И, кстати говоря, SWI уже давным-давно переименована в SVC.

Переименована в Cortex-M. А у ТС вроде как Classical ARM, а там не переименована.
SII
Цитата(jcxz @ Mar 24 2015, 09:39) *
Переименована в Cortex-M. А у ТС вроде как Classical ARM, а там не переименована


Переименована для всех, когда был введён унифицированный синтаксис языка ассемблера для систем команд ARM и Thumb -- а он распространяется не только на новые процессоры, но и на старые тоже, хотя в старой документации, естественно, остаётся мнемоника SWI. Однако ассемблер и компилятор используют SVC для любых процессоров (SWI можно применять в ассемблере, если включить использование старого синтаксиса, насчёт компилятора не знаю -- может, только SVC позволяет).
Д_М
Цитата(jcxz @ Mar 24 2015, 07:47) *
Неправильно. SWI - синхронное исключение, а не обычное асинхронное внешнее прерывание типа IRQ или FIQ. Т.е. - собственно для Вас это как простой вызов функции (с переключением CPU в привилегированный режим).
Если процессор перед вызовом SWI находился в режиме IRQ, то произойдёт переключение в режим SWI (с запретом FIQ и IRQ). При выходе из режима SWI произойдёт возврат в режим IRQ.
SWI например может использоваться для вызова функций OS из непривилегированного режима (режима пользователя).


А как тогда оформить код, который активируется в прерывании, но исполняется после всех прерываний? То есть менее приоритетный, чем прерывания, но более приоритетный, чем фоновая задача.
Спасибо!
jcxz
Цитата(Д_М @ Mar 24 2015, 18:41) *
А как тогда оформить код, который активируется в прерывании, но исполняется после всех прерываний? То есть менее приоритетный, чем прерывания, но более приоритетный, чем фоновая задача.

Использовать RTOS.
Д_М
Цитата(jcxz @ Mar 24 2015, 17:06) *
Использовать RTOS.


Из описания операционных систем я понял, что в них передача управления производится на системных тиках. Для некоторых задач одна миллисекунда - это слишком долго. Самый банальный пример - передача одного байта по UART, на скорости 9600, занимает примерно одну миллисекунду. Если в обработчике прерывания передачи делать только сохранения данных, а CRC считать в RTOS-задаче, то новый байт будет поступать до того, как будет посчитано CRC предыдущего байта. Вычислять CRC в обработчике прерывания - грубовато. Если бы можно было дать команду вызова диспетчера сразу же, а не по пришествию ближайшего тика, то было бы то, что нужно.
DmitryM
Цитата(Д_М @ Mar 24 2015, 17:18) *
Из описания операционных систем я понял, что в них передача управления производится на системных тиках. Для некоторых задач одна миллисекунда - это слишком долго. Самый банальный пример - передача одного байта по UART, на скорости 9600, занимает примерно одну миллисекунду. Если в обработчике прерывания передачи делать только сохранения данных, а CRC считать в RTOS-задаче, то новый байт будет поступать до того, как будет посчитано CRC предыдущего байта. Вычислять CRC в обработчике прерывания - грубовато. Если бы можно было дать команду вызова диспетчера сразу же, а не по пришествию ближайшего тика, то было бы то, что нужно.


scmRTOS, FreeRTOS так умеют делать, Вы невнимательно читали скорее всего.
SII
Цитата(Д_М @ Mar 24 2015, 15:41) *
А как тогда оформить код, который активируется в прерывании, но исполняется после всех прерываний? То есть менее приоритетный, чем прерывания, но более приоритетный, чем фоновая задача


Применительно к Кортексам-М можно сделать примерно так.

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

Работу для PendSV можно "спускать" с помощью очереди. Добавлять в неё элементы (в обработчиках обычных прерываний) и извлекать их оттуда (в обработчике PendSV) надо при полностью запрещённых прерываниях, чтоб процесс добавления-удаления не был нарушен. Этим путём можно обеспечить строго последовательную обработку любых запросов: в каком порядке они будут добавляться в эту очередь, в таком и будут обрабатываться в PendSV (который просто крутится в бесконечном цикле "взять очередной элемент из очереди -- обработать его").
Golikov A.
надо делать все не такsm.gif
Если мы говорим про UART, то его символы надо принимать при помощи ДМА в буфер. А в основном цикле-задаче уже по факту обрабатывать ни каждый пришедший символ, а столько сколько накопилось в этом буфере с момента прошлой обработки.

Если не нравиться ДМА, то можно в прерывании UART кидать символ в этот буфер.

Но делать такую сложную систему прерываний, с регулировкой до такта - это по моему перебор. У АРМа больше ресурсов чем в АВР, он имеет больше периферии, потому он будет больше всего делать и в итоге вы за ним не уследите... ИМХО...

описанный выше метод с PendSV - это аля как операционки контекст переключают... Но я бы не надеялся на переключение контекста за время приема символа. Надо ДМА подключать, это правильнее...
mantech
Цитата(Д_М @ Mar 24 2015, 17:18) *
Самый банальный пример - передача одного байта по UART, на скорости 9600, занимает примерно одну миллисекунду. Если в обработчике прерывания передачи делать только сохранения данных, а CRC считать в RTOS-задаче, то новый байт будет поступать до того, как будет посчитано CRC предыдущего байта. Вычислять CRC в обработчике прерывания - грубовато. Если бы можно было дать команду вызова диспетчера сразу же, а не по пришествию ближайшего тика, то было бы то, что нужно.


Обработчики данных устройств реального времени, уартов, и т.п. пишутся в виде драйверов и подвешиваются на соотв. прерывания поэтому даже если контекст будет переключаться 1 раз в 10 мс ничего нехорошего не произойдет.
DmitryM
Цитата(Golikov A. @ Mar 24 2015, 20:00) *
Но я бы не надеялся на переключение контекста за время приема символа. Надо ДМА подключать, это правильнее...

Дык речь про RTOS и идет. А с дма уарт как раз неправильнее, например, при работе с modbus, где нужно отслеживать тайм-ауты. Да и для обычной коммандной консоли на прием буфер нужен, дма нет.
Д_М
Цитата(Golikov A. @ Mar 24 2015, 21:00) *
надо делать все не такsm.gif
Если мы говорим про UART, то его символы надо принимать при помощи ДМА в буфер. А в основном цикле-задаче уже по факту обрабатывать ни каждый пришедший символ, а столько сколько накопилось в этом буфере с момента прошлой обработки.

Если не нравиться ДМА, то можно в прерывании UART кидать символ в этот буфер.

Но делать такую сложную систему прерываний, с регулировкой до такта - это по моему перебор. У АРМа больше ресурсов чем в АВР, он имеет больше периферии, потому он будет больше всего делать и в итоге вы за ним не уследите... ИМХО...

описанный выше метод с PendSV - это аля как операционки контекст переключают... Но я бы не надеялся на переключение контекста за время приема символа. Надо ДМА подключать, это правильнее...


Я тоже считал, что надо принимать данные в буфер, а потом в фоновой задаче считать CRC всего массива. Создать нечто промежуточное, между фоновой задачей и прерываниями, меня надоумил проект, в котором много математики. Вычисления производятся в основном цикле по принципу - сколько успел. По моим прикидкам, период вычисления всей математики составляет единицы миллисекунд (на AVR). Если в очередь основного цикла вставить подсчёт CRC UART, то очень долго придётся ждать, пока ему будет передано управление. Для AVR я написал вот такой обработчик-диспетчер псевдо-программного прерывания (используя внешнее прерывание):

Код
#pragma vector=INT0_vect // As Soft Ware interrupt
__interrupt void SWI_mng (void)
{
unsigned char ct;
void (*ptr)(void);

for(ct = 0; ct < qty_SWI_executors; ct++)
    if(SWI_exec[ct])
        {
        ptr = SWI_exec[ct];
        SWI_exec[ct] = NULL; // Deactivate further execution
        SW_Int = 1; // Stop interrupt
        GI_enable
        (*ptr)();
        break;
        }
}

Перед индексным вызовом кода разрешается прерывание, что даёт возможность работы обработчикам прерывания от аппаратных устройств.
Можно было бы сделать тоже самое и на ARM, но хочется что-то более изящного. С одной стороны не охота перетаскивать старьё, с другой стороны не хочется использовать то новое, которое не понимаю.
Д_М
В описании операционной системы RL-ARM от Keil углядел очень интересный механизм

В ОС предусмотрен системный вызов для установки флагов событий, предназначенный для вызова из обработчика прерывания:
void isr_evt_set(unsigned short event_flags, 0S_TID task);
Таким образом, типичный процесс, выполняющий обработку прерывания,
будет выглядеть следующим образом:
Код
void Task3(void) {
while(1)
{
os_evt_wait_or(0x0001, 0xFFFF); /* Ждем установки флага
события обработчиком */
......... // Обрабатываем прерывание
} // В следующем проходе цикла снова засыпаем
}
Обработчик прерывания в данном случае будет содержать минимальное
количество кода:
void FIQ_Handler (void) __fiq
{
isr_evt_set(0x0001,tsk3); /* Сообщаем процессу tsk3 о возникновении
прерывания */
EXTINT = 0x00000002; // Сбрасываем флаг прерывания
}

Можно ли быть уверенным в том, что управление будет сразу же передано обработчику, а не с наступлением системного тика?
mantech
Цитата(Д_М @ Mar 24 2015, 22:31) *
Можно ли быть уверенным в том, что управление будет сразу же передано обработчику, а не с наступлением системного тика?


Скорее всего данная процедура только подаст сигнал блоку Task swicher, что нужно передать управление ожидающему процессу по очередному тику, а не прямо след. тактом. Для таких задач нужно использовать прерывания устройства, либо виртуальный обработчик прерываний по дескрипторам и распределением их по активным задачам, как это делалось еще в 386расширенном режиме на pc-шках...
Д_М
Цитата(mantech @ Mar 25 2015, 00:19) *
Скорее всего данная процедура только подаст сигнал блоку Task swicher, что нужно передать управление ожидающему процессу по очередному тику, а не прямо след. тактом. Для таких задач нужно использовать прерывания устройства, либо виртуальный обработчик прерываний по дескрипторам и распределением их по активным задачам, как это делалось еще в 386расширенном режиме на pc-шках...


Вот что пишут производители http://infocenter.arm.com/help/index.jsp?t...isr_evt_set.htm

When the isr_evt_set function is called too frequently, it forces too many tick timer interrupts and os_clock_demon task scheduler is executed most of the time. It might happen that two isr_evt_set functions for the same task are called before the task gets a chance to run from one of the event waiting functions (os_evt_wait_).

Это даёт основание полагать, что после вызова этой функции управление сразу передаётся диспетчеру, а не с приходом очередного тика. Я прав?

SII
Цитата(Golikov A. @ Mar 24 2015, 20:00) *
описанный выше метод с PendSV - это аля как операционки контекст переключают... Но я бы не надеялся на переключение контекста за время приема символа. Надо ДМА подключать, это правильнее...


А зачем переключать контекст для приёма одного символа? Переключать надо, когда операция ввода-вывода закончена целиком (принято запланированное число символов или встречен символ, означающий конец последовательности, например). А всю быструю и простую обработку вести в первичных обработчиках прерываний (которые вызываются непосредственно аппаратными прерываниями).
jcxz
Цитата(Д_М @ Mar 25 2015, 01:31) *
Можно ли быть уверенным в том, что управление будет сразу же передано обработчику, а не с наступлением системного тика?

Во-первых: в embedded RTOS как правило можно легко менять значение системного тика. В uCOS при необходимости можете хоть 10кГц поставить. Только не нужно это, ибо - пустая трата ресурсов на работу шедулера.
Во-вторых: тот же uCOS может переключать задачи как только по сис.таймеру, так и по любому прерыванию. Это будет зависеть от того как Вы эти самые ISR оформите. Всё очень гибко.

Вам надо садиться и изучать работу RTOS. Они все многозадачные. Кроме "фоновой задачи" там можно создать сколько нужно других задач, одна из которых и будет обрабатывать ваши события от ISR UART
(заводите задачу с приоритетом выше фоновой, которая всё время сидит в ожиднаии некоторого мэйлбокса/семафора/или другого средства синхронизации ОС; от ISR посылаете событие в этот объект;
задача обрабатывает событие и опять переходит к ожиданию этого объекта). Это стандартный механизм работы задач под ОС, начиная от виндовых задач кончая embedded-областью.

Цитата(SII @ Mar 25 2015, 13:36) *
А зачем переключать контекст для приёма одного символа? Переключать надо, когда операция ввода-вывода закончена целиком (принято запланированное число символов или встречен символ, означающий конец последовательности, например). А всю быструю и простую обработку вести в первичных обработчиках прерываний (которые вызываются непосредственно аппаратными прерываниями).

Уже сколько народу тут талдычат ТС об этом, а он всё своё гнёт... Тяжкое наследие AVR? wink.gif
А CRC можно хоть по приходу всего кадра считать, хоть на лету в ISR. Больших затрат ресурсов на ARM это не требует.
mantech
Цитата(jcxz @ Mar 25 2015, 11:26) *
Уже сколько народу тут талдычат ТС об этом, а он всё своё гнёт... Тяжкое наследие AVR?


А что, в аврках нельзя было повесить уарт на свой обработчик прерывания?? biggrin.gif
Я конечно не ставил rtosы на авр, но использовал приоритетный метод с системой распределения вложенных прерываний, виртуальные таймеры и пр. няшки, все работало как надо...
jcxz
Цитата(mantech @ Mar 26 2015, 01:04) *
А что, в аврках нельзя было повесить уарт на свой обработчик прерывания?? biggrin.gif
Я конечно не ставил rtosы на авр, но использовал приоритетный метод с системой распределения вложенных прерываний, виртуальные таймеры и пр. няшки, все работало как надо...

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

И Вы вообще имеете представление как работает система прерываний в ядрах ARM7/9??? Как там реализуется возможность вложенных прерываний? О режимах работы CPU имеете представление?
Может расскажете как на ARM7/9 реализовать вложенные прерывания? wink.gif
Я вот прекрасно это представляю так как писал это.
На ARM автору тоже никто не мешает в ISR UART при необходимости возбуждать некоторое аппаратное прерывание (от несипользуемой аппаратуры), в ISR этого прерывания сделать руками
переключение прерванного контекста на контекст некой самопальной задачи (чтобы при её работе разрешить вложенные прерывания), а после завершения работы - переключать контекст обратно.
Для этого автору надо как минимум - изучить всю кухню режимов CPU ARM7/9 и работы системы прерываний. А также - ассемблер для ARM.

То же самое реализовать на Cortex-M несравненно проще, так как там NVIC он сам по своей природе сделан для поддержки вложенных прерываний.
Так что если хочется именно без ОС, своими силами - лучше поменять ядро на Cortex-M.
Но вообще это всё - изобретение своего велосипеда. Так как всё это уже реализовано в RTOS и смысла делать то же самое своё нет. После просто убедитесь, что в RTOS это сделано гораздо лучше wink.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.