demos_source/code_TestPasson.c

Go to the documentation of this file.
00001 /*
00002  * Femto OS v 0.91 - Copyright (C) 2008-2009 Ruud Vlaming
00003  *
00004  * This file is part of the Femto OS distribution.
00005  *
00006  * This program is free software: you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation, version 3 of the License.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00017  *
00018  * Please note that, due to the GPLv3 license, for application of this
00019  * work and/or combined work in embedded systems special obligations apply.
00020  * If these are not to you liking, please know the Femto OS is dual
00021  * licensed. A commercial license and support are available.
00022  * See http://www.femtoos.org/ for details.
00023  */
00024 
00025 
00038 /* This this the only include needed in your code .*/
00039 #include "femtoos_code.h"
00040 
00041 #define taskMutexRelease(Slot)             taskSyncRelease(Slot)
00042 
00043 
00044 /* This is called once at system boot, and before the creating of any of
00045  * the tasks. Use it to initialize the hardware. */
00046 void appBoot(void)
00047 { devLedDRR    = 0xFF;
00048   devLedPORT   = 0xFF;
00049   devSwitchDRR = 0x00; }
00050 
00051 /* Method to set the value of the led. Here you don't need access protection since the devLedPORT operations
00052  * are compiled to sbi/cbi instructions which atomic operations! Only if called with constants. */
00053 #define setLed(lednr,state)  if (state) { devLedPORT |= (1 << lednr); } else { devLedPORT &=  ~(1 << lednr); }
00054 
00055 #if (defSysOptimized == cfgTrue)
00056   /* Please note the use of "always_inline" attribute, if you remove this the register use explodes,
00057    * whereas with this trick the compiler can highly optimize your code (which of course gets longer). */
00058   static void HandOver(Tuint08 uiLed) __attribute__ ( ( naked, noreturn, always_inline ) );
00059 #else
00060   static void HandOver(Tuint08 uiLed) __attribute__ ( ( naked, noreturn ) );
00061 #endif
00062 
00063 
00064 /* The idea of this demo is that the state of a led (one/zero) is passed to its left
00065  * neighbor. For that to be possible, both leds must be locked so the state of the
00066  * on led can be read, whereas the other can be written. And, of course, the acces to
00067  * the display must be guarded as well, so this requires an other mutex. All these
00068  * tasks run concurrently and the effect is a moving image from right to left.
00069  *
00070  * We demonstrate the use of two different kinds of locks, to be chosen in the
00071  * configuration files. In case of cfgSyncSingleBlock we need to nested locks
00072  * before we can access both led variables. But with the cfgSyncDoubleBlock
00073  * setting this is a little easier, because the lock is entered when both
00074  * resources are available. This is coordinated by the OS.  */
00075 
00076 #if (cfgUseSynchronization == cfgSyncSingleBlock)
00077 
00078   #define taskMutexRequest(Slot,TicksToWait) taskSyncRequest(Slot,0,TicksToWait)
00079 
00080   static void HandOver(Tuint08 uiLed)
00081   { while (true)
00082     { Tuint08 uiSource = (uiLed & 0x07);
00083       Tuint08 uiTarget = ((uiLed+1) & 0x07);
00084       if (taskMutexRequest(uiSource+1,defLockDoNotBlock))
00085       { if (taskMutexRequest(uiTarget+1,defLockDoNotBlock))
00086         { taskMutexRequest(9,defLockBlockInfinite);
00087           Tuint08 uiBit = (devLedPORT >> uiSource) & 0x01;
00088           setLed(uiTarget,uiBit)
00089           taskMutexRelease(9);
00090           taskMutexRelease(uiTarget+1); }
00091         taskMutexRelease(uiSource+1); }
00092       taskDelayFromNow(300+(uiLed << 3)); } }
00093 
00094 #elif (cfgUseSynchronization == cfgSyncDoubleBlock)
00095 
00096   #define taskMutexRequest(Slot,TicksToWait) taskSyncRequest(Slot,0,0,TicksToWait)
00097 
00098   static void HandOver(Tuint08 uiLed)
00099   { while (true)
00100     { Tuint08 uiSource = (uiLed & 0x07);
00101       Tuint08 uiTarget = ((uiLed+1) & 0x07);
00102       Tuint08 uiDoubleSlot = (((uiSource+1)<<4) | (uiTarget+1));
00103       if (taskMutexRequest(uiDoubleSlot,defLockDoNotBlock))
00104       { taskMutexRequest(9,defLockBlockInfinite);
00105         Tuint08 uiBit = (devLedPORT >> uiSource) & 0x01;
00106         setLed(uiTarget,uiBit)
00107         taskMutexRelease(9);
00108         taskMutexRelease(uiDoubleSlot); }
00109       taskDelayFromNow(300+(uiLed << 3)); } }
00110 
00111 #else
00112   #error this is not possible
00113 #endif
00114 
00115 /* Reentrant calls to the HandOver lock managers. */
00116 
00117 #if (preTaskDefined(LEDtask0))
00118   void appLoop_LEDtask0(void) { HandOver(0); }
00119 #endif
00120 
00121 #if (preTaskDefined(LEDtask1))
00122   void appLoop_LEDtask1(void) { HandOver(1); }
00123 #endif
00124 
00125 #if (preTaskDefined(LEDtask2))
00126   void appLoop_LEDtask2(void) { HandOver(2); }
00127 #endif
00128 
00129 #if (preTaskDefined(LEDtask3))
00130   void appLoop_LEDtask3(void) { HandOver(3); }
00131 #endif
00132 
00133 #if (preTaskDefined(LEDtask4))
00134   void appLoop_LEDtask4(void) { HandOver(4); }
00135 #endif
00136 
00137 #if (preTaskDefined(LEDtask5))
00138   void appLoop_LEDtask5(void) { HandOver(5); }
00139 #endif
00140 
00141 #if (preTaskDefined(LEDtask6))
00142   void appLoop_LEDtask6(void) { HandOver(6); }
00143 #endif
00144 
00145 #if (preTaskDefined(LEDtask7))
00146   void appLoop_LEDtask7(void) { HandOver(7); }
00147 #endif
00148 
00149 
00150 /* Possibility to set the display to a start value in order to
00151  * start the process. Although this task may run in a higher
00152  * priority, it still has to wait until control over the display
00153  * is issued. */
00154 
00155 #if (preTaskDefined(Reset))
00156 
00157 void appLoop_Reset(void)
00158 { Tuint08 button  = devSwitchPIN & 01;
00159   Tuint08 lastbutton  = button;
00160   while (true)
00161   { button = devSwitchPIN & 01;
00162     if (button != lastbutton)
00163     { taskMutexRequest(9,defLockBlockInfinite);
00164       devLedPORT = 0xFE;
00165       taskMutexRelease(9);
00166       }
00167     taskDelayFromNow(100); } }
00168 
00169 #endif
00170 
00171 
00172 /* This demo has the tendency to get silent after a while. This is because
00173  * the system knows two fixpoints (all leds on, all leds off). To keep the demo
00174  * going, every 30 sec a seed is given if needed. */
00175 
00176 #if (preTaskDefined(AutoStart))
00177 
00178 void appLoop_AutoStart(void)
00179 { while(true)
00180   { taskMutexRequest(9,defLockBlockInfinite);
00181     Tuint08 uiLeds = devLedPORT;
00182     if ((uiLeds == 0x00) || (uiLeds == 0xFF)) { devLedPORT ^= 0x01; }
00183     taskMutexRelease(9);
00184     taskDelayFromNow(30000); } }
00185 
00186 #endif

Generated on Fri Oct 16 00:05:21 2009 for FemtoOS by  doxygen 1.5.2