This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 338b5d741563d166c248bd1c6a53d29b67a8e468
Author: wangjianyu3 <[email protected]>
AuthorDate: Fri Nov 24 23:36:57 2023 +0800

    Thermal: Support step_wise governor
    
    Signed-off-by: wangjianyu3 <[email protected]>
---
 drivers/thermal/Kconfig             |   6 ++
 drivers/thermal/Make.defs           |   4 +
 drivers/thermal/thermal_core.c      |   9 ++
 drivers/thermal/thermal_core.h      |   4 +
 drivers/thermal/thermal_step_wise.c | 182 ++++++++++++++++++++++++++++++++++++
 5 files changed, 205 insertions(+)

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 568c762edd..148a5fe08a 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -17,4 +17,10 @@ config THERMAL_DEFAULT_GOVERNOR
        ---help---
                Default governor name.
 
+config THERMAL_GOVERNOR_STEP_WISE
+       bool "Enable step wise governor"
+       default y
+       ---help---
+               Enable step wise governor.
+
 endif # THERMAL
diff --git a/drivers/thermal/Make.defs b/drivers/thermal/Make.defs
index 20c8c4f054..be098588d5 100644
--- a/drivers/thermal/Make.defs
+++ b/drivers/thermal/Make.defs
@@ -24,6 +24,10 @@ ifeq ($(CONFIG_THERMAL),y)
 
 CSRCS += thermal_core.c
 
+ifeq ($(CONFIG_THERMAL_GOVERNOR_STEP_WISE),y)
+CSRCS += thermal_step_wise.c
+endif
+
 DEPPATH += --dep-path thermal
 VPATH += thermal
 
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index a7de5fc86c..fe4d03de8c 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -839,5 +839,14 @@ int thermal_init(void)
 {
   int ret = OK;
 
+#ifdef CONFIG_THERMAL_GOVERNOR_STEP_WISE
+  ret = thermal_register_step_wise_governor();
+  if (ret < 0)
+    {
+      therr("Register step wise governor failed!\n");
+      return ret;
+    }
+#endif
+
   return ret;
 }
diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h
index 3ea97df9db..d55eff4530 100644
--- a/drivers/thermal/thermal_core.h
+++ b/drivers/thermal/thermal_core.h
@@ -73,4 +73,8 @@ int thermal_zone_get_trip_hyst(FAR struct 
thermal_zone_device_s *zdev,
                                int trip,
                                FAR int *hyst);
 
+/* Governor */
+
+int thermal_register_step_wise_governor(void);
+
 #endif /* __DRIVERS_THERMAL_THERMAL_CORE_H */
diff --git a/drivers/thermal/thermal_step_wise.c 
b/drivers/thermal/thermal_step_wise.c
new file mode 100644
index 0000000000..283f782267
--- /dev/null
+++ b/drivers/thermal/thermal_step_wise.c
@@ -0,0 +1,182 @@
+/****************************************************************************
+ * drivers/thermal/thermal_step_wise.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <debug.h>
+
+#include "thermal_core.h"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static unsigned int get_target_state(FAR struct thermal_instance_s *instance,
+                                     enum thermal_trend_e trend,
+                                     bool throttle);
+static int step_wise_throttle(FAR struct thermal_zone_device_s *zdev,
+                              int trip);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct thermal_governor_s g_step_wise_governor =
+{
+  .name = "step_wise",
+  .throttle = step_wise_throttle,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static inline unsigned int
+validate_state(FAR struct thermal_instance_s *instance, bool throttle,
+               unsigned int state, int value)
+{
+  if ((state == THERMAL_TARGET_MIN && value == -1) ||
+      (state == THERMAL_TARGET_MAX && value == 1))
+    {
+      value = 0;
+    }
+
+  if (state == THERMAL_NO_TARGET)
+    {
+      state = 0;
+    }
+
+  state += value;
+
+  if (state > instance->upper)
+    {
+      state = instance->upper;
+    }
+  else if(state < instance->lower && throttle)
+    {
+      state = instance->lower;
+    }
+
+  return state;
+}
+
+static unsigned int get_target_state(FAR struct thermal_instance_s *instance,
+                                     enum thermal_trend_e trend,
+                                     bool throttle)
+{
+  FAR struct thermal_cooling_device_s *cdev = instance->cdev;
+  unsigned int next_state = THERMAL_NO_TARGET;
+  unsigned int cur_state = instance->target;
+
+  if (!cdev->ops || !cdev->ops->get_state)
+    {
+      return next_state;
+    }
+
+  if (cur_state == THERMAL_NO_TARGET)
+    {
+      if (throttle)
+        {
+          next_state = validate_state(instance, throttle, cur_state, 1);
+        }
+
+      return next_state;
+    }
+
+  /* Update Cooling State */
+
+  switch (trend)
+    {
+      case THERMAL_TREND_RAISING:
+        if (throttle)
+          {
+            next_state = validate_state(instance, throttle, cur_state, 1);
+          }
+        break;
+
+      case THERMAL_TREND_DROPPING:
+        if (!throttle)
+          {
+            next_state = validate_state(instance, throttle, cur_state, -1);
+          }
+        break;
+
+      case THERMAL_TREND_STABLE:
+        break;
+
+      default:
+        break;
+    }
+
+  return next_state;
+}
+
+/* step_wise */
+
+static int step_wise_throttle(FAR struct thermal_zone_device_s *zdev,
+                              int trip)
+{
+  FAR struct thermal_instance_s *instance;
+  enum thermal_trend_e trend;
+  unsigned int next_state;
+  bool throttle = false;
+  int trip_temp;
+
+  thermal_zone_get_trip_temp(zdev, trip, &trip_temp);
+
+  trend = thermal_zone_get_trend(zdev);
+
+  if (zdev->temperature > trip_temp)
+    {
+      throttle = true;
+    }
+
+  list_for_every_entry(&zdev->instance_list, instance,
+                       struct thermal_instance_s, zdev_node)
+    {
+      if (instance->trip != trip)
+        {
+          continue;
+        }
+
+      next_state = get_target_state(instance, trend, throttle);
+
+      if (next_state == THERMAL_NO_TARGET || next_state == instance->target)
+        {
+          continue;
+        }
+
+      instance->target = next_state;
+      thermal_cooling_device_update(instance->cdev);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int thermal_register_step_wise_governor(void)
+{
+  return thermal_register_governor(&g_step_wise_governor);
+}

Reply via email to