![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Test session
Dependencies: FatFileSystem MCP23017 WattBob_TextLCD mbed
Fork of Assignment_2_herpe by
task_manager.cpp
- Committer:
- xouf2114
- Date:
- 2017-03-14
- Revision:
- 4:48761259552a
File content as of revision 4:48761259552a:
/** * This class manages all the tasks and ensures they are correctly executed. * It contains various error reporting for schedule issues. * * Currently it checks for tasks inside the called interrupt, delaying the tasks * execution slightly. This gets worse with an increasing number of tasks. * As such this should only used with a small number of tasks. * * Author: Jacob Baungard Hansen */ #include "task_manager.h" /** * * @param ticker_freq_ms how often we should check for tasks */ TaskManager::TaskManager(int ticker_freq_ms) { this->current_time=0; this->ticker_freq_ms = ticker_freq_ms; } /** * * @param ticker_freq_ms how often we should check for tasks * @param lcd pointer to LCDHelper object, used to display errors */ TaskManager::TaskManager(int ticker_freq_ms, LCDHelper * lcd) { this->current_time=0; this->ticker_freq_ms = ticker_freq_ms; this->lcd = lcd; } // empty TaskManager::~TaskManager() {} /** * Checks if any tasks needs to run, and if so run them. * Also checks for any scheduling conflicts, and ensures * the tasks execution time is not too long. */ void TaskManager::find_and_run(){ // start timer t.start(); // increase current time this->current_time += this->ticker_freq_ms; // if no tasks, give an error if (this->tasks.empty()) { this->schedule_error("No tasks"); this->stop(); } Task * task_to_run = NULL; // check if there's any tasks to run this timetamp for (unsigned int i=0; i<this->tasks.size(); i++) { if (this->tasks[i]->get_next_run_ms() == this->current_time) { if (task_to_run == NULL ) { task_to_run = this->tasks[i]; } else { // if more than one task this timestamp, it is an error this->schedule_error("Conflict"); this->stop(); break; } } } // run the found task, if any if (task_to_run != NULL) { task_to_run->increment_next_run(); task_to_run->action(); } // Ensure task didn't take too long // asume messuring code taskes at least 2ms. t.stop(); if (t.read_ms() > (this->ticker_freq_ms)-2) { this->schedule_error("Task too long"); this->stop(); } // reset timer for next timeaaround t.reset(); } /** * Prints a scheduling error * * @param msg message to print on line2 of lcd display */ void TaskManager::schedule_error(std::string msg) { if (this->lcd != NULL) { this->lcd->print("Schedule error:", msg); } this->stop(); } /** * Adds a task to the exeuction cycle * * @param task pointer to the task to add */ void TaskManager::add_task(Task * task) { // we need to ensure that the frequency for the task // and the ticker frequency is a match if (task->get_frequency_ms() % this->ticker_freq_ms != 0) { this->schedule_error("Bad task freq"); } // first possible slot for a task to run is at ticker_freq_ms (maybe this should be changed) // ensure tasks do not start earlier else if (task->get_next_run_ms() < this->ticker_freq_ms) { this->schedule_error("start<tickerfreq"); } // add task else { this->tasks.push_back(task); } } /** * Removes a task to the exeuction cycle * * @param task pointer to the task to remove */ void TaskManager::remove_task(Task * task) { for (unsigned int i=0; i<this->tasks.size(); i++) { if (this->tasks[i] == task) { this->tasks.erase(this->tasks.begin()+i); break; } } } /** * Starts running */ void TaskManager::start() { timestamp_t in_us = this->ticker_freq_ms*1000.0; // need to change priority in case of using // interupts in the activities. // a bit nasty NVIC_SetPriority(TIMER3_IRQn, 200); this->ticker.attach_us<TaskManager>(this, &TaskManager::find_and_run, in_us); while(1) {} } /** * Stops running */ void TaskManager::stop() { this->ticker.detach(); // might not want this in a general case (not sure) // although for this case it seems appropiate. while(1) {} }