cpu_relax(): New function.
authorbernie <bernie@38d2e660-2303-0410-9eaa-f027e97ec537>
Mon, 11 Aug 2008 11:32:19 +0000 (11:32 +0000)
committerbernie <bernie@38d2e660-2303-0410-9eaa-f027e97ec537>
Mon, 11 Aug 2008 11:32:19 +0000 (11:32 +0000)
git-svn-id: https://src.develer.com/svnoss/bertos/trunk@1624 38d2e660-2303-0410-9eaa-f027e97ec537

bertos/cpu/power.h [new file with mode: 0644]
bertos/drv/dataflash.c
bertos/drv/flash25.c
bertos/drv/ser.c

diff --git a/bertos/cpu/power.h b/bertos/cpu/power.h
new file mode 100644 (file)
index 0000000..04c0607
--- /dev/null
@@ -0,0 +1,111 @@
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction.  Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License.  This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2008 Bernie Innocenti <bernie@codewiz.org>
+ * -->
+ *
+ * \brief CPU power management functions
+ *
+ * \author Bernie Innocenti <bernie@codewiz.org>
+ */
+
+#ifndef CPU_POWER_H
+#define CPU_POWER_H
+
+#include <cfg/cfg_kern.h>
+#include <cfg/cfg_wdt.h>
+
+#if CONFIG_KERNEL
+       #include <kern/proc.h>
+#endif
+
+#if CONFIG_WATCHDOG
+       #include <drv/wdt.h>
+#endif
+
+/**
+ * Let the CPU rest in tight busy loops
+ *
+ * User code that sits in a busy loop should call cpu_relax() every
+ * once in a while to perform system-depndent idle processing.
+ *
+ * Depending on the system configuration, this might perform different
+ * actions:
+ *
+ *  - yield the CPU to other processes
+ *  - reset the watchdog timer to avoid it from triggering
+ *  - scale the CPU speed down to save power (unimplemented)
+ *  - let the event loop of the emulator process a few events
+ */
+INLINE void cpu_relax(void)
+{
+#if CONFIG_KERNEL
+       proc_yield();
+#endif
+
+#if CONFIG_WATCHDOG
+       wdt_reset();
+#endif
+}
+
+/**
+ * Stop the processor until the next interrupt occurs.
+ *
+ * Pausing the CPU effectively reduces power usage, and should be used
+ * whenever the program is idle waiting for the next event to occur.
+ *
+ * To avoid deadlocking, the caller should normally check for the
+ * desired condition with interrupts disabled, and enter this function
+ * while interrupts are still disabled:
+ *
+ * \code
+ *     IRQ_DISABLE();
+ *     while (!event_occurred)
+ *         cpu_pause();
+ *     IRQ_ENABLE();
+ * \endcode
+ *
+ * \note Some implementations of cpu_pause() may return before any interrupt has occurred
+ *       Caller code should be written taking this into account.
+ *
+ * \note This function is currently unimplemented
+ */
+INLINE void cpu_pause(void)
+{
+       //ASSERT_IRQ_DISABLED();
+       //IRQ_ENABLE();
+       cpu_relax();
+       //IRQ_DISABLE();
+}
+
+/**
+ * Safely call cpu_pause() until the COND predicate becomes true.
+ */
+#define CPU_PAUSE_ON(COND) ATOMIC(while (!(COND)) { cpu_pause(); })
+
+#endif /* CPU_POWER_H */
index ac1eeaf551b72bc4de4167dd5920d7cc06a27194..68047d5b5cac4e1743ea14df89140aadf84dd666 100644 (file)
  * the GNU General Public License.
  *
  * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
- *
  * -->
  *
  * \brief Function library for dataflash AT45DB family (implementation).
  *
- *
  * \version $Id: dataflash.c 21658 2008-06-05 16:42:54Z asterix $
  * \author Daniele Basile <asterix@develer.com>
  * \author Francesco Sacchi <batt@develer.com>
 
 #include <kern/kfile.h>
 
-#if CONFIG_KERNEL
-       #include <kern/proc.h>
-#else
-       #define proc_yield() do {} while(0)
-#endif
+#include <cpu/power.h> /* cpu_relax() */
 
 #include <string.h>
 
@@ -215,7 +209,7 @@ static uint8_t dataflash_cmd(DataFlash *fd, dataflash_page_t page_addr, dataflas
         * is high.
         */
        while (!(dataflash_stat(fd) & BUSY_BIT))
-               proc_yield();
+               cpu_relax();
 
        stat = dataflash_stat(fd);
 
index 807ff2114286be9b8b94600224c19487352337b7..793fab019dc546c3c298f6d44b0dc5dd4a8d7fee 100644 (file)
  * the GNU General Public License.
  *
  * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
- *
  * -->
  *
- *  \brief Function library for serial Flash memory.
+ * \brief Function library for serial Flash memory.
  *
  * Module provide a kfile interface, that ensure an abstraction
  * from comunication channel and give a standard interface.
 
 #include <kern/kfile.h>
 
-#if CONFIG_KERNEL
-       #include <kern/proc.h>
-#else
-       #define proc_yield() do {} while(0)
-#endif
+#include <cpu/relax.h> /* cpu_relax() */
 
 #warning FIXME:This file was change, but is untest!
 
@@ -81,8 +76,8 @@ static void flash25_waitReady(Flash25 *fd)
 
                if (!(stat & RDY_BIT))
                        break;
-               else
-                       proc_yield();
+
+               cpu_relax();
        }
 }
 
index 5f2b6fcd66af4298bdae8d95891c31276854ed57..cbcc33a388d9bdc435e2408f0de2950f2fde2134 100644 (file)
@@ -60,7 +60,9 @@
 
 #include <mware/formatwr.h>
 
-#include <string.h> /* memset */
+#include <cpu/power.h> /* cpu_relax() */
+
+#include <string.h> /* memset() */
 
 /*
  * Sanity check for config parameters required by this module.
        #error CONFIG_SER_DEFBAUDRATE missing in config.h
 #endif
 
-#if CONFIG_KERNEL && CONFIG_KERN_SCHED
-       #include <kern/proc.h>
-#else
-       #define proc_yield() do {} while(0)
-#endif
-
-#if CONFIG_SER_TXTIMEOUT != -1 || CONFIG_SER_RXTIMEOUT != -1
-       #include <drv/timer.h>
-#endif
-
 
 struct Serial *ser_handles[SER_CNT];
 
@@ -114,9 +106,7 @@ static int ser_putchar(int c, struct Serial *port)
                /* Wait while buffer is full... */
                do
                {
-                       /* Give up timeslice to other processes. */
-                       proc_yield();
-                       wdt_reset();
+                       cpu_relax();
 
 #if CONFIG_SER_TXTIMEOUT != -1
                        if (timer_clock() - start_time >= port->txtimeout)
@@ -162,9 +152,7 @@ static int ser_getchar(struct Serial *port)
                /* Wait while buffer is empty */
                do
                {
-                       /* Give up timeslice to other processes. */
-                       proc_yield();
-                       wdt_reset();
+                       cpu_relax();
 
 #if CONFIG_SER_RXTIMEOUT != -1
                        if (timer_clock() - start_time >= port->rxtimeout)
@@ -354,11 +342,7 @@ static int ser_flush(struct KFile *fd)
         */
        while (!fifo_isempty(&fds->txfifo)
               || fds->hw->table->txSending(fds->hw))
-       {
-                       /* Give up timeslice to other processes. */
-                       proc_yield();
-                       wdt_reset();
-       }
+               cpu_relax();
        return 0;
 }