Nut/OS  4.10.3
API Reference
timers.c
Go to the documentation of this file.
00001 
00053 #include <cfg/os.h>
00054 #ifdef NUTDEBUG
00055 #include <sys/osdebug.h>
00056 #endif
00057 
00058 #include <stdio.h>
00059 #include <io.h>
00060 
00061 #include <cfg/arch.h>
00062 #include <dev/board.h>
00063 
00064 #include <sys/thread.h>
00065 #include <sys/timer.h>
00066 #include <sys/event.h>
00067 #include <sys/heap.h>
00068 
00069 /*
00070  * Timer callback routine.
00071  *
00072  * This function is called by the system timer thread. It is executed 
00073  * at a very high priority and must return as soon as possible and must 
00074  * not call any potentially blocking function.
00075  *
00076  * To keep this example as simple as possible, we break the above rule 
00077  * and call print functions. However, this is not really a problem, 
00078  * because the UART output queue won't overflow on our few characters 
00079  * and return immediately after starting transmit interrupts, which are
00080  * running in the background.
00081  */
00082 
00083 void TimerCallback(HANDLE timer, void *arg)
00084 {
00085     NutEventPostAsync(arg);
00086 }
00087 
00088 THREAD(TimerEvent1, arg)
00089 {
00090     printf(" I1");
00091     NutThreadSetPriority(4);
00092     for (;;) {
00093         if (NutEventWait(arg, 12500))
00094             printf(" T1");
00095         else
00096             printf(" E1");
00097     }
00098 }
00099 
00100 THREAD(TimerEvent2, arg)
00101 {
00102     printf(" I2");
00103     NutThreadSetPriority(8);
00104     for (;;) {
00105         if (NutEventWait(arg, 12500))
00106             printf(" T2");
00107         else
00108             printf(" E2");
00109     }
00110 }
00111 
00112 THREAD(TimerEvent3, arg)
00113 {
00114     printf(" I3");
00115     NutThreadSetPriority(16);
00116     for (;;) {
00117         if (NutEventWait(arg, 12500))
00118             printf(" T3");
00119         else
00120             printf(" E3");
00121     }
00122 }
00123 
00124 THREAD(TimerEvent4, arg)
00125 {
00126     printf(" I4");
00127     NutThreadSetPriority(32);
00128     for (;;) {
00129         if (NutEventWait(arg, 12500))
00130             printf(" T4");
00131         else
00132             printf(" E4");
00133     }
00134 }
00135 
00136 THREAD(Sleeper1, arg)
00137 {
00138     NutThreadSetPriority(128);
00139     for (;;) {
00140         if (NutHeapAvailable() > 500)
00141             printf("\n%u free ", (unsigned int)NutHeapAvailable());
00142         else
00143             puts("Memory low");
00144         NutSleep(500);
00145     }
00146 }
00147 
00148 THREAD(Sleeper2, arg)
00149 {
00150     NutThreadSetPriority(129);
00151     for (;;) {
00152         NutSleep(500);
00153         printf(" S2");
00154     }
00155 }
00156 
00157 THREAD(Sleeper3, arg)
00158 {
00159     NutThreadSetPriority(130);
00160     for (;;) {
00161         NutSleep(500);
00162         printf(" S3");
00163     }
00164 }
00165 
00166 THREAD(Sleeper4, arg)
00167 {
00168     NutThreadSetPriority(131);
00169     for (;;) {
00170         NutSleep(500);
00171         printf(" S4");
00172     }
00173 }
00174 
00175 /*
00176  * Main application routine. 
00177  *
00178  */
00179 int main(void)
00180 {
00181     int seq;
00182     uint32_t baud = 115200;
00183     uint32_t sleep_ms = 2000;
00184     uint32_t timer_ms = 125;
00185     uint32_t cpu_crystal;
00186     int one_shot;
00187     HANDLE timer1, timer2, timer3, timer4;
00188     HANDLE event1 = 0, event2 = 0, event3 = 0, event4 = 0;
00189 
00190     /*
00191      * Register the UART device, open it, assign stdout to it and set 
00192      * the baudrate.
00193      */
00194     NutRegisterDevice(&DEV_CONSOLE, 0, 0);
00195     freopen(DEV_CONSOLE_NAME, "w", stdout);
00196     _ioctl(_fileno(stdout), UART_SETSPEED, &baud);
00197 
00198 #ifdef NUTDEBUG
00199     NutTraceHeap(stdout, 1);
00200     NutTraceOs(stdout, 1);
00201 #endif
00202 
00203     NutThreadSetPriority(8);
00204 
00205     /*
00206      * The timer functions automatically determine the
00207      * CPU speed during system initialization. Query that
00208      * value and print it on the console.
00209      */
00210     cpu_crystal = NutGetCpuClock();
00211     puts("\n*******************************************************************************");
00212     printf("Timer sample running on %u.%04u MHz CPU\n",
00213            (int) (cpu_crystal / 1000000UL), (int) ((cpu_crystal - (cpu_crystal / 1000000UL) * 1000000UL) / 100)
00214         );
00215 
00216     NutThreadCreate("tmr1", TimerEvent1, &event1, 512);
00217     NutThreadCreate("tmr2", TimerEvent2, &event2, 512);
00218     NutThreadCreate("tmr3", TimerEvent3, &event3, 512);
00219     NutThreadCreate("tmr4", TimerEvent4, &event4, 512);
00220 
00221     NutThreadCreate("slpr1", Sleeper1, 0, 512);
00222     NutThreadCreate("slpr2", Sleeper2, 0, 512);
00223     NutThreadCreate("slpr3", Sleeper3, 0, 512);
00224     NutThreadCreate("slpr4", Sleeper4, 0, 512);
00225 
00226     /*
00227      * Endless application loop.
00228      */
00229     for (seq = 0;; seq++) {
00230 
00231         /*
00232          * Predefine the one-shot option flag for the
00233          * timer started below. Each odd sequence starts
00234          * a one-shot timer, each even sequence a
00235          * priodical one.
00236          */
00237         if (seq & 1)
00238             one_shot = TM_ONESHOT;
00239         else
00240             one_shot = 0;
00241 
00242         /*
00243          * Start a timer with 1 second timer intervals.
00244          * This timer will call TimerCallback exactly one
00245          * time, if it's a one-shot timer or periodically,
00246          * if not a one-shot timer.
00247          *
00248          * We pass a pointer to the sequence counter,
00249          * which in turn is passed to the callback
00250          * function.
00251          */
00252         //if((timer_ms += 125) > 500)
00253         //    timer_ms = 0;
00254         printf("\nStart %s t1 ", one_shot ? "oneshot" : "periodic");
00255         timer1 = NutTimerStart(timer_ms, TimerCallback, &event1, one_shot);
00256 
00257         printf("\nStart %s t2 ", one_shot ? "oneshot" : "periodic");
00258         timer2 = NutTimerStart(timer_ms, TimerCallback, &event2, one_shot);
00259 
00260         printf("\nStart %s t3 ", one_shot ? "oneshot" : "periodic");
00261         timer3 = NutTimerStart(timer_ms, TimerCallback, &event3, one_shot);
00262 
00263         printf("\nStart %s t4 ", one_shot ? "oneshot" : "periodic");
00264         timer4 = NutTimerStart(timer_ms, TimerCallback, &event4, one_shot);
00265 
00266         /*
00267          * Sleep for a number of seconds.
00268          */
00269         if ((sleep_ms += 1000) > 30000)
00270             sleep_ms = 1000;
00271         printf("\nSleeping %u seconds ", (int) (sleep_ms / 1000UL));
00272         NutSleep(sleep_ms);
00273 
00274         /*
00275          * Stop periodical timer. One-shot timers
00276          * are automatically stopped by Nut/OS.
00277          */
00278         if (one_shot == 0) {
00279             printf("\nStop timers ");
00280             NutTimerStop(timer1);
00281             NutTimerStop(timer2);
00282             NutTimerStop(timer3);
00283             NutTimerStop(timer4);
00284         }
00285         //printf("\nSleeping %u seconds ", (int)(sleep_ms / 1000UL));
00286         //NutSleep(sleep_ms);
00287         printf("\n%u bytes free\n", (unsigned int)NutHeapAvailable());
00288     }
00289     return 0;
00290 }