void appMain(void) { uint16_t i; // ------------------------- serial number DPRINTF("Mote %#04x starting...\n", localAddress); // ------------------------- external flash #if WRITE_TO_FLASH prepareExtFlash(); #endif // ------------------------- light sensors if (localAddress != 0x0796) { PRINT("init isl\n"); islInit(); islOn(); } else { PRINT("init ads\n"); adsInit(); adsSelectInput(0); } // ------------------------- main loop mdelay(3000); DPRINTF("starting main loop...\n"); for (i = 0; i < 6; ++i) { redLedToggle(); mdelay(100); } ledOff(); uint32_t nextDataReadTime = 0; uint32_t nextBlinkTime = 0; for (;;) { uint32_t now = getRealTime(); if (timeAfter32(now, nextDataReadTime)) { if (getJiffies() < 300 * 1000ul ) { nextDataReadTime = now + DATA_INTERVAL_SMALL; } else { nextDataReadTime = now + DATA_INTERVAL; } DataPacket_t packet; readSensors(&packet); #if PRINT_PACKET printPacket(&packet); #endif } if (timeAfter32(now, nextBlinkTime)) { nextBlinkTime = now + BLINK_INTERVAL; ledOn(); msleep(100); ledOff(); } msleep(1000); } }
void alarmsProcess(void) { // // Note that this code works in the way that neither locking the list // nor disabling interrupts is required // uint32_t now = (uint32_t) getJiffies(); // PRINTF("processAlarms: jiffies=%lu\n", now); Alarm_t **a = &SLIST_FIRST(&alarmListHead); while (*a) { Alarm_t *ap = *a; // the alarm must have valid callback ASSERT(ap->callback != NULL); // PRINTF("processAlarms: ap=%p, ap->jiffies=%lu\n", ap, ap->jiffies); if (timeAfter32(ap->jiffies, now)) { break; } // save next alarm for later reference Alarm_t **next = &SLIST_NEXT(ap, chain); // remove the alarm from the list *a = *next; // call the callback ap->callback(ap->data); // move to the next a = next; } }
void alarmSchedule(Alarm_t *alarm, uint32_t milliseconds) { // we want to avoid inserting local variables in the global alarm list // (but this warning, not an error, because the user function may never return) WARN_ON(isStackAddress(alarm)); // PRINTF("alarmSchedule %p, ms=%lu\n", alarm, milliseconds); alarm->jiffies = (uint32_t)getJiffies() + milliseconds; // locking is required, because both kernel and user threads can be using this function Handle_t h; ATOMIC_START(h); // unschedule the alarm, if it was already scheduled SLIST_REMOVE_SAFE(&alarmListHead, alarm, Alarm_s, chain); // insert it in appropriate position Alarm_t **prev = &SLIST_FIRST(&alarmListHead); Alarm_t *a = *prev; while (a && timeAfter32(alarm->jiffies, a->jiffies)) { prev = &SLIST_NEXT(a, chain); a = *prev; } SLIST_INSERT(prev, alarm, chain); #if USE_THREADS // always reschedule alarm processing in case some alarm was added // that might need to be processed before end of current kernel sleep time processFlags.bits.alarmsProcess = true; // and make sure the kernel thread is awake and ready to deal with it threadWakeup(KERNEL_THREAD_INDEX, THREAD_READY); #endif ATOMIC_END(h); }
static uint8_t markAsSeen(MosShortAddr address, bool addNew) { uint32_t now = (uint32_t) getJiffies(); // MOTE_INFO_VALID_TIME - ? uint8_t i; for (i = 0; i < MAX_MOTES; ++i) { if (motes[i].address == address) { break; } } if (i == MAX_MOTES && addNew) { for (i = 0; i < MAX_MOTES; ++i) { if (motes[i].address == 0 || timeAfter32(now, motes[i].validUntil)) { break; } } // save its address motes[i].address = address; } if (i == MAX_MOTES) { if (addNew) PRINTF("recv rreq: no more space!\n"); return 0xff; } // mark it as seen motes[i].validUntil = now + MOTE_INFO_VALID_TIME; return i; }
// alarm timer interrupt handler ALARM_TIMER_INTERRUPT() { // read & unset the highest bit volatile uint16_t x = TIMER_INTERRUPT_VECTOR; (void) x; if (isInSleepMode) { // wakeup and return EXIT_SLEEP_MODE(); return; } uint16_t tar = ALARM_TIMER_READ(); // Advance jiffies (MansOS time counter) while counter register <= counter // Spurios interrupts may happen when the alarm timer is restarted after stopping! while (!timeAfter16(ALARM_TIMER_REGISTER, tar)) { jiffies += JIFFY_TIMER_MS; ALARM_TIMER_REGISTER += PLATFORM_ALARM_TIMER_PERIOD; } #if PLATFORM_HAS_CORRECTION_TIMER // // On MSP430 platforms binary ACLK oscillator usually is used. // It has constant rate 32768 Hz (the ACLK_SPEED define) // When ACLK ticks are converted to milliseconds, rounding error is introduced. // When TIMER_INTERRUPT_HZ = 1000, there are 32 ACLK ticks per millisecond; // The clock error is (32768 / 32) - 1000 = 1024 - 1000 = 24 milliseconds. // We improve the precision by applying a fix 24/3 = 8 times per second. // while (!timeAfter16(CORRECTION_TIMER_REGISTER, tar)) { CORRECTION_TIMER_REGISTER += PLATFORM_TIME_CORRECTION_PERIOD; jiffies -= 3; } #endif #ifdef USE_ALARMS if (hasAnyReadyAlarms(jiffies)) { alarmsProcess(); } #endif #ifdef USE_PROTOTHREADS if (etimer_pending() && !etimer_polled() && !timeAfter32(jiffies, etimer_next_expiration_time())) { etimer_request_poll(); EXIT_SLEEP_MODE(); } #endif // If TAR still > TACCR0 at this point, we are in trouble: // the interrupt will not be generated until the next wraparound (2 seconds). // So avoid it at all costs. while (!timeAfter16(ALARM_TIMER_REGISTER, ALARM_TIMER_READ() + 2)) { jiffies += JIFFY_TIMER_MS; ALARM_TIMER_REGISTER += PLATFORM_ALARM_TIMER_PERIOD; } }
//------------------------------------------- // Entry point for the application //------------------------------------------- void appMain(void) { PRINTF("\n\nAccelerometer data gathering app\n"); extFlashWake(); // start with clean and new... cleanFlash(); accelOn(); userButtonEnable(onUserButton); mdelay(START_DELAY); uint16_t lastSecond; uint16_t samplesPerSecond; for (;;) { while (!isActiveMode); redLedOn(); lastSecond = getTimeSec(); samplesPerSecond = 0; uint16_t i; for (i = 0; isActiveMode; i++) { if (i % 10 == 0) redLedToggle(); uint32_t now = getTimeMs(); uint32_t endTime = now + MAIN_LOOP_LENGTH; Packet_t p; p.timestamp = now; p.acc_x = accelReadX(); p.acc_y = accelReadY(); p.acc_z = accelReadZ(); printPacket(&p); samplesPerSecond++; uint16_t currentSecond = getTimeSec(); if (currentSecond != lastSecond) { PRINTF("samples per second = %u\n", samplesPerSecond); lastSecond = currentSecond; samplesPerSecond = 0; } while (timeAfter32(endTime, getTimeMs())); } redLedOff(); } }
static inline bool isRoutingInfoValid(void) { if (hopCountToRoot >= MAX_HOP_COUNT) return false; bool old = timeAfter32((uint32_t)getJiffies(), lastRootMessageTime + ROUTING_INFO_VALID_TIME); if (old) { hopCountToRoot = MAX_HOP_COUNT; return false; } return true; }
uint32_t readSensorU32(uint16_t code, ReadFunctionU32 func, uint16_t expireTime) { uint32_t now = getJiffies(); SensorCache_t *cacheValue = &sensorCache[code]; if (cacheValue->expireTime && !timeAfter32(now, cacheValue->expireTime)) { // take from cache return cacheValue->value.u32; } uint32_t result = func(); if (expireTime) { // add to cache cacheValue->value.u32 = result; cacheValue->expireTime = now + expireTime; } return result; }
static void roForwardTimerCb(void *x) { static uint8_t moteToProcess; bool roOK = isRoutingInfoValid(); if (motes[moteToProcess].address != 0 && timeAfter32(motes[moteToProcess].validUntil, (uint32_t)getJiffies()) && hopCountToRoot < MAX_HOP_COUNT && roOK) { forwardRoutingInfo(moteToProcess); } moteToProcess++; if (moteToProcess == MAX_MOTES) moteToProcess = 0; alarmSchedule(&roForwardTimer, calcNextForwardTime(moteToProcess)); }