Test session

Dependencies:   FatFileSystem MCP23017 WattBob_TextLCD mbed

Fork of Assignment_2_herpe by Xavier Herpe

Committer:
xouf2114
Date:
Tue Mar 14 14:46:43 2017 +0000
Revision:
4:48761259552a
Test of Assignment 2

Who changed what in which revision?

UserRevisionLine numberNew contents of line
xouf2114 4:48761259552a 1 /**
xouf2114 4:48761259552a 2 * This class manages all the tasks and ensures they are correctly executed.
xouf2114 4:48761259552a 3 * It contains various error reporting for schedule issues.
xouf2114 4:48761259552a 4 *
xouf2114 4:48761259552a 5 * Currently it checks for tasks inside the called interrupt, delaying the tasks
xouf2114 4:48761259552a 6 * execution slightly. This gets worse with an increasing number of tasks.
xouf2114 4:48761259552a 7 * As such this should only used with a small number of tasks.
xouf2114 4:48761259552a 8 *
xouf2114 4:48761259552a 9 * Author: Jacob Baungard Hansen
xouf2114 4:48761259552a 10 */
xouf2114 4:48761259552a 11
xouf2114 4:48761259552a 12 #include "task_manager.h"
xouf2114 4:48761259552a 13
xouf2114 4:48761259552a 14 /**
xouf2114 4:48761259552a 15 *
xouf2114 4:48761259552a 16 * @param ticker_freq_ms how often we should check for tasks
xouf2114 4:48761259552a 17 */
xouf2114 4:48761259552a 18 TaskManager::TaskManager(int ticker_freq_ms) {
xouf2114 4:48761259552a 19 this->current_time=0;
xouf2114 4:48761259552a 20 this->ticker_freq_ms = ticker_freq_ms;
xouf2114 4:48761259552a 21 }
xouf2114 4:48761259552a 22
xouf2114 4:48761259552a 23 /**
xouf2114 4:48761259552a 24 *
xouf2114 4:48761259552a 25 * @param ticker_freq_ms how often we should check for tasks
xouf2114 4:48761259552a 26 * @param lcd pointer to LCDHelper object, used to display errors
xouf2114 4:48761259552a 27 */
xouf2114 4:48761259552a 28 TaskManager::TaskManager(int ticker_freq_ms, LCDHelper * lcd) {
xouf2114 4:48761259552a 29 this->current_time=0;
xouf2114 4:48761259552a 30 this->ticker_freq_ms = ticker_freq_ms;
xouf2114 4:48761259552a 31 this->lcd = lcd;
xouf2114 4:48761259552a 32 }
xouf2114 4:48761259552a 33
xouf2114 4:48761259552a 34 // empty
xouf2114 4:48761259552a 35 TaskManager::~TaskManager() {}
xouf2114 4:48761259552a 36
xouf2114 4:48761259552a 37 /**
xouf2114 4:48761259552a 38 * Checks if any tasks needs to run, and if so run them.
xouf2114 4:48761259552a 39 * Also checks for any scheduling conflicts, and ensures
xouf2114 4:48761259552a 40 * the tasks execution time is not too long.
xouf2114 4:48761259552a 41 */
xouf2114 4:48761259552a 42 void TaskManager::find_and_run(){
xouf2114 4:48761259552a 43 // start timer
xouf2114 4:48761259552a 44 t.start();
xouf2114 4:48761259552a 45
xouf2114 4:48761259552a 46 // increase current time
xouf2114 4:48761259552a 47 this->current_time += this->ticker_freq_ms;
xouf2114 4:48761259552a 48
xouf2114 4:48761259552a 49 // if no tasks, give an error
xouf2114 4:48761259552a 50 if (this->tasks.empty()) {
xouf2114 4:48761259552a 51 this->schedule_error("No tasks");
xouf2114 4:48761259552a 52 this->stop();
xouf2114 4:48761259552a 53 }
xouf2114 4:48761259552a 54
xouf2114 4:48761259552a 55 Task * task_to_run = NULL;
xouf2114 4:48761259552a 56 // check if there's any tasks to run this timetamp
xouf2114 4:48761259552a 57 for (unsigned int i=0; i<this->tasks.size(); i++) {
xouf2114 4:48761259552a 58 if (this->tasks[i]->get_next_run_ms() == this->current_time) {
xouf2114 4:48761259552a 59 if (task_to_run == NULL ) {
xouf2114 4:48761259552a 60 task_to_run = this->tasks[i];
xouf2114 4:48761259552a 61 } else { // if more than one task this timestamp, it is an error
xouf2114 4:48761259552a 62 this->schedule_error("Conflict");
xouf2114 4:48761259552a 63 this->stop();
xouf2114 4:48761259552a 64 break;
xouf2114 4:48761259552a 65 }
xouf2114 4:48761259552a 66 }
xouf2114 4:48761259552a 67 }
xouf2114 4:48761259552a 68
xouf2114 4:48761259552a 69 // run the found task, if any
xouf2114 4:48761259552a 70 if (task_to_run != NULL) {
xouf2114 4:48761259552a 71 task_to_run->increment_next_run();
xouf2114 4:48761259552a 72 task_to_run->action();
xouf2114 4:48761259552a 73 }
xouf2114 4:48761259552a 74
xouf2114 4:48761259552a 75 // Ensure task didn't take too long
xouf2114 4:48761259552a 76 // asume messuring code taskes at least 2ms.
xouf2114 4:48761259552a 77 t.stop();
xouf2114 4:48761259552a 78 if (t.read_ms() > (this->ticker_freq_ms)-2) {
xouf2114 4:48761259552a 79 this->schedule_error("Task too long");
xouf2114 4:48761259552a 80 this->stop();
xouf2114 4:48761259552a 81 }
xouf2114 4:48761259552a 82 // reset timer for next timeaaround
xouf2114 4:48761259552a 83 t.reset();
xouf2114 4:48761259552a 84
xouf2114 4:48761259552a 85 }
xouf2114 4:48761259552a 86
xouf2114 4:48761259552a 87 /**
xouf2114 4:48761259552a 88 * Prints a scheduling error
xouf2114 4:48761259552a 89 *
xouf2114 4:48761259552a 90 * @param msg message to print on line2 of lcd display
xouf2114 4:48761259552a 91 */
xouf2114 4:48761259552a 92 void TaskManager::schedule_error(std::string msg) {
xouf2114 4:48761259552a 93 if (this->lcd != NULL) {
xouf2114 4:48761259552a 94 this->lcd->print("Schedule error:", msg);
xouf2114 4:48761259552a 95 }
xouf2114 4:48761259552a 96 this->stop();
xouf2114 4:48761259552a 97 }
xouf2114 4:48761259552a 98
xouf2114 4:48761259552a 99 /**
xouf2114 4:48761259552a 100 * Adds a task to the exeuction cycle
xouf2114 4:48761259552a 101 *
xouf2114 4:48761259552a 102 * @param task pointer to the task to add
xouf2114 4:48761259552a 103 */
xouf2114 4:48761259552a 104 void TaskManager::add_task(Task * task) {
xouf2114 4:48761259552a 105 // we need to ensure that the frequency for the task
xouf2114 4:48761259552a 106 // and the ticker frequency is a match
xouf2114 4:48761259552a 107 if (task->get_frequency_ms() % this->ticker_freq_ms != 0) {
xouf2114 4:48761259552a 108 this->schedule_error("Bad task freq");
xouf2114 4:48761259552a 109 }
xouf2114 4:48761259552a 110 // first possible slot for a task to run is at ticker_freq_ms (maybe this should be changed)
xouf2114 4:48761259552a 111 // ensure tasks do not start earlier
xouf2114 4:48761259552a 112 else if (task->get_next_run_ms() < this->ticker_freq_ms) {
xouf2114 4:48761259552a 113 this->schedule_error("start<tickerfreq");
xouf2114 4:48761259552a 114 }
xouf2114 4:48761259552a 115 // add task
xouf2114 4:48761259552a 116 else {
xouf2114 4:48761259552a 117 this->tasks.push_back(task);
xouf2114 4:48761259552a 118 }
xouf2114 4:48761259552a 119 }
xouf2114 4:48761259552a 120
xouf2114 4:48761259552a 121 /**
xouf2114 4:48761259552a 122 * Removes a task to the exeuction cycle
xouf2114 4:48761259552a 123 *
xouf2114 4:48761259552a 124 * @param task pointer to the task to remove
xouf2114 4:48761259552a 125 */
xouf2114 4:48761259552a 126 void TaskManager::remove_task(Task * task) {
xouf2114 4:48761259552a 127 for (unsigned int i=0; i<this->tasks.size(); i++) {
xouf2114 4:48761259552a 128 if (this->tasks[i] == task) {
xouf2114 4:48761259552a 129 this->tasks.erase(this->tasks.begin()+i);
xouf2114 4:48761259552a 130 break;
xouf2114 4:48761259552a 131 }
xouf2114 4:48761259552a 132 }
xouf2114 4:48761259552a 133 }
xouf2114 4:48761259552a 134
xouf2114 4:48761259552a 135 /**
xouf2114 4:48761259552a 136 * Starts running
xouf2114 4:48761259552a 137 */
xouf2114 4:48761259552a 138 void TaskManager::start() {
xouf2114 4:48761259552a 139 timestamp_t in_us = this->ticker_freq_ms*1000.0;
xouf2114 4:48761259552a 140 // need to change priority in case of using
xouf2114 4:48761259552a 141 // interupts in the activities.
xouf2114 4:48761259552a 142 // a bit nasty
xouf2114 4:48761259552a 143 NVIC_SetPriority(TIMER3_IRQn, 200);
xouf2114 4:48761259552a 144 this->ticker.attach_us<TaskManager>(this, &TaskManager::find_and_run, in_us);
xouf2114 4:48761259552a 145
xouf2114 4:48761259552a 146 while(1) {}
xouf2114 4:48761259552a 147 }
xouf2114 4:48761259552a 148
xouf2114 4:48761259552a 149 /**
xouf2114 4:48761259552a 150 * Stops running
xouf2114 4:48761259552a 151 */
xouf2114 4:48761259552a 152 void TaskManager::stop() {
xouf2114 4:48761259552a 153 this->ticker.detach();
xouf2114 4:48761259552a 154 // might not want this in a general case (not sure)
xouf2114 4:48761259552a 155 // although for this case it seems appropiate.
xouf2114 4:48761259552a 156 while(1) {}
xouf2114 4:48761259552a 157 }