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/
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 }