Как по проще организовать обработку очереди

33 views
Skip to first unread message

cham...@mail.ru

unread,
Mar 25, 2016, 2:03:48 PM3/25/16
to uOS embedded
Не подскажите, как по проще организовать обработку очереди.

Есть массив указателей (Buf), который нужно постепенно обрабатывать. Заполнение массива указателей происходит из прерывания (sys_handler).
Есть задача обработчик (task_obrabotka) и задача (task_razbor), которая разбирает массив указателей и посылает в задачу обработчик.

Приблизительно так:

ARRAY(stack_test1, 1000);
ARRAY(stack_test2, 1000);
ARRAY(stack_test3, 1000);

mutex_t lock1;
mutex_t lock2;
mutex_t lock3;
unsigned int *Buf[100]; //Массив указателей
int n = 0; //Размер массива указателей


void uos_init()
{

    //Задача: Обработчик очереди
    task_create(task_obrabotka, 0, "", 2, stack_test1, sizeof(stack_test1));
    //Задача: Передача указателей в обработчик очереди
    task_create(task_razbor, 0, "", 1, stack_test2, sizeof(stack_test2));
    //Задача: Обработчик прерываний
    task_create(task_irq, 0, "", 3, stack_test3, sizeof(stack_test3));   
}


//Задача: Обработчик очереди
void task_obrabotka(void* arg)
{   
    while (1)
    {
        mutex_lock(&lock1);
        mutex_wait(&lock1);
        debug_printf("Что-то делаем...");
        mutex_unlock(&lock1);
    }
}

//Задача: Передача указателей в обработчик очереди
void task_razbor(void* arg)
{   
    while (1)
    {
        mutex_lock(&lock2);
        mutex_wait(&lock2);

        while (n > 0) {
            mutex_signal (&lock1, (void *)Buf[n]);

            n--;

            //Ожидаем завершения задачи обработчика
            mutex_lock(&lock1);
            mutex_unlock(&lock1);
                  }


        mutex_unlock(&lock2);
    }
}




static bool_t sys_handler(void *arg)
{

    //Например добавим три указателя
    Buf[1] = ...;
    Buf[2] = ...;
    Buf[3] = ...;
    n = 3;

    //Постановка задачи в очередь
    mutex_activate (&lock2, 0);

    return 0; //Прерывание не полностью обработано, чтобы произошло переключение задач.
}


//Задача: Обработчик прерываний
void task_irq(void* arg)
{   
    mutex_attach_irq(&lock3, 15, sys_handler, 0);
    while (1)
    {
        mutex_wait(&lock3);

    }
}




Александр Литягин

unread,
Mar 25, 2016, 4:13:01 PM3/25/16
to uOS embedded
1) мне кажется task_irq и task_razbor стоит слить в одну задачу - task_razbor оставиить, и повесить обработчик на lock2.
2) цикл вида
    while (1)
    {
        mutex_lock(&lock1);
        mutex_wait(&lock1);
        debug_printf("Что-то делаем...");
        mutex_unlock(&lock1);
    }
неудачен, более адекватный вариант его:
    mutex_lock(&lock1);
    while (1)
    {

        mutex_wait(&lock1);
        debug_printf("Что-то делаем...");
    }
    mutex_unlock(&lock1);

ибо mutex_wait - он собственно и есть все в одном флаконе - и lock и unlock


пятница, 25 марта 2016 г., 20:03:48 UTC+2 пользователь cham...@mail.ru написал:

cham...@mail.ru

unread,
Mar 26, 2016, 12:50:01 PM3/26/16
to uOS embedded
1) мне кажется task_irq и task_razbor стоит слить в одну задачу - task_razbor оставиить, и повесить обработчик на lock2.

А, не получится коллизия, т. к. task_irq имеет более высокий приоритет, а task_razbor соответственно более низкий. Задача task_razbor может пропустить сообщения не успев встать в mutex_wait(&lock1); ???

Александр Литягин

unread,
Mar 27, 2016, 12:59:12 PM3/27/16
to uOS embedded
а это неизбежная коллизия, task_irq от нее тоже не застрахована. судя потому что Вы используете mutex_awake - вы догадываетесь что этот хандлер во всей программе единственный - более менее реал-тайм. вот он один точно будет вызываться на каждое прерывание. а вот задача task_irq - крутится в уровне юзера точно так же как и все остальные задачи, и может пропускать собщения.

содержимое task_razbor - тоже както пустовато, и складывается ощущение что она тоже лишняя. я б оставил одну task_orabotka, пусть она прямо на мутехе прерывания крутится, разбирает очередь и обрабатыает ее же.
просто не видно из вашего приложения зачем разделять разборку и обработку в разные задачи. если б вы разбирали очередь на несколько разных задач -разных ядер, или обрабатывали обной задачей сообщения от нескольких разных задач - было б понятно. а так - один источник и один обработчик, какой смысл накручивать промежуточные нитки?

суббота, 26 марта 2016 г., 18:50:01 UTC+2 пользователь Alex написал:
Reply all
Reply to author
Forward
0 new messages