GIU\ZF
Dependencies: MCP23017 WattBob_TextLCD mbed-rtos mbed
Fork of rtos_basic by
tasks/task_group1.cpp@19:2044bb5d7f29, 2018-03-28 (annotated)
- Committer:
- ihexx
- Date:
- Wed Mar 28 01:32:01 2018 +0000
- Revision:
- 19:2044bb5d7f29
- Parent:
- 17:a29ce6fc667c
- Child:
- 20:202e0046527e
Fully commented listings;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ihexx | 13:ab52f46c98ab | 1 | #include "core.h" |
ihexx | 15:524de2b2ef8e | 2 | namespace display{ |
ihexx | 19:2044bb5d7f29 | 3 | //Display on MBED text display: odometer value, average speed |
ihexx | 15:524de2b2ef8e | 4 | const float freq = 2.0f; //hz |
ihexx | 15:524de2b2ef8e | 5 | MCP23017 *port; |
ihexx | 15:524de2b2ef8e | 6 | WattBob_TextLCD *lcd; |
ihexx | 15:524de2b2ef8e | 7 | |
ihexx | 15:524de2b2ef8e | 8 | void init(){ |
ihexx | 15:524de2b2ef8e | 9 | port = new MCP23017(p9, p10, 0x40); |
ihexx | 15:524de2b2ef8e | 10 | lcd = new WattBob_TextLCD(port); |
ihexx | 15:524de2b2ef8e | 11 | port->write_bit(1,BL_BIT); // LCD backlight on. |
ihexx | 15:524de2b2ef8e | 12 | lcd->cls(); |
ihexx | 15:524de2b2ef8e | 13 | } |
ihexx | 15:524de2b2ef8e | 14 | static inline void hotLoop(){ |
ihexx | 15:524de2b2ef8e | 15 | lcd->cls(); |
ihexx | 15:524de2b2ef8e | 16 | |
ihexx | 15:524de2b2ef8e | 17 | runTimeParams::liveAccess.lock(); |
ihexx | 15:524de2b2ef8e | 18 | float odometer = runTimeParams::odometer; |
ihexx | 15:524de2b2ef8e | 19 | float avgSpeed = runTimeParams::avgSpeed; |
ihexx | 15:524de2b2ef8e | 20 | runTimeParams::liveAccess.unlock(); |
ihexx | 15:524de2b2ef8e | 21 | |
ihexx | 15:524de2b2ef8e | 22 | lcd->locate(0,0); //located col, row. |
ihexx | 15:524de2b2ef8e | 23 | lcd->printf("Odo=%.2f",odometer); |
ihexx | 15:524de2b2ef8e | 24 | |
ihexx | 15:524de2b2ef8e | 25 | lcd->locate(1,0); //located col, row. |
ihexx | 15:524de2b2ef8e | 26 | lcd->printf("Speed=%.2f",avgSpeed); |
ihexx | 15:524de2b2ef8e | 27 | } |
ihexx | 15:524de2b2ef8e | 28 | } |
ihexx | 17:a29ce6fc667c | 29 | namespace brakeIndicator{ |
ihexx | 17:a29ce6fc667c | 30 | //Show use of the brake on a LED on the RedBox Unit |
ihexx | 17:a29ce6fc667c | 31 | const float freq = 2.0f; //hz |
ihexx | 17:a29ce6fc667c | 32 | PwmOut led2(PORT_REDBOX_LED1); |
ihexx | 17:a29ce6fc667c | 33 | static inline void init(){ |
ihexx | 17:a29ce6fc667c | 34 | led2.period_ms(50); |
ihexx | 17:a29ce6fc667c | 35 | } |
ihexx | 17:a29ce6fc667c | 36 | static inline void hotLoop(){ |
ihexx | 17:a29ce6fc667c | 37 | runTimeParams::liveAccess.lock(); |
ihexx | 17:a29ce6fc667c | 38 | led2.write(runTimeParams::brakeForce); |
ihexx | 17:a29ce6fc667c | 39 | runTimeParams::liveAccess.unlock(); |
ihexx | 17:a29ce6fc667c | 40 | |
ihexx | 17:a29ce6fc667c | 41 | } |
ihexx | 17:a29ce6fc667c | 42 | } |
ihexx | 17:a29ce6fc667c | 43 | namespace speedIndicator{ |
ihexx | 17:a29ce6fc667c | 44 | //Monitor speed and if it goes over 88 mph switch on a LED on |
ihexx | 17:a29ce6fc667c | 45 | //the RedBox unit |
ihexx | 17:a29ce6fc667c | 46 | static const float freq = 1; //hz |
ihexx | 17:a29ce6fc667c | 47 | DigitalOut led(PORT_REDBOX_LED1); |
ihexx | 17:a29ce6fc667c | 48 | static inline void init(){ |
ihexx | 17:a29ce6fc667c | 49 | led = 0; |
ihexx | 17:a29ce6fc667c | 50 | } |
ihexx | 17:a29ce6fc667c | 51 | static inline void hotLoop(){ |
ihexx | 17:a29ce6fc667c | 52 | runTimeParams::liveAccess.lock(); |
ihexx | 17:a29ce6fc667c | 53 | led = (runTimeParams::avgSpeed>88); |
ihexx | 17:a29ce6fc667c | 54 | runTimeParams::liveAccess.unlock(); |
ihexx | 17:a29ce6fc667c | 55 | |
ihexx | 17:a29ce6fc667c | 56 | } |
ihexx | 17:a29ce6fc667c | 57 | } |
ihexx | 17:a29ce6fc667c | 58 | namespace sideLights{ |
ihexx | 17:a29ce6fc667c | 59 | //Read a single side light switch and set side lights accordingly |
ihexx | 17:a29ce6fc667c | 60 | static const float freq = 1; //hz |
ihexx | 17:a29ce6fc667c | 61 | DigitalIn lightSwitch(PORT_BRAKE); |
ihexx | 17:a29ce6fc667c | 62 | DigitalOut led(PORT_SIDE_LIGHTS); |
ihexx | 17:a29ce6fc667c | 63 | static inline void hotLoop(){ |
ihexx | 17:a29ce6fc667c | 64 | led = lightSwitch; |
ihexx | 17:a29ce6fc667c | 65 | } |
ihexx | 17:a29ce6fc667c | 66 | |
ihexx | 17:a29ce6fc667c | 67 | } |
ihexx | 17:a29ce6fc667c | 68 | namespace turnSignal{ |
ihexx | 17:a29ce6fc667c | 69 | //Read the two turn indicator switches and flash appropriate |
ihexx | 19:2044bb5d7f29 | 70 | //indicator LEDs at a rate of 1Hz |
ihexx | 17:a29ce6fc667c | 71 | static const float freq = 0.5; //hz |
ihexx | 17:a29ce6fc667c | 72 | DigitalIn lSwitch(PORT_TURN_SIGNAL_SWITCH_LEFT); |
ihexx | 17:a29ce6fc667c | 73 | DigitalIn rSwitch(PORT_TURN_SIGNAL_SWITCH_RIGHT); |
ihexx | 17:a29ce6fc667c | 74 | |
ihexx | 17:a29ce6fc667c | 75 | PwmOut lLed(PORT_TURN_SIGNAL_LED_LEFT); |
ihexx | 17:a29ce6fc667c | 76 | PwmOut rLed(PORT_TURN_SIGNAL_LED_RIGHT); |
ihexx | 17:a29ce6fc667c | 77 | |
ihexx | 17:a29ce6fc667c | 78 | static inline void hotLoop(){ |
ihexx | 17:a29ce6fc667c | 79 | int a = lSwitch.read(); |
ihexx | 17:a29ce6fc667c | 80 | int b = rSwitch.read(); |
ihexx | 19:2044bb5d7f29 | 81 | |
ihexx | 19:2044bb5d7f29 | 82 | //If both switches are switched on |
ihexx | 19:2044bb5d7f29 | 83 | //then flash both indicator LEDs at a rate of 2Hz (hazard mode) |
ihexx | 17:a29ce6fc667c | 84 | if(a&&b){ |
ihexx | 17:a29ce6fc667c | 85 | lLed.period(2.0f); |
ihexx | 17:a29ce6fc667c | 86 | rLed.period(2.0f); |
ihexx | 17:a29ce6fc667c | 87 | } |
ihexx | 17:a29ce6fc667c | 88 | else{ |
ihexx | 17:a29ce6fc667c | 89 | lLed.period(1.0f); |
ihexx | 17:a29ce6fc667c | 90 | rLed.period(1.0f); |
ihexx | 17:a29ce6fc667c | 91 | } |
ihexx | 17:a29ce6fc667c | 92 | a ? lLed.write(0.5f) : lLed.write(0.0f); |
ihexx | 17:a29ce6fc667c | 93 | b ? rLed.write(0.5f) : rLed.write(0.0f); |
ihexx | 17:a29ce6fc667c | 94 | } |
ihexx | 17:a29ce6fc667c | 95 | |
ihexx | 17:a29ce6fc667c | 96 | } |
ihexx | 17:a29ce6fc667c | 97 | |
ihexx | 17:a29ce6fc667c | 98 | |
ihexx | 17:a29ce6fc667c | 99 | |
ihexx | 17:a29ce6fc667c | 100 | |
ihexx | 13:ab52f46c98ab | 101 | |
ihexx | 13:ab52f46c98ab | 102 | namespace task_group_1{ |
ihexx | 13:ab52f46c98ab | 103 | Thread thread; |
ihexx | 13:ab52f46c98ab | 104 | const float freq = 2.0f; //hz |
ihexx | 13:ab52f46c98ab | 105 | |
ihexx | 13:ab52f46c98ab | 106 | |
ihexx | 13:ab52f46c98ab | 107 | void runTask(){ |
ihexx | 13:ab52f46c98ab | 108 | Timer executionTimer,sleepTimer; |
ihexx | 13:ab52f46c98ab | 109 | executionTimer.reset(); |
ihexx | 13:ab52f46c98ab | 110 | sleepTimer.reset(); |
ihexx | 17:a29ce6fc667c | 111 | |
ihexx | 13:ab52f46c98ab | 112 | display::init(); |
ihexx | 17:a29ce6fc667c | 113 | brakeIndicator::init(); |
ihexx | 17:a29ce6fc667c | 114 | speedIndicator::init(); |
ihexx | 13:ab52f46c98ab | 115 | |
ihexx | 19:2044bb5d7f29 | 116 | const int const_delay = int((1000.0f/freq)+0.5f); //ideal sched delay |
ihexx | 19:2044bb5d7f29 | 117 | int dynamic_delay = const_delay; //real sched delay (updated in loop) |
ihexx | 19:2044bb5d7f29 | 118 | |
ihexx | 19:2044bb5d7f29 | 119 | int tick = 0; //freq subsampler |
ihexx | 19:2044bb5d7f29 | 120 | #if DEBUG_MODE |
ihexx | 19:2044bb5d7f29 | 121 | int max_exec_time = 0; //for logging |
ihexx | 19:2044bb5d7f29 | 122 | #endif |
ihexx | 17:a29ce6fc667c | 123 | |
ihexx | 13:ab52f46c98ab | 124 | while(true){ |
ihexx | 19:2044bb5d7f29 | 125 | //Determine scheduling compensators: |
ihexx | 19:2044bb5d7f29 | 126 | //1: release time drift |
ihexx | 19:2044bb5d7f29 | 127 | //2: execution time |
ihexx | 13:ab52f46c98ab | 128 | sleepTimer.stop(); |
ihexx | 13:ab52f46c98ab | 129 | executionTimer.start(); |
ihexx | 13:ab52f46c98ab | 130 | int sleepTime = sleepTimer.read_ms(); |
ihexx | 13:ab52f46c98ab | 131 | const int drift = ((sleepTime - dynamic_delay) > 0)? |
ihexx | 13:ab52f46c98ab | 132 | (sleepTime - dynamic_delay) : 0; |
ihexx | 13:ab52f46c98ab | 133 | |
ihexx | 13:ab52f46c98ab | 134 | |
ihexx | 19:2044bb5d7f29 | 135 | // Run all tasks-------------- |
ihexx | 17:a29ce6fc667c | 136 | brakeIndicator::hotLoop(); |
ihexx | 16:0ada6cbd41e2 | 137 | |
ihexx | 17:a29ce6fc667c | 138 | static const int tick_interval_sIndicator = int((freq/speedIndicator::freq)+0.5f); |
ihexx | 17:a29ce6fc667c | 139 | if (!(tick%tick_interval_sIndicator)){ |
ihexx | 17:a29ce6fc667c | 140 | speedIndicator::hotLoop(); |
ihexx | 17:a29ce6fc667c | 141 | sideLights::hotLoop(); |
ihexx | 17:a29ce6fc667c | 142 | } |
ihexx | 17:a29ce6fc667c | 143 | static const int tick_interval_tSignal = int((freq/turnSignal::freq)+0.5f); |
ihexx | 17:a29ce6fc667c | 144 | if (!(tick%tick_interval_tSignal)){ |
ihexx | 17:a29ce6fc667c | 145 | turnSignal::hotLoop(); |
ihexx | 17:a29ce6fc667c | 146 | } |
ihexx | 17:a29ce6fc667c | 147 | display::hotLoop(); |
ihexx | 19:2044bb5d7f29 | 148 | //--------------Completed tasks |
ihexx | 13:ab52f46c98ab | 149 | |
ihexx | 14:8a6c20435523 | 150 | tick++; |
ihexx | 13:ab52f46c98ab | 151 | executionTimer.stop(); |
ihexx | 13:ab52f46c98ab | 152 | int exec_time = executionTimer.read_ms(); |
ihexx | 19:2044bb5d7f29 | 153 | |
ihexx | 13:ab52f46c98ab | 154 | |
ihexx | 13:ab52f46c98ab | 155 | #if DEBUG_MODE |
ihexx | 19:2044bb5d7f29 | 156 | //Debug Logs (once per dequeue call to avoid memory issues) |
ihexx | 19:2044bb5d7f29 | 157 | if (exec_time > max_exec_time) max_exec_time=exec_time; |
ihexx | 15:524de2b2ef8e | 158 | static const int tick_interval_debug_log = int((freq/dequeueMail::freq)+0.5f); |
ihexx | 15:524de2b2ef8e | 159 | if (!(tick%tick_interval_debug_log)){ |
ihexx | 17:a29ce6fc667c | 160 | runTimeParams::debugAccess.lock(); |
ihexx | 17:a29ce6fc667c | 161 | *runTimeParams::debugLog += "task_group_1," + to_string(max_exec_time) + "," |
ihexx | 14:8a6c20435523 | 162 | + to_string(sleepTime) + "," |
ihexx | 14:8a6c20435523 | 163 | + to_string(drift) + "\n\r"; |
ihexx | 17:a29ce6fc667c | 164 | runTimeParams::debugAccess.unlock(); |
ihexx | 14:8a6c20435523 | 165 | } |
ihexx | 17:a29ce6fc667c | 166 | #else |
ihexx | 17:a29ce6fc667c | 167 | static const int tick_interval_debug_log = 1; |
ihexx | 13:ab52f46c98ab | 168 | #endif |
ihexx | 19:2044bb5d7f29 | 169 | //Reset tick count |
ihexx | 17:a29ce6fc667c | 170 | static const int tick_LCM = |
ihexx | 17:a29ce6fc667c | 171 | tick_interval_debug_log* |
ihexx | 17:a29ce6fc667c | 172 | tick_interval_sIndicator* |
ihexx | 17:a29ce6fc667c | 173 | tick_interval_tSignal; |
ihexx | 17:a29ce6fc667c | 174 | |
ihexx | 17:a29ce6fc667c | 175 | if (tick==tick_LCM) tick=0; |
ihexx | 17:a29ce6fc667c | 176 | |
ihexx | 19:2044bb5d7f29 | 177 | |
ihexx | 13:ab52f46c98ab | 178 | executionTimer.reset(); |
ihexx | 13:ab52f46c98ab | 179 | sleepTimer.reset(); |
ihexx | 13:ab52f46c98ab | 180 | sleepTimer.start(); |
ihexx | 19:2044bb5d7f29 | 181 | //compensate for delays |
ihexx | 13:ab52f46c98ab | 182 | dynamic_delay = const_delay - (exec_time + drift); |
ihexx | 13:ab52f46c98ab | 183 | Thread::wait(dynamic_delay); |
ihexx | 13:ab52f46c98ab | 184 | } |
ihexx | 13:ab52f46c98ab | 185 | } |
ihexx | 13:ab52f46c98ab | 186 | } |