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; }
//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; }
/********************************************************** * 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(); }
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; }
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; }
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_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; }
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_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; }
int8_t nrk_reserve_consume (uint8_t reserve_id) { if (reserve_id >= NRK_MAX_RESERVES) { _nrk_errno_set (1); return NRK_ERROR; } if (_nrk_reserve[reserve_id].active == -1) { _nrk_errno_set (2); return NRK_ERROR; } _nrk_reserve_update (reserve_id); if ((_nrk_reserve[reserve_id].set_access <= _nrk_reserve[reserve_id].cur_access)) { // You violated your resource (like MJ after a little boy) nrk_int_enable (); if (_nrk_reserve[reserve_id].error != NULL) _nrk_reserve[reserve_id].error (); return NRK_ERROR; } else { // Reserve is fine. Take some of it. _nrk_reserve[reserve_id].cur_access++; } 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(); }
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 main (void) // // DESCRIPTION: // Startup routine and main loop //------------------------------------------------------------------------------ int main (void) { uint8_t i,length; uint32_t cnt; nrk_setup_ports(); nrk_setup_uart (UART_BAUDRATE_115K2); printf( "Basic TX...\r\n" ); nrk_led_set(0); nrk_led_set(1); nrk_led_clr(2); nrk_led_clr(3); /* while(1) { for(i=0; i<40; i++ ) halWait(10000); nrk_led_toggle(1); } */ rfRxInfo.pPayload = rx_buf; rfRxInfo.max_length = RF_MAX_PAYLOAD_SIZE; nrk_int_enable(); rf_init (&rfRxInfo, 26, 0x2420, 0x1214); cnt=0; while(1){ DPDS1 |= 0x3; DDRG |= 0x1; PORTG |= 0x1; DDRE|=0xE0; PORTE|=0xE0; rfTxInfo.pPayload=tx_buf; sprintf( tx_buf, "%lu", cnt); rfTxInfo.length= strlen(tx_buf) + 1; rfTxInfo.destAddr = 0x1215; rfTxInfo.cca = 0; rfTxInfo.ackRequest = 0; printf( "Sending\r\n" ); // nrk_gpio_set(NRK_DEBUG_0); if(rf_tx_packet(&rfTxInfo) != 1) printf("--- RF_TX ERROR ---\r\n"); // nrk_gpio_clr(NRK_DEBUG_0); cnt++; for(i=0; i<10; i++ ) halWait(10000); nrk_led_toggle(RED_LED); } }
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(); }
//------------------------------------------------------------------------------ // void main (void) // // DESCRIPTION: // Startup routine and main loop //------------------------------------------------------------------------------ int main (void) { uint8_t cnt,i,length; nrk_setup_ports(); nrk_setup_uart (UART_BAUDRATE_115K2); printf( "Basic TX...\r\n" ); nrk_led_set(0); nrk_led_set(1); nrk_led_clr(2); nrk_led_clr(3); /* while(1) { for(i=0; i<40; i++ ) halWait(10000); nrk_led_toggle(1); } */ rfRxInfo.pPayload = rx_buf; rfRxInfo.max_length = RF_MAX_PAYLOAD_SIZE; nrk_int_enable(); rf_init (&rfRxInfo, 13, 0x2420, 0x1214); cnt=0; while(1){ nrk_led_set(GREEN_LED); rfTxInfo.pPayload=tx_buf; sprintf( tx_buf, "This is my string counter %d", cnt); rfTxInfo.length= strlen(tx_buf) + 1; rfTxInfo.destAddr = 0x1215; rfTxInfo.cca = 0; rfTxInfo.ackRequest = 0; printf( "Sending\r\n" ); nrk_gpio_set(NRK_DEBUG_0); if(rf_tx_packet(&rfTxInfo) != 1) printf("--- RF_TX ERROR ---\r\n"); nrk_gpio_clr(NRK_DEBUG_0); cnt++; for(i=0; i<80; i++ ) halWait(10000); nrk_led_clr(GREEN_LED); for(i=0; i<20; i++ ) halWait(10000); } }
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; }
void Task1 () { uint16_t cnt; uint8_t len,i; //printf ("My node's address is %d\r\n", NODE_ADDR); //printf ("Task1 PID=%d\r\n", nrk_get_pid ()); rfRxInfo.pPayload = rx_buf; rfRxInfo.max_length = RF_MAX_PAYLOAD_SIZE; nrk_int_enable(); rf_init (&rfRxInfo, 13, 0x2420, 0x1214); cnt = 0; slip_init (stdin, stdout, 0, 0); rf_rx_on(); while (1) { while (rf_rx_packet_nonblock () != NRK_OK) { nrk_wait_until_next_period(); } rx_packet_len = rfRxInfo.length; for(i=0; i<rfRxInfo.length; i++ ) slip_tx_buf[i]=rfRxInfo.pPayload[i]; slip_tx_buf[10] = rfRxInfo.rssi; while(uart_tx_busy==1) nrk_wait_until_next_period(); uart_tx_busy=1; slip_tx (slip_tx_buf, rx_packet_len); uart_tx_busy=0; } }
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; }
void event_detector_task() { update_energy_sig=nrk_signal_create(); if(update_energy_sig==NRK_ERROR) nrk_kprintf(PSTR("Error creating update_energy_sig signal!\r\n")); nrk_signal_register(update_energy_sig); if(v==NRK_ERROR) nrk_kprintf( PSTR( "nrk_signal_register failed\r\n" )); //ev_timeout.secs=10; //ev_timeout.nano_secs=0; while(1) { // Wait on signal //nrk_set_next_wakeup(ev_timeout); my_sigs=nrk_event_wait( SIG(update_energy_sig) /*| SIG(nrk_wakeup_signal)*/ ); if(my_sigs!=0 && ticks_last>900) { tmp_d=current_total_last / ticks_last; if(tmp_d<0) tmp_d=0; tmp_d=sqrt(tmp_d); rms_current=(uint16_t)tmp_d; tmp_d=current_total2_last / ticks_last; if(tmp_d<0) tmp_d=0; tmp_d=sqrt(tmp_d); rms_current2=(uint16_t)tmp_d; tmp_d=voltage_total_last / ticks_last; if(tmp_d<0) tmp_d=0; tmp_d=sqrt(tmp_d); rms_voltage=(uint16_t)tmp_d; if(energy_total_last<0) energy_total_last=0; true_power=energy_total_last / ticks_last; if(true_power>TRUE_POWER_ON_THRESH) cummulative_energy.total+=true_power; if(energy_total2_last<0) energy_total2_last=0; true_power2=energy_total2_last / ticks_last; if(true_power2>TRUE_POWER_ON_THRESH) cummulative_energy2.total+=true_power2; total_secs++; // Divide by seconds per hour to give Watts per hour // If this is too slow, make a power of 2 shit instead... tmp_energy.total=cummulative_energy.total/3600; tmp_energy2.total=cummulative_energy2.total/3600; // Only care about lower 6 bytes of 8 byte long long // At max power this will last 239 years // Divide by P-scaler to get Watt*hrs if(total_secs%400==0 ) { nrk_int_disable(); nrk_eeprom_write_byte(EEPROM_ENERGY1_0_ADDR, cummulative_energy.byte[0]); nrk_eeprom_write_byte(EEPROM_ENERGY1_1_ADDR, cummulative_energy.byte[1]); nrk_eeprom_write_byte(EEPROM_ENERGY1_2_ADDR, cummulative_energy.byte[2]); nrk_eeprom_write_byte(EEPROM_ENERGY1_3_ADDR, cummulative_energy.byte[3]); nrk_eeprom_write_byte(EEPROM_ENERGY1_4_ADDR, cummulative_energy.byte[4]); nrk_eeprom_write_byte(EEPROM_ENERGY1_5_ADDR, cummulative_energy.byte[5]); nrk_eeprom_write_byte(EEPROM_ENERGY1_6_ADDR, cummulative_energy.byte[6]); nrk_eeprom_write_byte(EEPROM_ENERGY1_7_ADDR, cummulative_energy.byte[7]); nrk_eeprom_write_byte(EEPROM_ENERGY2_0_ADDR, cummulative_energy2.byte[0]); nrk_eeprom_write_byte(EEPROM_ENERGY2_1_ADDR, cummulative_energy2.byte[1]); nrk_eeprom_write_byte(EEPROM_ENERGY2_2_ADDR, cummulative_energy2.byte[2]); nrk_eeprom_write_byte(EEPROM_ENERGY2_3_ADDR, cummulative_energy2.byte[3]); nrk_eeprom_write_byte(EEPROM_ENERGY2_4_ADDR, cummulative_energy2.byte[4]); nrk_eeprom_write_byte(EEPROM_ENERGY2_5_ADDR, cummulative_energy2.byte[5]); nrk_eeprom_write_byte(EEPROM_ENERGY2_6_ADDR, cummulative_energy2.byte[6]); nrk_eeprom_write_byte(EEPROM_ENERGY2_7_ADDR, cummulative_energy2.byte[7]); nrk_int_enable(); } /* // EVENT DETECTOR tran_pkt.msgs_payload=async_buf; tran_pkt.num_msgs=0; //if(rms_current>current_last) delta=rms_current-current_last; //else delta=current_last-rms_current; if(true_power>true_power_last) delta=true_power-true_power_last; else delta=true_power_last-true_power; if(true_power2>true_power_last2) delta2=true_power2-true_power_last2; else delta=true_power_last2-true_power2; //if(rms_current2>current_last2) delta2=rms_current2-current_last2; //else delta2=current_last2-rms_current2; if((socket_0_push_enabled && (delta>socket_0_push_threshold*100)) || (socket_1_push_enabled && (delta2>socket_1_push_threshold*100))) { pd_pkt.type=DEBUG_PKT; pd_pkt.rms_voltage=rms_voltage; pd_pkt.rms_current=rms_current; pd_pkt.rms_current2=rms_current2; pd_pkt.true_power=true_power; pd_pkt.true_power2=true_power2; pd_pkt.freq=freq; pd_pkt.socket0_state= socket_0_active; pd_pkt.socket1_state= socket_1_active; for(len=0; len<6; len++ ) { pd_pkt.energy[len]=tmp_energy.byte[len]; pd_pkt.energy2[len]=tmp_energy2.byte[len]; } pd_pkt.current_p2p_high=l_c_p2p_high; pd_pkt.current_p2p_low=l_c_p2p_low; pd_pkt.current_p2p_high2=l_c_p2p_high2; pd_pkt.current_p2p_low2=l_c_p2p_low2; pd_pkt.voltage_p2p_high=l_v_p2p_high; pd_pkt.voltage_p2p_low=l_v_p2p_low; pd_pkt.total_secs=total_secs; tran_pkt.num_msgs=0; tran_pkt.checksum=0; tran_pkt.msgs_payload=&(async_buf[TRANSDUCER_PKT_HEADER_SIZE]); tran_msg.payload=&(async_buf[TRANSDUCER_PKT_HEADER_SIZE+TRANSDUCER_MSG_HEADER_SIZE]); tran_msg.type=TRAN_POWER_PKT; tran_msg.len=ff_power_debug_pack(tran_msg.payload, &pd_pkt); tran_msg.mac_addr=my_mac; len=transducer_msg_add( &tran_pkt, &tran_msg); len = transducer_pkt_pack(&tran_pkt, async_buf); val=push_p2p_pkt( async_buf,len,TRANSDUCER_PKT, 0x0 ); } */ true_power_last=true_power; true_power_last2=true_power2; } // toggle RED led if freq not above 50Hz //if(freq==0) nrk_led_toggle(RED_LED); } }
void inline _nrk_scheduler() { int8_t task_ID; uint16_t next_wake; uint16_t start_time_stamp; _nrk_precision_os_timer_reset(); // Enabling interrupts allows ISRs to run before we restore the stack pointer // to point to the task, which breaks the task<->kernel switch causing // unexpected microcontroller restarts (try enabling a timer with a callback // and add a task with ~20ms period). So, do not enable interrupts here; // keep them disabled and let reti in nrk_start_high_ready_task enable them. #if 0 nrk_int_enable(); // this should be removed... Not needed #endif #ifndef NRK_NO_BOUNDED_CONTEXT_SWAP _nrk_high_speed_timer_reset(); start_time_stamp=_nrk_high_speed_timer_get(); #endif _nrk_set_next_wakeup(MAX_SCHED_WAKEUP_TIME); // Set to huge number which will later get set to min next_wake=60000; // Safety zone starts here.... #ifdef NRK_WATCHDOG nrk_watchdog_reset(); #endif #ifdef NRK_SW_WDT _nrk_sw_wdt_check(); #endif //printf( "last run: %d\n",nrk_cur_task_TCB->task_ID ); //for (task_ID=0; task_ID < NRK_MAX_TASKS; task_ID++) //{ //printf( "%d nw:%lu\n",task_ID,nrk_task_TCB[task_ID].next_wakeup ); //} #ifdef NRK_KERNEL_TEST //nrk_kprintf( PSTR("*")); //Check if OS tick was delayed... // if(_nrk_cpu_state!=CPU_SLEEP && _nrk_os_timer_get()!=0) { // nrk_kprintf( PSTR("X" )); //printf( "%u ",_nrk_os_timer_get()); // } //printf( "%u\r\n",_nrk_prev_timer_val); if((_nrk_cpu_state!=CPU_ACTIVE) && (_nrk_os_timer_get()>nrk_max_sleep_wakeup_time)) nrk_max_sleep_wakeup_time=_nrk_os_timer_get(); #endif //while(_nrk_time_trigger>0) //{ nrk_system_time.nano_secs+=((uint32_t)_nrk_prev_timer_val*NANOS_PER_TICK); nrk_system_time.nano_secs-=(nrk_system_time.nano_secs%(uint32_t)NANOS_PER_TICK); #ifdef NRK_STATS_TRACKER if(nrk_cur_task_TCB->task_ID==NRK_IDLE_TASK_ID) { if(_nrk_cpu_state==CPU_SLEEP) _nrk_stats_sleep(_nrk_prev_timer_val); _nrk_stats_task_preempted(nrk_cur_task_TCB->task_ID, _nrk_prev_timer_val); // Add 0 time since the preempted call before set the correct value _nrk_stats_task_suspend(nrk_cur_task_TCB->task_ID, 0); } else { if(nrk_cur_task_TCB->suspend_flag==1) _nrk_stats_task_suspend(nrk_cur_task_TCB->task_ID, _nrk_prev_timer_val); else _nrk_stats_task_preempted(nrk_cur_task_TCB->task_ID, _nrk_prev_timer_val); } #endif while(nrk_system_time.nano_secs>=NANOS_PER_SEC) { nrk_system_time.nano_secs-=NANOS_PER_SEC; nrk_system_time.secs++; nrk_system_time.nano_secs-=(nrk_system_time.nano_secs%(uint32_t)NANOS_PER_TICK); } // _nrk_time_trigger--; //} if(nrk_cur_task_TCB->suspend_flag==1 && nrk_cur_task_TCB->task_state!=FINISHED) { // nrk_cur_task_TCB->task_state = EVENT_SUSPENDED; if(nrk_cur_task_TCB->event_suspend==RSRC_EVENT_SUSPENDED) nrk_cur_task_TCB->task_state = EVENT_SUSPENDED; else if( nrk_cur_task_TCB->event_suspend>0 && nrk_cur_task_TCB->nw_flag==0) nrk_cur_task_TCB->task_state = EVENT_SUSPENDED; else if( nrk_cur_task_TCB->event_suspend>0 && nrk_cur_task_TCB->nw_flag==1) nrk_cur_task_TCB->task_state = SUSPENDED; else { nrk_cur_task_TCB->task_state = SUSPENDED; nrk_cur_task_TCB->event_suspend=0; nrk_cur_task_TCB->nw_flag=0; // agr added to fix initial startup scheduling problem if(nrk_cur_task_TCB->next_wakeup==0) { nrk_cur_task_TCB->next_wakeup=nrk_cur_task_TCB->next_period; } } nrk_rem_from_readyQ(nrk_cur_task_TCB->task_ID); } // nrk_print_readyQ(); // Update cpu used value for ended task // If the task has used its reserve, suspend task // Don't disable IdleTask which is 0 // Don't decrease cpu_remaining if reserve is 0 and hence disabled if(nrk_cur_task_TCB->cpu_reserve!=0 && nrk_cur_task_TCB->task_ID!=NRK_IDLE_TASK_ID && nrk_cur_task_TCB->task_state!=FINISHED ) { if(nrk_cur_task_TCB->cpu_remaining<_nrk_prev_timer_val) { #ifdef NRK_STATS_TRACKER _nrk_stats_add_violation(nrk_cur_task_TCB->task_ID); #endif nrk_kernel_error_add(NRK_RESERVE_ERROR,nrk_cur_task_TCB->task_ID); nrk_cur_task_TCB->cpu_remaining=0; } else nrk_cur_task_TCB->cpu_remaining-=_nrk_prev_timer_val; task_ID= nrk_cur_task_TCB->task_ID; if (nrk_cur_task_TCB->cpu_remaining ==0 ) { #ifdef NRK_STATS_TRACKER _nrk_stats_add_violation(nrk_cur_task_TCB->task_ID); #endif nrk_kernel_error_add(NRK_RESERVE_VIOLATED,task_ID); nrk_cur_task_TCB->task_state = SUSPENDED; nrk_rem_from_readyQ(task_ID); } } // Check I/O nrk_queues to add tasks with remaining cpu back... // Add eligable tasks back to the ready Queue // At the same time find the next earliest wakeup for (task_ID=0; task_ID < NRK_MAX_TASKS; task_ID++) { if(nrk_task_TCB[task_ID].task_ID==-1) continue; nrk_task_TCB[task_ID].suspend_flag=0; if( nrk_task_TCB[task_ID].task_ID!=NRK_IDLE_TASK_ID && nrk_task_TCB[task_ID].task_state!=FINISHED ) { if( nrk_task_TCB[task_ID].next_wakeup >= _nrk_prev_timer_val ) nrk_task_TCB[task_ID].next_wakeup-=_nrk_prev_timer_val; else { nrk_task_TCB[task_ID].next_wakeup=0; } // Do next period book keeping. // next_period needs to be set such that the period is kept consistent even if other // wait until functions are called. if( nrk_task_TCB[task_ID].next_period >= _nrk_prev_timer_val ) nrk_task_TCB[task_ID].next_period-=_nrk_prev_timer_val; else { if(nrk_task_TCB[task_ID].period>_nrk_prev_timer_val) nrk_task_TCB[task_ID].next_period= nrk_task_TCB[task_ID].period-_nrk_prev_timer_val; else nrk_task_TCB[task_ID].next_period= _nrk_prev_timer_val % nrk_task_TCB[task_ID].period; } if(nrk_task_TCB[task_ID].next_period==0) nrk_task_TCB[task_ID].next_period=nrk_task_TCB[task_ID].period; } // Look for Next Task that Might Wakeup to interrupt current task if (nrk_task_TCB[task_ID].task_state == SUSPENDED ) { //printf( "Task: %d nw: %d\n",task_ID,nrk_task_TCB[task_ID].next_wakeup); // If a task needs to become READY, make it ready if (nrk_task_TCB[task_ID].next_wakeup == 0) { // printf( "Adding back %d\n",task_ID ); if(nrk_task_TCB[task_ID].event_suspend>0 && nrk_task_TCB[task_ID].nw_flag==1) nrk_task_TCB[task_ID].active_signal_mask=SIG(nrk_wakeup_signal); //if(nrk_task_TCB[task_ID].event_suspend==0) nrk_task_TCB[task_ID].active_signal_mask=0; nrk_task_TCB[task_ID].event_suspend=0; nrk_task_TCB[task_ID].nw_flag=0; nrk_task_TCB[task_ID].suspend_flag=0; if(nrk_task_TCB[task_ID].num_periods==1) { nrk_task_TCB[task_ID].cpu_remaining = nrk_task_TCB[task_ID].cpu_reserve; nrk_task_TCB[task_ID].task_state = READY; nrk_task_TCB[task_ID].next_wakeup = nrk_task_TCB[task_ID].next_period; // If there is no period set, don't wakeup periodically if(nrk_task_TCB[task_ID].period==0) nrk_task_TCB[task_ID].next_wakeup = MAX_SCHED_WAKEUP_TIME; nrk_add_to_readyQ(task_ID); } else { nrk_task_TCB[task_ID].cpu_remaining = nrk_task_TCB[task_ID].cpu_reserve; //nrk_task_TCB[task_ID].next_wakeup = nrk_task_TCB[task_ID].next_period; //nrk_task_TCB[task_ID].num_periods--; nrk_task_TCB[task_ID].next_wakeup = (nrk_task_TCB[task_ID].period*(nrk_task_TCB[task_ID].num_periods-1)); nrk_task_TCB[task_ID].next_period = (nrk_task_TCB[task_ID].period*(nrk_task_TCB[task_ID].num_periods-1)); if(nrk_task_TCB[task_ID].period==0) nrk_task_TCB[task_ID].next_wakeup = MAX_SCHED_WAKEUP_TIME; nrk_task_TCB[task_ID].num_periods=1; // printf( "np = %d\r\n",nrk_task_TCB[task_ID].next_wakeup); // nrk_task_TCB[task_ID].num_periods=1; } } if(nrk_task_TCB[task_ID].next_wakeup!=0 && nrk_task_TCB[task_ID].next_wakeup<next_wake ) { // Find closest next_wake task next_wake=nrk_task_TCB[task_ID].next_wakeup; } } } #ifdef NRK_STATS_TRACKER _nrk_stats_task_start(nrk_cur_task_TCB->task_ID); #endif task_ID = nrk_get_high_ready_task_ID(); nrk_high_ready_prio = nrk_task_TCB[task_ID].task_prio; nrk_high_ready_TCB = &nrk_task_TCB[task_ID]; #if 0 if (task_ID != nrk_cur_task_TCB->task_ID) { printf("%lu %lu %d->%d\r\n", nrk_system_time.secs, nrk_system_time.nano_secs, nrk_cur_task_TCB->task_ID, task_ID); } #endif // next_wake should hold next time when a suspended task might get run // task_ID holds the highest priority READY task ID // So nrk_task_TCB[task_ID].cpu_remaining holds the READY task's end time // Now we pick the next wakeup (either the end of the current task, or the possible resume // of a suspended task) if(task_ID!=NRK_IDLE_TASK_ID) { // You are a non-Idle Task if(nrk_task_TCB[task_ID].cpu_reserve!=0 && nrk_task_TCB[task_ID].cpu_remaining<MAX_SCHED_WAKEUP_TIME) { if(next_wake>nrk_task_TCB[task_ID].cpu_remaining) next_wake=nrk_task_TCB[task_ID].cpu_remaining; } else { if(next_wake>MAX_SCHED_WAKEUP_TIME) next_wake=MAX_SCHED_WAKEUP_TIME; } } else { // This is the idle task // Make sure you wake up from the idle task a little earlier // if you would go into deep sleep... // After waking from deep sleep, the next context swap must be at least // NRK_SLEEP_WAKEUP_TIME-1 away to make sure the CPU wakes up in time. #ifndef NRK_NO_POWER_DOWN if(next_wake>NRK_SLEEP_WAKEUP_TIME) { if(next_wake-NRK_SLEEP_WAKEUP_TIME<MAX_SCHED_WAKEUP_TIME) { if(next_wake-NRK_SLEEP_WAKEUP_TIME<NRK_SLEEP_WAKEUP_TIME) { next_wake=NRK_SLEEP_WAKEUP_TIME-1; } else { next_wake=next_wake-NRK_SLEEP_WAKEUP_TIME; } } else if(next_wake>NRK_SLEEP_WAKEUP_TIME+MAX_SCHED_WAKEUP_TIME) { next_wake=MAX_SCHED_WAKEUP_TIME; } else { next_wake=MAX_SCHED_WAKEUP_TIME-NRK_SLEEP_WAKEUP_TIME; } } #endif } /* // Some code to catch the case when the scheduler wakes up // from deep sleep and has to execute again before NRK_SLEEP_WAKEUP_TIME-1 if(_nrk_cpu_state==2 && next_wake<NRK_SLEEP_WAKEUP_TIME-1) { nrk_int_disable(); while(1) { nrk_spin_wait_us(60000); nrk_led_toggle(RED_LED); nrk_spin_wait_us(60000); nrk_led_toggle(GREEN_LED); printf( "crash: %d %d %d\r\n",task_ID,next_wake,_nrk_cpu_state); } }*/ // If we disable power down, we still need to wakeup before the overflow #ifdef NRK_NO_POWER_DOWN if(next_wake>MAX_SCHED_WAKEUP_TIME) next_wake=MAX_SCHED_WAKEUP_TIME; #endif //printf( "nw = %d %d %d\r\n",task_ID,_nrk_cpu_state,next_wake); nrk_cur_task_prio = nrk_high_ready_prio; nrk_cur_task_TCB = nrk_high_ready_TCB; #ifdef NRK_KERNEL_TEST if(nrk_high_ready_TCB==NULL) { nrk_kprintf( PSTR( "KERNEL TEST: BAD TCB!\r\n" )); } #endif //printf( "n %u %u %u %u\r\n",task_ID, _nrk_prev_timer_val, next_wake,_nrk_os_timer_get()); _nrk_prev_timer_val=next_wake; // Maybe the signals are triggering this problem? if((_nrk_os_timer_get()+1)>=next_wake) // just bigger then, or equal? { // FIXME: Terrible Terrible... // Need to find out why this is happening... #ifdef NRK_KERNEL_TEST // Ignore if you are the idle task coming from deep sleep if(!(task_ID==NRK_IDLE_TASK_ID && _nrk_cpu_state==CPU_SLEEP)) nrk_kernel_error_add(NRK_WAKEUP_MISSED,task_ID); #endif // This is bad news, but keeps things running // +2 just in case we are on the edge of the last tick next_wake=_nrk_os_timer_get()+2; _nrk_prev_timer_val=next_wake; } if(task_ID!=NRK_IDLE_TASK_ID) _nrk_cpu_state=CPU_ACTIVE; _nrk_set_next_wakeup(next_wake); #ifndef NRK_NO_BOUNDED_CONTEXT_SWAP // Bound Context Swap to 100us nrk_high_speed_timer_wait(start_time_stamp,CONTEXT_SWAP_TIME_BOUND); #endif nrk_stack_pointer_restore(); //nrk_int_enable(); nrk_start_high_ready_task(); }
void deep_sleep_button() { int i,cnt; nrk_int_disable(); nrk_eeprom_write_byte(EEPROM_SLEEP_STATE_ADDR,1); nrk_led_set(0); nrk_spin_wait_us(50000); nrk_led_clr(0); nrk_led_clr(1); nrk_led_clr(2); nrk_led_clr(3); nrk_watchdog_disable(); nrk_int_disable(); _nrk_os_timer_stop(); nrk_gpio_direction(NRK_BUTTON, NRK_PIN_INPUT); rf_power_down(); // Enable Pullup for button //PORTD = 0xff; nrk_gpio_set(NRK_BUTTON); nrk_ext_int_configure( NRK_EXT_INT_1,NRK_LEVEL_TRIGGER, &wakeup_func); EIFR=0xff; nrk_ext_int_enable( NRK_EXT_INT_1); nrk_int_enable(); DDRA=0x0; DDRB=0x0; DDRC=0x0; ASSR=0; TRXPR = 1 << SLPTR; set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_enable(); sleep_cpu(); // reboot while(1) { //printf( "awake!\r\n" ); nrk_led_clr(0); nrk_led_clr(1); nrk_led_set(1); cnt=0; for(i=0; i<100; i++ ) { //if((PIND & 0x2)==0x2)cnt++; if(nrk_gpio_get(NRK_BUTTON)==0)cnt++; nrk_spin_wait_us(10000); } printf( "cnt=%d\n",cnt ); if(cnt>=50 ) { // reboot nrk_led_clr(1); nrk_led_set(0); nrk_eeprom_write_byte(EEPROM_SLEEP_STATE_ADDR,0); nrk_spin_wait_us(50000); nrk_spin_wait_us(50000); nrk_watchdog_enable(); while(1); } nrk_led_clr(0); nrk_led_clr(1); TRXPR = 1 << SLPTR; set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_enable(); sleep_cpu(); } }
//------------------------------------------------------------------------------ // void main (void) // // DESCRIPTION: // Startup routine and main loop //------------------------------------------------------------------------------ int main (void) { uint8_t cnt,i,length,n; nrk_setup_ports(); nrk_setup_uart (UART_BAUDRATE_115K2); printf( "Receiver\r\n" ); nrk_led_clr(0); nrk_led_clr(1); nrk_led_clr(2); nrk_led_clr(3); rfRxInfo.pPayload = rx_buf; rfRxInfo.max_length = RF_MAX_PAYLOAD_SIZE; rfRxInfo.ackRequest= 0; nrk_int_enable(); rf_init (&rfRxInfo, 13, 0x2420, 0x1215); printf( "Waiting for packet...\r\n" ); nrk_led_set(ORANGE_LED); while(1) { nrk_led_set(BLUE_LED); rf_polling_rx_on(); while ((n = rf_rx_check_sfd()) == 0) continue; if (n != 0) { nrk_led_toggle(ORANGE_LED); n = 0; // Packet on its way cnt=0; while ((n = rf_polling_rx_packet ()) == 0) { nrk_led_toggle(GREEN_LED); if (cnt > 50) { //printf( "PKT Timeout\r\n" ); break; // huge timeout as failsafe } halWait(10000); cnt++; } } nrk_led_clr(BLUE_LED); if (n == 1) { nrk_led_clr(RED_LED); // nrk_led_toggle(BLUE_LED); // CRC and checksum passed // printf("packet received\r\n"); // printf("SEQNUM: %d SRCADDR: 0x%x SNR: %d\r\n[",rfRxInfo.seqNumber, rfRxInfo.srcAddr, rfRxInfo.rssi); // printf("\r\n%d, ",rfRxInfo.seqNumber); for(i=0; i<rfRxInfo.length; i++ ) // printf( "%c", rfRxInfo.pPayload[i]); putchar(rfRxInfo.pPayload[i]); // printf( "]\r\n\r\n" ); // printf("\r\nR%d = %d",rfRxInfo.seqNumber,rfRxInfo.length); } else if(n != 0) { printf( "CRC failed!\r\n" ); nrk_led_set(RED_LED); } } }