Esempio n. 1
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)
{
	
    //  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;

}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
    }
}
Esempio n. 4
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);
}
Esempio n. 5
0
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;
}
Esempio n. 6
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();

}
Esempio n. 7
0
/**
 * 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;
}
Esempio n. 8
0
/**
 * 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;
}
Esempio n. 9
0
//-------------------------------------------------------------------------------------------------------
//  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()
Esempio n. 10
0
/**
 *  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);
	
}
Esempio n. 11
0
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;
}
Esempio n. 12
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

//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();

}
Esempio n. 13
0
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();

}
Esempio n. 14
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);
                    //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);
}
Esempio n. 15
0
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;
  }
}
Esempio n. 16
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);
    
}