1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/pkg/openwsn/scheduler/scheduler.c
2020-10-23 15:31:57 +02:00

100 lines
2.4 KiB
C

/*
* Copyright (C) 2020 Inria
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup pkg_openwsn
* @{
*
* @file
* @brief Event based implementation of OpenWSN scheduler
*
* @author Francisco Molina <francois-xavier.molina@inria.fr>
*
* @}
*/
#include "event.h"
#include "event/callback.h"
#include "memarray.h"
#include "periph/pm.h"
#include "scheduler.h"
#include "debugpins.h"
#include "leds.h"
#ifndef LOG_LEVEL
#define LOG_LEVEL LOG_ERROR
#endif
#include "log.h"
static scheduler_vars_t _scheduler_vars;
/* event queues for every priority */
static event_queue_t _queues[TASKPRIO_MAX];
#if SCHEDULER_DEBUG_ENABLE
scheduler_dbg_t scheduler_dbg;
#endif
void scheduler_init(void)
{
#if SCHEDULER_DEBUG_ENABLE
memset(&scheduler_dbg, 0, sizeof(scheduler_dbg_t));
#endif
memset(&_scheduler_vars, 0, sizeof(scheduler_vars_t));
memarray_init(&_scheduler_vars.memarray, &_scheduler_vars.task_buff,
sizeof(event_callback_t), TASK_LIST_DEPTH);
event_queues_init_detached(_queues, TASKPRIO_MAX);
}
void scheduler_start(unsigned state)
{
irq_restore(state);
/* claim all queues */
event_queues_claim(_queues, TASKPRIO_MAX);
/* wait for events */
event_t *event;
while ((event = event_wait_multi(_queues, TASKPRIO_MAX))) {
debugpins_task_set();
event->handler(event);
/* remove from task list */
memarray_free(&_scheduler_vars.memarray, event);
#if SCHEDULER_DEBUG_ENABLE
scheduler_dbg.numTasksCur--;
#endif
debugpins_task_clr();
}
}
void scheduler_push_task(task_cbt cb, task_prio_t prio)
{
unsigned state = irq_disable();
/* get a free event from the queue */
event_callback_t *event = memarray_calloc(&_scheduler_vars.memarray);
if (!event) {
/* task list has overflown. This should never happen! */
LOG_ERROR("[openos/scheduler]: critical, task list overflow\n");
leds_error_blink();
pm_off();
}
event_callback_init(event, (void (*)(void *)) cb, NULL);
event_post(&_queues[prio], (event_t *)event);
#if SCHEDULER_DEBUG_ENABLE
scheduler_dbg.numTasksCur++;
if (scheduler_dbg.numTasksCur > scheduler_dbg.numTasksMax) {
scheduler_dbg.numTasksMax = scheduler_dbg.numTasksCur;
}
#endif
irq_restore(state);
}