реклама на сайте
подробности

 
 
3 страниц V  < 1 2 3  
Reply to this topicStart new topic
> SWI, Смысл использовать SWI
Д_М
сообщение Mar 24 2015, 14:18
Сообщение #31


Частый гость
**

Группа: Участник
Сообщений: 121
Регистрация: 15-04-05
Из: Краснодар
Пользователь №: 4 185



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


Из описания операционных систем я понял, что в них передача управления производится на системных тиках. Для некоторых задач одна миллисекунда - это слишком долго. Самый банальный пример - передача одного байта по UART, на скорости 9600, занимает примерно одну миллисекунду. Если в обработчике прерывания передачи делать только сохранения данных, а CRC считать в RTOS-задаче, то новый байт будет поступать до того, как будет посчитано CRC предыдущего байта. Вычислять CRC в обработчике прерывания - грубовато. Если бы можно было дать команду вызова диспетчера сразу же, а не по пришествию ближайшего тика, то было бы то, что нужно.
Go to the top of the page
 
+Quote Post
DmitryM
сообщение Mar 24 2015, 16:15
Сообщение #32


Знающий
****

Группа: Свой
Сообщений: 583
Регистрация: 7-06-06
Из: Таганрог
Пользователь №: 17 840



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


scmRTOS, FreeRTOS так умеют делать, Вы невнимательно читали скорее всего.
Go to the top of the page
 
+Quote Post
SII
сообщение Mar 24 2015, 16:24
Сообщение #33


Знающий
****

Группа: Свой
Сообщений: 549
Регистрация: 13-07-10
Из: Солнечногорск-7
Пользователь №: 58 414



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


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

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

Работу для PendSV можно "спускать" с помощью очереди. Добавлять в неё элементы (в обработчиках обычных прерываний) и извлекать их оттуда (в обработчике PendSV) надо при полностью запрещённых прерываниях, чтоб процесс добавления-удаления не был нарушен. Этим путём можно обеспечить строго последовательную обработку любых запросов: в каком порядке они будут добавляться в эту очередь, в таком и будут обрабатываться в PendSV (который просто крутится в бесконечном цикле "взять очередной элемент из очереди -- обработать его").
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Mar 24 2015, 17:00
Сообщение #34


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



надо делать все не такsm.gif
Если мы говорим про UART, то его символы надо принимать при помощи ДМА в буфер. А в основном цикле-задаче уже по факту обрабатывать ни каждый пришедший символ, а столько сколько накопилось в этом буфере с момента прошлой обработки.

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

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

описанный выше метод с PendSV - это аля как операционки контекст переключают... Но я бы не надеялся на переключение контекста за время приема символа. Надо ДМА подключать, это правильнее...
Go to the top of the page
 
+Quote Post
mantech
сообщение Mar 24 2015, 17:27
Сообщение #35


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



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


Обработчики данных устройств реального времени, уартов, и т.п. пишутся в виде драйверов и подвешиваются на соотв. прерывания поэтому даже если контекст будет переключаться 1 раз в 10 мс ничего нехорошего не произойдет.
Go to the top of the page
 
+Quote Post
DmitryM
сообщение Mar 24 2015, 17:28
Сообщение #36


Знающий
****

Группа: Свой
Сообщений: 583
Регистрация: 7-06-06
Из: Таганрог
Пользователь №: 17 840



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

Дык речь про RTOS и идет. А с дма уарт как раз неправильнее, например, при работе с modbus, где нужно отслеживать тайм-ауты. Да и для обычной коммандной консоли на прием буфер нужен, дма нет.
Go to the top of the page
 
+Quote Post
Д_М
сообщение Mar 24 2015, 18:24
Сообщение #37


Частый гость
**

Группа: Участник
Сообщений: 121
Регистрация: 15-04-05
Из: Краснодар
Пользователь №: 4 185



Цитата(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, но хочется что-то более изящного. С одной стороны не охота перетаскивать старьё, с другой стороны не хочется использовать то новое, которое не понимаю.

Сообщение отредактировал IgorKossak - Mar 25 2015, 18:30
Причина редактирования: [codebox] для длинного кода, [code] - для короткого
Go to the top of the page
 
+Quote Post
Д_М
сообщение Mar 24 2015, 19:31
Сообщение #38


Частый гость
**

Группа: Участник
Сообщений: 121
Регистрация: 15-04-05
Из: Краснодар
Пользователь №: 4 185



В описании операционной системы 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; // Сбрасываем флаг прерывания
}

Можно ли быть уверенным в том, что управление будет сразу же передано обработчику, а не с наступлением системного тика?

Сообщение отредактировал IgorKossak - Mar 25 2015, 18:30
Причина редактирования: [codebox] для длинного кода, [code] - для короткого
Go to the top of the page
 
+Quote Post
mantech
сообщение Mar 24 2015, 20:19
Сообщение #39


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



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


Скорее всего данная процедура только подаст сигнал блоку Task swicher, что нужно передать управление ожидающему процессу по очередному тику, а не прямо след. тактом. Для таких задач нужно использовать прерывания устройства, либо виртуальный обработчик прерываний по дескрипторам и распределением их по активным задачам, как это делалось еще в 386расширенном режиме на pc-шках...
Go to the top of the page
 
+Quote Post
Д_М
сообщение Mar 25 2015, 06:16
Сообщение #40


Частый гость
**

Группа: Участник
Сообщений: 121
Регистрация: 15-04-05
Из: Краснодар
Пользователь №: 4 185



Цитата(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_).

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

Go to the top of the page
 
+Quote Post
SII
сообщение Mar 25 2015, 07:36
Сообщение #41


Знающий
****

Группа: Свой
Сообщений: 549
Регистрация: 13-07-10
Из: Солнечногорск-7
Пользователь №: 58 414



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


А зачем переключать контекст для приёма одного символа? Переключать надо, когда операция ввода-вывода закончена целиком (принято запланированное число символов или встречен символ, означающий конец последовательности, например). А всю быструю и простую обработку вести в первичных обработчиках прерываний (которые вызываются непосредственно аппаратными прерываниями).
Go to the top of the page
 
+Quote Post
jcxz
сообщение Mar 25 2015, 08:26
Сообщение #42


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Д_М @ 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 это не требует.
Go to the top of the page
 
+Quote Post
mantech
сообщение Mar 25 2015, 19:04
Сообщение #43


Гуру
******

Группа: Участник
Сообщений: 2 219
Регистрация: 16-08-12
Из: Киров
Пользователь №: 73 143



Цитата(jcxz @ Mar 25 2015, 11:26) *
Уже сколько народу тут талдычат ТС об этом, а он всё своё гнёт... Тяжкое наследие AVR?


А что, в аврках нельзя было повесить уарт на свой обработчик прерывания?? biggrin.gif
Я конечно не ставил rtosы на авр, но использовал приоритетный метод с системой распределения вложенных прерываний, виртуальные таймеры и пр. няшки, все работало как надо...

Сообщение отредактировал mantech - Mar 25 2015, 19:08
Go to the top of the page
 
+Quote Post
jcxz
сообщение Mar 26 2015, 05:35
Сообщение #44


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(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
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 09:52
Рейтинг@Mail.ru


Страница сгенерированна за 0.01497 секунд с 7
ELECTRONIX ©2004-2016