⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msched.c

📁 MANTIS是由科罗拉多大学开发的传感器网络嵌入式操作系统。 这是mantis的0.9.5版本的源码。
💻 C
📖 第 1 页 / 共 2 页
字号:
   SET_SLEEP_OCR_VALUE(time);      // must wait for these bits to be updated on the async clock   WAIT_FOR_ASYNC_UPDATE();   handle_t int_handle = mos_disable_ints();   ENABLE_SLEEP_TIMER();   PRE_KERNEL_SLEEP();      ENABLE_INTS();   SLEEP();      mos_enable_ints(int_handle);   POST_KERNEL_SLEEP();}static void idle_mode(void){   handle_t int_handle;   int_handle = mos_disable_ints();      ENABLE_IDLE();   ENABLE_INTS();   IDLE();      mos_enable_ints(int_handle);}inline static uint8_t decide_power_save_mode(void){   handle_t i;   uint8_t suspend_state;      suspend_state = threads[0].suspend_state;   // pass over idle thread (index 0)   for(i = 1; i < MAX_THREADS; i++) {      if(threads[i].suspend_state < suspend_state) {	 suspend_state = threads[i].suspend_state;	 if(suspend_state == SUSPEND_STATE_IDLE) {	    break;	 }      }   }   // just re-using the index var here   i = mos_disable_ints();   //suspend_state = SUSPEND_STATE_IDLE;   switch(suspend_state) {   case SUSPEND_STATE_SLEEP:      ENABLE_SLEEP();      DISABLE_TSLICE_TIMER();      break;   case SUSPEND_STATE_IDLE:   default:      ENABLE_IDLE();   }   mos_enable_ints(i);   return suspend_state;}inline static uint8_t set_last_sleep_time(thread_t *sleep_thread){   uint32_t st;   uint8_t ocr_val;      st = sleep_thread->st;   if(st > MSECS_MAX_SLEEP) {      ocr_val = 255;      last_sleep_time = MSECS_MAX_SLEEP;   } else {      ocr_val = st / MSECS_PER_SLEEP_TICK;      ocr_val -= ocr_val % SLEEP_TICK_OVERFLOW;      // TODO: what if st is 0 here? (we'll just increment for now)      if(!ocr_val)	 ocr_val++;      last_sleep_time = st;   }   return ocr_val;}/** @brief The idle loop. * * The lowest priority thread (idle thread) runs this loop. * It contains the sleep logic */void idle_loop(void){   thread_t *sleep_thread;   // Do power management, deadlock detection, etc. stuff here...   while(1) {      sleep_thread = mos_tlist_head(&sleepQ);      if(sleep_thread) { //threads on sleep q	 uint8_t ocr_val;	 if(decide_power_save_mode() == SUSPEND_STATE_IDLE) {	    idle_mode();	    continue;	 }	 ocr_val = set_last_sleep_time(sleep_thread);//get ocr val	 kernel_sleep(ocr_val);//sleep for the ocr value      } else { //no sleeping threads	 idle_mode();      }   }}uint8_t mos_thread_new(void (*function_start) (void),		       uint16_t stack_size,		       uint8_t priority){	   stackval_t *stack_addr;   handle_t int_handle;   uint8_t id, i;      int_handle = mos_disable_ints();   for(id = 0; id < MAX_THREADS; id++) {      if(threads[id].state == EMPTY)	 break;   }   if(id == MAX_THREADS) {      mos_enable_ints(int_handle);      return NO_MORE_THREADS;   }     //Allocate memory for the stack space.   stack_addr = mos_mem_alloc(stack_size);   if(stack_addr == NULL) {      mos_enable_ints(int_handle);      return NO_MORE_MEMORY; // Can't continue if we don't have memory   }      // Now save the memory addr and point to the top of the stack.   threads[id].stack = stack_addr;   stack_addr += stack_size - 1;   threads[id].stackSize = stack_size;   threads[id].func = function_start;   threads[id].state = READY; // Init thread state   threads[id].suspend_state = SUSPEND_STATE_IDLE;   threads[id].priority = priority;     CONTEXT_SWITCH_PREAMBLE();      mos_tlist_add(&readyQ[priority], &threads[id]);	     mos_enable_ints(int_handle);   if(running)      dispatcher();      return THREAD_OK;}uint8_t mos_thread_new_havestack(void (*function_start) (void),				 uint16_t stack_size,				 stackval_t* stack_addr,				 uint8_t priority){	   handle_t int_handle;   uint8_t id, i;      int_handle = mos_disable_ints();   for(id = 0; id < MAX_THREADS; id++) {      if(threads[id].state == EMPTY)	 break;   }   if(id == MAX_THREADS) {      mos_enable_ints(int_handle);      return NO_MORE_THREADS;   }     // Stack space is already allocated, but check pointer anyway   if(stack_addr == NULL) {      mos_enable_ints(int_handle);      return NO_MORE_MEMORY; // Can't continue if we don't have memory   }      // Make it look like the stack was allocated from the memory manager.   // This will allow us to free it in case the thread exits.   // (I originally wrote this function to avoid the overhead of the memory   // manager.  But this "overhead" is only six bytes per block.  The real   // usefulness of this function is that we can see the stack during static   // analysis.)   node_t *block = (node_t *)stack_addr;   stack_size -= sizeof(node_t);   stack_addr += sizeof(node_t);   block->size = stack_size;      // Flag the block for debugging, normally memory manager does this   uint16_t j;   for(j = 0; j < stack_size; j++)      stack_addr[j] = 0xEF;      // Now save the memory addr and point to the top of the stack.   threads[id].stack = stack_addr;   stack_addr += stack_size - 1;   threads[id].stackSize = stack_size;   threads[id].func = function_start;   threads[id].state = READY; // Init thread state   threads[id].suspend_state = SUSPEND_STATE_IDLE;   threads[id].priority = priority;     CONTEXT_SWITCH_PREAMBLE();      mos_tlist_add(&readyQ[priority], &threads[id]);	     mos_enable_ints(int_handle);   if(running)      dispatcher();      return THREAD_OK;}/** @brief A wrapper for starting threads so we can guarantee that they are *  de-allocated after completion.  */void start_wrapper(void){   _current_thread->func();      mos_thread_exit();}void mos_thread_exit(void){   uint8_t id;   handle_t int_handle;      int_handle = mos_disable_ints();   // Find the id of the currently running thread   for(id = 0; id < MAX_THREADS; id++) {      if(&threads[id] == _current_thread)	 break;   }   // De-allocate the stack memory and free the thread space   mos_mem_free(threads[id].stack);   threads[id].state = EMPTY;   mos_enable_ints(int_handle);   dispatcher();}/** @brief Sets the timer value to trigger the dispatch function. * * We can't set it to the exact output compare value because * it could get missed so we give it a couple cycles spare time. * * trigger_dispatch() not used  *//*inline void trigger_dispatch(void){   DO_SOFT_INT();}*/#ifdef DEBUG_MEMORY// Print list of allocated threads and their stack usagevoid print_threads(uint8_t verbose){   uint8_t nt = 0;   uint16_t totstack = 0;   uint16_t usestack = 0;   uint8_t ok = 1;      uint8_t i;   for(i = 0; i < MAX_THREADS; i++) {      if(threads[i].state != EMPTY) {	 // check for flag bytes that haven't been clobbered	 uint16_t unused = mos_check_stack(&threads[i]);	 if(verbose)	    printf_P(sThreadRow, i, threads[i].sp, threads[i].stack, 		     threads[i].stackSize, unused, threads[i].state,		     threads[i].priority);	 nt++;	 totstack += threads[i].stackSize;	 usestack += threads[i].sp - threads[i].stack;	 if(threads[i].sp < threads[i].stack) {	    printf_P(sStackOver, i);	    ok = 0;	 }	 if(unused == 0) {	    printf_P(sStackFull, i);	    ok = 0;	 }      }   }   printf_P(sThreadTot, nt, totstack, usestack);}#endifSLEEP_INT_HEADER(){   if(SLEEP_TIMER_EXPIRED)   {      SET_TSLICE_TIMER_VALUE(0);      DISABLE_SLEEP_TIMER();         ENABLE_TSLICE_TIMER();            //we have woken up from sleep, idle thread will call dispatcher      if(running)	 mos_thread_wakeup(last_sleep_time);   }}TSLICE_INT_HEADER(){   static uint16_t sleep_time = 0;   if(TSLICE_TIMER_EXPIRED)   {      //the time slice has gone off, trigger a dispatch      sleep_time += (10 * TIMESLICE_20_MS) / (CLOCK_SPEED_1024 / 100);      if(running) {	 mos_thread_wakeup(sleep_time);	 sleep_time = 0;      }   }}/*SOFT_INT_HEADER(){   //PORTE |= (1 << TRIGGER_INT_BIT);   DISABLE_SOFT_INT();      uint16_t sleep_time;      if (TSLICE_TIMER_VALUE < 8)      sleep_time = 1;   else      sleep_time = (10 * TSLICE_TIMER_VALUE) / (CLOCK_SPEED_1024 / 100);   TSLICE_TIMER_VALUE = 0;   //software interrupt occurred, trigger a dispatch   if(running)      mos_thread_wakeup (sleep_time);}*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -