timers/timers.c

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-2006 by egnite Software GmbH - visit http://www.ethernut.de/