Test session
Dependencies: FatFileSystem MCP23017 WattBob_TextLCD mbed
Fork of Assignment_2_herpe by
task_manager.cpp
00001 /** 00002 * This class manages all the tasks and ensures they are correctly executed. 00003 * It contains various error reporting for schedule issues. 00004 * 00005 * Currently it checks for tasks inside the called interrupt, delaying the tasks 00006 * execution slightly. This gets worse with an increasing number of tasks. 00007 * As such this should only used with a small number of tasks. 00008 * 00009 * Author: Jacob Baungard Hansen 00010 */ 00011 00012 #include "task_manager.h" 00013 00014 /** 00015 * 00016 * @param ticker_freq_ms how often we should check for tasks 00017 */ 00018 TaskManager::TaskManager(int ticker_freq_ms) { 00019 this->current_time=0; 00020 this->ticker_freq_ms = ticker_freq_ms; 00021 } 00022 00023 /** 00024 * 00025 * @param ticker_freq_ms how often we should check for tasks 00026 * @param lcd pointer to LCDHelper object, used to display errors 00027 */ 00028 TaskManager::TaskManager(int ticker_freq_ms, LCDHelper * lcd) { 00029 this->current_time=0; 00030 this->ticker_freq_ms = ticker_freq_ms; 00031 this->lcd = lcd; 00032 } 00033 00034 // empty 00035 TaskManager::~TaskManager() {} 00036 00037 /** 00038 * Checks if any tasks needs to run, and if so run them. 00039 * Also checks for any scheduling conflicts, and ensures 00040 * the tasks execution time is not too long. 00041 */ 00042 void TaskManager::find_and_run(){ 00043 // start timer 00044 t.start(); 00045 00046 // increase current time 00047 this->current_time += this->ticker_freq_ms; 00048 00049 // if no tasks, give an error 00050 if (this->tasks.empty()) { 00051 this->schedule_error("No tasks"); 00052 this->stop(); 00053 } 00054 00055 Task * task_to_run = NULL; 00056 // check if there's any tasks to run this timetamp 00057 for (unsigned int i=0; i<this->tasks.size(); i++) { 00058 if (this->tasks[i]->get_next_run_ms() == this->current_time) { 00059 if (task_to_run == NULL ) { 00060 task_to_run = this->tasks[i]; 00061 } else { // if more than one task this timestamp, it is an error 00062 this->schedule_error("Conflict"); 00063 this->stop(); 00064 break; 00065 } 00066 } 00067 } 00068 00069 // run the found task, if any 00070 if (task_to_run != NULL) { 00071 task_to_run->increment_next_run(); 00072 task_to_run->action(); 00073 } 00074 00075 // Ensure task didn't take too long 00076 // asume messuring code taskes at least 2ms. 00077 t.stop(); 00078 if (t.read_ms() > (this->ticker_freq_ms)-2) { 00079 this->schedule_error("Task too long"); 00080 this->stop(); 00081 } 00082 // reset timer for next timeaaround 00083 t.reset(); 00084 00085 } 00086 00087 /** 00088 * Prints a scheduling error 00089 * 00090 * @param msg message to print on line2 of lcd display 00091 */ 00092 void TaskManager::schedule_error(std::string msg) { 00093 if (this->lcd != NULL) { 00094 this->lcd->print("Schedule error:", msg); 00095 } 00096 this->stop(); 00097 } 00098 00099 /** 00100 * Adds a task to the exeuction cycle 00101 * 00102 * @param task pointer to the task to add 00103 */ 00104 void TaskManager::add_task(Task * task) { 00105 // we need to ensure that the frequency for the task 00106 // and the ticker frequency is a match 00107 if (task->get_frequency_ms() % this->ticker_freq_ms != 0) { 00108 this->schedule_error("Bad task freq"); 00109 } 00110 // first possible slot for a task to run is at ticker_freq_ms (maybe this should be changed) 00111 // ensure tasks do not start earlier 00112 else if (task->get_next_run_ms() < this->ticker_freq_ms) { 00113 this->schedule_error("start<tickerfreq"); 00114 } 00115 // add task 00116 else { 00117 this->tasks.push_back(task); 00118 } 00119 } 00120 00121 /** 00122 * Removes a task to the exeuction cycle 00123 * 00124 * @param task pointer to the task to remove 00125 */ 00126 void TaskManager::remove_task(Task * task) { 00127 for (unsigned int i=0; i<this->tasks.size(); i++) { 00128 if (this->tasks[i] == task) { 00129 this->tasks.erase(this->tasks.begin()+i); 00130 break; 00131 } 00132 } 00133 } 00134 00135 /** 00136 * Starts running 00137 */ 00138 void TaskManager::start() { 00139 timestamp_t in_us = this->ticker_freq_ms*1000.0; 00140 // need to change priority in case of using 00141 // interupts in the activities. 00142 // a bit nasty 00143 NVIC_SetPriority(TIMER3_IRQn, 200); 00144 this->ticker.attach_us<TaskManager>(this, &TaskManager::find_and_run, in_us); 00145 00146 while(1) {} 00147 } 00148 00149 /** 00150 * Stops running 00151 */ 00152 void TaskManager::stop() { 00153 this->ticker.detach(); 00154 // might not want this in a general case (not sure) 00155 // although for this case it seems appropiate. 00156 while(1) {} 00157 }
Generated on Thu Jul 14 2022 10:33:15 by
1.7.2
