timers/timers.c

Copyright (C) 2001-2005 by egnite Software GmbH. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holders nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

For additional information see http://www.ethernut.de/

Log
Revision 1.5 2005/11/22 09:17:31 haraldkipp Replaced specific device names by generalized macros. Thread stack size increased to get it running on ARM CPUs.

Revision 1.4 2005/04/19 08:57:52 haraldkipp Description updated and ARM support added

Revision 1.3 2005/04/05 18:00:29 haraldkipp Make it work on the Gameboy Advance.

Revision 1.2 2004/09/08 10:18:23 haraldkipp For EB40A

Revision 1.1 2003/08/05 18:59:05 haraldkipp Release 3.3 update

Revision 1.14 2003/02/04 18:19:40 harald Version 3 released

Revision 1.13 2003/02/04 16:24:37 harald Adapted to version 3

Revision 1.12 2002/11/02 15:13:18 harald Library dependencies removed

Revision 1.11 2002/10/31 16:27:40 harald Mods by troth for Linux

Revision 1.10 2002/07/03 16:33:21 harald Broken watchdog patch

Revision 1.9 2002/06/26 17:29:07 harald First pre-release with 2.4 stack

Revision 1.8 2002/06/12 10:59:23 harald *** empty log message ***

Revision 1.7 2002/06/04 18:48:50 harald Problems with ATmega128 watchdog

Revision 1.6 2002/05/11 21:01:47 harald Adding more stress to test timer functions

Revision 1.5 2002/05/09 21:49:57 harald Using new default UART. Bufgix: Event queues must be set 0.

Revision 1.4 2002/05/08 16:02:34 harald First Imagecraft compilation

Revision 1.3 2002/05/02 18:48:03 harald *** empty log message ***

Revision 1.2 2002/01/28 19:49:28 harald Testing new timer layout

Revision 1.1 2001/06/28 18:43:13 harald Preview release

This sample demonstrates the usage of Nut/OS timer functions.

In addition it demonstrates how to enable system debug output. You need the debug version of the Nut/OS libraries. To create them, you must enable the RTOS Kernel - OS Debug option in the Configurator. Then use the Build Menu in the Configurator to generate the build tree again and build Nut/OS.

Note, that the debug version consumes much more memory than the original version. If in doubt, check the map file.

00001 
00110 #include <cfg/os.h>
00111 #ifdef NUTDEBUG
00112 #include <sys/osdebug.h>
00113 #endif
00114 
00115 #include <stdio.h>
00116 #include <io.h>
00117 
00118 #include <cfg/arch.h>
00119 #include <dev/board.h>
00120 
00121 #include <sys/thread.h>
00122 #include <sys/timer.h>
00123 #include <sys/event.h>
00124 #include <sys/heap.h>
00125 
00126 /*
00127  * Timer callback routine.
00128  *
00129  * This function is called by the system timer thread. It is executed 
00130  * at a very high priority and must return as soon as possible and must 
00131  * not call any potentially blocking function.
00132  *
00133  * To keep this example as simple as possible, we break the above rule 
00134  * and call print functions. However, this is not really a problem, 
00135  * because the UART output queue won't overflow on our few characters 
00136  * and return immediately after starting transmit interrupts, which are
00137  * running in the background.
00138  */
00139 
00140 void TimerCallback(HANDLE timer, void *arg)
00141 {
00142     NutEventPostAsync(arg);
00143 }
00144 
00145 THREAD(TimerEvent1, arg)
00146 {
00147     printf(" I1");
00148     NutThreadSetPriority(4);
00149     for (;;) {
00150         if (NutEventWait(arg, 12500))
00151             printf(" T1");
00152         else
00153             printf(" E1");
00154     }
00155 }
00156 
00157 THREAD(TimerEvent2, arg)
00158 {
00159     printf(" I2");
00160     NutThreadSetPriority(8);
00161     for (;;) {
00162         if (NutEventWait(arg, 12500))
00163             printf(" T2");
00164         else
00165             printf(" E2");
00166     }
00167 }
00168 
00169 THREAD(TimerEvent3, arg)
00170 {
00171     printf(" I3");
00172     NutThreadSetPriority(16);
00173     for (;;) {
00174         if (NutEventWait(arg, 12500))
00175             printf(" T3");
00176         else
00177             printf(" E3");
00178     }
00179 }
00180 
00181 THREAD(TimerEvent4, arg)
00182 {
00183     printf(" I4");
00184     NutThreadSetPriority(32);
00185     for (;;) {
00186         if (NutEventWait(arg, 12500))
00187             printf(" T4");
00188         else
00189             printf(" E4");
00190     }
00191 }
00192 
00193 THREAD(Sleeper1, arg)
00194 {
00195     NutThreadSetPriority(128);
00196     for (;;) {
00197         if (NutHeapAvailable() > 500)
00198             printf("\n%u free ", (u_int)NutHeapAvailable());
00199         else
00200             puts("Memory low");
00201         NutSleep(500);
00202     }
00203 }
00204 
00205 THREAD(Sleeper2, arg)
00206 {
00207     NutThreadSetPriority(129);
00208     for (;;) {
00209         NutSleep(500);
00210         printf(" S2");
00211     }
00212 }
00213 
00214 THREAD(Sleeper3, arg)
00215 {
00216     NutThreadSetPriority(130);
00217     for (;;) {
00218         NutSleep(500);
00219         printf(" S3");
00220     }
00221 }
00222 
00223 THREAD(Sleeper4, arg)
00224 {
00225     NutThreadSetPriority(131);
00226     for (;;) {
00227         NutSleep(500);
00228         printf(" S4");
00229     }
00230 }
00231 
00232 /*
00233  * Main application routine. 
00234  *
00235  */
00236 int main(void)
00237 {
00238     int seq;
00239     u_long baud = 115200;
00240     u_long sleep_ms = 2000;
00241     u_long timer_ms = 125;
00242     u_long cpu_crystal;
00243     int one_shot;
00244     HANDLE timer1, timer2, timer3, timer4;
00245     HANDLE event1 = 0, event2 = 0, event3 = 0, event4 = 0;
00246 
00247     /*
00248      * Register the UART device, open it, assign stdout to it and set 
00249      * the baudrate.
00250      */
00251     NutRegisterDevice(&DEV_DEBUG, 0, 0);
00252     freopen(DEV_DEBUG_NAME, "w", stdout);
00253     _ioctl(_fileno(stdout), UART_SETSPEED, &baud);
00254 
00255 #ifdef NUTDEBUG
00256     NutTraceHeap(stdout, 1);
00257     NutTraceOs(stdout, 1);
00258 #endif
00259 
00260     NutThreadSetPriority(8);
00261 
00262     /*
00263      * The timer functions automatically determine the
00264      * CPU speed during system initialization. Query that
00265      * value and print it on the console.
00266      */
00267     cpu_crystal = NutGetCpuClock();
00268     puts("\n*******************************************************************************");
00269     printf("Timer sample running on %u.%04u MHz CPU\n",
00270            (int) (cpu_crystal / 1000000UL), (int) ((cpu_crystal - (cpu_crystal / 1000000UL) * 1000000UL) / 100)
00271         );
00272 
00273     NutThreadCreate("tmr1", TimerEvent1, &event1, 512);
00274     NutThreadCreate("tmr2", TimerEvent2, &event2, 512);
00275     NutThreadCreate("tmr3", TimerEvent3, &event3, 512);
00276     NutThreadCreate("tmr4", TimerEvent4, &event4, 512);
00277 
00278     NutThreadCreate("slpr1", Sleeper1, 0, 512);
00279     NutThreadCreate("slpr2", Sleeper2, 0, 512);
00280     NutThreadCreate("slpr3", Sleeper3, 0, 512);
00281     NutThreadCreate("slpr4", Sleeper4, 0, 512);
00282 
00283     /*
00284      * Endless application loop.
00285      */
00286     for (seq = 0;; seq++) {
00287 
00288         /*
00289          * Predefine the one-shot option flag for the
00290          * timer started below. Each odd sequence starts
00291          * a one-shot timer, each even sequence a
00292          * priodical one.
00293          */
00294         if (seq & 1)
00295             one_shot = TM_ONESHOT;
00296         else
00297             one_shot = 0;
00298 
00299         /*
00300          * Start a timer with 1 second timer intervals.
00301          * This timer will call TimerCallback exactly one
00302          * time, if it's a one-shot timer or periodically,
00303          * if not a one-shot timer.
00304          *
00305          * We pass a pointer to the sequence counter,
00306          * which in turn is passed to the callback
00307          * function.
00308          */
00309         //if((timer_ms += 125) > 500)
00310         //    timer_ms = 0;
00311         printf("\nStart %s t1 ", one_shot ? "oneshot" : "periodic");
00312         timer1 = NutTimerStart(timer_ms, TimerCallback, &event1, one_shot);
00313 
00314         printf("\nStart %s t2 ", one_shot ? "oneshot" : "periodic");
00315         timer2 = NutTimerStart(timer_ms, TimerCallback, &event2, one_shot);
00316 
00317         printf("\nStart %s t3 ", one_shot ? "oneshot" : "periodic");
00318         timer3 = NutTimerStart(timer_ms, TimerCallback, &event3, one_shot);
00319 
00320         printf("\nStart %s t4 ", one_shot ? "oneshot" : "periodic");
00321         timer4 = NutTimerStart(timer_ms, TimerCallback, &event4, one_shot);
00322 
00323         /*
00324          * Sleep for a number of seconds.
00325          */
00326         if ((sleep_ms += 1000) > 30000)
00327             sleep_ms = 1000;
00328         printf("\nSleeping %u seconds ", (int) (sleep_ms / 1000UL));
00329         NutSleep(sleep_ms);
00330 
00331         /*
00332          * Stop periodical timer. One-shot timers
00333          * are automatically stopped by Nut/OS.
00334          */
00335         if (one_shot == 0) {
00336             printf("\nStop timers ");
00337             NutTimerStop(timer1);
00338             NutTimerStop(timer2);
00339             NutTimerStop(timer3);
00340             NutTimerStop(timer4);
00341         }
00342         //printf("\nSleeping %u seconds ", (int)(sleep_ms / 1000UL));
00343         //NutSleep(sleep_ms);
00344         printf("\n%u bytes free\n", (u_int)NutHeapAvailable());
00345     }
00346 }

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/