| Patrick Venture | d801218 | 2018-03-08 08:21:38 -0800 | [diff] [blame] | 1 | /** | 
|  | 2 | * Copyright 2017 Google Inc. | 
|  | 3 | * | 
|  | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 5 | * you may not use this file except in compliance with the License. | 
|  | 6 | * You may obtain a copy of the License at | 
|  | 7 | * | 
|  | 8 | *     http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 9 | * | 
|  | 10 | * Unless required by applicable law or agreed to in writing, software | 
|  | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 13 | * See the License for the specific language governing permissions and | 
|  | 14 | * limitations under the License. | 
|  | 15 | */ | 
|  | 16 |  | 
|  | 17 | #include <chrono> | 
|  | 18 | #include <map> | 
|  | 19 | #include <memory> | 
|  | 20 | #include <thread> | 
|  | 21 | #include <vector> | 
|  | 22 |  | 
|  | 23 | #include "pidthread.hpp" | 
|  | 24 |  | 
|  | 25 | #include "pid/controller.hpp" | 
|  | 26 | #include "sensors/sensor.hpp" | 
|  | 27 |  | 
|  | 28 |  | 
| Patrick Venture | 5c7cc54 | 2018-06-11 14:29:38 -0700 | [diff] [blame] | 29 | static void ProcessThermals(PIDZone* zone) | 
| Patrick Venture | d801218 | 2018-03-08 08:21:38 -0800 | [diff] [blame] | 30 | { | 
|  | 31 | // Get the latest margins. | 
|  | 32 | zone->updateSensors(); | 
|  | 33 | // Zero out the RPM set point goals. | 
|  | 34 | zone->clearRPMSetPoints(); | 
|  | 35 | // Run the margin PIDs. | 
|  | 36 | zone->process_thermals(); | 
|  | 37 | // Get the maximum RPM set-point. | 
|  | 38 | zone->determineMaxRPMRequest(); | 
|  | 39 | } | 
|  | 40 |  | 
|  | 41 |  | 
| Patrick Venture | 5c7cc54 | 2018-06-11 14:29:38 -0700 | [diff] [blame] | 42 | void PIDControlThread(PIDZone* zone) | 
| Patrick Venture | d801218 | 2018-03-08 08:21:38 -0800 | [diff] [blame] | 43 | { | 
|  | 44 | int ms100cnt = 0; | 
|  | 45 | /* | 
|  | 46 | * This should sleep on the conditional wait for the listen thread to tell | 
|  | 47 | * us it's in sync.  But then we also need a timeout option in case | 
|  | 48 | * phosphor-hwmon is down, we can go into some weird failure more. | 
|  | 49 | * | 
|  | 50 | * Another approach would be to start all sensors in worst-case values, | 
|  | 51 | * and fail-safe mode and then clear out of fail-safe mode once we start | 
|  | 52 | * getting values.  Which I think it is a solid approach. | 
|  | 53 | * | 
|  | 54 | * For now this runs before it necessarily has any sensor values.  For the | 
|  | 55 | * host sensors they start out in fail-safe mode.  For the fans, they start | 
|  | 56 | * out as 0 as input and then are adjusted once they have values. | 
|  | 57 | * | 
|  | 58 | * If a fan has failed, it's value will be whatever we're told or however | 
|  | 59 | * we retrieve it.  This program disregards fan values of 0, so any code | 
|  | 60 | * providing a fan speed can set to 0 on failure and that fan value will be | 
|  | 61 | * effectively ignored.  The PID algorithm will be unhappy but nothing bad | 
|  | 62 | * will happen. | 
|  | 63 | * | 
|  | 64 | * TODO(venture): If the fan value is 0 should that loop just be skipped? | 
|  | 65 | * Right now, a 0 value is ignored in FanController::input_proc() | 
|  | 66 | */ | 
|  | 67 | #ifdef __TUNING_LOGGING__ | 
|  | 68 | zone->initializeLog(); | 
|  | 69 | #endif | 
|  | 70 | zone->initializeCache(); | 
|  | 71 | ProcessThermals(zone); | 
|  | 72 |  | 
|  | 73 | while (true) | 
|  | 74 | { | 
|  | 75 | using namespace std::literals::chrono_literals; | 
|  | 76 | std::this_thread::sleep_for(0.1s); | 
|  | 77 |  | 
|  | 78 | // Check if we should just go back to sleep. | 
|  | 79 | if (zone->getManualMode()) | 
|  | 80 | { | 
|  | 81 | continue; | 
|  | 82 | } | 
|  | 83 |  | 
|  | 84 | // Get the latest fan speeds. | 
|  | 85 | zone->updateFanTelemetry(); | 
|  | 86 |  | 
|  | 87 | if (10 <= ms100cnt) | 
|  | 88 | { | 
|  | 89 | ms100cnt = 0; | 
|  | 90 |  | 
|  | 91 | ProcessThermals(zone); | 
|  | 92 | } | 
|  | 93 |  | 
|  | 94 | // Run the fan PIDs every iteration. | 
|  | 95 | zone->process_fans(); | 
|  | 96 |  | 
|  | 97 | #ifdef __TUNING_LOGGING__ | 
| Patrick Venture | 5f02ad2 | 2018-04-24 10:18:40 -0700 | [diff] [blame] | 98 | zone->getLogHandle() << "," << zone->getFailSafeMode(); | 
| Patrick Venture | d801218 | 2018-03-08 08:21:38 -0800 | [diff] [blame] | 99 | zone->getLogHandle() << std::endl; | 
|  | 100 | #endif | 
|  | 101 |  | 
|  | 102 | ms100cnt += 1; | 
|  | 103 | } | 
|  | 104 |  | 
|  | 105 | return; | 
|  | 106 | } | 
|  | 107 |  | 
|  | 108 |  |