Dubov 0 9 июня, 2014 Опубликовано 9 июня, 2014 (изменено) · Жалоба Недавно задался вопросом, как лучше организовать опрос флага в ОСРВ(FreeRTOS, SYSBIOS... др.) Поясню задачу: контроллер DMA по заполнению буфера выставляет один бит в регистре готовности данных. Прочитать этот бит должна т.н. background подпрограмма. Вопрос: как осуществляется решение подобной задачи в ОСРВ? Пока на ум приходит только опрос через while(1) { if(flag == 1) data_proc(); } Есть более грамотные решения? Изменено 9 июня, 2014 пользователем Dubov Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
megajohn 3 9 июня, 2014 Опубликовано 9 июня, 2014 · Жалоба создаете семафор с нулевым значением подпрограмма должна попытаться захватить семафор, но раз ноль, то подпрограмма будет заблокирована в прерывании DMA освобождаете семафор, и сразу после этого планировщик переведет вашу задачу в состояние ready P.S. Пишите RTOS или ОСРВ, вы же не пишите Москоу Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Intel4004 2 9 июня, 2014 Опубликовано 9 июня, 2014 · Жалоба Ну, обычно этот-же бит является флагом прерывания. Написать обработчик этого прерывания, который будет взводить семафор, а в background-подпрограмме ждать его. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dubov 0 9 июня, 2014 Опубликовано 9 июня, 2014 (изменено) · Жалоба Сколько не смотрю примеры, а от while(1) всё равно никуда не деться, хоть выставляй семафор в прерывании, хоть опрашивай флаг регистра напрямую... Пример из SYSBIOS: task() { UInt events; while (TRUE) { /* Wait for ANY of the ISR events to be posted * events = Event_pend(myEvent, Event_Id_NONE, Event_Id_00 + Event_Id_01 + Event_Id_02, BIOS_WAIT_FOREVER); /* Process all the events that have occurred */ if (events & Event_Id_00) { processISR0(); } if (events & Event_Id_01) { processISR1(); } if (events & Event_Id_02) { processISR2(); } } } Изменено 9 июня, 2014 пользователем Dubov Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
megajohn 3 9 июня, 2014 Опубликовано 9 июня, 2014 · Жалоба когда не пришло прерывание, этот task находится в Event_pend в заблокированном состоянии, и дает возможность выполнятся более низкоприоритетным задачам. Если же тупо опрашивать бит, то процессор впустую будет молотить на одном месте Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrewlekar 0 9 июня, 2014 Опубликовано 9 июня, 2014 · Жалоба Вопрос: как осуществляется решение подобной задачи в ОСРВ? Через семафор. Однако если лень и производительность не критична, можно тупо читать битовый флаг. А также можно читать флаги и переменные без опаски до тех пор, пока они не превышают размера регистра процессора. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
A. Fig Lee 0 9 июня, 2014 Опубликовано 9 июня, 2014 · Жалоба Че его организовывать? В CoOS: ret = CoWaitForSingleFlag(myFlag, 10); ждет 10 миллисекунд, например. Если 0, ждет до бесконечности. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 9 июня, 2014 Опубликовано 9 июня, 2014 · Жалоба В Keil RTX у каждой задачи могут быть до 16 событий (Event), по которым они могут выполняться. События устанавливаются в других задачах, а проверяются в планировщике. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться