Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2006, Technical University of Munich 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the Institute nor the names of its contributors 00014 * may be used to endorse or promote products derived from this software 00015 * without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00018 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00021 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00023 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00024 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00025 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00027 * SUCH DAMAGE. 00028 * 00029 * This file is part of the Contiki operating system. 00030 * 00031 */ 00032 #define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args) 00033 00034 #define ANNOUNCE_BOOT 1 //adds about 600 bytes to program size 00035 #if ANNOUNCE_BOOT 00036 #define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args) 00037 #else 00038 #define PRINTA(...) 00039 #endif 00040 00041 #define DEBUG 0 00042 #if DEBUG 00043 #define PRINTD(FORMAT,args...) printf_P(PSTR(FORMAT),##args) 00044 #else 00045 #define PRINTD(...) 00046 #endif 00047 00048 #include <avr/pgmspace.h> 00049 #include <avr/fuse.h> 00050 #include <avr/eeprom.h> 00051 #include <stdio.h> 00052 #include <string.h> 00053 #include <dev/watchdog.h> 00054 00055 #include "loader/symbols-def.h" 00056 #include "loader/symtab.h" 00057 00058 #include "params.h" 00059 #include "radio/rf230bb/rf230bb.h" 00060 #include "net/mac/frame802154.h" 00061 #include "net/mac/framer-802154.h" 00062 #include "net/sicslowpan.h" 00063 00064 #include "contiki.h" 00065 #include "contiki-net.h" 00066 #include "contiki-lib.h" 00067 00068 #include "dev/rs232.h" 00069 #include "dev/serial-line.h" 00070 #include "dev/slip.h" 00071 00072 #ifdef RAVEN_LCD_INTERFACE 00073 #include "raven-lcd.h" 00074 #endif 00075 00076 #if AVR_WEBSERVER 00077 #include "httpd-fs.h" 00078 #include "httpd-cgi.h" 00079 #endif 00080 00081 #ifdef COFFEE_FILES 00082 #include "cfs/cfs.h" 00083 #include "cfs/cfs-coffee.h" 00084 #endif 00085 00086 #if UIP_CONF_ROUTER&&0 00087 #include "net/routing/rimeroute.h" 00088 #include "net/rime/rime-udp.h" 00089 #endif 00090 00091 #include "net/rime.h" 00092 00093 /* Track interrupt flow through mac, rdc and radio driver */ 00094 //#define DEBUGFLOWSIZE 32 00095 #if DEBUGFLOWSIZE 00096 uint8_t debugflowsize,debugflow[DEBUGFLOWSIZE]; 00097 #define DEBUGFLOW(c) if (debugflowsize<(DEBUGFLOWSIZE-1)) debugflow[debugflowsize++]=c 00098 #else 00099 #define DEBUGFLOW(c) 00100 #endif 00101 00102 /* Get periodic prints from idle loop, from clock seconds or rtimer interrupts */ 00103 /* Use of rtimer will conflict with other rtimer interrupts such as contikimac radio cycling */ 00104 /* STAMPS will print ENERGEST outputs if that is enabled. */ 00105 #define PERIODICPRINTS 1 00106 #if PERIODICPRINTS 00107 //#define PINGS 64 00108 #define ROUTES 600 00109 #define STAMPS 60 00110 #define STACKMONITOR 1024 00111 uint32_t clocktime; 00112 #define TESTRTIMER 0 00113 #if TESTRTIMER 00114 uint8_t rtimerflag=1; 00115 struct rtimer rt; 00116 void rtimercycle(void) {rtimerflag=1;} 00117 #endif 00118 #endif 00119 00120 uint16_t ledtimer; 00121 00122 /*-------------------------------------------------------------------------*/ 00123 /*----------------------Configuration of the .elf file---------------------*/ 00124 #if 1 00125 /* The proper way to set the signature is */ 00126 #include <avr/signature.h> 00127 #else 00128 /* Older avr-gcc's may not define the needed SIGNATURE bytes. Do it manually if you get an error */ 00129 typedef struct {const unsigned char B2;const unsigned char B1;const unsigned char B0;} __signature_t; 00130 #define SIGNATURE __signature_t __signature __attribute__((section (".signature"))) 00131 SIGNATURE = { 00132 .B2 = 0x01,//SIGNATURE_2, //ATMEGA128rfa1 00133 .B1 = 0xA7,//SIGNATURE_1, //128KB flash 00134 .B0 = 0x1E,//SIGNATURE_0, //Atmel 00135 }; 00136 #endif 00137 00138 #if 1 00139 /* JTAG, SPI enabled, Internal RC osc, Boot flash size 4K, 6CK+65msec delay, brownout disabled */ 00140 FUSES ={.low = 0xe2, .high = 0x99, .extended = 0xff,}; 00141 #else 00142 /* JTAG+SPI, Boot 4096 words @ $F000, Internal oscillator, startup 6 CK +0 ms, Brownout 1.8 volts */ 00143 FUSES ={.low = 0xC2, .high = 0x99, .extended = 0xfe,}; 00144 #endif 00145 00146 uint8_t 00147 rng_get_uint8(void) { 00148 #if 1 00149 /* Upper two RSSI reg bits (RND_VALUE) are random in rf231 */ 00150 uint8_t j; 00151 j = (PHY_RSSI&0xc0) + ((PHY_RSSI>>2)&0x30) + ((PHY_RSSI>>4)&0x0c) + ((PHY_RSSI>>6)&0x03); 00152 #else 00153 /* Get a pseudo random number using the ADC */ 00154 uint8_t i,j; 00155 ADCSRA=1<<ADEN; //Enable ADC, not free running, interrupt disabled, fastest clock 00156 for (i=0;i<4;i++) { 00157 ADMUX = 0; //toggle reference to increase noise 00158 ADMUX =0x1E; //Select AREF as reference, measure 1.1 volt bandgap reference. 00159 ADCSRA|=1<<ADSC; //Start conversion 00160 while (ADCSRA&(1<<ADSC)); //Wait till done 00161 j = (j<<2) + ADC; 00162 } 00163 ADCSRA=0; //Disable ADC 00164 #endif 00165 PRINTD("rng issues %d\n",j); 00166 return j; 00167 } 00168 00169 /*-------------------------Low level initialization------------------------*/ 00170 /*------Done in a subroutine to keep main routine stack usage small--------*/ 00171 void initialize(void) 00172 { 00173 watchdog_init(); 00174 watchdog_start(); 00175 00176 /* The Raven implements a serial command and data interface via uart0 to a 3290p, 00177 * which could be duplicated using another host computer. 00178 */ 00179 #if !RF230BB_CONF_LEDONPORTE1 //Conflicts with USART0 00180 #ifdef RAVEN_LCD_INTERFACE 00181 rs232_init(RS232_PORT_0, USART_BAUD_38400,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8); 00182 rs232_set_input(0,raven_lcd_serial_input); 00183 #else 00184 /* Generic or slip connection on uart0 */ 00185 rs232_init(RS232_PORT_0, USART_BAUD_38400,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8); 00186 #endif 00187 #endif 00188 00189 /* Second rs232 port for debugging or slip alternative */ 00190 rs232_init(RS232_PORT_1, USART_BAUD_57600,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8); 00191 /* Redirect stdout */ 00192 #if RF230BB_CONF_LEDONPORTE1 || defined(RAVEN_LCD_INTERFACE) 00193 rs232_redirect_stdout(RS232_PORT_1); 00194 #else 00195 rs232_redirect_stdout(RS232_PORT_0); 00196 #endif 00197 clock_init(); 00198 00199 if(MCUSR & (1<<PORF )) PRINTD("Power-on reset.\n"); 00200 if(MCUSR & (1<<EXTRF)) PRINTD("External reset!\n"); 00201 if(MCUSR & (1<<BORF )) PRINTD("Brownout reset!\n"); 00202 if(MCUSR & (1<<WDRF )) PRINTD("Watchdog reset!\n"); 00203 if(MCUSR & (1<<JTRF )) PRINTD("JTAG reset!\n"); 00204 00205 #if STACKMONITOR 00206 /* Simple stack pointer highwater monitor. Checks for magic numbers in the main 00207 * loop. In conjuction with PERIODICPRINTS, never-used stack will be printed 00208 * every STACKMONITOR seconds. 00209 */ 00210 { 00211 extern uint16_t __bss_end; 00212 uint16_t p=(uint16_t)&__bss_end; 00213 do { 00214 *(uint16_t *)p = 0x4242; 00215 p+=10; 00216 } while (p<SP-10); //don't overwrite our own stack 00217 } 00218 #endif 00219 00220 #define CONF_CALIBRATE_OSCCAL 0 00221 #if CONF_CALIBRATE_OSCCAL 00222 void calibrate_rc_osc_32k(); 00223 { 00224 extern uint8_t osccal_calibrated; 00225 uint8_t i; 00226 PRINTD("\nBefore calibration OSCCAL=%x\n",OSCCAL); 00227 for (i=0;i<10;i++) { 00228 calibrate_rc_osc_32k(); 00229 PRINTD("Calibrated=%x\n",osccal_calibrated); 00230 //#include <util/delay_basic.h> 00231 //#define delay_us( us ) ( _delay_loop_2(1+(us*F_CPU)/4000000UL) ) 00232 // delay_us(50000); 00233 } 00234 clock_init(); 00235 } 00236 #endif 00237 00238 PRINTA("\n*******Booting %s*******\n",CONTIKI_VERSION_STRING); 00239 00240 /* rtimers needed for radio cycling */ 00241 rtimer_init(); 00242 00243 /* Initialize process subsystem */ 00244 process_init(); 00245 00246 /* etimers must be started before ctimer_init */ 00247 process_start(&etimer_process, NULL); 00248 ctimer_init(); 00249 00250 /* Start radio and radio receive process */ 00251 NETSTACK_RADIO.init(); 00252 00253 /* Get a random seed for the 802.15.4 packet sequence number. 00254 * Some layers will ignore duplicates found in a history (e.g. Contikimac) 00255 * causing the initial packets to be ignored after a short-cycle restart. 00256 */ 00257 random_init(rng_get_uint8()); 00258 00259 /* Set addresses BEFORE starting tcpip process */ 00260 00261 rimeaddr_t addr; 00262 00263 if (params_get_eui64(addr.u8)) { 00264 PRINTA("Random EUI64 address generated\n"); 00265 } 00266 00267 #if UIP_CONF_IPV6 00268 memcpy(&uip_lladdr.addr, &addr.u8, sizeof(rimeaddr_t)); 00269 #elif WITH_NODE_ID 00270 node_id=get_panaddr_from_eeprom(); 00271 addr.u8[1]=node_id&0xff; 00272 addr.u8[0]=(node_id&0xff00)>>8; 00273 PRINTA("Node ID from eeprom: %X\n",node_id); 00274 #endif 00275 rimeaddr_set_node_addr(&addr); 00276 00277 rf230_set_pan_addr(params_get_panid(),params_get_panaddr(),(uint8_t *)&addr.u8); 00278 rf230_set_channel(params_get_channel()); 00279 rf230_set_txpower(params_get_txpower()); 00280 00281 #if UIP_CONF_IPV6 00282 PRINTA("EUI-64 MAC: %x-%x-%x-%x-%x-%x-%x-%x\n",addr.u8[0],addr.u8[1],addr.u8[2],addr.u8[3],addr.u8[4],addr.u8[5],addr.u8[6],addr.u8[7]); 00283 #else 00284 PRINTA("MAC address "); 00285 uint8_t i; 00286 for (i=sizeof(rimeaddr_t); i>0; i--){ 00287 PRINTA("%x:",addr.u8[i-1]); 00288 } 00289 PRINTA("\n"); 00290 #endif 00291 00292 /* Initialize stack protocols */ 00293 queuebuf_init(); 00294 NETSTACK_RDC.init(); 00295 NETSTACK_MAC.init(); 00296 NETSTACK_NETWORK.init(); 00297 00298 #if ANNOUNCE_BOOT 00299 PRINTA("%s %s, channel %u , check rate %u Hz tx power %u\n",NETSTACK_MAC.name, NETSTACK_RDC.name, rf230_get_channel(), 00300 CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1:NETSTACK_RDC.channel_check_interval()), 00301 rf230_get_txpower()); 00302 #if UIP_CONF_IPV6_RPL 00303 PRINTA("RPL Enabled\n"); 00304 #endif 00305 #if UIP_CONF_ROUTER 00306 PRINTA("Routing Enabled\n"); 00307 #endif 00308 00309 #endif /* ANNOUNCE_BOOT */ 00310 00311 process_start(&tcpip_process, NULL); 00312 00313 #ifdef RAVEN_LCD_INTERFACE 00314 process_start(&raven_lcd_process, NULL); 00315 #endif 00316 00317 /* Autostart other processes */ 00318 autostart_start(autostart_processes); 00319 00320 /*---If using coffee file system create initial web content if necessary---*/ 00321 #if COFFEE_FILES 00322 int fa = cfs_open( "/index.html", CFS_READ); 00323 if (fa<0) { //Make some default web content 00324 PRINTA("No index.html file found, creating upload.html!\n"); 00325 PRINTA("Formatting FLASH file system for coffee..."); 00326 cfs_coffee_format(); 00327 PRINTA("Done!\n"); 00328 fa = cfs_open( "/index.html", CFS_WRITE); 00329 int r = cfs_write(fa, &"It works!", 9); 00330 if (r<0) PRINTA("Can''t create /index.html!\n"); 00331 cfs_close(fa); 00332 // fa = cfs_open("upload.html"), CFW_WRITE); 00333 // <html><body><form action="upload.html" enctype="multipart/form-data" method="post"><input name="userfile" type="file" size="50" /><input value="Upload" type="submit" /></form></body></html> 00334 } 00335 #endif /* COFFEE_FILES */ 00336 00337 /* Add addresses for testing */ 00338 #if 0 00339 { 00340 uip_ip6addr_t ipaddr; 00341 uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); 00342 uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); 00343 // uip_ds6_prefix_add(&ipaddr,64,0); 00344 } 00345 #endif 00346 00347 /*--------------------------Announce the configuration---------------------*/ 00348 #if ANNOUNCE_BOOT 00349 #if AVR_WEBSERVER 00350 { uint8_t i; 00351 char buf[80]; 00352 unsigned int size; 00353 00354 for (i=0;i<UIP_DS6_ADDR_NB;i++) { 00355 if (uip_ds6_if.addr_list[i].isused) { 00356 httpd_cgi_sprint_ip6(uip_ds6_if.addr_list[i].ipaddr,buf); 00357 PRINTA("IPv6 Address: %s\n",buf); 00358 } 00359 } 00360 cli(); 00361 eeprom_read_block (buf,eemem_server_name, sizeof(eemem_server_name)); 00362 sei(); 00363 buf[sizeof(eemem_server_name)]=0; 00364 PRINTA("%s",buf); 00365 cli(); 00366 eeprom_read_block (buf,eemem_domain_name, sizeof(eemem_domain_name)); 00367 sei(); 00368 buf[sizeof(eemem_domain_name)]=0; 00369 size=httpd_fs_get_size(); 00370 #ifndef COFFEE_FILES 00371 PRINTA(".%s online with fixed %u byte web content\n",buf,size); 00372 #elif COFFEE_FILES==1 00373 PRINTA(".%s online with static %u byte EEPROM file system\n",buf,size); 00374 #elif COFFEE_FILES==2 00375 PRINTA(".%s online with dynamic %u KB EEPROM file system\n",buf,size>>10); 00376 #elif COFFEE_FILES==3 00377 PRINTA(".%s online with static %u byte program memory file system\n",buf,size); 00378 #elif COFFEE_FILES==4 00379 PRINTA(".%s online with dynamic %u KB program memory file system\n",buf,size>>10); 00380 #endif /* COFFEE_FILES */ 00381 } 00382 #else 00383 PRINTA("Online\n"); 00384 #endif 00385 #endif /* ANNOUNCE_BOOT */ 00386 00387 #if RF230BB_CONF_LEDONPORTE1 00388 /* NB: PORTE1 conflicts with UART0 */ 00389 DDRE|=(1<<DDE1); //set led pin to output (Micheal Hatrtman board) 00390 PORTE&=~(1<<PE1); //and low to turn led off 00391 #endif 00392 } 00393 00394 #if ROUTES && UIP_CONF_IPV6 00395 static void 00396 ipaddr_add(const uip_ipaddr_t *addr) 00397 { 00398 uint16_t a; 00399 int8_t i, f; 00400 for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) { 00401 a = (addr->u8[i] << 8) + addr->u8[i + 1]; 00402 if(a == 0 && f >= 0) { 00403 if(f++ == 0) PRINTF("::"); 00404 } else { 00405 if(f > 0) { 00406 f = -1; 00407 } else if(i > 0) { 00408 PRINTF(":"); 00409 } 00410 PRINTF("%x",a); 00411 } 00412 } 00413 } 00414 #endif 00415 00416 /*-------------------------------------------------------------------------*/ 00417 /*------------------------- Main Scheduler loop----------------------------*/ 00418 /*-------------------------------------------------------------------------*/ 00419 int 00420 main(void) 00421 { 00422 initialize(); 00423 00424 while(1) { 00425 process_run(); 00426 watchdog_periodic(); 00427 00428 /* Turn off LED after a while */ 00429 if (ledtimer) { 00430 if (--ledtimer==0) { 00431 #if RF230BB_CONF_LEDONPORTE1 00432 PORTE&=~(1<<PE1); 00433 #endif 00434 #if defined(RAVEN_LCD_INTERFACE)&&0 00435 /* ledtimer can be set by received ping; ping the other way for testing */ 00436 extern void raven_ping6(void); 00437 raven_ping6(); 00438 #endif 00439 } 00440 } 00441 00442 #if 0 00443 /* Various entry points for debugging in the AVR Studio simulator. 00444 * Set as next statement and step into the routine. 00445 */ 00446 NETSTACK_RADIO.send(packetbuf_hdrptr(), 42); 00447 process_poll(&rf230_process); 00448 packetbuf_clear(); 00449 len = rf230_read(packetbuf_dataptr(), PACKETBUF_SIZE); 00450 packetbuf_set_datalen(42); 00451 NETSTACK_RDC.input(); 00452 #endif 00453 00454 #if 0 00455 /* Clock.c can trigger a periodic PLL calibration in the RF230BB driver. 00456 * This can show when that happens. 00457 */ 00458 extern uint8_t rf230_calibrated; 00459 if (rf230_calibrated) { 00460 PRINTD("\nRF230 calibrated!\n"); 00461 rf230_calibrated=0; 00462 } 00463 #endif 00464 00465 /* Set DEBUGFLOWSIZE in contiki-conf.h to track path through MAC, RDC, and RADIO */ 00466 #if DEBUGFLOWSIZE 00467 if (debugflowsize) { 00468 debugflow[debugflowsize]=0; 00469 PRINTF("%s",debugflow); 00470 debugflowsize=0; 00471 } 00472 #endif 00473 00474 #if PERIODICPRINTS 00475 #if TESTRTIMER 00476 /* Timeout can be increased up to 8 seconds maximum. 00477 * A one second cycle is convenient for triggering the various debug printouts. 00478 * The triggers are staggered to avoid printing everything at once. 00479 */ 00480 if (rtimerflag) { 00481 rtimer_set(&rt, RTIMER_NOW()+ RTIMER_ARCH_SECOND*1UL, 1,(void *) rtimercycle, NULL); 00482 rtimerflag=0; 00483 #else 00484 if (clocktime!=clock_seconds()) { 00485 clocktime=clock_seconds(); 00486 #endif 00487 00488 #if STAMPS 00489 if ((clocktime%STAMPS)==0) { 00490 #if ENERGEST_CONF_ON 00491 #include "lib/print-stats.h" 00492 print_stats(); 00493 #elif RADIOSTATS 00494 extern volatile unsigned long radioontime; 00495 PRINTF("%u(%u)s\n",clocktime,radioontime); 00496 #else 00497 PRINTF("%us\n",clocktime); 00498 #endif 00499 00500 } 00501 #endif 00502 #if TESTRTIMER 00503 clocktime+=1; 00504 #endif 00505 00506 #if PINGS && UIP_CONF_IPV6 00507 extern void raven_ping6(void); 00508 if ((clocktime%PINGS)==1) { 00509 PRINTF("**Ping\n"); 00510 raven_ping6(); 00511 } 00512 #endif 00513 00514 #if ROUTES && UIP_CONF_IPV6 00515 if ((clocktime%ROUTES)==2) { 00516 00517 extern uip_ds6_nbr_t uip_ds6_nbr_cache[]; 00518 extern uip_ds6_route_t uip_ds6_routing_table[]; 00519 extern uip_ds6_netif_t uip_ds6_if; 00520 00521 uint8_t i,j; 00522 PRINTF("\nAddresses [%u max]\n",UIP_DS6_ADDR_NB); 00523 for (i=0;i<UIP_DS6_ADDR_NB;i++) { 00524 if (uip_ds6_if.addr_list[i].isused) { 00525 ipaddr_add(&uip_ds6_if.addr_list[i].ipaddr); 00526 PRINTF("\n"); 00527 } 00528 } 00529 PRINTF("\nNeighbors [%u max]\n",UIP_DS6_NBR_NB); 00530 for(i = 0,j=1; i < UIP_DS6_NBR_NB; i++) { 00531 if(uip_ds6_nbr_cache[i].isused) { 00532 ipaddr_add(&uip_ds6_nbr_cache[i].ipaddr); 00533 PRINTF("\n"); 00534 j=0; 00535 } 00536 } 00537 if (j) PRINTF(" <none>"); 00538 PRINTF("\nRoutes [%u max]\n",UIP_DS6_ROUTE_NB); 00539 for(i = 0,j=1; i < UIP_DS6_ROUTE_NB; i++) { 00540 if(uip_ds6_routing_table[i].isused) { 00541 ipaddr_add(&uip_ds6_routing_table[i].ipaddr); 00542 PRINTF("/%u (via ", uip_ds6_routing_table[i].length); 00543 ipaddr_add(&uip_ds6_routing_table[i].nexthop); 00544 // if(uip_ds6_routing_table[i].state.lifetime < 600) { 00545 PRINTF(") %lus\n", uip_ds6_routing_table[i].state.lifetime); 00546 // } else { 00547 // PRINTF(")\n"); 00548 // } 00549 j=0; 00550 } 00551 } 00552 if (j) PRINTF(" <none>"); 00553 PRINTF("\n---------\n"); 00554 } 00555 #endif 00556 00557 #if STACKMONITOR 00558 if ((clocktime%STACKMONITOR)==3) { 00559 extern uint16_t __bss_end; 00560 uint16_t p=(uint16_t)&__bss_end; 00561 do { 00562 if (*(uint16_t *)p != 0x4242) { 00563 PRINTF("Never-used stack > %d bytes\n",p-(uint16_t)&__bss_end); 00564 break; 00565 } 00566 p+=10; 00567 } while (p<RAMEND-10); 00568 } 00569 #endif 00570 00571 } 00572 #endif /* PERIODICPRINTS */ 00573 00574 #if RF230BB&&0 00575 extern uint8_t rf230processflag; 00576 if (rf230processflag) { 00577 PRINTF("rf230p%d",rf230processflag); 00578 rf230processflag=0; 00579 } 00580 #endif 00581 00582 #if RF230BB&&0 00583 extern uint8_t rf230_interrupt_flag; 00584 if (rf230_interrupt_flag) { 00585 // if (rf230_interrupt_flag!=11) { 00586 PRINTF("**RI%u",rf230_interrupt_flag); 00587 // } 00588 rf230_interrupt_flag=0; 00589 } 00590 #endif 00591 } 00592 return 0; 00593 } 00594 00595 /*---------------------------------------------------------------------------*/ 00596 00597 void log_message(char *m1, char *m2) 00598 { 00599 PRINTF("%s%s\n", m1, m2); 00600 }