示例#1
0
文件: nrk.c 项目: prabalsharma/NanoRK
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;

}
示例#2
0
int8_t nrk_TCB_init(nrk_task_type *Task, NRK_STK *ptos, NRK_STK *pbos, uint16_t stk_size, void *pext, uint16_t opt)
//////////NRK_TCB *nrk_TCB_init(nrk_task_type *Task, NRK_STK *ptos, NRK_STK *pbos, uint16_t stk_size, void *pext, uint16_t opt)
{
    NRK_TCB *newTCB;///////////// = malloc(sizeof(NRK_TCB));
	
    //  Already in critical section so no needenter critical section
    if(Task->Type!=IDLE_TASK){
	//check for task id conflict..fix srinivas
    	check_taskID_conflict();
    	Task->task_ID=nrk_task_init_cnt;
    }
    else Task->task_ID=NRK_IDLE_TASK_ID;

//////////    if(nrk_task_init_cnt>=NRK_MAX_TASKS_TCB) nrk_kernel_error_add(NRK_EXTRA_TASK,0);
   // if(tasksNumber>=NRK_MAX_TASKS_ALLOWED) nrk_kernel_error_add(NRK_EXTRA_TASK,0);
    
    if(Task->Type!=IDLE_TASK) {
      nrk_task_init_cnt++; 
      newTCB = &mallocTCBs[tasksNumber-1];//malloc(sizeof(NRK_TCB));
      //newTCB = (NRK_TCB *)nrk_malloc(sizeof(NRK_TCB));
      tasksNumber++;
    }//PAJA:Check, 2 loooks the same, put in the same if part !!!!! optimize
    else {
      newTCB = &nrk_task_TCB;
    }


 
    //initialize member of TCB structure
    
    //Paja: Check this in CS 
//////////    newTCB = &nrk_task_TCB[Task->task_ID];        
    Task->taskTCB = newTCB;
    
    if (Task->Type!=IDLE_TASK) {
    _tailTCB->Next = newTCB;
    newTCB->Prev = _tailTCB;
    newTCB->Next = NULL;
    _tailTCB = newTCB;
    }
    
    newTCB->OSTaskStkPtr = ptos;
    newTCB->task_prio = Task->prio;
    newTCB->task_state = SUSPENDED;
    newTCB->event_suspend=0;//fix srinivas
    newTCB->SchType=Task->SchType;//fix srinivas
    newTCB->task_ID = Task->task_ID;
    newTCB->suspend_flag = 0;
    newTCB->period= _nrk_time_to_ticks( Task->period );
    newTCB->next_wakeup= _nrk_time_to_ticks( Task->offset);
    newTCB->next_period= newTCB->period+newTCB->next_wakeup;
    newTCB->cpu_reserve= _nrk_time_to_ticks(Task->cpu_reserve);
    newTCB->cpu_remaining = newTCB->cpu_reserve;
    newTCB->num_periods = 1;
    newTCB->OSTCBStkBottom = pbos;
    newTCB->errno= NRK_OK;

    return NRK_OK;
//////        return newTCB;
}
示例#3
0
文件: bmac.c 项目: jonleung/AccelPlot
int8_t _bmac_tx()
{
uint8_t v,backoff, backoff_count;
uint16_t b;

#ifdef DEBUG
nrk_kprintf( PSTR("_bmac_tx()\r\n"));
#endif
if(cca_active)
{

// Add random time here to stop nodes from synchronizing with eachother
b=_nrk_time_to_ticks(&_bmac_check_period);
b=b/((rand()%10)+1);
//printf( "waiting %d\r\n",b );
nrk_wait_until_ticks(b);
//nrk_wait_ticks(b);

	backoff_count=1;
	do{
	v=_bmac_channel_check();
	rf_rx_off(); 
	if(v==1) break;
	// Channel is busy
	backoff=rand()%(_b_pow(backoff_count));
			#ifdef DEBUG
			printf( "backoff %d\r\n",backoff );
			#endif
//	printf( "backoff %d\r\n",backoff );
	nrk_wait_until_next_n_periods(backoff);
	backoff_count++;
	if(backoff_count>6) backoff_count=6; // cap it at 64	
	b=_nrk_time_to_ticks(&_bmac_check_period);
	b=b/((rand()%10)+1);
//	printf( "waiting %d\r\n",b );
	nrk_wait_until_ticks(b);
//	nrk_wait_ticks(b);

	} while(v==0);
}

	rf_test_mode();
	rf_carrier_on(); 
	nrk_wait(_bmac_check_period);
	//nrk_wait_until_next_period();
	rf_carrier_off(); 
	rf_data_mode();
	// send packet
	rf_rx_off();
	pkt_got_ack=rf_tx_packet (&bmac_rfTxInfo);
	rf_rx_off(); 	
tx_data_ready=0;
nrk_event_signal (bmac_tx_pkt_done_signal);
return NRK_OK;
}
示例#4
0
文件: bmac.cpp 项目: ESE519/EVM-2013
int8_t _bmac_tx()
{
	uint8_t v,result, backoff, backoff_count;
	uint16_t b;
	
	if(cca_active) {
				// Add random time here to stop nodes from synchronizing with eachother
				b=_nrk_time_to_ticks(&_bmac_check_period);
        b=b/((rand()%10)+1);
				//printf( "waiting %d\r\n",b );
        nrk_wait_until_ticks(b);
				//nrk_wait_ticks(b);

        backoff_count=1;
        do
        {
            v=_bmac_channel_check();
            rf_rx_off();
            if(v==1) break;
            // Channel is busy
            backoff=rand()%(_b_pow(backoff_count));
						
						//	printf( "backoff %d\r\n",backoff );
            nrk_wait_until_next_n_periods(backoff);
            backoff_count++;
            if(backoff_count>6) backoff_count=6; // cap it at 64
            b=_nrk_time_to_ticks(&_bmac_check_period);
            b=b/((rand()%10)+1);
						//	printf( "waiting %d\r\n",b );
            nrk_wait_until_ticks(b);
						//	nrk_wait_ticks(b);
					}
        while(v==0);
    }
	
	// Give check_period worth of channel activity
	rf_test_mode();
	rf_carrier_on();
	nrk_wait(_bmac_check_period);
	rf_carrier_off();
	rf_data_mode();
		
		rf_rx_off();
		pkt_got_ack = rf_tx_packet(&bmac_rfTxInfo);
		rf_rx_off();
		tx_data_ready = 0;
	// Should signal user task here that Tx is done
	return NRK_OK;
}
示例#5
0
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;
}
示例#6
0
文件: nrk_task.c 项目: prashar/nanork
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;
}
示例#7
0
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();

}
示例#8
0
文件: bmac.c 项目: adamselevan/dicio
int8_t _bmac_tx ()
{
  uint8_t v, backoff, backoff_count;
  uint16_t b;

#ifdef DEBUG
  nrk_kprintf (PSTR ("_bmac_tx()\r\n"));
#endif
  if (cca_active) {

// Add random time here to stop nodes from synchronizing with eachother
    b = _nrk_time_to_ticks (&_bmac_check_period);
    b = b / ((rand () % 10) + 1);
//printf( "waiting %d\r\n",b );
    nrk_wait_until_ticks (b);
//nrk_wait_ticks(b);

    backoff_count = 1;
    do {
#ifdef BMAC_MOD_CCA
	v=_bmac_rx();
	v=!v;
        if (v == 1) { 
		break; 
	}
        nrk_event_signal (bmac_rx_pkt_signal);
#else
      v = _bmac_channel_check ();
      if (v == 1)
        break;
#endif
      // Channel is busy
      backoff = rand () % (_b_pow (backoff_count));
#ifdef DEBUG
      printf ("backoff %d\r\n", backoff);
#endif
//      printf( "backoff %d\r\n",backoff );
      nrk_wait_until_next_n_periods (backoff);
      backoff_count++;
      if (backoff_count > 6)
        backoff_count = 6;      // cap it at 64    
      b = _nrk_time_to_ticks (&_bmac_check_period);
      b = b / ((rand () % 10) + 1);
//      printf( "waiting %d\r\n",b );
      nrk_wait_until_ticks (b);
//      nrk_wait_ticks(b);

    }
    while (v == 0);
  }

  // send extended preamble
  bmac_rfTxInfo.cca = 0;
  bmac_rfTxInfo.ackRequest = 0;

  uint16_t ms = _bmac_check_period.secs * 1000;
  ms += _bmac_check_period.nano_secs / 1000000;
  //printf( "CR ms: %u\n",ms );
  //target_t.nano_secs+=20*NANOS_PER_MS;
  rf_rx_on ();
  pkt_got_ack = rf_tx_packet_repeat (&bmac_rfTxInfo, ms);

  // send packet
  // pkt_got_ack=rf_tx_packet (&bmac_rfTxInfo);
  rf_rx_off ();                 // Just in case auto-ack left radio on
  tx_data_ready = 0;
  nrk_event_signal (bmac_tx_pkt_done_signal);
  return NRK_OK;
}