int main () { uint16_t div; nrk_int_disable(); // Configure relay port directions DDRE |= 0x10; socket_0_enable(); // Configure led port directions DDRE |= 0x0c; DDRD |= 0x00; PORTD |= 0xff; DDRF = 0; socket_0_active=nrk_eeprom_read_byte(EEPROM_STATE_ADDR); // turn outlet on if active or throttled for testing if(socket_0_active==1 || socket_0_active==2) { socket_0_enable(); plug_led_green_set(); } else { socket_0_disable(); plug_led_green_clr(); } // If PUD value set, then we expect it wasn't a clean reboot (unexpected restart). // Try to force a proper watchdog reboot if((MCUCR&0x10)!=0 ) { //nrk_watchdog_enable(); nrk_int_disable(); MCUSR &= ~(1<<WDRF); WDTCSR |= (1<<WDCE) | (1<<WDE); WDTCSR = (1<<WDE) | (1<<WDP2) | (1<<WDP0); // Disable interrupts to stop pending timers etc while(1); } nrk_setup_uart (UART_BAUDRATE_115K2); MCUCR |= BM(PUD); nrk_init (); nrk_time_set (0, 0); tdma_set_error_callback(&tdma_error); tdma_task_config(); nrk_create_taskset (); nrk_start (); return 0; }
nrk_status_t nrk_terminate_task(nrk_task_type * Task) { nrk_queue *curNode; //PAJA: CRITICAL SECTIONS!!!!!!! nrk_int_disable(); //////// nrk_rem_from_readyQ(nrk_cur_task_TCB->task_ID); nrk_rem_from_readyQ(Task->task_ID); nrk_cur_task_TCB->task_state = FINISHED; //(Task->taskTCB)->task_state = FINISHED; (Task->taskTCB)->event_suspend = 0; //fix srinivas tasksNumber--; curNode = _free_node; //free node can not be NULL while (curNode->Next!=NULL) curNode = curNode->Next; if (_free_node->Next!=NULL) (curNode->Prev)->Next = NULL; else _free_node = NULL; //free(curNode); paja: mui importante!!!!!!!!! nrk_int_enable(); // HAHA, there is NO next period... nrk_wait_until_next_period (); return NRK_OK; }
//return the number removed from signal set int8_t nrk_signal_delete(nrk_sig_t sig_id) { uint8_t task_ID; uint32_t sig_mask; sig_mask=SIG(sig_id); if( (sig_mask & _nrk_signal_list)==0) return NRK_ERROR; nrk_int_disable(); for (task_ID=0; task_ID < NRK_MAX_TASKS; task_ID++){ if(nrk_task_TCB[task_ID].task_ID==-1) continue; // Check for tasks waiting on the signal // If there is a task that is waiting on just this signal // then we need to change it to the normal SUSPEND state if(nrk_task_TCB[task_ID].registered_signal_mask==sig_mask) //check to make sure its only signal its waiting on { // printf("delete t(%i) signal(%li)\r\n",task_ID,nrk_task_TCB[task_ID].registered_signal_mask); nrk_task_TCB[task_ID].active_signal_mask=0; nrk_task_TCB[task_ID].event_suspend=0; nrk_task_TCB[task_ID].task_state=SUSPENDED; } nrk_task_TCB[task_ID].registered_signal_mask&=~sig_mask; //cheaper to remove than do a check nrk_task_TCB[task_ID].active_signal_mask&=~sig_mask; //cheaper to remove than do a check } _nrk_signal_list&=~SIG(sig_id); nrk_int_enable(); return NRK_OK; }
int8_t nrk_wait_until_next_n_periods (uint16_t p) { uint8_t timer; nrk_stack_check (); if (p == 0) p = 1; // Next Period Wakeup Time is Set inside scheduler when a task becomes Runnable nrk_int_disable (); nrk_cur_task_TCB->suspend_flag = 1; nrk_cur_task_TCB->num_periods = p; timer = _nrk_os_timer_get (); //nrk_cur_task_TCB->cpu_remaining=_nrk_prev_timer_val+1; // +2 allows for potential time conflict resolution if (timer < (MAX_SCHED_WAKEUP_TIME - TIME_PAD)) // 254 8bit overflow point - 2 if ((timer + TIME_PAD) <= _nrk_get_next_wakeup ()) { timer += TIME_PAD; _nrk_prev_timer_val = timer; _nrk_set_next_wakeup (timer); } nrk_int_enable (); _nrk_wait_for_scheduler (); return NRK_OK; }
int8_t nrk_wait (nrk_time_t t) { uint8_t timer; uint16_t nw; nrk_stack_check (); nrk_int_disable (); nrk_cur_task_TCB->suspend_flag = 1; nrk_cur_task_TCB->num_periods = 1; timer = _nrk_os_timer_get (); //printf( "t1 %lu %lu\n",t.secs, t.nano_secs/NANOS_PER_MS); nw = _nrk_time_to_ticks (t); //printf( "t2 %u\n",nw ); nrk_cur_task_TCB->next_wakeup = nw + timer; //printf( "wu %u\n",nrk_cur_task_TCB->next_wakeup ); if (timer < (MAX_SCHED_WAKEUP_TIME - TIME_PAD)) if ((timer + TIME_PAD) <= _nrk_get_next_wakeup ()) { timer += TIME_PAD; _nrk_prev_timer_val = timer; _nrk_set_next_wakeup (timer); } nrk_int_enable (); _nrk_wait_for_scheduler (); return NRK_OK; }
void initialise_network_layer() { int8_t i; // loop index /* initialise the data structures required for the network layer */ nl.count = 0; // no neighbors recorded yet nl.my_addr = NODE_ADDR; // assign my network layer address for(i = 0; i < MAX_NGBS; i++) // an addr = BCAST_ADDR indicates an invalid entry nl.ngbs[i].addr = BCAST_ADDR; DEFAULT_GATEWAY = BCAST_ADDR; // initially the default gateway is unknown ROUTING_ALGORITHM = DEFAULT_ROUTING_ALGORITHM; // set the routing algorithm FLOODING_TYPE = DEFAULT_FLOODING_TYPE; // set the flooding type to be ttl-based P_DISTRIBUTION = DEFAULT_PDISTRIBUTION; // set the probability distribution initialise_routing_table(); nl_sem = nrk_sem_create(1,MAX_TASK_PRIORITY); // create the mutex if(nl_sem == NULL) { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: Error creating semaphore in initialise_network_layer()\r\n")); } create_network_layer_tasks(); // create the two tasks return; }
/********************************************************** * start timer * (start atmega 128 Timer/Counter) */ void wd_timer_start() { nrk_int_disable(); periodic_time_offset = 0; logical_time = 0; alarm_time = 0; alarm_type = 0; is_alarm_set = false; is_periodic_enabled = false; #if USE_TIMER_COUNTER == 1 TCCR1A = 0; // Compare Output Mode : Normal TCNT1 = 0; // reset timer value TIFR&=~BM(OCF1A); // clear OCF flag TIMSK|=BM(OCIE1A); // enable compare interrupt OCR1A = (uint16_t)(WD_CLOCK_TICKS); // set compare value TCCR1B = TIMER_CLK_DIV1; // set timer scale TCCR1B |= BM(WGM12); // Waveform Generation Mode: Clear Timer on Compare #elif USE_TIMER_COUNTER == 3 TCCR3A = 0; // Compare Output Mode : Normal TCNT3 = 0; // reset timer value ETIFR&=~BM(OCF3A); // clear OCF flag ETIMSK|=BM(OCIE3A); // enable compare interrupt OCR3A = (uint16_t)(WD_CLOCK_TICKS); // set compare value TCCR3B = TCLK_CPU_DIV; // set timer scale TCCR3B |= BM(WGM32); // Waveform Generation Mode: Clear Timer on Compare #else #error "Must define USE_TIMER_COUNTER in wd_timer.h as 1 or 3." #endif nrk_int_enable(); }
int8_t nrk_wait_until_next_period () { uint8_t timer; //Abhijeet disabled this... Haww //NVIC_EnableIRQ(TIMER0_IRQn); //NVIC_EnableIRQ(TIMER1_IRQn); //nrk_stack_check (); // Next Period Wakeup Time is Set inside scheduler when a task becomes Runnable nrk_int_disable (); nrk_cur_task_TCB->num_periods = 1; nrk_cur_task_TCB->suspend_flag = 1; timer = _nrk_os_timer_get (); //nrk_cur_task_TCB->cpu_remaining=_nrk_prev_timer_val+1; if (timer < (MAX_SCHED_WAKEUP_TIME - TIME_PAD)) // if(timer<(250-10)) if ((timer + TIME_PAD) <= _nrk_get_next_wakeup ()) { timer += TIME_PAD; _nrk_prev_timer_val = timer; // pdiener: why is this only set in this special case? _nrk_set_next_wakeup (timer); // pdiener: Set next wakeup to NOW...Ask Madhur and Abhijeet } nrk_int_enable (); _nrk_wait_for_scheduler (); //pc6.printf("should not come here"); return NRK_OK; }
int8_t nrk_wait_until_next_period () { uint16_t timer; nrk_stack_check (); // Next Period Wakeup Time is Set inside scheduler when a task becomes Runnable // EXCEPT THIS CAUSES A FIRST-TIME-THROUGH BUG nrk_int_disable (); nrk_cur_task_TCB->num_periods = 1; nrk_cur_task_TCB->suspend_flag = 1; nrk_cur_task_TCB->next_wakeup = nrk_cur_task_TCB->next_period; timer = _nrk_os_timer_get (); //nrk_cur_task_TCB->cpu_remaining=_nrk_prev_timer_val+1; if (timer < (MAX_SCHED_WAKEUP_TIME - TIME_PAD)) if ((timer + TIME_PAD) <= _nrk_get_next_wakeup ()) { timer += TIME_PAD; _nrk_prev_timer_val = timer; _nrk_set_next_wakeup (timer); } nrk_int_enable (); _nrk_wait_for_scheduler (); return NRK_OK; }
// This is an interrupts routine that handles the button press. // It has a 300ms debounce void button_handler() { int8_t v; // Make sure button is depressed for at least 50 us nrk_spin_wait_us(50); v=nrk_gpio_get(NRK_PORTD_0); if(v!=0) return; nrk_time_get(&button_cur_press); nrk_time_sub(&button_tmp_press, button_cur_press, button_last_press ); if(button_tmp_press.secs>=1 || button_tmp_press.nano_secs>=(300*NANOS_PER_MS)) { // Reboot the node... socket_0_disable(); power_socket_disable(0); nrk_int_disable(); while(1); if(socket_0_active==1) { plug_led_green_clr(); power_socket_disable(0); } else { plug_led_green_set(); power_socket_enable(0); } button_last_press.secs=button_cur_press.secs; button_last_press.nano_secs=button_cur_press.nano_secs; } }
int8_t nrk_sem_post(nrk_sem_t *rsrc) { int8_t id=nrk_get_resource_index(rsrc); int8_t task_ID; if(id==-1) { _nrk_errno_set(1); return NRK_ERROR;} if(id==NRK_MAX_RESOURCE_CNT) { _nrk_errno_set(2); return NRK_ERROR; } if(nrk_sem_list[id].value<nrk_sem_list[id].count) { // Signal RSRC Event nrk_int_disable(); nrk_sem_list[id].value++; sc = system_ceiling(); nrk_cur_task_TCB->elevated_prio_flag=0; for (task_ID=0; task_ID < NRK_MAX_TASKS; task_ID++){ if(nrk_task_TCB[task_ID].event_suspend==RSRC_EVENT_SUSPENDED) if((nrk_task_TCB[task_ID].active_signal_mask == id)) { nrk_task_TCB[task_ID].task_state=SUSPENDED; nrk_task_TCB[task_ID].next_wakeup=0; nrk_task_TCB[task_ID].event_suspend=0; nrk_task_TCB[task_ID].active_signal_mask=0; } } nrk_int_enable(); } return NRK_OK; }
int8_t nrk_sem_pend(nrk_sem_t *rsrc ) { int8_t id; id=nrk_get_resource_index(rsrc); if(id==-1) { _nrk_errno_set(1); return NRK_ERROR;} if(id==NRK_MAX_RESOURCE_CNT) { _nrk_errno_set(2); return NRK_ERROR; } nrk_int_disable(); if(nrk_sem_list[id].value==0) { nrk_cur_task_TCB->event_suspend|=RSRC_EVENT_SUSPENDED; nrk_cur_task_TCB->active_signal_mask=id; // Wait on suspend event nrk_int_enable(); nrk_wait_until_ticks(0); } nrk_sem_list[id].value--; sc = system_ceiling(); nrk_cur_task_TCB->task_prio_ceil=nrk_sem_list[id].resource_ceiling; nrk_cur_task_TCB->elevated_prio_flag=1; nrk_int_enable(); return NRK_OK; }
int8_t nrk_wait_until_next_period () { uint8_t timer; nrk_stack_check (); // Next Period Wakeup Time is Set inside scheduler when a task becomes Runnable nrk_int_disable (); nrk_cur_task_TCB->num_periods = 1; nrk_cur_task_TCB->suspend_flag = 1; timer = _nrk_os_timer_get (); //nrk_cur_task_TCB->cpu_remaining=_nrk_prev_timer_val+1; if (timer < (MAX_SCHED_WAKEUP_TIME - TIME_PAD)) if ((timer + TIME_PAD) <= _nrk_get_next_wakeup ()) { timer += TIME_PAD; _nrk_prev_timer_val = timer; // pdiener: why is this only set in this special case? _nrk_set_next_wakeup (timer); // pdiener: Set next wakeup to NOW } nrk_int_enable (); _nrk_wait_for_scheduler (); return NRK_OK; }
void nrk_kernel_error_add (uint8_t n, uint8_t task) { error_num = n; error_task = task; #ifdef NRK_LOG_ERRORS _nrk_log_error(error_num, error_task); #endif #ifdef NRK_REPORT_ERRORS nrk_error_print (); #endif /* */ #ifdef NRK_SOFT_REBOOT_ON_ERROR #ifdef NRK_WATCHDOG nrk_watchdog_disable(); #endif asm volatile("jmp 0x0000\n\t" ::); #endif #ifdef NRK_REBOOT_ON_ERROR // wait for watchdog to kick in if(n!=NRK_WATCHDOG_ERROR && n!=NRK_BOD_ERROR && n!=NRK_EXT_RST_ERROR) { nrk_watchdog_enable(); nrk_int_disable(); while(1); } #endif #ifdef NRK_HALT_ON_ERROR uint8_t t; uint8_t i; while (1) { for(i=0; i<20; i++ ) { nrk_led_set (2); nrk_led_clr (3); for (t = 0; t < 100; t++) nrk_spin_wait_us (1000); nrk_led_set (3); nrk_led_clr (2); for (t = 0; t < 100; t++) nrk_spin_wait_us (1000); } nrk_led_clr (3); nrk_led_clr (2); blink_morse_code_error( task ); blink_morse_code_error( n ); } #endif /* */ }
int8_t nrk_wait_until_next_period() { uint8_t timer; nrk_stack_check(); // Next Period Wakeup Time is Set inside scheduler when a task becomes Runnable nrk_int_disable(); nrk_cur_task_TCB->num_periods = 1; nrk_cur_task_TCB->suspend_flag = 1; timer = _nrk_os_timer_get(); //nrk_cur_task_TCB->cpu_remaining=_nrk_prev_timer_val+1; if (timer < (MAX_SCHED_WAKEUP_TIME - TIME_PAD)) if ((timer + TIME_PAD) <= _nrk_get_next_wakeup()) { timer += TIME_PAD; _nrk_prev_timer_val = timer; _nrk_set_next_wakeup(timer); } printf("Task %u finished in %u. \r\n",nrk_cur_task_TCB->task_ID,timer); nrk_int_enable(); _nrk_wait_for_scheduler(); return NRK_OK; }
void nrk_watchdog_disable() { nrk_int_disable(); nrk_watchdog_reset(); MCUSR &= ~(1<<WDRF); WDTCR |= (1<<WDCE) | (1<<WDE); WDTCR = 0; nrk_int_enable(); }
/****************************** FUNCTION DEFINITIONS ****************************************/ void go_into_panic(char *str) // This function is for signalling error conditions { nrk_int_disable(); nrk_led_set(RED_LED); while(1) printf("PANIC: %s. This should never happen\n", str); return; }
int8_t nrk_event_signal(int8_t sig_id) { uint8_t task_ID; uint8_t event_occured=0; uint32_t sig_mask; sig_mask=SIG(sig_id); // Check if signal was created // Signal was not created if((sig_mask & _nrk_signal_list)==0 ) { _nrk_errno_set(1); return NRK_ERROR;} //needs to be atomic otherwise run the risk of multiple tasks being scheduled late and not in order of priority. nrk_int_disable(); for (task_ID=0; task_ID < NRK_MAX_TASKS; task_ID++){ // if (nrk_task_TCB[task_ID].task_state == EVENT_SUSPENDED) // { // printf( "task %d is event suspended\r\n",task_ID ); if(nrk_task_TCB[task_ID].event_suspend==SIG_EVENT_SUSPENDED) if((nrk_task_TCB[task_ID].active_signal_mask & sig_mask)) { nrk_task_TCB[task_ID].task_state=SUSPENDED; nrk_task_TCB[task_ID].next_wakeup=0; nrk_task_TCB[task_ID].event_suspend=0; // Add the event trigger here so it is returned // from nrk_event_wait() nrk_task_TCB[task_ID].active_signal_mask=sig_mask; event_occured=1; } if(nrk_task_TCB[task_ID].event_suspend==RSRC_EVENT_SUSPENDED) if((nrk_task_TCB[task_ID].active_signal_mask == sig_mask)) { nrk_task_TCB[task_ID].task_state=SUSPENDED; nrk_task_TCB[task_ID].next_wakeup=0; nrk_task_TCB[task_ID].event_suspend=0; // Add the event trigger here so it is returned // from nrk_event_wait() nrk_task_TCB[task_ID].active_signal_mask=0; event_occured=1; } // } } nrk_int_enable(); if(event_occured) { return NRK_OK; } // No task was waiting on the signal _nrk_errno_set(2); return NRK_ERROR; }
void nrk_watchdog_enable() { // Enable watchdog with 1024K cycle timeout // No Interrupt Trigger nrk_int_disable(); MCUSR &= ~(1<<WDRF); nrk_watchdog_reset(); WDTCR |= (1<<WDCE) | (1<<WDE); WDTCR = (1<<WDE) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0); nrk_int_enable(); }
int8_t power_socket_enable (uint8_t socket) { if (socket == 0) { socket_0_enable (); socket_0_active = 1; nrk_int_disable(); nrk_eeprom_write_byte(EEPROM_STATE_ADDR, socket_0_active); nrk_int_enable(); } nrk_timer_int_start (NRK_APP_TIMER_0); return 1; }
void _nrk_reserve_update (uint8_t reserve_id) { nrk_time_t t; nrk_int_disable (); nrk_time_get (&t); _nrk_reserve[reserve_id].cur_time = (int32_t) _nrk_time_to_ticks_long (t); if (_nrk_reserve[reserve_id].cur_time >= _nrk_reserve[reserve_id].set_time) { // If the reserve is passed its period then replenish it _nrk_reserve[reserve_id].set_time = _nrk_reserve[reserve_id].cur_time + _nrk_reserve[reserve_id].period_ticks; _nrk_reserve[reserve_id].cur_access = 0; } nrk_int_enable (); }
int8_t nrk_wait_until_nw() { uint8_t timer; nrk_int_disable(); nrk_cur_task_TCB->suspend_flag = 1; nrk_cur_task_TCB->nw_flag = 1; timer = _nrk_os_timer_get(); if (timer < MAX_SCHED_WAKEUP_TIME - TIME_PAD) if ((timer + TIME_PAD) <= _nrk_get_next_wakeup()) { timer += TIME_PAD; _nrk_prev_timer_val = timer; _nrk_set_next_wakeup(timer); } //else nrk_cur_task_TCB->next_wakeup=ticks+1; nrk_int_enable(); //while(nrk_cur_task_TCB->suspend_flag==1); _nrk_wait_for_scheduler(); return NRK_OK; }
int8_t power_socket_disable (uint8_t socket) { if (socket == 0) { socket_0_disable (); socket_0_active = 0; nrk_int_disable(); nrk_eeprom_write_byte(EEPROM_STATE_ADDR, socket_0_active); nrk_int_enable(); } /* if (socket_1_active == 0 && socket_0_active == 0) { // Turn interrupt off to save power nrk_timer_int_stop (NRK_APP_TIMER_0); // Shutdown monitor circuit to save power power_mon_disable (); } */ return 1; }
int8_t nrk_sem_pend(nrk_sem_t *rsrc ) { int8_t id; id=nrk_get_resource_index(rsrc); if(id==-1) { _nrk_errno_set(1); return NRK_ERROR;} if(id==NRK_MAX_RESOURCE_CNT) { _nrk_errno_set(2); return NRK_ERROR; } /* if (_nrk_system_ceiling > nrk_sem_list[id].resource_ceiling) */ /* { */ /* nrk_wait_until_ticks(0); */ /* } */ //get access to the semaphore nrk_int_disable(); nrk_sem_list[id].value--; if(_nrk_system_ceiling < rsrc->resource_ceiling) _nrk_system_ceiling = rsrc->resource_ceiling; _nrk_ceiling_stack[++_nrk_ceiling_tos]= nrk_sem_list[id].resource_ceiling; nrk_int_enable(); //nrk_wait_until_ticks(0); return NRK_OK; }
int8_t nrk_set_next_wakeup(nrk_time_t t) { uint8_t timer; uint16_t nw; nrk_int_disable(); timer = _nrk_os_timer_get(); nw = _nrk_time_to_ticks(t); if (nw <= TIME_PAD) return NRK_ERROR; nrk_cur_task_TCB->next_wakeup = nw + timer; /* if(timer<(254-TIME_PAD)) if((timer+TIME_PAD)<=_nrk_get_next_wakeup()) { timer+=TIME_PAD; _nrk_prev_timer_val=timer; _nrk_set_next_wakeup(timer); } */ // nrk_cur_task_TCB->nw_flag=1; nrk_int_enable(); return NRK_OK; }
/************************* Function definitions ***************************/ int8_t sendToSerial(uint8_t *buf, uint8_t len) // CHECKED { while( slip_started () == NRK_ERROR ) // wait till the serial task starts the SLIPstream module nrk_wait_until_next_period(); /* if(len > SIZE_SLIP_TX_BUF) { nrk_kprintf(PSTR("SR: sendToSerial(): Buffer length too big\r\n")); return NRK_ERROR; } */ if( slip_tx (buf, len) == NRK_ERROR ) { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("SR: sendToSerial(): Error sending out message over serial port\r\n")); } return NRK_OK; }
/* void sendToSerial(uint8_t *buf, int8_t length) { putchar(END); if(DEBUG_SR == 2) printf("%d ", END); while(length > 0) { switch(*buf) { case END: putchar(ESC); putchar(ESC_END); if(DEBUG_SR == 2) printf("%d %d ",ESC, ESC_END); break; case ESC: putchar(ESC); putchar(ESC_ESC); if(DEBUG_SR == 2) printf("%d %d ",ESC, ESC_ESC); break; default: putchar(*buf); if(DEBUG_SR == 2) printf("%d ", *buf); } // end switch buf++; length--; } // end while putchar(END); if(DEBUG_SR == 2) printf("%d ", END); return; } */ void sendToSerial(uint8_t *buf, int8_t len) { while( slip_started () == NRK_ERROR ) { nrk_wait_until_next_period(); } if(DEBUG_SR == 2) { nrk_kprintf(PSTR("Calling slip_tx\r\n")); } if( slip_tx (buf, len) == NRK_ERROR ) { nrk_int_disable(); nrk_led_set(RED_LED); while(1) { nrk_kprintf(PSTR("Error sending out NGB_LIST message over serial\r\n")); } } return; }
int8_t nrk_sem_post(nrk_sem_t *rsrc) { int8_t id=nrk_get_resource_index(rsrc); int8_t task_ID; if(id==-1) { _nrk_errno_set(1); return NRK_ERROR;} if(id==NRK_MAX_RESOURCE_CNT) { _nrk_errno_set(2); return NRK_ERROR; } if(nrk_sem_list[id].value<nrk_sem_list[id].count) { // Signal RSRC Event nrk_int_disable(); nrk_sem_list[id].value++; //nrk_cur_task_TCB->elevated_prio_flag=0; //should not be blocking under srp /* for (task_ID=0; task_ID < NRK_MAX_TASKS; task_ID++){ if(nrk_task_TCB[task_ID].event_suspend==RSRC_EVENT_SUSPENDED) if((nrk_task_TCB[task_ID].active_signal_mask == id)) { nrk_task_TCB[task_ID].task_state=SUSPENDED; nrk_task_TCB[task_ID].next_wakeup=0; nrk_task_TCB[task_ID].event_suspend=0; nrk_task_TCB[task_ID].active_signal_mask=0; } }*/ if(_nrk_system_ceiling == _nrk_ceiling_stack[_nrk_ceiling_tos--]) _nrk_system_ceiling= _nrk_ceiling_stack[_nrk_ceiling_tos]; nrk_int_enable(); nrk_wait_until_ticks(0); } return NRK_OK; }
/********************************* FUNCTION DEFINITIONS ****************************/ void nrk_init_nw_stack() { if(endianness() == ERROR_ENDIAN) { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("Error in calculating endianness in init_nw_stack()")); } // initialise a random number generator srand(NODE_ADDR); initialise_serial_communication(); if(DEBUG_NWSC == 2) nrk_kprintf(PSTR("Serial communications initalized\r\n")); initialise_buffer_manager(); if(DEBUG_NWSC == 2) nrk_kprintf(PSTR("Buffer manager initialised\r\n")); initialise_transport_layer_udp(); if(DEBUG_NWSC == 2) nrk_kprintf(PSTR("Transport layer initialised\r\n")); //widom mac will be init in network rx task //bmac_task_config(); //if(DEBUG_NWSC == 2) // nrk_kprintf(PSTR("Link layer initialised\r\n")); initialise_network_layer(); if(DEBUG_NWSC == 2) nrk_kprintf(PSTR("Network layer initialised\r\n")); return; }
void nl_tx_task() { TransmitBuffer *ptr = NULL; // pointer to the buffer to be transmitted nrk_sig_t tx_done_signal; // to hold the tx_done signal from the link layer int8_t ret; // to hold the return value of various functions int8_t port_index; // to store the index of the corresponding port element int8_t sent; // to count the number of times the HELLO msg was sent int8_t isApplication; // flag to indicate whether the packet in the transmit // buffer is an APPLICATION / NW_CONTROL packet nrk_time_t timeout; nrk_time_t start; // used for sending network control messages nrk_time_t end; nrk_time_t elapsed; // wait for the nl_rx_task to start bmac while(!bmac_started()) nrk_wait_until_next_period(); // retrieve and register for the 'transmit done' signal from bmac tx_done_signal = bmac_get_tx_done_signal(); if( nrk_signal_register(tx_done_signal) == NRK_ERROR ) { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: Error while registering for the bmax_tx_done_signal\r\n")); } // initialise the timer nrk_time_get(&start); end.secs = start.secs; end.nano_secs = start.nano_secs; sent = 0; // set the radio power if( bmac_set_rf_power(10) == NRK_ERROR) { nrk_led_set(RED_LED); nrk_int_disable(); while(1) nrk_kprintf(PSTR("Error setting the transmit power\r\n")); } while(1) { isApplication = FALSE; // assume at the beginning that a nw_ctrl pkt will be transmitted ret = nrk_time_sub(&elapsed, end, start); if(ret == 0) { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: Error returned by nrk_time_sub\r\n")); } nrk_time_compact_nanos(&elapsed); if(elapsed.secs >= HELLO_PERIOD) { sent++; build_Msg_Hello(&mhe); // build the 'HELLO' message if(DEBUG_NL == 2) { nrk_kprintf(PSTR("After building Msg_Hello, packet = ")); print_pkt(&pkt_tx); } enter_cr(bm_sem, 34); ret = insert_tx_aq(&pkt_tx); // insert it into the transmit queue leave_cr(bm_sem, 34); if(DEBUG_NL == 2) { nrk_kprintf(PSTR("build_Msg_Hello() inserted packet.")); print_tx_buffer(); //print_pkt_header(&pkt_tx); } if(ret == NRK_ERROR && DEBUG_NL == 2) { nrk_kprintf(PSTR("HELLO msg was not inserted into the transmit queue\r\n")); } start.secs = end.secs; start.nano_secs = end.nano_secs; // reinitialise the timer } if(sent >= 3) //NGB_LIST_PERIOD / HELLO_PERIOD) // NGB_LIST period is always a multiple of HELLO_PERIOD { build_Msg_NgbList(&mn); // build the 'NGB_LIST' message enter_cr(bm_sem, 34); ret = insert_tx_aq(&pkt_tx); // insert it into the transmit queue leave_cr(bm_sem, 34); if(DEBUG_NL == 2) { nrk_kprintf(PSTR("build_Msg_NgbList() inserted packet.")); print_tx_buffer(); //print_pkt_header(&pkt_tx); } if(ret == NRK_ERROR && DEBUG_NL == 2) { nrk_kprintf(PSTR("NGB_LIST msg was not inserted into the transmit queue\r\n")); } sent = 0; // reset the value of 'sent' } if(rand() % 2 == 0) // random number generator collect_queue_statistics(); enter_cr(bm_sem, 34); ptr = remove_tx_aq(); leave_cr(bm_sem, 34); if(ptr == NULL) // transmit queue is empty { if(DEBUG_NL == 2) nrk_kprintf(PSTR("NL:Transmit queue is empty\r\n")); // update the end time nrk_time_get(&end); nrk_wait_until_next_period(); // FIX ME continue; } if(DEBUG_NL == 2) { nrk_kprintf(PSTR("NL: nl_tx_task(): Packet removed. Packet = ")); //print_pkt_header( &(ptr -> pkt) ); print_pkt( &(ptr -> pkt) ); //print_tx_buffer(); } // check to see the type of packet. It should be of type APPLICATION and be sent by this // node if( (pkt_type(&(ptr -> pkt)) == APPLICATION) && ((ptr -> pkt).src == NODE_ADDR) ) { // remove the encapsulated TL segment from the packet unpack_TL_UDP_header(&seg, (ptr -> pkt).data); memcpy(seg.data, (ptr -> pkt).data + SIZE_TRANSPORT_UDP_HEADER, MAX_APP_PAYLOAD); if(DEBUG_NL == 2) { nrk_kprintf(PSTR("NL: nl_tx_task(): Segment Removed = ")); print_seg(&seg); } isApplication = TRUE; } // pack the network packet header into the transmit buffer pack_NW_Packet_header(tx_buf, &(ptr -> pkt)); // append the network payload into the transmit buffer memcpy(tx_buf + SIZE_NW_PACKET_HEADER, (ptr -> pkt).data, MAX_NETWORK_PAYLOAD); enter_cr(bm_sem, 34); insert_tx_fq(ptr); // release the transmit buffer into the free queue leave_cr(bm_sem, 34); if(DEBUG_NL == 2) { nrk_kprintf(PSTR("NL: nl_tx_task(): Released transmit buffer back into queue\n")); print_tx_buffer(); } do { ret = bmac_tx_pkt_nonblocking(tx_buf, SIZE_NW_PACKET); // try to queue the buffer in link layer if(ret == NRK_ERROR) if(nrk_event_wait(SIG(tx_done_signal)) == 0) { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: Error returned by nrk_event_wait(tx_done_signal)\r\n")); } }while(ret == NRK_ERROR); // packet is queued at link layer timeout.secs = 10; // set a wait period of maximum 10 seconds timeout.nano_secs = 0; if( nrk_signal_register(nrk_wakeup_signal) == NRK_ERROR ) { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL:nl_tx(): Error registering for nrk_wakeup_signal\r\n")); } if( nrk_set_next_wakeup(timeout) == NRK_ERROR) { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: nl_tx(): Error returned by nrk_set_next_wakeup()\r\n")); } nrk_led_set(BLUE_LED); ret = nrk_event_wait (SIG(tx_done_signal) | SIG(nrk_wakeup_signal)); // wait for its transmission if(ret == 0) { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: Error returned by nrk_event_wait(tx_done_signal)\r\n")); } if(ret & SIG(tx_done_signal)) // bmac has successfully sent the packet over the radio { if(isApplication == TRUE) // it was an application layer packet { enter_cr(tl_sem, 34); port_index = port_to_port_index(seg.srcPort); if(port_index == NRK_ERROR) // sanity check { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: nl_tx_task: Bug detected in implementation of port element array\r\n")); } // signal 'send done' signal if(nrk_event_signal(ports[port_index].send_done_signal) == NRK_ERROR) { if(nrk_errno_get() == 1) // sanity check. This means signal was not created { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: nl_tx_task: Bug detected in creating signals in port element array\r\n")); } } leave_cr(tl_sem, 34); }// end if(isApplication == TRUE) else // a network control message was transmitted. Nothing to signal ; // do nothing } // end if(signal received = tx_done_signal) else if(ret & SIG(nrk_wakeup_signal)) { //nrk_led_set(RED_LED); //nrk_int_disable(); //while(1) //{ nrk_kprintf(PSTR("BMAC did not transmit the packet within specified time\r\n")); //} } else // unknown signal caught { nrk_int_disable(); nrk_led_set(RED_LED); while(1) nrk_kprintf(PSTR("NL: nl_tx_task(): Unknown signal caught\r\n")); } nrk_led_clr(BLUE_LED); // update the end time nrk_time_get(&end); } // end while(1) return; }