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 }