GIU\ZF
Dependencies: MCP23017 WattBob_TextLCD mbed-rtos mbed
Fork of rtos_basic by
Revision 19:2044bb5d7f29, committed 2018-03-28
- Comitter:
- ihexx
- Date:
- Wed Mar 28 01:32:01 2018 +0000
- Parent:
- 18:d48324fd3440
- Child:
- 20:202e0046527e
- Commit message:
- Fully commented listings;
Changed in this revision
--- a/tasks/MailTasks.cpp Wed Mar 28 00:47:12 2018 +0000 +++ b/tasks/MailTasks.cpp Wed Mar 28 01:32:01 2018 +0000 @@ -9,10 +9,8 @@ Thread thread; const float freq = 0.2; //hz - //I/O void runTask(){ - Timer executionTimer,sleepTimer; executionTimer.reset(); sleepTimer.reset(); @@ -22,12 +20,15 @@ int tick = 0; while(1){ + //Determine scheduling compensators: + //1: release time drift + //2: execution time sleepTimer.stop(); executionTimer.start(); int sleepTime = sleepTimer.read_ms(); const int drift = ((sleepTime - dynamic_delay) > 0)? (sleepTime - dynamic_delay) : 0; - //Core Loop: + //Core Task----------------- using namespace mailData; mail_t *mail = mailBox.alloc(); @@ -40,13 +41,14 @@ runTimeParams::liveAccess.unlock(); mailBox.put(mail); - //End of Core loop + //End of Core task tick++; executionTimer.stop(); int exec_time = executionTimer.read_ms(); #if DEBUG_MODE + //Debug Logs (once per dequeue call to avoid memory issues) const int debug_log_interval = int(freq/dequeueMail::freq); if (!(tick%debug_log_interval)){ runTimeParams::debugAccess.lock(); @@ -58,10 +60,12 @@ } #endif + executionTimer.reset(); sleepTimer.reset(); sleepTimer.start(); + //compensate for delays dynamic_delay = const_delay - (exec_time + drift); Thread::wait(dynamic_delay); } @@ -72,15 +76,12 @@ namespace dequeueMail{ //Dump contents of feature_7 MAIL queue to the serial connection to the PC Thread thread; - const float freq = 0.05; //hz - - Serial pc(USBTX, USBRX); // tx, rx - void runTask(){ + //init Timer executionTimer,sleepTimer; executionTimer.reset(); sleepTimer.reset(); @@ -91,14 +92,16 @@ pc.printf("speed,acceleration,brake\n\r"); while(true){ - + //Determine scheduling compensators: + //1: release time drift + //2: execution time sleepTimer.stop(); executionTimer.start(); int sleepTime = sleepTimer.read_ms(); const int drift = ((sleepTime - dynamic_delay) > 0)? (sleepTime - dynamic_delay) : 0; - /* Mail */ + // Mail Dump------------ using namespace mailData; osEvent evt = mailBox.get(1); while (evt.status == osEventMail){ @@ -107,15 +110,19 @@ mailBox.free(mail); evt = mailBox.get(1); } + //---------------------- executionTimer.stop(); int exec_time = executionTimer.read_ms(); #if DEBUG_MODE + //Debug Logs (once per dequeue call to avoid memory issues) runTimeParams::debugAccess.lock(); *runTimeParams::debugLog += "Dequeue Mail," + to_string(exec_time) + "," + to_string(sleepTime) + "," + to_string(drift) + "\n\r"; + + //Buffer Swap so other tasks can prempt this one and keep logging string * message; if (runTimeParams::debugLog == & runTimeParams::debugLogBuffer1){ runTimeParams::debugLog = & runTimeParams::debugLogBuffer2; @@ -129,8 +136,6 @@ runTimeParams::debugAccess.unlock(); pc.printf(message->c_str()); - - #endif executionTimer.reset();
--- a/tasks/core.h Wed Mar 28 00:47:12 2018 +0000 +++ b/tasks/core.h Wed Mar 28 01:32:01 2018 +0000 @@ -8,7 +8,7 @@ #include <sstream> //Compile Flags -#define DEBUG_MODE 1 +#define DEBUG_MODE 0 //Inputs------------------------- #define PORT_TURN_SIGNAL_SWITCH_RIGHT p17 @@ -52,14 +52,11 @@ namespace task_group_1{ //Display, extern Thread thread; - extern const float freq; //hz - void runTask(); } namespace task_group_2{ //Read Accel/Brake, carSimulator extern Thread thread; - extern const float freq; void runTask(); } @@ -76,7 +73,6 @@ //Send speed, accelerometer and brake values to a 100 element //MAIL queue extern Thread thread; - extern const float freq; void runTask(); } namespace dequeueMail{
--- a/tasks/task_group1.cpp Wed Mar 28 00:47:12 2018 +0000 +++ b/tasks/task_group1.cpp Wed Mar 28 01:32:01 2018 +0000 @@ -1,9 +1,7 @@ #include "core.h" namespace display{ - //Display on MBED text display • odometer value • average speed + //Display on MBED text display: odometer value, average speed const float freq = 2.0f; //hz - - //I/O MCP23017 *port; WattBob_TextLCD *lcd; @@ -69,11 +67,8 @@ } namespace turnSignal{ //Read the two turn indicator switches and flash appropriate - //indicator LEDs at a rate of 1Hz. If both switches are switched on - //then flash both indicator LEDs at a rate of 2Hz (hazard mode). + //indicator LEDs at a rate of 1Hz static const float freq = 0.5; //hz - - //I/O DigitalIn lSwitch(PORT_TURN_SIGNAL_SWITCH_LEFT); DigitalIn rSwitch(PORT_TURN_SIGNAL_SWITCH_RIGHT); @@ -83,6 +78,9 @@ static inline void hotLoop(){ int a = lSwitch.read(); int b = rSwitch.read(); + + //If both switches are switched on + //then flash both indicator LEDs at a rate of 2Hz (hazard mode) if(a&&b){ lLed.period(2.0f); rLed.period(2.0f); @@ -115,12 +113,18 @@ brakeIndicator::init(); speedIndicator::init(); - const int const_delay = int((1000.0f/freq)+0.5f); - int dynamic_delay = const_delay; - int tick = 0; - int max_exec_time = 0; + const int const_delay = int((1000.0f/freq)+0.5f); //ideal sched delay + int dynamic_delay = const_delay; //real sched delay (updated in loop) + + int tick = 0; //freq subsampler + #if DEBUG_MODE + int max_exec_time = 0; //for logging + #endif while(true){ + //Determine scheduling compensators: + //1: release time drift + //2: execution time sleepTimer.stop(); executionTimer.start(); int sleepTime = sleepTimer.read_ms(); @@ -128,8 +132,7 @@ (sleepTime - dynamic_delay) : 0; - // Run all tasks - + // Run all tasks-------------- brakeIndicator::hotLoop(); static const int tick_interval_sIndicator = int((freq/speedIndicator::freq)+0.5f); @@ -141,15 +144,17 @@ if (!(tick%tick_interval_tSignal)){ turnSignal::hotLoop(); } - display::hotLoop(); + //--------------Completed tasks tick++; executionTimer.stop(); int exec_time = executionTimer.read_ms(); - if (exec_time > max_exec_time) max_exec_time=exec_time; + #if DEBUG_MODE + //Debug Logs (once per dequeue call to avoid memory issues) + if (exec_time > max_exec_time) max_exec_time=exec_time; static const int tick_interval_debug_log = int((freq/dequeueMail::freq)+0.5f); if (!(tick%tick_interval_debug_log)){ runTimeParams::debugAccess.lock(); @@ -161,7 +166,7 @@ #else static const int tick_interval_debug_log = 1; #endif - + //Reset tick count static const int tick_LCM = tick_interval_debug_log* tick_interval_sIndicator* @@ -169,9 +174,11 @@ if (tick==tick_LCM) tick=0; + executionTimer.reset(); sleepTimer.reset(); sleepTimer.start(); + //compensate for delays dynamic_delay = const_delay - (exec_time + drift); Thread::wait(dynamic_delay); }
--- a/tasks/task_group2.cpp Wed Mar 28 00:47:12 2018 +0000 +++ b/tasks/task_group2.cpp Wed Mar 28 01:32:01 2018 +0000 @@ -1,9 +1,8 @@ #include "core.h" namespace getControls{ - //I/O + //Read Accelerator and Brake AnalogIn brake(PORT_BRAKE); AnalogIn accel(PORT_ACCEL); - const float freq = 10.0f; static inline void hotLoop(){ @@ -15,9 +14,7 @@ } namespace getIgnition{ //Read engine on/off switch and show current state on a LED - static const float freq = 2; //hz - - //I/O + const float freq = 2; //hz DigitalIn ignition(PORT_IGNITION); DigitalOut led1(IGNITION_LED); @@ -25,22 +22,14 @@ led1 = ignition.read(); } } - namespace carSimulator{ - Thread thread; + //Compute speed given car controls and timing data const float freq = 20.0f; - static inline void hotLoop(){ - - static int i = 0; - const int i_prev = i; - i = (i>=3)? 0: i+1; - - const float friction = 0.1f; - + const float friction = 0.1f; //constant retardation runTimeParams::liveAccess.lock(); - //v2 = at+v1 + //Check if ignition is on, and don't accelerate if it isn't float accel; if (getIgnition::ignition.read()){ accel = runTimeParams::accelForce - @@ -50,10 +39,14 @@ accel= -(runTimeParams::brakeForce+friction); } + static int i = 0; //iterator for speed + const int i_prev = i; + i = (i>=3)? 0: i+1; + //Store to speed array in round robin format float tmpSpeed = accel * + runTimeParams::speed[i_prev]; runTimeParams::speed[i] = (tmpSpeed>0)?tmpSpeed:0; + runTimeParams::liveAccess.unlock(); - } } namespace filterSpeed{ @@ -65,7 +58,6 @@ runTimeParams::speed[1] + runTimeParams::speed[2])/3; runTimeParams::liveAccess.unlock(); - } } @@ -73,24 +65,27 @@ namespace task_group_2{ Thread thread; const float freq = 20.0f; //hz - DigitalOut led2(LED2); void runTask(){ + //Init Timer executionTimer,sleepTimer; executionTimer.reset(); sleepTimer.reset(); - const int const_delay = int((1000.0f/freq)+0.5f); - int dynamic_delay = const_delay; - int tick = 0; - int max_exec_time = 0; + const int const_delay = int((1000.0f/freq)+0.5f); //ideal scheduling rate + int dynamic_delay = const_delay; //compensating for release/execution time + int tick = 0; //downsample task frequencies + + #if DEBUG_MODE + int max_exec_time = 0; //for logging + #endif + while(true){ - - + //Determine scheduling compensators: + //1: release time drift + //2: execution time sleepTimer.stop(); executionTimer.start(); - - int sleepTime = sleepTimer.read_ms(); const int drift = ((sleepTime - dynamic_delay) > 0)? (sleepTime - dynamic_delay) : 0; @@ -107,14 +102,16 @@ static const int tick_interval_ignitionLED = int((freq/getIgnition::freq)+0.5f); if (!(tick%tick_interval_ignitionLED )) getIgnition::hotLoop(); - // Completed tasks + //-------------Completed tasks tick++; executionTimer.stop(); int exec_time = executionTimer.read_ms(); - if (exec_time > max_exec_time) max_exec_time=exec_time; + #if DEBUG_MODE + //Debug Logs (once per dequeue call to avoid memory issues) + if (exec_time > max_exec_time) max_exec_time=exec_time; static const int debug_log_interval = int(freq/dequeueMail::freq); if (!(tick%debug_log_interval)){ runTimeParams::debugAccess.lock(); @@ -128,6 +125,7 @@ static const int debug_log_interval = 1; #endif + //Reset tick count static const int tick_LCM = debug_log_interval* tick_interval_ignitionLED* @@ -139,7 +137,7 @@ executionTimer.reset(); sleepTimer.reset(); sleepTimer.start(); - + //compensate for delays dynamic_delay = const_delay -(exec_time + drift); Thread::wait(dynamic_delay); }