timers.c

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

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