Dubov 0 June 9, 2014 Posted June 9, 2014 (edited) · Report post Недавно задался вопросом, как лучше организовать опрос флага в ОСРВ(FreeRTOS, SYSBIOS... др.) Поясню задачу: контроллер DMA по заполнению буфера выставляет один бит в регистре готовности данных. Прочитать этот бит должна т.н. background подпрограмма. Вопрос: как осуществляется решение подобной задачи в ОСРВ? Пока на ум приходит только опрос через while(1) { if(flag == 1) data_proc(); } Есть более грамотные решения? Edited June 9, 2014 by Dubov Quote Share this post Link to post Share on other sites More sharing options...
megajohn 13 June 9, 2014 Posted June 9, 2014 · Report post создаете семафор с нулевым значением подпрограмма должна попытаться захватить семафор, но раз ноль, то подпрограмма будет заблокирована в прерывании DMA освобождаете семафор, и сразу после этого планировщик переведет вашу задачу в состояние ready P.S. Пишите RTOS или ОСРВ, вы же не пишите Москоу Quote Share this post Link to post Share on other sites More sharing options...
Intel4004 1 June 9, 2014 Posted June 9, 2014 · Report post Ну, обычно этот-же бит является флагом прерывания. Написать обработчик этого прерывания, который будет взводить семафор, а в background-подпрограмме ждать его. Quote Share this post Link to post Share on other sites More sharing options...
Dubov 0 June 9, 2014 Posted June 9, 2014 (edited) · Report post Сколько не смотрю примеры, а от 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(); } } } Edited June 9, 2014 by Dubov Quote Share this post Link to post Share on other sites More sharing options...
megajohn 13 June 9, 2014 Posted June 9, 2014 · Report post когда не пришло прерывание, этот task находится в Event_pend в заблокированном состоянии, и дает возможность выполнятся более низкоприоритетным задачам. Если же тупо опрашивать бит, то процессор впустую будет молотить на одном месте Quote Share this post Link to post Share on other sites More sharing options...
andrewlekar 0 June 9, 2014 Posted June 9, 2014 · Report post Вопрос: как осуществляется решение подобной задачи в ОСРВ? Через семафор. Однако если лень и производительность не критична, можно тупо читать битовый флаг. А также можно читать флаги и переменные без опаски до тех пор, пока они не превышают размера регистра процессора. Quote Share this post Link to post Share on other sites More sharing options...
A. Fig Lee 0 June 9, 2014 Posted June 9, 2014 · Report post Че его организовывать? В CoOS: ret = CoWaitForSingleFlag(myFlag, 10); ждет 10 миллисекунд, например. Если 0, ждет до бесконечности. Quote Share this post Link to post Share on other sites More sharing options...
ViKo 1 June 9, 2014 Posted June 9, 2014 · Report post В Keil RTX у каждой задачи могут быть до 16 событий (Event), по которым они могут выполняться. События устанавливаются в других задачах, а проверяются в планировщике. Quote Share this post Link to post Share on other sites More sharing options...