int8_t nrk_TCB_init (nrk_task_type *Task, NRK_STK *ptos, NRK_STK *pbos, uint16_t stk_size, void *pext, uint16_t opt) { // Already in critical section so no needenter critical section if(Task->Type!=IDLE_TASK) Task->task_ID=nrk_task_init_cnt; else Task->task_ID=NRK_IDLE_TASK_ID; if(nrk_task_init_cnt>=NRK_MAX_TASKS) nrk_kernel_error_add(NRK_EXTRA_TASK,0); if(Task->Type!=IDLE_TASK) nrk_task_init_cnt++; if(nrk_task_init_cnt==NRK_IDLE_TASK_ID) nrk_task_init_cnt++; //initialize member of TCB structure nrk_task_TCB[Task->task_ID].OSTaskStkPtr = ptos; nrk_task_TCB[Task->task_ID].task_prio = Task->prio; nrk_task_TCB[Task->task_ID].task_state = SUSPENDED; nrk_task_TCB[Task->task_ID].task_prelevel = Task->prelevel; nrk_task_TCB[Task->task_ID].task_ID = Task->task_ID; nrk_task_TCB[Task->task_ID].suspend_flag = 0; nrk_task_TCB[Task->task_ID].period= _nrk_time_to_ticks( &(Task->period) ); if(Task->period.secs > 61) nrk_kernel_error_add(NRK_PERIOD_OVERFLOW,Task->task_ID); nrk_task_TCB[Task->task_ID].next_wakeup= _nrk_time_to_ticks( &(Task->offset)); nrk_task_TCB[Task->task_ID].next_period= nrk_task_TCB[Task->task_ID].period+nrk_task_TCB[Task->task_ID].next_wakeup; nrk_task_TCB[Task->task_ID].cpu_reserve= _nrk_time_to_ticks(&(Task->cpu_reserve)); nrk_task_TCB[Task->task_ID].cpu_remaining = nrk_task_TCB[Task->task_ID].cpu_reserve; nrk_task_TCB[Task->task_ID].num_periods = 1; nrk_task_TCB[Task->task_ID].OSTCBStkBottom = pbos; nrk_task_TCB[Task->task_ID].errno= NRK_OK; return NRK_OK; }
int8_t tdma_init (uint8_t mode, uint8_t chan, uint16_t my_mac) { tx_reserve = -1; tdma_rx_failure_cnt = 0; tdma_mode = mode; tdma_tx_slots = 0; sync_status=0; tdma_slots_per_cycle = TDMA_DEFAULT_SLOTS_PER_CYCLE; tdma_rx_pkt_signal = nrk_signal_create (); if (tdma_rx_pkt_signal == NRK_ERROR) { nrk_kprintf (PSTR ("TDMA ERROR: creating rx signal failed\r\n")); nrk_kernel_error_add (NRK_SIGNAL_CREATE_ERROR, nrk_cur_task_TCB->task_ID); return NRK_ERROR; } tdma_tx_pkt_done_signal = nrk_signal_create (); if (tdma_tx_pkt_done_signal == NRK_ERROR) { nrk_kprintf (PSTR ("TDMA ERROR: creating tx signal failed\r\n")); nrk_kernel_error_add (NRK_SIGNAL_CREATE_ERROR, nrk_cur_task_TCB->task_ID); return NRK_ERROR; } tdma_enable_signal = nrk_signal_create (); if (tdma_enable_signal == NRK_ERROR) { nrk_kprintf (PSTR ("TDMA ERROR: creating enable signal failed\r\n")); nrk_kernel_error_add (NRK_SIGNAL_CREATE_ERROR, nrk_cur_task_TCB->task_ID); return NRK_ERROR; } // Set the one main rx buffer tdma_rx_pkt_set_buffer (tdma_rx_buf, TDMA_MAX_PKT_SIZE); tdma_rx_buf_empty = 1; tx_data_ready = 0; // Setup the radio rf_init (&tdma_rfRxInfo, chan, 0xffff, my_mac); tdma_chan = chan; tdma_my_mac = my_mac; //FASTSPI_SETREG (CC2420_RSSI, 0xE580); // CCA THR=-25 //FASTSPI_SETREG (CC2420_TXCTRL, 0x80FF); // TX TURNAROUND = 128 us //FASTSPI_SETREG (CC2420_RXCTRL1, 0x0A56); // default cca thresh of -45 rf_set_cca_thresh (-45); asm volatile ("":::"memory"); tdma_running = 1; tdma_is_enabled = 1; return NRK_OK; }
uint8_t dev_manager_adc(uint8_t state,uint8_t opt,uint8_t *buffer,uint8_t size) { uint8_t count=0; switch(state) { case INIT_STATE: init_adc(); return 1; case OPEN_STATE: { switch(opt) { case READ_STATE: //sensors_on(); return 1; case WRITE_STATE: //sensors_on(); return 2; case RW_STATE: return 3; default: //printf("option for device does not exist\n"); nrk_kernel_error_add(NRK_DEVICE_DRIVER,0); return -1; } } case READ_STATE: for(count=0; count<size; count++) { /* Conversion to 8-bit value*/ uint16_t val=get_adc_val(); buffer[count]=val >>2 & 0xFF; } return count; case CLOSE_STATE: //sensors_off(); return 1; /*SET STATUS AND GET STATUS CALLS DEFINED HERE*/ case GET_ADC_STATE: return 1; default: nrk_kernel_error_add(NRK_DEVICE_DRIVER,0); return 0; } }
void nrk_start (void) { int8_t task_ID; uint8_t i,j; // NRK_STK *x; // unsigned char *stkc; /* - Get highest priority task from rdy list - set cur prio and start the task */ // Check to make sure all tasks unique for(i=0; i<NRK_MAX_TASKS; i++ ) { task_ID = nrk_task_TCB[i].task_ID; // only check activated tasks if(task_ID!=-1) { for(j=0; j<NRK_MAX_TASKS; j++ ) { if(i!=j && task_ID==nrk_task_TCB[j].task_ID) { nrk_kernel_error_add(NRK_DUP_TASK_ID,task_ID); } } } } task_ID = nrk_get_high_ready_task_ID(); nrk_high_ready_prio = nrk_task_TCB[task_ID].task_prio; nrk_high_ready_TCB = nrk_cur_task_TCB = &nrk_task_TCB[task_ID]; nrk_cur_task_prio = nrk_high_ready_prio; // nrk_stack_pointer_restore(); /* #ifdef KERNEL_STK_ARRAY stkc = (uint16_t*)&nrk_kernel_stk[NRK_KERNEL_STACKSIZE-1]; #else stkc = NRK_KERNEL_STK_TOP; #endif *stkc++ = (uint16_t)((uint16_t)_nrk_timer_tick>>8); *stkc = (uint16_t)((uint16_t)_nrk_timer_tick&0xFF); //TODO: this way on msp // *stkc++ = (uint16_t)((uint16_t)_nrk_timer_tick&0xFF); // *stkc = (uint16_t)((uint16_t)_nrk_timer_tick>>8); */ nrk_target_start(); nrk_stack_pointer_init(); nrk_start_high_ready_task(); // you should never get here while(1); }
int8_t slip_init (FILE * device_in, FILE * device_out, bool echo, uint8_t delay) { g_dv_in = device_in; g_dv_out = device_out; g_echo = echo; g_delay = delay; #ifndef UART_PCP_CEILING #define UART_PCP_CEILING 255 #endif slip_tx_sem = nrk_sem_create (1, UART_PCP_CEILING); if (slip_tx_sem == NRK_ERROR) nrk_kernel_error_add (NRK_SEMAPHORE_CREATE_ERROR, nrk_get_pid ()); _slip_started = NRK_OK; return NRK_OK; }
void inline _nrk_scheduler() { int8_t task_ID; uint16_t next_wake; //uint16_t start_time_stamp; /* _nrk_precision_os_timer_reset(); */ /* nrk_int_disable(); */ // this should be removed... Not needed #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 #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; } 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) { // Update CASH and cpu_remaining // First use up any available CASH budget uint8_t ticksToAccountFor = _nrk_prev_timer_val; nrk_budget_t *budgetFromCASH = nrk_peek_budget(); while (ticksToAccountFor > 0 && budgetFromCASH) { // We've found some cash budget uint8_t availableCASH = budgetFromCASH->amount_left; nrk_time_t system_time; nrk_time_get(&system_time); // We need to look at the deadline for the cash budget // If it has passed, we can only use the portion that came before the deadline if (nrk_time_compare(&system_time, &budgetFromCASH->expire_time) == 1) { nrk_time_t difference; nrk_time_sub(&difference, system_time, budgetFromCASH->expire_time); uint8_t differenceInTicks = _nrk_time_to_ticks(&difference); // Check if it expired before we got a chance to use it if (differenceInTicks > ticksToAccountFor) { availableCASH = 0; } else { uint8_t usableBudget = ticksToAccountFor - _nrk_time_to_ticks(&difference); // Take the minimum of available vs usable availableCASH = usableBudget < availableCASH ? usableBudget : availableCASH; } // pop it off the queue. Expired now. nrk_get_budget(); } if (availableCASH > ticksToAccountFor) { budgetFromCASH->amount_left -= ticksToAccountFor; ticksToAccountFor = 0; } else { ticksToAccountFor -= availableCASH; // Pop the now empty cash budget off the queue nrk_get_budget(); } budgetFromCASH = budgetFromCASH->Next; } // If we still have ticks to account for, take them off cpu_remaining if (ticksToAccountFor > 0) { nrk_cur_task_TCB->cpu_remaining -= ticksToAccountFor; } // For finished tasks that still have cpu remaining, give it to the CASH queue if (nrk_cur_task_TCB->task_state==FINISHED && nrk_cur_task_TCB->cpu_remaining > 0) { // Add to CASH queue nrk_add_nrk_budget(nrk_cur_task_TCB->absolute_deadline, nrk_cur_task_TCB->cpu_remaining); } else if (nrk_cur_task_TCB->cpu_remaining ==0 ) { // Support for Constant Bandwith Servers if(nrk_cur_task_TCB->task_type == CBS_TASK) { // Recharge budget nrk_cur_task_TCB->cpu_remaining = nrk_cur_task_TCB->cpu_reserve; // Increase the absolute deadline nrk_time_t increase = _nrk_ticks_to_time(nrk_cur_task_TCB->period); nrk_time_add(&nrk_cur_task_TCB->absolute_deadline, nrk_cur_task_TCB->absolute_deadline, increase); // Remove/re-add from ready queue to re-sort based on new absolute deadline nrk_rem_from_readyQ(nrk_cur_task_TCB->task_ID); nrk_add_to_readyQ(nrk_cur_task_TCB->task_ID); } else { #ifdef NRK_STATS_TRACKER _nrk_stats_add_violation(nrk_cur_task_TCB->task_ID); #endif nrk_kernel_error_add(NRK_RESERVE_VIOLATED,nrk_cur_task_TCB->task_ID); nrk_cur_task_TCB->task_state = SUSPENDED; nrk_rem_from_readyQ(nrk_cur_task_TCB->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]; // 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; 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(); }
/** * isa_init() * * This function sets up the low level link layer parameters. * This starts the main timer routine that will then automatically * trigger whenever a packet might be sent or received. * This should be called before ANY scheduling information is set * since it will clear some default values. * */ uint8_t isa_init (isa_node_mode_t mode, uint8_t id, uint8_t src_id) { uint8_t i; /* Generate signals */ isa_rx_pkt_signal=nrk_signal_create(); if(isa_rx_pkt_signal==NRK_ERROR){ nrk_kprintf(PSTR("ISA ERROR: creating rx signal failed\r\n")); nrk_kernel_error_add(NRK_SIGNAL_CREATE_ERROR,nrk_cur_task_TCB->task_ID); return NRK_ERROR; } isa_tx_done_signal=nrk_signal_create(); if(isa_tx_done_signal==NRK_ERROR){ nrk_kprintf(PSTR("ISA ERROR: creating tx signal failed\r\n")); nrk_kernel_error_add(NRK_SIGNAL_CREATE_ERROR,nrk_cur_task_TCB->task_ID); return NRK_ERROR; } // No buffer to start with isa_rfRxInfo.pPayload = NULL; isa_rfRxInfo.max_length = 0; /*FIXME Actually we dont need to always run the high speed timer */ _nrk_high_speed_timer_start(); /* clear everything out */ global_cycle = 0; global_slot = MAX_ISA_GLOBAL_SLOTS; _isa_sync_ok = 0; _isa_join_ok = 0; slot_expired = 0; isa_node_mode = mode; isa_id = id;//change isa_clk_src_id=src_id; //change isa_rx_data_ready = 0; isa_tx_data_ready = 0; isa_param.mobile_sync_timeout = 100; isa_param.rx_timeout = 8000; // 8000 *.125us = 1ms isa_param.tx_guard_time = TX_GUARD_TIME; isa_param.channel = 15; isa_param.mac_addr = 0x1980; for (i = 0; i < ISA_SLOTS_PER_FRAME; i++) { isa_sched[i] = 0; } isa_tdma_rx_mask = 0; isa_tdma_tx_mask = 0; /* Setup the cc2420 chip */ rf_init (&isa_rfRxInfo, isa_param.channel, 0x2420, isa_param.mac_addr); AFTER_FIRST_SYNC = 1; /* Setup fisrt hopping channel */ #ifdef CHANNEL_HOPPING slowIndex=0; if(id!=0){ channelIndex = src_id; currentChannel = slottedPattern[channelIndex]; }else{ channelIndex = 0; currentChannel = slottedPattern[channelIndex]; } isa_set_channel(currentChannel); #endif #ifdef JOIN_PROCESS if(mode==ISA_GATEWAY){ for(i=22;i<=24;i++){ isa_tx_info[i].pPayload = join_pkt_buf; isa_tx_info[i].length = PKT_DATA_START+1; // pass le pointer isa_tx_info[i].DHDR = configDHDR(); isa_tx_data_ready |= ((uint32_t) 1 << i); // set the flag } } #endif return NRK_OK; }
/** * isa_init() * * This function sets up the low level link layer parameters. * This starts the main timer routine that will then automatically * trigger whenever a packet might be sent or received. * This should be called before ANY scheduling information is set * since it will clear some default values. * */ uint8_t isa_init (isa_node_mode_t mode, uint8_t id) { uint8_t i; /* Generate signals */ isa_rx_pkt_signal=nrk_signal_create(); if(isa_rx_pkt_signal==NRK_ERROR){ nrk_kprintf(PSTR("ISA ERROR: creating rx signal failed\r\n")); nrk_kernel_error_add(NRK_SIGNAL_CREATE_ERROR,nrk_cur_task_TCB->task_ID); return NRK_ERROR; } isa_tx_done_signal=nrk_signal_create(); if(isa_tx_done_signal==NRK_ERROR){ nrk_kprintf(PSTR("ISA ERROR: creating tx signal failed\r\n")); nrk_kernel_error_add(NRK_SIGNAL_CREATE_ERROR,nrk_cur_task_TCB->task_ID); return NRK_ERROR; } // No buffer to start with isa_rfRxInfo.pPayload = NULL; isa_rfRxInfo.max_length = 0; /*FIXME Actually we dont need to always run the high speed timer */ _nrk_high_speed_timer_start(); /* clear everything out */ global_cycle = 0; global_slot = MAX_ISA_GLOBAL_SLOTS; _isa_sync_ok = 0; slot_expired = 0; isa_node_mode = mode; isa_id = id;//change isa_rx_data_ready = 0; isa_tx_data_ready = 0; isa_param.mobile_sync_timeout = 100; isa_param.rx_timeout = 8000; // 8000 *.125us = 1ms isa_param.tx_guard_time = TX_GUARD_TIME; isa_param.channel = 12; isa_param.mac_addr = 0x1980; for (i = 0; i < ISA_SLOTS_PER_FRAME; i++) { isa_sched[i] = 0; } isa_tdma_rx_mask = 0; isa_tdma_tx_mask = 0; /* Setup the cc2420 chip */ rf_init (&isa_rfRxInfo, isa_param.channel, 0x2420, isa_param.mac_addr); AFTER_FIRST_SYNC = 1; /* Setup fisrt hopping channel */ #ifdef CHANNEL_HOPPING if(id!=0){ channelIndex = id-1; currentChannel = channelPattern[channelIndex]; }else{ channelIndex = 0; currentChannel = channelPattern[channelIndex]; } #endif return NRK_OK; }
//------------------------------------------------------------------------------------------------------- // void rf_init(RF_RX_INFO *pRRI, uint8_t channel, WORD panId, WORD myAddr) // // DESCRIPTION: // Initializes CC2420 for radio communication via the basic RF library functions. Turns on the // voltage regulator, resets the CC2420, turns on the crystal oscillator, writes all necessary // registers and protocol addresses (for automatic address recognition). Note that the crystal // oscillator will remain on (forever). // // ARGUMENTS: // RF_RX_INFO *pRRI // A pointer the RF_RX_INFO data structure to be used during the first packet reception. // The structure can be switched upon packet reception. // uint8_t channel // The RF channel to be used (11 = 2405 MHz to 26 = 2480 MHz) // WORD panId // The personal area network identification number // WORD myAddr // The 16-bit short address which is used by this node. Must together with the PAN ID form a // unique 32-bit identifier to avoid addressing conflicts. Normally, in a 802.15.4 network, the // short address will be given to associated nodes by the PAN coordinator. //------------------------------------------------------------------------------------------------------- void rf_init(RF_RX_INFO *pRRI, uint8_t channel, uint16_t panId, uint16_t myAddr) { uint8_t n; #ifdef RADIO_PRIORITY_CEILING int8_t v; radio_sem = nrk_sem_create(1,RADIO_PRIORITY_CEILING); if (radio_sem == NULL) nrk_kernel_error_add (NRK_SEMAPHORE_CREATE_ERROR, nrk_get_pid ()); v = nrk_sem_pend (radio_sem); if (v == NRK_ERROR) { nrk_kprintf (PSTR ("CC2420 ERROR: Access to semaphore failed\r\n")); } #endif // Make sure that the voltage regulator is on, and that the reset pin is inactive SET_VREG_ACTIVE(); halWait(1000); SET_RESET_ACTIVE(); halWait(1); SET_RESET_INACTIVE(); halWait(100); // Initialize the FIFOP external interrupt //FIFOP_INT_INIT(); //ENABLE_FIFOP_INT(); // Turn off all interrupts while we're accessing the CC2420 registers DISABLE_GLOBAL_INT(); FASTSPI_STROBE(CC2420_SXOSCON); mdmctrl0=0x02E2; FASTSPI_SETREG(CC2420_MDMCTRL0, mdmctrl0); // Std Preamble, CRC, no auto ack, no hw addr decoding //FASTSPI_SETREG(CC2420_MDMCTRL0, 0x0AF2); // Turn on automatic packet acknowledgment // Turn on hw addre decoding FASTSPI_SETREG(CC2420_MDMCTRL1, 0x0500); // Set the correlation threshold = 20 FASTSPI_SETREG(CC2420_IOCFG0, 0x007F); // Set the FIFOP threshold to maximum FASTSPI_SETREG(CC2420_SECCTRL0, 0x01C4); // Turn off "Security" FASTSPI_SETREG(CC2420_RXCTRL1, 0x1A56); // All default except // reference bias current to RX // bandpass filter is set to 3uA /* // FIXME: remove later for auto ack myAddr=MY_MAC; panId=0x02; FASTSPI_SETREG(CC2420_MDMCTRL0, 0x0AF2); // Turn on automatic packet acknowledgment // FASTSPI_SETREG(CC2420_MDMCTRL0, 0x0AE2); // Turn on automatic packet acknowledgment nrk_spin_wait_us(500); nrk_spin_wait_us(500); FASTSPI_WRITE_RAM_LE(&myAddr, CC2420RAM_SHORTADDR, 2, n); nrk_spin_wait_us(500); FASTSPI_WRITE_RAM_LE(&panId, CC2420RAM_PANID, 2, n); nrk_spin_wait_us(500); printf( "myAddr=%d\r\n",myAddr ); */ nrk_spin_wait_us(500); FASTSPI_WRITE_RAM_LE(&panId, CC2420RAM_PANID, 2, n); nrk_spin_wait_us(500); ENABLE_GLOBAL_INT(); // Set the RF channel halRfSetChannel(channel); // Turn interrupts back on ENABLE_GLOBAL_INT(); // Set the protocol configuration rfSettings.pRxInfo = pRRI; rfSettings.panId = panId; rfSettings.myAddr = myAddr; rfSettings.txSeqNumber = 0; rfSettings.receiveOn = FALSE; // Wait for the crystal oscillator to become stable halRfWaitForCrystalOscillator(); // Write the short address and the PAN ID to the CC2420 RAM (requires that the XOSC is on and stable) // DISABLE_GLOBAL_INT(); // FASTSPI_WRITE_RAM_LE(&myAddr, CC2420RAM_SHORTADDR, 2, n); // FASTSPI_WRITE_RAM_LE(&panId, CC2420RAM_PANID, 2, n); // ENABLE_GLOBAL_INT(); #ifdef RADIO_PRIORITY_CEILING v = nrk_sem_post (radio_sem); if (v == NRK_ERROR) { nrk_kprintf (PSTR ("CC2420 ERROR: Release of semaphore failed\r\n")); _nrk_errno_set (2); } #endif auto_ack_enable=0; security_enable=0; last_pkt_encrypted=0; } // rf_init()
/** * nrk_init(); * * - Init TCBlist - linked list of empty TCBs * - Init global variables * - Init event list * - Create idle task */ void nrk_init() { uint8_t i; // unsigned char *stkc; nrk_task_type IdleTask; nrk_wakeup_signal = nrk_signal_create(); if(nrk_wakeup_signal==NRK_ERROR) nrk_kernel_error_add(NRK_SIGNAL_CREATE_ERROR,0); //if((volatile)TCCR1B!=0) nrk_kernel_error_add(NRK_STACK_OVERFLOW,0); #ifndef NRK_SOFT_REBOOT_ON_ERROR i=_nrk_startup_error(); if((i&0x1)!=0) nrk_kernel_error_add(NRK_BAD_STARTUP,0); #ifndef IGNORE_EXT_RST_ERROR if((i&0x2)!=0) nrk_kernel_error_add(NRK_EXT_RST_ERROR,0); #endif #ifndef IGNORE_BROWN_OUT_ERROR if((i&0x4)!=0) nrk_kernel_error_add(NRK_BOD_ERROR,0); #endif //if((i&0x8)!=0) nrk_kernel_error_add(NRK_BAD_STARTUP,0); //if(_nrk_startup_ok()==0) nrk_kernel_error_add(NRK_BAD_STARTUP,0); #endif #ifdef NRK_STARTUP_VOLTAGE_CHECK if(nrk_voltage_status()==0) nrk_kernel_error_add(NRK_LOW_VOLTAGE,0); #endif #ifdef NRK_REBOOT_ON_ERROR #ifndef NRK_WATCHDOG while(1) { nrk_kprintf( PSTR("KERNEL CONFIG CONFLICT: NRK_REBOOT_ON_ERROR needs watchdog!\r\n") ); for (i = 0; i < 100; i++) nrk_spin_wait_us (1000); } #endif #endif #ifdef NRK_WATCHDOG if(nrk_watchdog_check()==NRK_ERROR) { nrk_watchdog_disable(); nrk_kernel_error_add(NRK_WATCHDOG_ERROR,0); } nrk_watchdog_enable(); #endif // nrk_stack_pointer_init(); /* #ifdef KERNEL_STK_ARRAY stkc = (uint16_t*)&nrk_kernel_stk[NRK_KERNEL_STACKSIZE-1]; nrk_kernel_stk[0]=STK_CANARY_VAL; nrk_kernel_stk_ptr = &nrk_kernel_stk[NRK_KERNEL_STACKSIZE-1]; #else stkc = NRK_KERNEL_STK_TOP-NRK_KERNEL_STACKSIZE; *stkc = STK_CANARY_VAL; stkc = NRK_KERNEL_STK_TOP; nrk_kernel_stk_ptr = NRK_KERNEL_STK_TOP; #endif *stkc++ = (uint16_t)((uint16_t)_nrk_timer_tick>>8); *stkc = (uint16_t)((uint16_t)_nrk_timer_tick&0xFF); */ // printf( "Init kernel_entry= %d %d\n",kernel_entry[1], kernel_entry[0] ); nrk_cur_task_prio = 0; nrk_cur_task_TCB = NULL; nrk_high_ready_TCB = NULL; nrk_high_ready_prio = 0; #ifdef NRK_STATS_TRACKER nrk_stats_reset(); #endif #ifdef NRK_MAX_RESERVES // Setup the reserve structures _nrk_reserve_init(); #endif _nrk_resource_cnt=0; //NRK_MAX_RESOURCE_CNT; for(i=0;i<NRK_MAX_RESOURCE_CNT;i++) { nrk_sem_list[i].count=-1; nrk_sem_list[i].value=-1; nrk_sem_list[i].resource_ceiling=-1; //nrk_resource_count[i]=-1; //nrk_resource_value[i]=-1; //nrk_resource_ceiling[i]=-1; } for (i= 0; i<NRK_MAX_TASKS; i++) { nrk_task_TCB[i].task_prio = TCB_EMPTY_PRIO; nrk_task_TCB[i].task_ID = -1; } // Setup a double linked list of Ready Tasks for (i=0;i<NRK_MAX_TASKS;i++) { _nrk_readyQ[i].Next = &_nrk_readyQ[i+1]; _nrk_readyQ[i+1].Prev = &_nrk_readyQ[i]; } _nrk_readyQ[0].Prev = NULL; _nrk_readyQ[NRK_MAX_TASKS].Next = NULL; _head_node = NULL; _free_node = &_nrk_readyQ[0]; nrk_task_set_entry_function( &IdleTask, nrk_idle_task); nrk_task_set_stk( &IdleTask, nrk_idle_task_stk, NRK_TASK_IDLE_STK_SIZE); nrk_idle_task_stk[0]=STK_CANARY_VAL; //IdleTask.task_ID = NRK_IDLE_TASK_ID; IdleTask.prio = 0; IdleTask.period.secs = 0; IdleTask.period.nano_secs = 0; IdleTask.cpu_reserve.secs = 0; IdleTask.cpu_reserve.nano_secs = 0; IdleTask.offset.secs = 0; IdleTask.offset.nano_secs = 0; IdleTask.FirstActivation = TRUE; IdleTask.Type = IDLE_TASK; IdleTask.SchType = PREEMPTIVE; nrk_activate_task(&IdleTask); }
int8_t bmac_init (uint8_t chan) { bmac_running=0; tx_reserve=-1; cca_active=true; rx_failure_cnt=0; #ifdef NRK_SW_WDT #ifdef BMAC_SW_WDT_ID _bmac_check_period.secs=30; _bmac_check_period.nano_secs=0; nrk_sw_wdt_init(BMAC_SW_WDT_ID, &_bmac_check_period, NULL ); nrk_sw_wdt_start(BMAC_SW_WDT_ID); #endif #endif _bmac_check_period.secs=0; _bmac_check_period.nano_secs=BMAC_DEFAULT_CHECK_RATE_MS*NANOS_PER_MS; bmac_rx_pkt_signal=nrk_signal_create(); if(bmac_rx_pkt_signal==NRK_ERROR) { nrk_kprintf(PSTR("BMAC ERROR: creating rx signal failed\r\n")); nrk_kernel_error_add(NRK_SIGNAL_CREATE_ERROR,nrk_cur_task_TCB->task_ID); return NRK_ERROR; } bmac_tx_pkt_done_signal=nrk_signal_create(); if(bmac_tx_pkt_done_signal==NRK_ERROR) { nrk_kprintf(PSTR("BMAC ERROR: creating tx signal failed\r\n")); nrk_kernel_error_add(NRK_SIGNAL_CREATE_ERROR,nrk_cur_task_TCB->task_ID); return NRK_ERROR; } bmac_enable_signal=nrk_signal_create(); if(bmac_enable_signal==NRK_ERROR) { nrk_kprintf(PSTR("BMAC ERROR: creating enable signal failed\r\n")); nrk_kernel_error_add(NRK_SIGNAL_CREATE_ERROR,nrk_cur_task_TCB->task_ID); return NRK_ERROR; } tx_data_ready=0; // Set the one main rx buffer rx_buf_empty=0; bmac_rfRxInfo.pPayload = NULL; bmac_rfRxInfo.max_length = 0; // Setup the cc2420 chip rf_init (&bmac_rfRxInfo, chan, 0xffff, 0); g_chan=chan; FASTSPI_SETREG(CC2420_RSSI, 0xE580); // CCA THR=-25 FASTSPI_SETREG(CC2420_TXCTRL, 0x80FF); // TX TURNAROUND = 128 us FASTSPI_SETREG(CC2420_RXCTRL1, 0x0A56); // default cca thresh of -45 //rf_set_cca_thresh(-45); rf_set_cca_thresh(-45); bmac_running=1; is_enabled=1; return NRK_OK; }
void inline _nrk_scheduler() { int8_t task_ID; uint16_t next_wake; uint16_t start_time_stamp; _nrk_precision_os_timer_reset(); nrk_int_disable(); // this should be removed... Not needed #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]; // 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 inline _nrk_scheduler() { int8_t task_ID; uint16_t next_wake; uint16_t start_time_stamp; nrk_int_disable(); // this should be removed... Not needed #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_KERNEL_TEST if(_nrk_cpu_state && _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==2) _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 printf("==============================\r\n"); printf("ENTERING SCHEDULER @ %u \r\n", nrk_system_time.nano_secs); printf("!! Interrupted TID %u after %u.\r\n ", nrk_cur_task_TCB->task_ID, _nrk_prev_timer_val); 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; } 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 printf("< MISS > Deadline Missed for Task %u\r\n",task_ID); 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 printf("xxxxxx >> Deadline Violated for Task %u\r\n",task_ID); 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; nrk_task_TCB[task_ID].abs_deadline += nrk_task_TCB[task_ID].period; 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].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)); 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; } printf("SQueue Contents :\r\n"); printf( "%u. TID %u, CPU Rem %u, CPU Res %u, Period %u, State %u, NW %u, NP %u, AD %u \r\n", task_ID, nrk_task_TCB[task_ID].task_ID, nrk_task_TCB[task_ID].cpu_remaining, nrk_task_TCB[task_ID].cpu_reserve, nrk_task_TCB[task_ID].period, nrk_task_TCB[task_ID].task_state, nrk_task_TCB[task_ID].next_wakeup, nrk_task_TCB[task_ID].next_period, nrk_task_TCB[task_ID].abs_deadline); } } printf(">>> next_wake is @ %u after loop .\r\n", next_wake); #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]; // 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. 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; } } } printf(">>> next_wake CHANGED TO REM_TIME,i.e. %u .\r\n", next_wake); /* // 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); } }*/ //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 _nrk_prev_timer_val = next_wake; if (_nrk_os_timer_get() >= 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==2)) 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 = 0; nrk_queue * printer = _head_node; int j = 0; printf("RQueue Contents :\r\n"); while (printer) { printf( "%u. TID %u, CPU Rem %u, CPU Res %u, Period %u, State %u, NW %u, NP %u, AD %u . \r\n", j, printer->task_ID, nrk_task_TCB[printer->task_ID].cpu_remaining, nrk_task_TCB[printer->task_ID].cpu_reserve, nrk_task_TCB[printer->task_ID].period, nrk_task_TCB[printer->task_ID].task_state, nrk_task_TCB[printer->task_ID].next_wakeup, nrk_task_TCB[printer->task_ID].next_period, nrk_task_TCB[printer->task_ID].abs_deadline); printer = printer->Next; j++; } _nrk_set_next_wakeup(next_wake); printf("Setting TACCR0 to (nw-1) -> %u \r\n", (next_wake - 1)); printf("Starting TID %u \r\n", task_ID); printf("EXITING SCHEDULER\r\n"); printf("==============================\r\n"); _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 nrk_start (void) { int8_t task_ID; uint8_t i,j; // NRK_STK *x; // unsigned char *stkc; /* - Get highest priority task from rdy list - set cur prio and start the task */ // Check to make sure all tasks unique for(i=0; i<NRK_MAX_TASKS; i++ ) { task_ID = nrk_task_TCB[i].task_ID; // only check activated tasks if(task_ID!=-1) { for(j=0; j<NRK_MAX_TASKS; j++ ) { if(i!=j && task_ID==nrk_task_TCB[j].task_ID) { nrk_kernel_error_add(NRK_DUP_TASK_ID,task_ID); //pc.printf("in task error"); } } } } task_ID = nrk_get_high_ready_task_ID(); nrk_high_ready_prio = nrk_task_TCB[task_ID].task_prio; nrk_high_ready_TCB = nrk_cur_task_TCB = &nrk_task_TCB[task_ID]; nrk_cur_task_prio = nrk_high_ready_prio; // nrk_stack_pointer_restore(); /* #ifdef KERNEL_STK_ARRAY stkc = (uint16_t*)&nrk_kernel_stk[NRK_KERNEL_STACKSIZE-1]; #else stkc = NRK_KERNEL_STK_TOP; #endif *stkc++ = (uint16_t)((uint16_t)_nrk_timer_tick>>8); *stkc = (uint16_t)((uint16_t)_nrk_timer_tick&0xFF); //TODO: this way on msp // *stkc++ = (uint16_t)((uint16_t)_nrk_timer_tick&0xFF); // *stkc = (uint16_t)((uint16_t)_nrk_timer_tick>>8); */ nrk_target_start(); //_nrk_setup_timer_test(); //pc.printf("call nrk_foo()\r\n"); //nrk_foo(); nrk_stack_pointer_init(); //nrk_led_set(RED_LED); task_addr = (unsigned int) nrk_task_TCB[task_ID].task_addr; // Abhijeet's statement //pc1.printf("first tcb address:%x",nrk_high_ready_TCB); //NVIC_SetPriority(SVCall_IRQn, 2); //NVIC_SetPriority(TIMER0_IRQn, 1); //NVIC_SetPriority(PendSV_IRQn, 3); nrk_start_high_ready_task(); //_startos(); // you should never get here while(1); }
uint8_t dev_manager_eeg(uint8_t action,uint8_t opt,uint8_t *buffer,uint8_t size) { uint8_t count=0; //TODO: what is this for? // key and value get passed as opt and size uint8_t key=opt; uint8_t value=size; uint16_t val; switch(action) { case INIT: init_eeg(); return 1; case OPEN: if(opt&READ_FLAG) { eeg_adc_fd=nrk_open(ADC_DEV_MANAGER,READ); if(eeg_adc_fd==NRK_ERROR) { nrk_kprintf( "Failed to open ADC driver for EEG\r\n"); return NRK_ERROR; } val=nrk_set_status(eeg_adc_fd,ADC_CHAN,0); if(val==NRK_ERROR) nrk_kprintf( "Failed to set ADC status\r\n"); return NRK_OK; } if(opt&WRITE_FLAG) { return NRK_ERROR; } if(opt&APPEND_FLAG) { return NRK_ERROR; } if((opt&(READ_FLAG|WRITE_FLAG|APPEND_FLAG))==0) return NRK_ERROR; else return NRK_OK; case READ: /* Conversion to 8-bit value*/ val=get_eeg_val(); buffer[count]=val & 0xff; count++; buffer[count]=(val>>8) & 0xff; count++; return count; case CLOSE: EEG_DISABLE(); return NRK_OK; case GET_STATUS: // use "key" here if(key==EEG_CHAN) return eeg_channel; return NRK_ERROR; case SET_STATUS: // use "key" and "value" here switch(key) { case EEG_CHAN: eeg_channel = value; EEG_SET_CHANNEL(eeg_channel); return NRK_OK; case EEG_GAIN: eeg_gain = value; EEG_SET_GAIN(eeg_gain); return NRK_OK; case ECG_GAIN: ecg_gain = value; ECG_SET_GAIN(ecg_gain); return NRK_OK; default: return NRK_ERROR; } default: nrk_kernel_error_add(NRK_DEVICE_DRIVER,0); return 0; } }
void nrk_init() { uint8_t i; // unsigned char *stkc; nrk_task_type IdleTask; nrk_wakeup_signal = nrk_signal_create(); if(nrk_wakeup_signal==NRK_ERROR) nrk_kernel_error_add(NRK_SIGNAL_CREATE_ERROR,0); //if((volatile)TCCR1B!=0) nrk_kernel_error_add(NRK_STACK_OVERFLOW,0); /* if(_nrk_startup_ok()==0) nrk_kernel_error_add(NRK_BAD_STARTUP,0); #ifdef NRK_STARTUP_VOLTAGE_CHECK if(nrk_voltage_status()==0) nrk_kernel_error_add(NRK_LOW_VOLTAGE,0); #endif #ifdef NRK_REBOOT_ON_ERROR #ifndef NRK_WATCHDOG while(1) { nrk_kprintf( PSTR("KERNEL CONFIG CONFLICT: NRK_REBOOT_ON_ERROR needs watchdog!\r\n") ); for (i = 0; i < 100; i++) nrk_spin_wait_us (1000); } #endif #endif #ifdef NRK_WATCHDOG if(nrk_watchdog_check()==NRK_ERROR) { nrk_watchdog_disable(); nrk_kernel_error_add(NRK_WATCHDOG_ERROR,0); } nrk_watchdog_enable(); #endif // nrk_stack_pointer_init(); */ nrk_cur_task_prio = 0; nrk_cur_task_TCB = NULL; nrk_high_ready_TCB = NULL; nrk_high_ready_prio = 0; /* #ifdef NRK_MAX_RESERVES // Setup the reserve structures _nrk_reserve_init(); #endif */ _nrk_resource_cnt=0; //NRK_MAX_RESOURCE_CNT; //PAJA: CHECK THIS for(i=0;i<NRK_MAX_RESOURCE_CNT;i++) { nrk_sem_list[i].count=-1; nrk_sem_list[i].value=-1; nrk_sem_list[i].resource_ceiling=-1; //nrk_resource_count[i]=-1; //nrk_resource_value[i]=-1; //nrk_resource_ceiling[i]=-1; } ////// //PAJA: CHECK THIS ////// for (i= 0; i<NRK_MAX_TASKS_TCB; i++) ////// { ////// nrk_task_TCB[i].task_prio = TCB_EMPTY_PRIO; ////// nrk_task_TCB[i].task_ID = -1; ////// nrk_task_TCB[i].Next = NULL; //PAJA:check this ////// nrk_task_TCB[i].Prev = NULL; ////// } ////// ////// _headTCB = &nrk_task_TCB[0]; ////// _tailTCB = _headTCB; tasksNumber = 1; //idle tasks nrk_task_init_cnt = 1; nrk_task_TCB.task_prio = TCB_EMPTY_PRIO; nrk_task_TCB.task_ID = -1; nrk_task_TCB.Next = NULL; //PAJA:check this nrk_task_TCB.Prev = NULL; _headTCB = &nrk_task_TCB; _tailTCB = _headTCB; // Setup a double linked list of Ready Tasks for (i=0;i<NRK_MAX_TASKS;i++) { _nrk_readyQ[i].Next = &_nrk_readyQ[i+1]; _nrk_readyQ[i+1].Prev = &_nrk_readyQ[i]; } _nrk_readyQ[0].Prev = NULL; _nrk_readyQ[NRK_MAX_TASKS].Next = NULL; _head_node = NULL; _free_node = &_nrk_readyQ[0]; nrk_task_set_entry_function( &IdleTask, (uint32_t)nrk_idle_task); nrk_task_set_stk( &IdleTask, nrk_idle_task_stk, NRK_TASK_IDLE_STK_SIZE); nrk_idle_task_stk[0]=STK_CANARY_VAL; //IdleTask.task_ID = NRK_IDLE_TASK_ID; IdleTask.prio = 0; IdleTask.offset.secs = 0; IdleTask.offset.nano_secs = 0; IdleTask.FirstActivation = TRUE; IdleTask.Type = IDLE_TASK; IdleTask.SchType = PREEMPTIVE; nrk_activate_task(&IdleTask); }